System Calls Need to Adjust the PC Registers


The Mips processor is a "two-stage" pipeline processor; that is, it has 2 program counter registers - PCReg and NextPCReg. The PCReg is for the next instruction to execute and NextPCReg is for the instruction after that. While the processor is executing one instruction, it can simultaneously be preparing the next one to execute.

There is a problem here which is discussed in Narten's guide. The problem is with the program counter registers - PCReg, NextPCReg. The question is how should these registers be adjusted before returning from a system call that simply continues execution of the user thread that made the system call. For a page fault exception, the Mips instruction that caused the page fault will need to be executed again. For a system call, we should not execute the Mips instruction that caused the exception, since it was the syscall instruction, as this would cause an infinite loop of calls.

So the question is whether the PC registers have already been incremented when the syscall is made or not. The answer is that they have not been incremented. So before returning from the Write system call, the PC registers for the calling thread must be incremented properly. Narten provides the code for doing so:

void AdjustPCRegs()
{
  int pc;

  pc = machine->ReadRegister(PCReg);
  machine->WriteRegister(PrevPCReg, pc);
  pc = machine->ReadRegister(NextPCReg);
  machine->WriteRegister(PCReg, pc);
  pc += 4;
  machine->WriteRegister(NextPCReg, pc);
  
}