Core: Have CRegisters::DoAddressError to not directly modify program counter
This commit is contained in:
parent
2d09178449
commit
a5a4873e84
|
@ -134,6 +134,8 @@ void CInterpreterCPU::ExecuteCPU()
|
|||
if ((PROGRAM_COUNTER & 0x3) != 0)
|
||||
{
|
||||
GenerateAddressErrorException((int32_t)JumpToLocation, true);
|
||||
PROGRAM_COUNTER = JumpToLocation;
|
||||
PipelineStage = PIPELINE_STAGE_NORMAL;
|
||||
}
|
||||
else if (CheckTimer)
|
||||
{
|
||||
|
|
|
@ -3045,9 +3045,7 @@ bool R4300iOp::MemoryBreakpoint()
|
|||
|
||||
void R4300iOp::GenerateAddressErrorException(uint64_t VAddr, bool FromRead)
|
||||
{
|
||||
g_Reg->DoAddressError(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP, VAddr, FromRead);
|
||||
g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
|
||||
g_Reg->DoAddressError(VAddr, FromRead);
|
||||
}
|
||||
|
||||
void R4300iOp::GenerateTLBReadException(uint64_t VAddr, const char * function)
|
||||
|
|
|
@ -528,7 +528,7 @@ void CRegisters::CheckInterrupts()
|
|||
}
|
||||
}
|
||||
|
||||
void CRegisters::DoAddressError(bool DelaySlot, uint64_t BadVaddr, bool FromRead)
|
||||
void CRegisters::DoAddressError(uint64_t BadVaddr, bool FromRead)
|
||||
{
|
||||
if (BreakOnAddressError())
|
||||
{
|
||||
|
@ -549,7 +549,7 @@ void CRegisters::DoAddressError(bool DelaySlot, uint64_t BadVaddr, bool FromRead
|
|||
XCONTEXT_REGISTER.BadVPN2 = BadVaddr >> 13;
|
||||
XCONTEXT_REGISTER.R = BadVaddr >> 61;
|
||||
|
||||
if (DelaySlot)
|
||||
if (m_System->m_PipelineStage == PIPELINE_STAGE_JUMP)
|
||||
{
|
||||
CAUSE_REGISTER.BranchDelay = 1;
|
||||
EPC_REGISTER = (int32_t)(m_PROGRAM_COUNTER - 4);
|
||||
|
@ -560,7 +560,8 @@ void CRegisters::DoAddressError(bool DelaySlot, uint64_t BadVaddr, bool FromRead
|
|||
EPC_REGISTER = (int32_t)m_PROGRAM_COUNTER;
|
||||
}
|
||||
STATUS_REGISTER.ExceptionLevel = 1;
|
||||
m_PROGRAM_COUNTER = 0x80000180;
|
||||
m_System->m_JumpToLocation = 0x80000180;
|
||||
m_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
|
||||
}
|
||||
|
||||
void CRegisters::FixFpuLocations()
|
||||
|
|
|
@ -450,7 +450,7 @@ public:
|
|||
CRegisters(CN64System * System, CSystemEvents * SystemEvents);
|
||||
|
||||
void CheckInterrupts();
|
||||
void DoAddressError(bool DelaySlot, uint64_t BadVaddr, bool FromRead);
|
||||
void DoAddressError(uint64_t BadVaddr, bool FromRead);
|
||||
bool DoIntrException();
|
||||
void DoTLBReadMiss(bool DelaySlot, uint64_t BadVaddr);
|
||||
void DoTLBWriteMiss(bool DelaySlot, uint64_t BadVaddr);
|
||||
|
|
|
@ -9659,7 +9659,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
|||
ExitCodeBlock();
|
||||
break;
|
||||
case ExitReason_DoSysCall:
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", InDelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.push(0);
|
||||
m_Assembler.PushImm32("EXC_SYSCALL", EXC_SYSCALL);
|
||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::TriggerException), "CRegisters::TriggerException", 12);
|
||||
|
@ -9669,7 +9669,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
|||
ExitCodeBlock();
|
||||
break;
|
||||
case ExitReason_Break:
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", InDelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.push(0);
|
||||
m_Assembler.PushImm32("EXC_BREAK", EXC_BREAK);
|
||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::TriggerException), "CRegisters::TriggerException", 12);
|
||||
|
@ -9679,7 +9679,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
|||
ExitCodeBlock();
|
||||
break;
|
||||
case ExitReason_COP1Unuseable:
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", InDelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.push(1);
|
||||
m_Assembler.PushImm32("EXC_CPU", EXC_CPU);
|
||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::TriggerException), "CRegisters::TriggerException", 12);
|
||||
|
@ -9707,7 +9707,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
|||
ExitCodeBlock();
|
||||
break;
|
||||
case ExitReason_ExceptionOverflow:
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", InDelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.push(0);
|
||||
m_Assembler.PushImm32("EXC_OV", EXC_OV);
|
||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::TriggerException), "CRegisters::TriggerException", 12);
|
||||
|
@ -9717,28 +9717,34 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
|
|||
ExitCodeBlock();
|
||||
break;
|
||||
case ExitReason_AddressErrorExceptionRead32:
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", InDelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.push(1);
|
||||
m_Assembler.MoveVariableToX86reg(asmjit::x86::edx, &m_TempValue32, "TempValue32");
|
||||
m_Assembler.mov(asmjit::x86::eax, asmjit::x86::edx);
|
||||
m_Assembler.sar(asmjit::x86::eax, 31);
|
||||
m_Assembler.push(asmjit::x86::eax);
|
||||
m_Assembler.push(asmjit::x86::edx);
|
||||
m_Assembler.PushImm32(InDelaySlot ? "true" : "false", InDelaySlot);
|
||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::DoAddressError), "CRegisters::DoAddressError", 12);
|
||||
m_Assembler.MoveVariableToX86reg(asmjit::x86::edx, &g_System->m_JumpToLocation, "System->m_JumpToLocation");
|
||||
m_Assembler.MoveX86regToVariable(&g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER", asmjit::x86::edx);
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->m_PipelineStage", PIPELINE_STAGE_NORMAL);
|
||||
ExitCodeBlock();
|
||||
break;
|
||||
case ExitReason_AddressErrorExceptionRead64:
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", InDelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.push(1);
|
||||
m_Assembler.MoveVariableToX86reg(asmjit::x86::edx, &m_TempValue64, "TempValue64");
|
||||
m_Assembler.MoveVariableToX86reg(asmjit::x86::eax, &m_TempValue64 + 4, "TempValue64+4");
|
||||
m_Assembler.push(asmjit::x86::eax);
|
||||
m_Assembler.push(asmjit::x86::edx);
|
||||
m_Assembler.PushImm32(InDelaySlot ? "true" : "false", InDelaySlot);
|
||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::DoAddressError), "CRegisters::DoAddressError", 12);
|
||||
m_Assembler.MoveVariableToX86reg(asmjit::x86::edx, &g_System->m_JumpToLocation, "System->m_JumpToLocation");
|
||||
m_Assembler.MoveX86regToVariable(&g_Reg->m_PROGRAM_COUNTER, "PROGRAM_COUNTER", asmjit::x86::edx);
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "g_System->m_PipelineStage", PIPELINE_STAGE_NORMAL);
|
||||
ExitCodeBlock();
|
||||
break;
|
||||
case ExitReason_IllegalInstruction:
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.MoveConstToVariable(&g_System->m_PipelineStage, "System->m_PipelineStage", InDelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
|
||||
m_Assembler.push(0);
|
||||
m_Assembler.PushImm32("EXC_II", EXC_II);
|
||||
m_Assembler.CallThis((uint32_t)g_Reg, AddressOf(&CRegisters::TriggerException), "CRegisters::TriggerException", 12);
|
||||
|
|
Loading…
Reference in New Issue