Core: Change NextInstruction to PipelineStage

This commit is contained in:
zilmar 2022-01-18 18:17:21 +10:30
parent de0a59ac54
commit 7fd239cf82
18 changed files with 561 additions and 584 deletions

View File

@ -215,8 +215,6 @@ bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2)
void CInterpreterCPU::BuildCPU() void CInterpreterCPU::BuildCPU()
{ {
R4300iOp::m_TestTimer = false; R4300iOp::m_TestTimer = false;
R4300iOp::m_NextInstruction = NORMAL;
R4300iOp::m_JumpToLocation = 0;
if (g_Settings->LoadBool(Game_32Bit)) if (g_Settings->LoadBool(Game_32Bit))
{ {
@ -230,12 +228,6 @@ void CInterpreterCPU::BuildCPU()
void CInterpreterCPU::InPermLoop() void CInterpreterCPU::InPermLoop()
{ {
// Changed
//if (CPU_Type == CPU_SyncCores)
//{
// SyncRegisters.CP0[9] +=5;
//}
// Interrupts enabled // Interrupts enabled
if ((g_Reg->STATUS_REGISTER & STATUS_IE) == 0 || if ((g_Reg->STATUS_REGISTER & STATUS_IE) == 0 ||
(g_Reg->STATUS_REGISTER & STATUS_EXL) != 0 || (g_Reg->STATUS_REGISTER & STATUS_EXL) != 0 ||
@ -267,9 +259,10 @@ void CInterpreterCPU::ExecuteCPU()
WriteTrace(TraceN64System, TraceDebug, "Start"); WriteTrace(TraceN64System, TraceDebug, "Start");
bool & Done = g_System->m_EndEmulation; bool & Done = g_System->m_EndEmulation;
PIPELINE_STAGE & PipelineStage = g_System->m_PipelineStage;
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER; uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
OPCODE & Opcode = R4300iOp::m_Opcode; OPCODE & Opcode = R4300iOp::m_Opcode;
uint32_t & JumpToLocation = R4300iOp::m_JumpToLocation; uint32_t & JumpToLocation = g_System->m_JumpToLocation;
bool & TestTimer = R4300iOp::m_TestTimer; bool & TestTimer = R4300iOp::m_TestTimer;
const int32_t & bDoSomething = g_SystemEvents->DoSomething(); const int32_t & bDoSomething = g_SystemEvents->DoSomething();
uint32_t CountPerOp = g_System->CountPerOp(); uint32_t CountPerOp = g_System->CountPerOp();
@ -282,8 +275,8 @@ void CInterpreterCPU::ExecuteCPU()
{ {
if (!g_MMU->LW_VAddr(PROGRAM_COUNTER, Opcode.Hex)) if (!g_MMU->LW_VAddr(PROGRAM_COUNTER, Opcode.Hex))
{ {
g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP, PROGRAM_COUNTER); g_Reg->DoTLBReadMiss(PipelineStage == PIPELINE_STAGE_JUMP, PROGRAM_COUNTER);
R4300iOp::m_NextInstruction = NORMAL; PipelineStage = PIPELINE_STAGE_NORMAL;
continue; continue;
} }
@ -326,20 +319,20 @@ void CInterpreterCPU::ExecuteCPU()
if (CDebugSettings::HaveDebugger()) { g_Debugger->CPUStepEnded(); } if (CDebugSettings::HaveDebugger()) { g_Debugger->CPUStepEnded(); }
PROGRAM_COUNTER += 4; PROGRAM_COUNTER += 4;
switch (R4300iOp::m_NextInstruction) switch (PipelineStage)
{ {
case NORMAL: case PIPELINE_STAGE_NORMAL:
break; break;
case DELAY_SLOT: case PIPELINE_STAGE_DELAY_SLOT:
R4300iOp::m_NextInstruction = JUMP; PipelineStage = PIPELINE_STAGE_JUMP;
break; break;
case PERMLOOP_DO_DELAY: case PIPELINE_STAGE_PERMLOOP_DO_DELAY:
R4300iOp::m_NextInstruction = PERMLOOP_DELAY_DONE; PipelineStage = PIPELINE_STAGE_PERMLOOP_DELAY_DONE;
break; break;
case JUMP: case PIPELINE_STAGE_JUMP:
CheckTimer = (JumpToLocation < PROGRAM_COUNTER - 4 || TestTimer); CheckTimer = (JumpToLocation < PROGRAM_COUNTER - 4 || TestTimer);
PROGRAM_COUNTER = JumpToLocation; PROGRAM_COUNTER = JumpToLocation;
R4300iOp::m_NextInstruction = NORMAL; PipelineStage = PIPELINE_STAGE_NORMAL;
if (CheckTimer) if (CheckTimer)
{ {
TestTimer = false; TestTimer = false;
@ -353,9 +346,9 @@ void CInterpreterCPU::ExecuteCPU()
} }
} }
break; break;
case PERMLOOP_DELAY_DONE: case PIPELINE_STAGE_PERMLOOP_DELAY_DONE:
PROGRAM_COUNTER = JumpToLocation; PROGRAM_COUNTER = JumpToLocation;
R4300iOp::m_NextInstruction = NORMAL; PipelineStage = PIPELINE_STAGE_NORMAL;
CInterpreterCPU::InPermLoop(); CInterpreterCPU::InPermLoop();
g_SystemTimer->TimerDone(); g_SystemTimer->TimerDone();
if (bDoSomething) if (bDoSomething)
@ -380,7 +373,8 @@ void CInterpreterCPU::ExecuteOps(int32_t Cycles)
bool & Done = g_System->m_EndEmulation; bool & Done = g_System->m_EndEmulation;
uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER; uint32_t & PROGRAM_COUNTER = *_PROGRAM_COUNTER;
OPCODE & Opcode = R4300iOp::m_Opcode; OPCODE & Opcode = R4300iOp::m_Opcode;
uint32_t & JumpToLocation = R4300iOp::m_JumpToLocation; PIPELINE_STAGE & PipelineStage = g_System->m_PipelineStage;
uint32_t & JumpToLocation = g_System->m_JumpToLocation;
bool & TestTimer = R4300iOp::m_TestTimer; bool & TestTimer = R4300iOp::m_TestTimer;
const int32_t & DoSomething = g_SystemEvents->DoSomething(); const int32_t & DoSomething = g_SystemEvents->DoSomething();
uint32_t CountPerOp = g_System->CountPerOp(); uint32_t CountPerOp = g_System->CountPerOp();
@ -426,23 +420,23 @@ void CInterpreterCPU::ExecuteOps(int32_t Cycles)
} }
}*/ }*/
switch (R4300iOp::m_NextInstruction) switch (PipelineStage)
{ {
case NORMAL: case PIPELINE_STAGE_NORMAL:
PROGRAM_COUNTER += 4; PROGRAM_COUNTER += 4;
break; break;
case DELAY_SLOT: case PIPELINE_STAGE_DELAY_SLOT:
R4300iOp::m_NextInstruction = JUMP; PipelineStage = PIPELINE_STAGE_JUMP;
PROGRAM_COUNTER += 4; PROGRAM_COUNTER += 4;
break; break;
case PERMLOOP_DO_DELAY: case PIPELINE_STAGE_PERMLOOP_DO_DELAY:
R4300iOp::m_NextInstruction = PERMLOOP_DELAY_DONE; PipelineStage = PIPELINE_STAGE_PERMLOOP_DELAY_DONE;
PROGRAM_COUNTER += 4; PROGRAM_COUNTER += 4;
break; break;
case JUMP: case PIPELINE_STAGE_JUMP:
CheckTimer = (JumpToLocation < PROGRAM_COUNTER || TestTimer); CheckTimer = (JumpToLocation < PROGRAM_COUNTER || TestTimer);
PROGRAM_COUNTER = JumpToLocation; PROGRAM_COUNTER = JumpToLocation;
R4300iOp::m_NextInstruction = NORMAL; PipelineStage = PIPELINE_STAGE_NORMAL;
if (CheckTimer) if (CheckTimer)
{ {
TestTimer = false; TestTimer = false;
@ -456,9 +450,9 @@ void CInterpreterCPU::ExecuteOps(int32_t Cycles)
} }
} }
break; break;
case PERMLOOP_DELAY_DONE: case PIPELINE_STAGE_PERMLOOP_DELAY_DONE:
PROGRAM_COUNTER = JumpToLocation; PROGRAM_COUNTER = JumpToLocation;
R4300iOp::m_NextInstruction = NORMAL; PipelineStage = PIPELINE_STAGE_NORMAL;
CInterpreterCPU::InPermLoop(); CInterpreterCPU::InPermLoop();
g_SystemTimer->TimerDone(); g_SystemTimer->TimerDone();
if (DoSomething) if (DoSomething)
@ -472,8 +466,8 @@ void CInterpreterCPU::ExecuteOps(int32_t Cycles)
} }
else else
{ {
g_Reg->DoTLBReadMiss(R4300iOp::m_NextInstruction == JUMP, PROGRAM_COUNTER); g_Reg->DoTLBReadMiss(PipelineStage == PIPELINE_STAGE_JUMP, PROGRAM_COUNTER);
R4300iOp::m_NextInstruction = NORMAL; PipelineStage = PIPELINE_STAGE_NORMAL;
} }
} }
} }

View File

@ -24,13 +24,8 @@ float truncf(float num)
} }
#endif #endif
void InPermLoop();
void TestInterpreterJump(uint32_t PC, uint32_t TargetPC, int32_t Reg1, int32_t Reg2);
bool R4300iOp::m_TestTimer = false; bool R4300iOp::m_TestTimer = false;
uint32_t R4300iOp::m_NextInstruction;
OPCODE R4300iOp::m_Opcode; OPCODE R4300iOp::m_Opcode;
uint32_t R4300iOp::m_JumpToLocation;
R4300iOp::Func R4300iOp::Jump_Opcode[64]; R4300iOp::Func R4300iOp::Jump_Opcode[64];
R4300iOp::Func R4300iOp::Jump_Special[64]; R4300iOp::Func R4300iOp::Jump_Special[64];
@ -55,28 +50,28 @@ const int32_t R4300iOp::LWL_SHIFT[4] = { 0, 8, 16, 24 };
const int32_t R4300iOp::LWR_SHIFT[4] = { 24, 16, 8, 0 }; const int32_t R4300iOp::LWR_SHIFT[4] = { 24, 16, 8, 0 };
#define ADDRESS_ERROR_EXCEPTION(Address,FromRead) \ #define ADDRESS_ERROR_EXCEPTION(Address,FromRead) \
g_Reg->DoAddressError(m_NextInstruction == JUMP,Address,FromRead);\ g_Reg->DoAddressError(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address,FromRead);\
m_NextInstruction = JUMP;\ g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
m_JumpToLocation = (*_PROGRAM_COUNTER);\ g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return; return;
#define TEST_COP1_USABLE_EXCEPTION() \ #define TEST_COP1_USABLE_EXCEPTION() \
if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) {\ if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) {\
g_Reg->DoCopUnusableException(m_NextInstruction == JUMP,1);\ g_Reg->DoCopUnusableException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,1);\
m_NextInstruction = JUMP;\ g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
m_JumpToLocation = (*_PROGRAM_COUNTER);\ g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;}\ return;}\
#define TLB_READ_EXCEPTION(Address) \ #define TLB_READ_EXCEPTION(Address) \
g_Reg->DoTLBReadMiss(m_NextInstruction == JUMP,Address);\ g_Reg->DoTLBReadMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address);\
m_NextInstruction = JUMP;\ g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
m_JumpToLocation = (*_PROGRAM_COUNTER);\ g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return; return;
#define TLB_WRITE_EXCEPTION(Address) \ #define TLB_WRITE_EXCEPTION(Address) \
g_Reg->DoTLBWriteMiss(m_NextInstruction == JUMP,Address);\ g_Reg->DoTLBWriteMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address);\
m_NextInstruction = JUMP;\ g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
m_JumpToLocation = (*_PROGRAM_COUNTER);\ g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return; return;
void R4300iOp::SPECIAL() void R4300iOp::SPECIAL()
@ -725,121 +720,107 @@ R4300iOp::Func * R4300iOp::BuildInterpreter()
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
void TestInterpreterJump(uint32_t PC, uint32_t TargetPC, int32_t Reg1, int32_t Reg2)
{
if (PC != TargetPC)
{
return;
}
if (DelaySlotEffectsCompare(PC, Reg1, Reg2))
{
return;
}
R4300iOp::m_NextInstruction = PERMLOOP_DO_DELAY;
R4300iOp::m_TestTimer = true;
}
// Opcode functions // Opcode functions
void R4300iOp::J() void R4300iOp::J()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2); g_System->m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
void R4300iOp::JAL() void R4300iOp::JAL()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2); g_System->m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2);
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
void R4300iOp::BEQ() void R4300iOp::BEQ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW) if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp::BNE() void R4300iOp::BNE()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW) if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp::BLEZ() void R4300iOp::BLEZ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW <= 0) if (_GPR[m_Opcode.rs].DW <= 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp::BGTZ() void R4300iOp::BGTZ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW > 0) if (_GPR[m_Opcode.rs].DW > 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -928,20 +909,20 @@ void R4300iOp::BEQL()
{ {
if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW) if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -949,20 +930,20 @@ void R4300iOp::BNEL()
{ {
if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW) if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -970,20 +951,20 @@ void R4300iOp::BLEZL()
{ {
if (_GPR[m_Opcode.rs].DW <= 0) if (_GPR[m_Opcode.rs].DW <= 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -991,20 +972,20 @@ void R4300iOp::BGTZL()
{ {
if (_GPR[m_Opcode.rs].DW > 0) if (_GPR[m_Opcode.rs].DW > 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -1722,31 +1703,31 @@ void R4300iOp::SPECIAL_SRAV()
void R4300iOp::SPECIAL_JR() void R4300iOp::SPECIAL_JR()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = _GPR[m_Opcode.rs].UW[0]; g_System->m_JumpToLocation = _GPR[m_Opcode.rs].UW[0];
m_TestTimer = true; m_TestTimer = true;
} }
void R4300iOp::SPECIAL_JALR() void R4300iOp::SPECIAL_JALR()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = _GPR[m_Opcode.rs].UW[0]; g_System->m_JumpToLocation = _GPR[m_Opcode.rs].UW[0];
_GPR[m_Opcode.rd].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[m_Opcode.rd].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
m_TestTimer = true; m_TestTimer = true;
} }
void R4300iOp::SPECIAL_SYSCALL() void R4300iOp::SPECIAL_SYSCALL()
{ {
g_Reg->DoSysCallException(m_NextInstruction == JUMP); g_Reg->DoSysCallException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER); g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
} }
void R4300iOp::SPECIAL_BREAK() void R4300iOp::SPECIAL_BREAK()
{ {
g_Reg->DoBreakException(m_NextInstruction == JUMP); g_Reg->DoBreakException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER); g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);
} }
void R4300iOp::SPECIAL_SYNC() void R4300iOp::SPECIAL_SYNC()
@ -1992,7 +1973,7 @@ void R4300iOp::SPECIAL_TEQ()
{ {
if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW) if (_GPR[m_Opcode.rs].DW == _GPR[m_Opcode.rt].DW)
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2000,7 +1981,7 @@ void R4300iOp::SPECIAL_TGE()
{ {
if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW) if (_GPR[m_Opcode.rs].DW >= _GPR[m_Opcode.rt].DW)
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2008,7 +1989,7 @@ void R4300iOp::SPECIAL_TGEU()
{ {
if (_GPR[m_Opcode.rs].UDW >= _GPR[m_Opcode.rt].UDW) if (_GPR[m_Opcode.rs].UDW >= _GPR[m_Opcode.rt].UDW)
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2016,7 +1997,7 @@ void R4300iOp::SPECIAL_TLT()
{ {
if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW) if (_GPR[m_Opcode.rs].DW < _GPR[m_Opcode.rt].DW)
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2024,7 +2005,7 @@ void R4300iOp::SPECIAL_TLTU()
{ {
if (_GPR[m_Opcode.rs].UDW < _GPR[m_Opcode.rt].UDW) if (_GPR[m_Opcode.rs].UDW < _GPR[m_Opcode.rt].UDW)
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2032,7 +2013,7 @@ void R4300iOp::SPECIAL_TNE()
{ {
if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW) if (_GPR[m_Opcode.rs].DW != _GPR[m_Opcode.rt].DW)
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2070,11 +2051,11 @@ void R4300iOp::SPECIAL_DSRA32()
void R4300iOp::REGIMM_BLTZ() void R4300iOp::REGIMM_BLTZ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW < 0) if (_GPR[m_Opcode.rs].DW < 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -2084,17 +2065,17 @@ void R4300iOp::REGIMM_BLTZ()
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp::REGIMM_BGEZ() void R4300iOp::REGIMM_BGEZ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW >= 0) if (_GPR[m_Opcode.rs].DW >= 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -2104,7 +2085,7 @@ void R4300iOp::REGIMM_BGEZ()
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -2112,9 +2093,9 @@ void R4300iOp::REGIMM_BLTZL()
{ {
if (_GPR[m_Opcode.rs].DW < 0) if (_GPR[m_Opcode.rs].DW < 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -2124,8 +2105,8 @@ void R4300iOp::REGIMM_BLTZL()
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -2133,9 +2114,9 @@ void R4300iOp::REGIMM_BGEZL()
{ {
if (_GPR[m_Opcode.rs].DW >= 0) if (_GPR[m_Opcode.rs].DW >= 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -2145,18 +2126,18 @@ void R4300iOp::REGIMM_BGEZL()
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp::REGIMM_BLTZAL() void R4300iOp::REGIMM_BLTZAL()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW < 0) if (_GPR[m_Opcode.rs].DW < 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -2166,18 +2147,18 @@ void R4300iOp::REGIMM_BLTZAL()
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
} }
void R4300iOp::REGIMM_BGEZAL() void R4300iOp::REGIMM_BGEZAL()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].DW >= 0) if (_GPR[m_Opcode.rs].DW >= 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (CDebugSettings::HaveDebugger()) if (CDebugSettings::HaveDebugger())
{ {
@ -2185,9 +2166,9 @@ void R4300iOp::REGIMM_BGEZAL()
{ {
// Break out of possible checksum halt // Break out of possible checksum halt
g_Notify->DisplayMessage(5, "Broke out of permanent loop! Invalid checksum?"); g_Notify->DisplayMessage(5, "Broke out of permanent loop! Invalid checksum?");
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
R4300iOp::m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
return; return;
} }
} }
@ -2199,7 +2180,7 @@ void R4300iOp::REGIMM_BGEZAL()
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
} }
@ -2208,7 +2189,7 @@ void R4300iOp::REGIMM_TEQI()
{ {
if (_GPR[m_Opcode.rs].DW == (int64_t)((int16_t)m_Opcode.immediate)) if (_GPR[m_Opcode.rs].DW == (int64_t)((int16_t)m_Opcode.immediate))
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2216,7 +2197,7 @@ void R4300iOp::REGIMM_TGEI()
{ {
if (_GPR[m_Opcode.rs].DW >= (int64_t)((int16_t)m_Opcode.immediate)) if (_GPR[m_Opcode.rs].DW >= (int64_t)((int16_t)m_Opcode.immediate))
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2228,7 +2209,7 @@ void R4300iOp::REGIMM_TGEIU()
imm64 = imm32; imm64 = imm32;
if (_GPR[m_Opcode.rs].UDW >= (uint64_t)imm64) if (_GPR[m_Opcode.rs].UDW >= (uint64_t)imm64)
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2236,7 +2217,7 @@ void R4300iOp::REGIMM_TLTI()
{ {
if (_GPR[m_Opcode.rs].DW < (int64_t)((int16_t)m_Opcode.immediate)) if (_GPR[m_Opcode.rs].DW < (int64_t)((int16_t)m_Opcode.immediate))
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2248,7 +2229,7 @@ void R4300iOp::REGIMM_TLTIU()
imm64 = imm32; imm64 = imm32;
if (_GPR[m_Opcode.rs].UDW < (uint64_t)imm64) if (_GPR[m_Opcode.rs].UDW < (uint64_t)imm64)
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2256,7 +2237,7 @@ void R4300iOp::REGIMM_TNEI()
{ {
if (_GPR[m_Opcode.rs].DW != (int64_t)((int16_t)m_Opcode.immediate)) if (_GPR[m_Opcode.rs].DW != (int64_t)((int16_t)m_Opcode.immediate))
{ {
g_Reg->DoTrapException(m_NextInstruction == JUMP); g_Reg->DoTrapException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP);
} }
} }
@ -2373,15 +2354,15 @@ void R4300iOp::COP0_CO_TLBP()
void R4300iOp::COP0_CO_ERET() void R4300iOp::COP0_CO_ERET()
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
if ((g_Reg->STATUS_REGISTER & STATUS_ERL) != 0) if ((g_Reg->STATUS_REGISTER & STATUS_ERL) != 0)
{ {
m_JumpToLocation = g_Reg->ERROREPC_REGISTER; g_System->m_JumpToLocation = g_Reg->ERROREPC_REGISTER;
g_Reg->STATUS_REGISTER &= ~STATUS_ERL; g_Reg->STATUS_REGISTER &= ~STATUS_ERL;
} }
else else
{ {
m_JumpToLocation = g_Reg->EPC_REGISTER; g_System->m_JumpToLocation = g_Reg->EPC_REGISTER;
g_Reg->STATUS_REGISTER &= ~STATUS_EXL; g_Reg->STATUS_REGISTER &= ~STATUS_EXL;
} }
(*_LLBit) = 0; (*_LLBit) = 0;
@ -2455,28 +2436,28 @@ void R4300iOp::COP1_CT()
void R4300iOp::COP1_BCF() void R4300iOp::COP1_BCF()
{ {
TEST_COP1_USABLE_EXCEPTION(); TEST_COP1_USABLE_EXCEPTION();
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if ((_FPCR[31] & FPCSR_C) == 0) if ((_FPCR[31] & FPCSR_C) == 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp::COP1_BCT() void R4300iOp::COP1_BCT()
{ {
TEST_COP1_USABLE_EXCEPTION(); TEST_COP1_USABLE_EXCEPTION();
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if ((_FPCR[31] & FPCSR_C) != 0) if ((_FPCR[31] & FPCSR_C) != 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -2485,13 +2466,13 @@ void R4300iOp::COP1_BCFL()
TEST_COP1_USABLE_EXCEPTION(); TEST_COP1_USABLE_EXCEPTION();
if ((_FPCR[31] & FPCSR_C) == 0) if ((_FPCR[31] & FPCSR_C) == 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -2500,13 +2481,13 @@ void R4300iOp::COP1_BCTL()
TEST_COP1_USABLE_EXCEPTION(); TEST_COP1_USABLE_EXCEPTION();
if ((_FPCR[31] & FPCSR_C) != 0) if ((_FPCR[31] & FPCSR_C) != 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }

View File

@ -210,9 +210,7 @@ public:
static Func* BuildInterpreter(); static Func* BuildInterpreter();
static bool m_TestTimer; static bool m_TestTimer;
static uint32_t m_NextInstruction;
static OPCODE m_Opcode; static OPCODE m_Opcode;
static uint32_t m_JumpToLocation;
static bool MemoryBreakpoint(); static bool MemoryBreakpoint();

View File

@ -1,6 +1,7 @@
#include "stdafx.h" #include "stdafx.h"
#include "InterpreterOps32.h" #include "InterpreterOps32.h"
#include <Project64-core/N64System/SystemGlobals.h> #include <Project64-core/N64System/SystemGlobals.h>
#include <Project64-core/N64System/N64System.h>
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h> #include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
#include <Project64-core/N64System/Mips/SystemTiming.h> #include <Project64-core/N64System/Mips/SystemTiming.h>
#include <Project64-core/N64System/Interpreter/InterpreterCPU.h> #include <Project64-core/N64System/Interpreter/InterpreterCPU.h>
@ -10,24 +11,23 @@
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2); bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
#define ADDRESS_ERROR_EXCEPTION(Address,FromRead) \ #define ADDRESS_ERROR_EXCEPTION(Address,FromRead) \
g_Reg->DoAddressError(m_NextInstruction == JUMP,Address,FromRead);\ g_Reg->DoAddressError(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address,FromRead);\
m_NextInstruction = JUMP;\ g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
m_JumpToLocation = (*_PROGRAM_COUNTER);\ g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return; return;
//#define TEST_COP1_USABLE_EXCEPTION
#define TEST_COP1_USABLE_EXCEPTION \ #define TEST_COP1_USABLE_EXCEPTION \
if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) {\ if ((g_Reg->STATUS_REGISTER & STATUS_CU1) == 0) {\
g_Reg->DoCopUnusableException(m_NextInstruction == JUMP,1);\ g_Reg->DoCopUnusableException(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,1);\
m_NextInstruction = JUMP;\ g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
m_JumpToLocation = (*_PROGRAM_COUNTER);\ g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return;\ return;\
} }
#define TLB_READ_EXCEPTION(Address) \ #define TLB_READ_EXCEPTION(Address) \
g_Reg->DoTLBReadMiss(m_NextInstruction == JUMP,Address);\ g_Reg->DoTLBReadMiss(g_System->m_PipelineStage == PIPELINE_STAGE_JUMP,Address);\
m_NextInstruction = JUMP;\ g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;\
m_JumpToLocation = (*_PROGRAM_COUNTER);\ g_System->m_JumpToLocation = (*_PROGRAM_COUNTER);\
return; return;
R4300iOp32::Func * R4300iOp32::BuildInterpreter() R4300iOp32::Func * R4300iOp32::BuildInterpreter()
@ -626,92 +626,93 @@ R4300iOp32::Func * R4300iOp32::BuildInterpreter()
void R4300iOp32::JAL() void R4300iOp32::JAL()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2); g_System->m_JumpToLocation = ((*_PROGRAM_COUNTER) & 0xF0000000) + (m_Opcode.target << 2);
_GPR[31].UW[0] = (*_PROGRAM_COUNTER) + 8; _GPR[31].UW[0] = (*_PROGRAM_COUNTER) + 8;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
void R4300iOp32::BEQ() void R4300iOp32::BEQ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0]) if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0])
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BNE() void R4300iOp32::BNE()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0]) if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0])
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BLEZ() { void R4300iOp32::BLEZ()
m_NextInstruction = DELAY_SLOT; {
g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] <= 0) if (_GPR[m_Opcode.rs].W[0] <= 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::BGTZ() void R4300iOp32::BGTZ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] > 0) if (_GPR[m_Opcode.rs].W[0] > 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -800,20 +801,20 @@ void R4300iOp32::BEQL()
{ {
if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0]) if (_GPR[m_Opcode.rs].W[0] == _GPR[m_Opcode.rt].W[0])
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -821,20 +822,20 @@ void R4300iOp32::BNEL()
{ {
if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0]) if (_GPR[m_Opcode.rs].W[0] != _GPR[m_Opcode.rt].W[0])
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, m_Opcode.rt))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -842,20 +843,20 @@ void R4300iOp32::BLEZL()
{ {
if (_GPR[m_Opcode.rs].W[0] <= 0) if (_GPR[m_Opcode.rs].W[0] <= 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -863,20 +864,20 @@ void R4300iOp32::BGTZL()
{ {
if (_GPR[m_Opcode.rs].W[0] > 0) if (_GPR[m_Opcode.rs].W[0] > 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare(*_PROGRAM_COUNTER, m_Opcode.rs, 0))
{ {
m_NextInstruction = PERMLOOP_DO_DELAY; g_System->m_PipelineStage = PIPELINE_STAGE_PERMLOOP_DO_DELAY;
} }
} }
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -1138,8 +1139,8 @@ void R4300iOp32::SPECIAL_SRAV()
void R4300iOp32::SPECIAL_JALR() void R4300iOp32::SPECIAL_JALR()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = _GPR[m_Opcode.rs].UW[0]; g_System->m_JumpToLocation = _GPR[m_Opcode.rs].UW[0];
_GPR[m_Opcode.rd].W[0] = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[m_Opcode.rd].W[0] = (int32_t)((*_PROGRAM_COUNTER) + 8);
m_TestTimer = true; m_TestTimer = true;
} }
@ -1221,11 +1222,11 @@ void R4300iOp32::SPECIAL_TEQ()
void R4300iOp32::REGIMM_BLTZ() void R4300iOp32::REGIMM_BLTZ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] < 0) if (_GPR[m_Opcode.rs].W[0] < 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -1235,17 +1236,17 @@ void R4300iOp32::REGIMM_BLTZ()
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::REGIMM_BGEZ() void R4300iOp32::REGIMM_BGEZ()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] >= 0) if (_GPR[m_Opcode.rs].W[0] >= 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -1255,7 +1256,7 @@ void R4300iOp32::REGIMM_BGEZ()
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -1263,9 +1264,9 @@ void R4300iOp32::REGIMM_BLTZL()
{ {
if (_GPR[m_Opcode.rs].W[0] < 0) if (_GPR[m_Opcode.rs].W[0] < 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -1275,8 +1276,8 @@ void R4300iOp32::REGIMM_BLTZL()
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
@ -1284,9 +1285,9 @@ void R4300iOp32::REGIMM_BGEZL()
{ {
if (_GPR[m_Opcode.rs].W[0] >= 0) if (_GPR[m_Opcode.rs].W[0] >= 0)
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -1296,18 +1297,18 @@ void R4300iOp32::REGIMM_BGEZL()
} }
else else
{ {
m_NextInstruction = JUMP; g_System->m_PipelineStage = PIPELINE_STAGE_JUMP;
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
} }
void R4300iOp32::REGIMM_BLTZAL() void R4300iOp32::REGIMM_BLTZAL()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] < 0) if (_GPR[m_Opcode.rs].W[0] < 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0)) if (!DelaySlotEffectsCompare((*_PROGRAM_COUNTER), m_Opcode.rs, 0))
{ {
@ -1317,18 +1318,18 @@ void R4300iOp32::REGIMM_BLTZAL()
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
_GPR[31].W[0] = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[31].W[0] = (int32_t)((*_PROGRAM_COUNTER) + 8);
} }
void R4300iOp32::REGIMM_BGEZAL() void R4300iOp32::REGIMM_BGEZAL()
{ {
m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
if (_GPR[m_Opcode.rs].W[0] >= 0) if (_GPR[m_Opcode.rs].W[0] >= 0)
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + ((int16_t)m_Opcode.offset << 2) + 4;
if ((*_PROGRAM_COUNTER) == m_JumpToLocation) if ((*_PROGRAM_COUNTER) == g_System->m_JumpToLocation)
{ {
if (CDebugSettings::HaveDebugger()) if (CDebugSettings::HaveDebugger())
{ {
@ -1336,9 +1337,9 @@ void R4300iOp32::REGIMM_BGEZAL()
{ {
// Break out of possible checksum halt // Break out of possible checksum halt
g_Notify->DisplayMessage(5, "Broke out of permanent loop! Invalid checksum?"); g_Notify->DisplayMessage(5, "Broke out of permanent loop! Invalid checksum?");
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
_GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[31].DW = (int32_t)((*_PROGRAM_COUNTER) + 8);
R4300iOp::m_NextInstruction = DELAY_SLOT; g_System->m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
return; return;
} }
} }
@ -1350,7 +1351,7 @@ void R4300iOp32::REGIMM_BGEZAL()
} }
else else
{ {
m_JumpToLocation = (*_PROGRAM_COUNTER) + 8; g_System->m_JumpToLocation = (*_PROGRAM_COUNTER) + 8;
} }
_GPR[31].W[0] = (int32_t)((*_PROGRAM_COUNTER) + 8); _GPR[31].W[0] = (int32_t)((*_PROGRAM_COUNTER) + 8);
} }

View File

@ -42,7 +42,7 @@ CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesR
m_RspBroke(true), m_RspBroke(true),
m_DMAUsed(false), m_DMAUsed(false),
m_TestTimer(false), m_TestTimer(false),
m_NextInstruction(0), m_PipelineStage(PIPELINE_STAGE_NORMAL),
m_JumpToLocation(0), m_JumpToLocation(0),
m_TLBLoadAddress(0), m_TLBLoadAddress(0),
m_TLBStoreAddress(0), m_TLBStoreAddress(0),
@ -920,8 +920,6 @@ bool CN64System::SetActiveSystem(bool bActive)
if (g_System) if (g_System)
{ {
g_System->m_TestTimer = R4300iOp::m_TestTimer; g_System->m_TestTimer = R4300iOp::m_TestTimer;
g_System->m_NextInstruction = R4300iOp::m_NextInstruction;
g_System->m_JumpToLocation = R4300iOp::m_JumpToLocation;
} }
g_System = this; g_System = this;
@ -944,8 +942,6 @@ bool CN64System::SetActiveSystem(bool bActive)
g_TLBStoreAddress = &m_TLBStoreAddress; g_TLBStoreAddress = &m_TLBStoreAddress;
g_RecompPos = m_Recomp ? m_Recomp->RecompPos() : nullptr; g_RecompPos = m_Recomp ? m_Recomp->RecompPos() : nullptr;
R4300iOp::m_TestTimer = m_TestTimer; R4300iOp::m_TestTimer = m_TestTimer;
R4300iOp::m_NextInstruction = m_NextInstruction;
R4300iOp::m_JumpToLocation = m_JumpToLocation;
g_Random = &m_Random; g_Random = &m_Random;
} }
else else

View File

@ -75,10 +75,6 @@ public:
bool LoadState(); bool LoadState();
uint32_t GetButtons(int32_t Control) const; uint32_t GetButtons(int32_t Control) const;
bool DmaUsed() const { return m_DMAUsed; }
void SetDmaUsed(bool DMAUsed) { m_DMAUsed = DMAUsed; }
CPlugins * GetPlugins() { return m_Plugins; }
// Variable used to track that the SP is being handled and stays the same as the real SP in sync core // Variable used to track that the SP is being handled and stays the same as the real SP in sync core
#ifdef TEST_SP_TRACKING #ifdef TEST_SP_TRACKING
uint32_t m_CurrentSP; uint32_t m_CurrentSP;
@ -89,6 +85,13 @@ public:
void SyncCPUPC(CN64System * const SecondCPU); void SyncCPUPC(CN64System * const SecondCPU);
void SyncSystem(); void SyncSystem();
void SyncSystemPC(); void SyncSystemPC();
bool DmaUsed() const { return m_DMAUsed; }
void SetDmaUsed(bool DMAUsed) { m_DMAUsed = DMAUsed; }
CPlugins * GetPlugins() { return m_Plugins; }
PIPELINE_STAGE PipelineStage() const { return m_PipelineStage; }
uint32_t JumpToLocation() const { return m_JumpToLocation; }
private: private:
// Make sure plugins can directly access this information // Make sure plugins can directly access this information
friend class CGfxPlugin; friend class CGfxPlugin;
@ -99,7 +102,11 @@ private:
// Recompiler has access to manipulate and call functions // Recompiler has access to manipulate and call functions
friend class CSystemTimer; friend class CSystemTimer;
friend class CRecompiler; friend class CRecompiler;
friend class CX86RecompilerOps;
friend class CMipsMemoryVM; friend class CMipsMemoryVM;
friend class CInterpreterCPU;
friend class R4300iOp32;
friend class R4300iOp;
// Used for loading and potentially executing the CPU in its own thread // Used for loading and potentially executing the CPU in its own thread
static void StartEmulationThread(CThread * thread); static void StartEmulationThread(CThread * thread);
@ -147,7 +154,7 @@ private:
bool m_DMAUsed; bool m_DMAUsed;
uint32_t m_Buttons[4]; uint32_t m_Buttons[4];
bool m_TestTimer; bool m_TestTimer;
uint32_t m_NextInstruction; PIPELINE_STAGE m_PipelineStage;
uint32_t m_JumpToLocation; uint32_t m_JumpToLocation;
uint32_t m_TLBLoadAddress; uint32_t m_TLBLoadAddress;
uint32_t m_TLBStoreAddress; uint32_t m_TLBStoreAddress;

View File

@ -110,20 +110,20 @@ enum PROFILE_TIMERS
Timer_Max = 9, Timer_Max = 9,
}; };
enum STEP_TYPE enum PIPELINE_STAGE
{ {
NORMAL = 0, PIPELINE_STAGE_NORMAL,
DO_DELAY_SLOT = 1, PIPELINE_STAGE_DO_DELAY_SLOT,
DO_END_DELAY_SLOT = 2, PIPELINE_STAGE_DO_END_DELAY_SLOT,
DELAY_SLOT = 3, PIPELINE_STAGE_DELAY_SLOT,
END_DELAY_SLOT = 4, PIPELINE_STAGE_END_DELAY_SLOT,
LIKELY_DELAY_SLOT = 5, PIPELINE_STAGE_LIKELY_DELAY_SLOT,
JUMP = 6, PIPELINE_STAGE_JUMP,
DELAY_SLOT_DONE = 7, PIPELINE_STAGE_DELAY_SLOT_DONE,
LIKELY_DELAY_SLOT_DONE = 8, PIPELINE_STAGE_LIKELY_DELAY_SLOT_DONE,
END_BLOCK = 9, PIPELINE_STAGE_END_BLOCK,
PERMLOOP_DO_DELAY = 10, PIPELINE_STAGE_PERMLOOP_DO_DELAY,
PERMLOOP_DELAY_DONE = 11, PIPELINE_STAGE_PERMLOOP_DELAY_DONE,
}; };
union MIPS_WORD union MIPS_WORD

View File

@ -24,7 +24,7 @@ CPU_Message("%s: %X t2: %X", __FUNCTION__,TestValue, g_Reg->m_GPR[10].UW[0]);
}*/ }*/
void CArmRecompilerOps::PreCompileOpcode(void) void CArmRecompilerOps::PreCompileOpcode(void)
{ {
if (m_NextInstruction != DELAY_SLOT_DONE) if (m_PipelineStage != DELAY_SLOT_DONE)
{ {
CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC));
} }
@ -39,7 +39,7 @@ void CArmRecompilerOps::PreCompileOpcode(void)
CallFunction(AddressOf(&TestFunc), "TestFunc"); CallFunction(AddressOf(&TestFunc), "TestFunc");
m_RegWorkingSet.AfterCallDirect();*/ m_RegWorkingSet.AfterCallDirect();*/
/*if ((m_CompilePC == 0x8027F564 || m_CompilePC == 0x8027F574) && m_NextInstruction == NORMAL) /*if ((m_CompilePC == 0x8027F564 || m_CompilePC == 0x8027F574) && m_PipelineStage == NORMAL)
{ {
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
MoveConstToArmReg(Arm_R0,(uint32_t)&TestValue, "TestValue"); MoveConstToArmReg(Arm_R0,(uint32_t)&TestValue, "TestValue");
@ -64,7 +64,7 @@ void CArmRecompilerOps::PreCompileOpcode(void)
} }
}*/ }*/
/*if (m_CompilePC == 0x8027F564 && m_NextInstruction == NORMAL) /*if (m_CompilePC == 0x8027F564 && m_PipelineStage == NORMAL)
{ {
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
UpdateCounters(m_RegWorkingSet,false,true); UpdateCounters(m_RegWorkingSet,false,true);
@ -89,7 +89,7 @@ void CArmRecompilerOps::PostCompileOpcode(void)
} }
CArmRecompilerOps::CArmRecompilerOps() : CArmRecompilerOps::CArmRecompilerOps() :
m_NextInstruction(NORMAL) m_PipelineStage(NORMAL)
{ {
memset(&m_Opcode, 0, sizeof(m_Opcode)); memset(&m_Opcode, 0, sizeof(m_Opcode));
} }
@ -192,7 +192,7 @@ void CArmRecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
static bool EffectDelaySlot; static bool EffectDelaySlot;
OPCODE Command = { 0 }; OPCODE Command = { 0 };
if (m_NextInstruction == NORMAL) if (m_PipelineStage == NORMAL)
{ {
if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT) if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT)
{ {
@ -368,9 +368,9 @@ void CArmRecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
ResetRegProtection(); ResetRegProtection();
RegBeforeDelay = m_RegWorkingSet; RegBeforeDelay = m_RegWorkingSet;
} }
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == DELAY_SLOT_DONE)
{ {
if (EffectDelaySlot) if (EffectDelaySlot)
{ {
@ -424,7 +424,7 @@ void CArmRecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
CPU_Message(" %s:", JumpInfo->BranchLabel.c_str()); CPU_Message(" %s:", JumpInfo->BranchLabel.c_str());
LinkJump(*JumpInfo); LinkJump(*JumpInfo);
JumpInfo->FallThrough = true; JumpInfo->FallThrough = true;
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
m_RegWorkingSet = RegBeforeDelay; m_RegWorkingSet = RegBeforeDelay;
return; return;
} }
@ -461,20 +461,20 @@ void CArmRecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
} }
} }
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
else else
{ {
if (HaveDebugger()) if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_PipelineStage).c_str());
} }
} }
} }
void CArmRecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link) void CArmRecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link)
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == NORMAL)
{ {
if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT) if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT)
{ {
@ -572,14 +572,14 @@ void CArmRecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Li
} }
else else
{ {
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
if (g_System->bLinkBlocks()) if (g_System->bLinkBlocks())
{ {
m_Section->m_Jump.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
else else
{ {
@ -590,20 +590,20 @@ void CArmRecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Li
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
} }
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == DELAY_SLOT_DONE)
{ {
ResetRegProtection(); ResetRegProtection();
m_Section->m_Jump.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
else if (HaveDebugger()) else if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_PipelineStage).c_str());
} }
} }
@ -1835,7 +1835,7 @@ void CArmRecompilerOps::COP1_BCT_Compare()
void CArmRecompilerOps::J() void CArmRecompilerOps::J()
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == NORMAL)
{ {
if ((m_CompilePC & 0xFFC) == 0xFFC) if ((m_CompilePC & 0xFFC) == 0xFFC)
{ {
@ -1857,23 +1857,23 @@ void CArmRecompilerOps::J()
m_Section->m_Jump.FallThrough = true; m_Section->m_Jump.FallThrough = true;
m_Section->m_Jump.LinkLocation = nullptr; m_Section->m_Jump.LinkLocation = nullptr;
m_Section->m_Jump.LinkLocation2 = nullptr; m_Section->m_Jump.LinkLocation2 = nullptr;
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == DELAY_SLOT_DONE)
{ {
m_Section->m_Jump.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
else if (HaveDebugger()) else if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_PipelineStage).c_str());
} }
} }
void CArmRecompilerOps::JAL() void CArmRecompilerOps::JAL()
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == NORMAL)
{ {
Map_GPR_32bit(31, true, -1); Map_GPR_32bit(31, true, -1);
MoveVariableToArmReg(_PROGRAM_COUNTER, "_PROGRAM_COUNTER", GetMipsRegMapLo(31)); MoveVariableToArmReg(_PROGRAM_COUNTER, "_PROGRAM_COUNTER", GetMipsRegMapLo(31));
@ -1903,9 +1903,9 @@ void CArmRecompilerOps::JAL()
m_Section->m_Jump.FallThrough = true; m_Section->m_Jump.FallThrough = true;
m_Section->m_Jump.LinkLocation = nullptr; m_Section->m_Jump.LinkLocation = nullptr;
m_Section->m_Jump.LinkLocation2 = nullptr; m_Section->m_Jump.LinkLocation2 = nullptr;
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == DELAY_SLOT_DONE)
{ {
if (m_Section->m_JumpSection) if (m_Section->m_JumpSection)
{ {
@ -1930,7 +1930,7 @@ void CArmRecompilerOps::JAL()
CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, bCheck ? CExitInfo::Normal : CExitInfo::Normal_NoSysCheck); CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, bCheck ? CExitInfo::Normal : CExitInfo::Normal_NoSysCheck);
} }
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
else else
{ {
@ -2800,7 +2800,7 @@ void CArmRecompilerOps::SPECIAL_SRAV()
void CArmRecompilerOps::SPECIAL_JR() void CArmRecompilerOps::SPECIAL_JR()
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == NORMAL)
{ {
if ((m_CompilePC & 0xFFC) == 0xFFC) if ((m_CompilePC & 0xFFC) == 0xFFC)
{ {
@ -2847,9 +2847,9 @@ void CArmRecompilerOps::SPECIAL_JR()
} }
m_RegWorkingSet.SetArmRegProtected(PCTempReg, false); m_RegWorkingSet.SetArmRegProtected(PCTempReg, false);
} }
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == DELAY_SLOT_DONE)
{ {
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0))
{ {
@ -2884,17 +2884,17 @@ void CArmRecompilerOps::SPECIAL_JR()
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
} }
} }
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
else if (HaveDebugger()) else if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_PipelineStage).c_str());
} }
} }
void CArmRecompilerOps::SPECIAL_JALR() void CArmRecompilerOps::SPECIAL_JALR()
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == NORMAL)
{ {
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0) && (m_CompilePC & 0xFFC) != 0xFFC) if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0) && (m_CompilePC & 0xFFC) != 0xFFC)
{ {
@ -2939,9 +2939,9 @@ void CArmRecompilerOps::SPECIAL_JALR()
m_Section->m_Cont.LinkLocation = nullptr; m_Section->m_Cont.LinkLocation = nullptr;
m_Section->m_Cont.LinkLocation2 = nullptr; m_Section->m_Cont.LinkLocation2 = nullptr;
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == DELAY_SLOT_DONE)
{ {
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0))
{ {
@ -2963,18 +2963,18 @@ void CArmRecompilerOps::SPECIAL_JALR()
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
} }
} }
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
else if (HaveDebugger()) else if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_PipelineStage).c_str());
} }
} }
void CArmRecompilerOps::SPECIAL_SYSCALL() void CArmRecompilerOps::SPECIAL_SYSCALL()
{ {
CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::DoSysCall); CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::DoSysCall);
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
void CArmRecompilerOps::SPECIAL_MFLO() void CArmRecompilerOps::SPECIAL_MFLO()
@ -4000,7 +4000,7 @@ void CArmRecompilerOps::COP0_CO_ERET()
UpdateCounters(m_RegWorkingSet, true, true); UpdateCounters(m_RegWorkingSet, true, true);
CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal); CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal);
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
// COP1 functions // COP1 functions
@ -4693,7 +4693,7 @@ void CArmRecompilerOps::UnknownOpcode()
MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex");
CallFunction((void *)R4300iOp::UnknownOpcode, "R4300iOp::UnknownOpcode"); CallFunction((void *)R4300iOp::UnknownOpcode, "R4300iOp::UnknownOpcode");
ExitCodeBlock(); ExitCodeBlock();
if (m_NextInstruction == NORMAL) { m_NextInstruction = END_BLOCK; } if (m_PipelineStage == NORMAL) { m_PipelineStage = END_BLOCK; }
} }
void CArmRecompilerOps::EnterCodeBlock() void CArmRecompilerOps::EnterCodeBlock()
@ -4718,7 +4718,7 @@ void CArmRecompilerOps::CompileExitCode()
CPU_Message(""); CPU_Message("");
CPU_Message(" $Exit_%d", ExitIter->ID); CPU_Message(" $Exit_%d", ExitIter->ID);
SetJump20(ExitIter->JumpLoc, (uint32_t *)*g_RecompPos); SetJump20(ExitIter->JumpLoc, (uint32_t *)*g_RecompPos);
m_NextInstruction = ExitIter->NextInstruction; m_PipelineStage = ExitIter->PipelineStage;
CompileExit((uint32_t)-1, ExitIter->TargetPC, ExitIter->ExitRegSet, ExitIter->reason); CompileExit((uint32_t)-1, ExitIter->TargetPC, ExitIter->ExitRegSet, ExitIter->reason);
} }
} }
@ -5276,14 +5276,14 @@ void CArmRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
ExitCodeBlock(); ExitCodeBlock();
break; break;
case CExitInfo::DoSysCall: case CExitInfo::DoSysCall:
bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT; bDelay = m_PipelineStage == JUMP || m_PipelineStage == DELAY_SLOT;
MoveConstToArmReg(Arm_R1, (uint32_t)bDelay, bDelay ? "true" : "false"); MoveConstToArmReg(Arm_R1, (uint32_t)bDelay, bDelay ? "true" : "false");
MoveConstToArmReg(Arm_R0, (uint32_t)g_Reg); MoveConstToArmReg(Arm_R0, (uint32_t)g_Reg);
CallFunction(AddressOf(&CRegisters::DoSysCallException), "CRegisters::DoSysCallException"); CallFunction(AddressOf(&CRegisters::DoSysCallException), "CRegisters::DoSysCallException");
ExitCodeBlock(); ExitCodeBlock();
break; break;
case CExitInfo::COP1_Unuseable: case CExitInfo::COP1_Unuseable:
bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT; bDelay = m_PipelineStage == JUMP || m_PipelineStage == DELAY_SLOT;
MoveConstToArmReg(Arm_R2, (uint32_t)1, "1"); MoveConstToArmReg(Arm_R2, (uint32_t)1, "1");
MoveConstToArmReg(Arm_R1, (uint32_t)bDelay, bDelay ? "true" : "false"); MoveConstToArmReg(Arm_R1, (uint32_t)bDelay, bDelay ? "true" : "false");
MoveConstToArmReg(Arm_R0, (uint32_t)g_Reg); MoveConstToArmReg(Arm_R0, (uint32_t)g_Reg);
@ -5291,7 +5291,7 @@ void CArmRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
ExitCodeBlock(); ExitCodeBlock();
break; break;
case CExitInfo::TLBReadMiss: case CExitInfo::TLBReadMiss:
bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT; bDelay = m_PipelineStage == JUMP || m_PipelineStage == DELAY_SLOT;
MoveVariableToArmReg(g_TLBLoadAddress, "g_TLBLoadAddress", Arm_R2); MoveVariableToArmReg(g_TLBLoadAddress, "g_TLBLoadAddress", Arm_R2);
MoveConstToArmReg(Arm_R1, (uint32_t)bDelay, bDelay ? "true" : "false"); MoveConstToArmReg(Arm_R1, (uint32_t)bDelay, bDelay ? "true" : "false");
MoveConstToArmReg(Arm_R0, (uint32_t)g_Reg); MoveConstToArmReg(Arm_R0, (uint32_t)g_Reg);
@ -5316,7 +5316,7 @@ void CArmRecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
ExitInfo.TargetPC = TargetPC; ExitInfo.TargetPC = TargetPC;
ExitInfo.ExitRegSet = ExitRegSet; ExitInfo.ExitRegSet = ExitRegSet;
ExitInfo.reason = reason; ExitInfo.reason = reason;
ExitInfo.NextInstruction = m_NextInstruction; ExitInfo.PipelineStage = m_PipelineStage;
ExitInfo.JumpLoc = (uint32_t *)(*g_RecompPos - 4); ExitInfo.JumpLoc = (uint32_t *)(*g_RecompPos - 4);
m_ExitInfo.push_back(ExitInfo); m_ExitInfo.push_back(ExitInfo);
} }
@ -5870,12 +5870,12 @@ void CArmRecompilerOps::SetCurrentSection(CCodeSection * section)
void CArmRecompilerOps::SetNextStepType(STEP_TYPE StepType) void CArmRecompilerOps::SetNextStepType(STEP_TYPE StepType)
{ {
m_NextInstruction = StepType; m_PipelineStage = StepType;
} }
STEP_TYPE CArmRecompilerOps::GetNextStepType(void) STEP_TYPE CArmRecompilerOps::GetNextStepType(void)
{ {
return m_NextInstruction; return m_PipelineStage;
} }
const OPCODE &CArmRecompilerOps::GetOpcode(void) const const OPCODE &CArmRecompilerOps::GetOpcode(void) const
@ -5970,7 +5970,7 @@ void CArmRecompilerOps::OverflowDelaySlot(bool TestTimer)
CallFunction(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem"); CallFunction(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem");
} }
MoveConstToVariable(JUMP, &R4300iOp::m_NextInstruction, "R4300iOp::m_NextInstruction"); MoveConstToVariable(JUMP, &R4300iOp::m_PipelineStage, "R4300iOp::m_PipelineStage");
if (TestTimer) if (TestTimer)
{ {
@ -5991,7 +5991,7 @@ void CArmRecompilerOps::OverflowDelaySlot(bool TestTimer)
} }
ExitCodeBlock(); ExitCodeBlock();
m_NextInstruction = END_BLOCK; m_PipelineStage = END_BLOCK;
} }
void CArmRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr) void CArmRecompilerOps::SW_Const(uint32_t Value, uint32_t VAddr)

View File

@ -268,7 +268,7 @@ private:
void OverflowDelaySlot(bool TestTimer); void OverflowDelaySlot(bool TestTimer);
EXIT_LIST m_ExitInfo; EXIT_LIST m_ExitInfo;
STEP_TYPE m_NextInstruction; STEP_TYPE m_PipelineStage;
uint32_t m_CompilePC; uint32_t m_CompilePC;
OPCODE m_Opcode; OPCODE m_Opcode;
CCodeSection * m_Section; CCodeSection * m_Section;

View File

@ -429,7 +429,7 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
m_CompiledLocation = *g_RecompPos; m_CompiledLocation = *g_RecompPos;
m_RecompilerOps->SetRegWorkingSet(m_RegEnter); m_RecompilerOps->SetRegWorkingSet(m_RegEnter);
m_RecompilerOps->SetCurrentPC(m_EnterPC); m_RecompilerOps->SetCurrentPC(m_EnterPC);
m_RecompilerOps->SetNextStepType(m_DelaySlot ? JUMP : NORMAL); m_RecompilerOps->SetNextStepType(m_DelaySlot ? PIPELINE_STAGE_JUMP : PIPELINE_STAGE_NORMAL);
if (m_RecompilerOps->GetCurrentPC() < m_BlockInfo->VAddrFirst()) if (m_RecompilerOps->GetCurrentPC() < m_BlockInfo->VAddrFirst())
{ {
@ -727,11 +727,11 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
if ((m_RecompilerOps->GetCurrentPC() & 0xFFC) == 0xFFC) if ((m_RecompilerOps->GetCurrentPC() & 0xFFC) == 0xFFC)
{ {
if (m_RecompilerOps->GetNextStepType() == DO_DELAY_SLOT) if (m_RecompilerOps->GetNextStepType() == PIPELINE_STAGE_DO_DELAY_SLOT)
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
if (m_RecompilerOps->GetNextStepType() == NORMAL) if (m_RecompilerOps->GetNextStepType() == PIPELINE_STAGE_NORMAL)
{ {
if (m_DelaySlot) if (m_DelaySlot)
{ {
@ -741,26 +741,26 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
{ {
m_RecompilerOps->CompileExit(m_RecompilerOps->GetCurrentPC(), m_RecompilerOps->GetCurrentPC() + 4, m_RecompilerOps->GetRegWorkingSet(), CExitInfo::Normal); m_RecompilerOps->CompileExit(m_RecompilerOps->GetCurrentPC(), m_RecompilerOps->GetCurrentPC() + 4, m_RecompilerOps->GetRegWorkingSet(), CExitInfo::Normal);
} }
m_RecompilerOps->SetNextStepType(END_BLOCK); m_RecompilerOps->SetNextStepType(PIPELINE_STAGE_END_BLOCK);
} }
} }
switch (m_RecompilerOps->GetNextStepType()) switch (m_RecompilerOps->GetNextStepType())
{ {
case NORMAL: case PIPELINE_STAGE_NORMAL:
m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() + 4); m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() + 4);
break; break;
case DO_DELAY_SLOT: case PIPELINE_STAGE_DO_DELAY_SLOT:
m_RecompilerOps->SetNextStepType(DELAY_SLOT); m_RecompilerOps->SetNextStepType(PIPELINE_STAGE_DELAY_SLOT);
m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() + 4); m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() + 4);
break; break;
case DELAY_SLOT: case PIPELINE_STAGE_DELAY_SLOT:
m_RecompilerOps->SetNextStepType(DELAY_SLOT_DONE); m_RecompilerOps->SetNextStepType(PIPELINE_STAGE_DELAY_SLOT_DONE);
m_RecompilerOps->GetRegWorkingSet().SetBlockCycleCount(m_RecompilerOps->GetRegWorkingSet().GetBlockCycleCount() - g_System->CountPerOp()); m_RecompilerOps->GetRegWorkingSet().SetBlockCycleCount(m_RecompilerOps->GetRegWorkingSet().GetBlockCycleCount() - g_System->CountPerOp());
m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() - 4); m_RecompilerOps->SetCurrentPC(m_RecompilerOps->GetCurrentPC() - 4);
break; break;
case JUMP: case PIPELINE_STAGE_JUMP:
case END_BLOCK: case PIPELINE_STAGE_END_BLOCK:
// Do nothing, the block will end // Do nothing, the block will end
break; break;
default: default:
@ -782,11 +782,11 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
{ {
m_RecompilerOps->CompileExit(m_Jump.JumpPC, m_Jump.TargetPC, m_RecompilerOps->GetRegWorkingSet(), CExitInfo::Normal); m_RecompilerOps->CompileExit(m_Jump.JumpPC, m_Jump.TargetPC, m_RecompilerOps->GetRegWorkingSet(), CExitInfo::Normal);
} }
m_RecompilerOps->SetNextStepType(END_BLOCK); m_RecompilerOps->SetNextStepType(PIPELINE_STAGE_END_BLOCK);
} }
else if (m_RecompilerOps->GetNextStepType() != END_BLOCK && m_RecompilerOps->GetCurrentPC() == ContinueSectionPC) else if (m_RecompilerOps->GetNextStepType() != PIPELINE_STAGE_END_BLOCK && m_RecompilerOps->GetCurrentPC() == ContinueSectionPC)
{ {
if (m_RecompilerOps->GetNextStepType() != NORMAL) if (m_RecompilerOps->GetNextStepType() != PIPELINE_STAGE_NORMAL)
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
@ -795,9 +795,9 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
m_Cont.FallThrough = true; m_Cont.FallThrough = true;
m_Cont.JumpPC = m_RecompilerOps->GetCurrentPC(); m_Cont.JumpPC = m_RecompilerOps->GetCurrentPC();
GenerateSectionLinkage(); GenerateSectionLinkage();
m_RecompilerOps->SetNextStepType(END_BLOCK); m_RecompilerOps->SetNextStepType(PIPELINE_STAGE_END_BLOCK);
} }
} while (m_RecompilerOps->GetNextStepType() != END_BLOCK); } while (m_RecompilerOps->GetNextStepType() != PIPELINE_STAGE_END_BLOCK);
return true; return true;
} }

View File

@ -22,7 +22,7 @@ struct CExitInfo
uint32_t TargetPC; uint32_t TargetPC;
CRegInfo ExitRegSet; CRegInfo ExitRegSet;
EXIT_REASON reason; EXIT_REASON reason;
STEP_TYPE NextInstruction; PIPELINE_STAGE PipelineStage;
uint32_t * JumpLoc; // 32-bit jump uint32_t * JumpLoc; // 32-bit jump
}; };

View File

@ -19,7 +19,7 @@ LoopAnalysis::LoopAnalysis(CCodeBlock * CodeBlock, CCodeSection * Section) :
m_EnterSection(Section), m_EnterSection(Section),
m_BlockInfo(CodeBlock), m_BlockInfo(CodeBlock),
m_PC((uint32_t)-1), m_PC((uint32_t)-1),
m_NextInstruction(NORMAL), m_PipelineStage(PIPELINE_STAGE_NORMAL),
m_Test(m_BlockInfo->NextTest()) m_Test(m_BlockInfo->NextTest())
{ {
memset(&m_Command, 0, sizeof(m_Command)); memset(&m_Command, 0, sizeof(m_Command));
@ -166,7 +166,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID); RegisterMap::iterator itr = m_EnterRegisters.find(Section->m_SectionID);
m_Reg = itr != m_EnterRegisters.end() ? *(itr->second) : Section->m_RegEnter; m_Reg = itr != m_EnterRegisters.end() ? *(itr->second) : Section->m_RegEnter;
m_NextInstruction = NORMAL; m_PipelineStage = PIPELINE_STAGE_NORMAL;
uint32_t ContinueSectionPC = Section->m_ContinueSection ? Section->m_ContinueSection->m_EnterPC : (uint32_t)-1; uint32_t ContinueSectionPC = Section->m_ContinueSection ? Section->m_ContinueSection->m_EnterPC : (uint32_t)-1;
CPU_Message("ContinueSectionPC = %08X", ContinueSectionPC); CPU_Message("ContinueSectionPC = %08X", ContinueSectionPC);
@ -233,7 +233,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
break; break;
default: default:
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
m_PC -= 4; m_PC -= 4;
} }
break; break;
@ -245,7 +245,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
break; break;
case R4300i_REGIMM_BLTZ: case R4300i_REGIMM_BLTZ:
case R4300i_REGIMM_BGEZ: case R4300i_REGIMM_BGEZ:
m_NextInstruction = DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (Section->m_Cont.TargetPC != m_PC + 8 && if (Section->m_Cont.TargetPC != m_PC + 8 &&
Section->m_ContinueSection != nullptr && Section->m_ContinueSection != nullptr &&
@ -270,7 +270,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
break; break;
case R4300i_REGIMM_BLTZL: case R4300i_REGIMM_BLTZL:
case R4300i_REGIMM_BGEZL: case R4300i_REGIMM_BGEZL:
m_NextInstruction = LIKELY_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_LIKELY_DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (Section->m_Cont.TargetPC != m_PC + 8 && if (Section->m_Cont.TargetPC != m_PC + 8 &&
Section->m_ContinueSection != nullptr && Section->m_ContinueSection != nullptr &&
@ -312,7 +312,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
break; break;
case R4300i_J: case R4300i_J:
m_NextInstruction = DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (Section->m_Jump.TargetPC != (m_PC & 0xF0000000) + (m_Command.target << 2)) if (Section->m_Jump.TargetPC != (m_PC & 0xF0000000) + (m_Command.target << 2))
{ {
@ -327,7 +327,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_BEQ: case R4300i_BEQ:
if (m_PC + ((int16_t)m_Command.offset << 2) + 4 != m_PC + 8) if (m_PC + ((int16_t)m_Command.offset << 2) + 4 != m_PC + 8)
{ {
m_NextInstruction = DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (m_Command.rs != 0 || m_Command.rt != 0) if (m_Command.rs != 0 || m_Command.rt != 0)
{ {
@ -364,7 +364,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_BGTZ: case R4300i_BGTZ:
if (m_PC + ((int16_t)m_Command.offset << 2) + 4 != m_PC + 8) if (m_PC + ((int16_t)m_Command.offset << 2) + 4 != m_PC + 8)
{ {
m_NextInstruction = DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (Section->m_Cont.TargetPC != m_PC + 8 && if (Section->m_Cont.TargetPC != m_PC + 8 &&
Section->m_ContinueSection != nullptr && Section->m_ContinueSection != nullptr &&
@ -462,17 +462,17 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_COP0_CO_TLBWI: break; case R4300i_COP0_CO_TLBWI: break;
case R4300i_COP0_CO_TLBWR: break; case R4300i_COP0_CO_TLBWR: break;
case R4300i_COP0_CO_TLBP: break; case R4300i_COP0_CO_TLBP: break;
case R4300i_COP0_CO_ERET: m_NextInstruction = END_BLOCK; break; case R4300i_COP0_CO_ERET: m_PipelineStage = PIPELINE_STAGE_END_BLOCK; break;
default: default:
g_Notify->DisplayError(stdstr_f("Unhandled R4300i opcode in FillSectionInfo\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); g_Notify->DisplayError(stdstr_f("Unhandled R4300i opcode in FillSectionInfo\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str());
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
m_PC -= 4; m_PC -= 4;
} }
} }
else else
{ {
g_Notify->DisplayError(stdstr_f("Unhandled R4300i opcode in FillSectionInfo 3\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); g_Notify->DisplayError(stdstr_f("Unhandled R4300i opcode in FillSectionInfo 3\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str());
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
m_PC -= 4; m_PC -= 4;
} }
} }
@ -491,7 +491,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
{ {
case R4300i_COP1_BC_BCFL: case R4300i_COP1_BC_BCFL:
case R4300i_COP1_BC_BCTL: case R4300i_COP1_BC_BCTL:
m_NextInstruction = LIKELY_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_LIKELY_DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (Section->m_Cont.TargetPC != m_PC + 8 && if (Section->m_Cont.TargetPC != m_PC + 8 &&
Section->m_ContinueSection != nullptr && Section->m_ContinueSection != nullptr &&
@ -507,7 +507,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
break; break;
case R4300i_COP1_BC_BCF: case R4300i_COP1_BC_BCF:
case R4300i_COP1_BC_BCT: case R4300i_COP1_BC_BCT:
m_NextInstruction = DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (Section->m_Cont.TargetPC != m_PC + 8 && if (Section->m_Cont.TargetPC != m_PC + 8 &&
Section->m_ContinueSection != nullptr && Section->m_ContinueSection != nullptr &&
@ -536,7 +536,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_COP1_L: break; case R4300i_COP1_L: break;
default: default:
g_Notify->DisplayError(stdstr_f("Unhandled R4300i opcode in FillSectionInfo 2\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str()); g_Notify->DisplayError(stdstr_f("Unhandled R4300i opcode in FillSectionInfo 2\n%s", R4300iOpcodeName(m_Command.Hex, m_PC)).c_str());
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
m_PC -= 4; m_PC -= 4;
} }
break; break;
@ -544,7 +544,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_BNEL: case R4300i_BNEL:
case R4300i_BLEZL: case R4300i_BLEZL:
case R4300i_BGTZL: case R4300i_BGTZL:
m_NextInstruction = LIKELY_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_LIKELY_DELAY_SLOT;
#ifdef CHECKED_BUILD #ifdef CHECKED_BUILD
if (Section->m_Cont.TargetPC != m_PC + 8 && if (Section->m_Cont.TargetPC != m_PC + 8 &&
Section->m_ContinueSection != nullptr && Section->m_ContinueSection != nullptr &&
@ -628,7 +628,7 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
case R4300i_SDC1: break; case R4300i_SDC1: break;
case R4300i_SD: break; case R4300i_SD: break;
default: default:
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
m_PC -= 4; m_PC -= 4;
if (m_Command.Hex == 0x7C1C97C0) { break; } if (m_Command.Hex == 0x7C1C97C0) { break; }
if (m_Command.Hex == 0x7FFFFFFF) { break; } if (m_Command.Hex == 0x7FFFFFFF) { break; }
@ -642,60 +642,60 @@ bool LoopAnalysis::CheckLoopRegisterUsage(CCodeSection * Section)
if (Section->m_DelaySlot) if (Section->m_DelaySlot)
{ {
if (m_NextInstruction != NORMAL && m_NextInstruction != END_BLOCK) if (m_PipelineStage != PIPELINE_STAGE_NORMAL && m_PipelineStage != PIPELINE_STAGE_END_BLOCK)
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
SetJumpRegSet(Section, m_Reg); SetJumpRegSet(Section, m_Reg);
} }
else else
{ {
switch (m_NextInstruction) switch (m_PipelineStage)
{ {
case NORMAL: case PIPELINE_STAGE_NORMAL:
m_PC += 4; m_PC += 4;
break; break;
case DELAY_SLOT: case PIPELINE_STAGE_DELAY_SLOT:
m_NextInstruction = DELAY_SLOT_DONE; m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT_DONE;
m_PC += 4; m_PC += 4;
if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000)) if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000))
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
break; break;
case LIKELY_DELAY_SLOT: case PIPELINE_STAGE_LIKELY_DELAY_SLOT:
SetContinueRegSet(Section, m_Reg); SetContinueRegSet(Section, m_Reg);
SetJumpRegSet(Section, m_Reg); SetJumpRegSet(Section, m_Reg);
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
break; break;
case DELAY_SLOT_DONE: case PIPELINE_STAGE_DELAY_SLOT_DONE:
SetContinueRegSet(Section, m_Reg); SetContinueRegSet(Section, m_Reg);
SetJumpRegSet(Section, m_Reg); SetJumpRegSet(Section, m_Reg);
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
break; break;
case LIKELY_DELAY_SLOT_DONE: default:
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
break; break;
} }
} }
if (m_PC == ContinueSectionPC) if (m_PC == ContinueSectionPC)
{ {
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
SetContinueRegSet(Section, m_Reg); SetContinueRegSet(Section, m_Reg);
} }
if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000)) if ((m_PC & 0xFFFFF000) != (m_EnterSection->m_EnterPC & 0xFFFFF000))
{ {
if (m_NextInstruction != END_BLOCK && m_NextInstruction != NORMAL) if (m_PipelineStage != PIPELINE_STAGE_END_BLOCK && m_PipelineStage != PIPELINE_STAGE_NORMAL)
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
} while (m_NextInstruction != END_BLOCK); } while (m_PipelineStage != PIPELINE_STAGE_END_BLOCK);
if (!CheckLoopRegisterUsage(Section->m_ContinueSection)) { return false; } if (!CheckLoopRegisterUsage(Section->m_ContinueSection)) { return false; }
if (!CheckLoopRegisterUsage(Section->m_JumpSection)) { return false; } if (!CheckLoopRegisterUsage(Section->m_JumpSection)) { return false; }
@ -828,13 +828,13 @@ void LoopAnalysis::SPECIAL_SRAV()
void LoopAnalysis::SPECIAL_JR() void LoopAnalysis::SPECIAL_JR()
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
m_NextInstruction = DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
} }
void LoopAnalysis::SPECIAL_JALR() void LoopAnalysis::SPECIAL_JALR()
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
m_NextInstruction = DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DELAY_SLOT;
} }
void LoopAnalysis::SPECIAL_SYSCALL(CCodeSection * Section) void LoopAnalysis::SPECIAL_SYSCALL(CCodeSection * Section)
@ -853,7 +853,7 @@ void LoopAnalysis::SPECIAL_SYSCALL(CCodeSection * Section)
#else #else
Section = Section; Section = Section;
#endif #endif
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
m_PC -= 4; m_PC -= 4;
} }
@ -873,7 +873,7 @@ void LoopAnalysis::SPECIAL_BREAK(CCodeSection * Section)
#else #else
Section = Section; Section = Section;
#endif #endif
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
m_PC -= 4; m_PC -= 4;
} }

View File

@ -1,8 +1,8 @@
#pragma once #pragma once
#include <Project64-core/N64System/Recompiler/RegInfo.h> #include <Project64-core/N64System/Recompiler/RegInfo.h>
#include <Project64-core/N64System/Mips/OpCode.h> #include <Project64-core/N64System/Mips/OpCode.h>
#include <Project64-core/N64System/N64Types.h> #include <Project64-core/N64System/N64Types.h>
#include <map>
class CCodeSection; class CCodeSection;
class CCodeBlock; class CCodeBlock;
@ -74,7 +74,7 @@ private:
CCodeBlock * m_BlockInfo; CCodeBlock * m_BlockInfo;
uint32_t m_PC; uint32_t m_PC;
CRegInfo m_Reg; CRegInfo m_Reg;
STEP_TYPE m_NextInstruction; PIPELINE_STAGE m_PipelineStage;
OPCODE m_Command; OPCODE m_Command;
uint32_t m_Test; uint32_t m_Test;
}; };

View File

@ -224,8 +224,8 @@ public:
virtual void SetCurrentPC(uint32_t ProgramCounter) = 0; virtual void SetCurrentPC(uint32_t ProgramCounter) = 0;
virtual uint32_t GetCurrentPC(void) = 0; virtual uint32_t GetCurrentPC(void) = 0;
virtual void SetCurrentSection(CCodeSection * section) = 0; virtual void SetCurrentSection(CCodeSection * section) = 0;
virtual void SetNextStepType(STEP_TYPE StepType) = 0; virtual void SetNextStepType(PIPELINE_STAGE StepType) = 0;
virtual STEP_TYPE GetNextStepType(void) = 0; virtual PIPELINE_STAGE GetNextStepType(void) = 0;
virtual const OPCODE & GetOpcode(void) const = 0; virtual const OPCODE & GetOpcode(void) const = 0;
virtual void PreCompileOpcode(void) = 0; virtual void PreCompileOpcode(void) = 0;
virtual void PostCompileOpcode(void) = 0; virtual void PostCompileOpcode(void) = 0;

View File

@ -22,7 +22,7 @@
CCodeSection * CX86RecompilerOps::m_Section = nullptr; CCodeSection * CX86RecompilerOps::m_Section = nullptr;
CRegInfo CX86RecompilerOps::m_RegWorkingSet; CRegInfo CX86RecompilerOps::m_RegWorkingSet;
STEP_TYPE CX86RecompilerOps::m_NextInstruction; PIPELINE_STAGE CX86RecompilerOps::m_PipelineStage;
uint32_t CX86RecompilerOps::m_CompilePC; uint32_t CX86RecompilerOps::m_CompilePC;
OPCODE CX86RecompilerOps::m_Opcode; OPCODE CX86RecompilerOps::m_Opcode;
uint32_t CX86RecompilerOps::m_BranchCompare = 0; uint32_t CX86RecompilerOps::m_BranchCompare = 0;
@ -67,7 +67,7 @@ static void x86_compiler_Break_Point()
} while (CDebugSettings::isStepping()); } while (CDebugSettings::isStepping());
if (R4300iOp::m_NextInstruction != NORMAL) if (g_System->PipelineStage() != PIPELINE_STAGE_NORMAL)
{ {
CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
if (g_SyncSystem) if (g_SyncSystem)
@ -90,7 +90,7 @@ static void x86_Break_Point_DelaySlot()
{ {
x86_compiler_Break_Point(); x86_compiler_Break_Point();
} }
if (R4300iOp::m_NextInstruction != NORMAL) if (g_System->PipelineStage() != PIPELINE_STAGE_NORMAL)
{ {
CInterpreterCPU::ExecuteOps(g_System->CountPerOp()); CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
if (g_SyncSystem) if (g_SyncSystem)
@ -183,16 +183,16 @@ static void x86TestWriteBreakpoint64()
void CX86RecompilerOps::PreCompileOpcode(void) void CX86RecompilerOps::PreCompileOpcode(void)
{ {
if (m_NextInstruction != DELAY_SLOT_DONE) if (m_PipelineStage != PIPELINE_STAGE_DELAY_SLOT_DONE)
{ {
CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC)); CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(m_Opcode.Hex, m_CompilePC));
} }
/*if (m_CompilePC == 0x803245C4 && m_NextInstruction == NORMAL) /*if (m_CompilePC == 0x803245C4 && m_PipelineStage == NORMAL)
{ {
X86BreakPoint(__FILE__, __LINE__); X86BreakPoint(__FILE__, __LINE__);
}*/ }*/
/*if (m_CompilePC >= 0x80000000 && m_CompilePC <= 0x80400000 && m_NextInstruction == NORMAL) /*if (m_CompilePC >= 0x80000000 && m_CompilePC <= 0x80400000 && m_PipelineStage == NORMAL)
{ {
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
UpdateCounters(m_RegWorkingSet, false, true); UpdateCounters(m_RegWorkingSet, false, true);
@ -211,7 +211,7 @@ void CX86RecompilerOps::PreCompileOpcode(void)
/*if ((m_CompilePC == 0x8031C0E4 || m_CompilePC == 0x8031C118 || /*if ((m_CompilePC == 0x8031C0E4 || m_CompilePC == 0x8031C118 ||
m_CompilePC == 0x8031CD88 || m_CompilePC == 0x8031CE24 || m_CompilePC == 0x8031CD88 || m_CompilePC == 0x8031CE24 ||
m_CompilePC == 0x8031CE30 || m_CompilePC == 0x8031CE40) && m_NextInstruction == NORMAL) m_CompilePC == 0x8031CE30 || m_CompilePC == 0x8031CE40) && m_PipelineStage == NORMAL)
{ {
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
UpdateCounters(m_RegWorkingSet, false, true); UpdateCounters(m_RegWorkingSet, false, true);
@ -236,7 +236,7 @@ void CX86RecompilerOps::PreCompileOpcode(void)
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();
}*/ }*/
/*if (m_CompilePC >= 0x801C1AF8 && m_CompilePC <= 0x801C1C00 && m_NextInstruction == NORMAL) /*if (m_CompilePC >= 0x801C1AF8 && m_CompilePC <= 0x801C1C00 && m_PipelineStage == NORMAL)
{ {
UpdateCounters(m_RegWorkingSet,false,true); UpdateCounters(m_RegWorkingSet,false,true);
MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER"); MoveConstToVariable(m_CompilePC,&g_Reg->m_PROGRAM_COUNTER,"PROGRAM_COUNTER");
@ -248,12 +248,12 @@ void CX86RecompilerOps::PreCompileOpcode(void)
} }
}*/ }*/
/*if ((m_CompilePC == 0x80263900) && m_NextInstruction == NORMAL) /*if ((m_CompilePC == 0x80263900) && m_PipelineStage == NORMAL)
{ {
X86BreakPoint(__FILEW__,__LINE__); X86BreakPoint(__FILEW__,__LINE__);
}*/ }*/
/*if ((m_CompilePC >= 0x80325D80 && m_CompilePC <= 0x80325DF0) && m_NextInstruction == NORMAL) /*if ((m_CompilePC >= 0x80325D80 && m_CompilePC <= 0x80325DF0) && m_PipelineStage == NORMAL)
{ {
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
UpdateCounters(m_RegWorkingSet,false,true); UpdateCounters(m_RegWorkingSet,false,true);
@ -269,12 +269,12 @@ void CX86RecompilerOps::PreCompileOpcode(void)
#endif #endif
} }
}*/ }*/
/*if ((m_CompilePC == 0x80324E14) && m_NextInstruction == NORMAL) /*if ((m_CompilePC == 0x80324E14) && m_PipelineStage == NORMAL)
{ {
X86BreakPoint(__FILEW__,__LINE__); X86BreakPoint(__FILEW__,__LINE__);
}*/ }*/
/*if (m_CompilePC == 0x80324E18 && m_NextInstruction == NORMAL) /*if (m_CompilePC == 0x80324E18 && m_PipelineStage == NORMAL)
{ {
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
UpdateCounters(m_RegWorkingSet,false,true); UpdateCounters(m_RegWorkingSet,false,true);
@ -290,7 +290,7 @@ void CX86RecompilerOps::PreCompileOpcode(void)
#endif #endif
} }
}*/ }*/
/*if (m_CompilePC >= 0x80324E00 && m_CompilePC <= 0x80324E18 && m_NextInstruction == NORMAL) /*if (m_CompilePC >= 0x80324E00 && m_CompilePC <= 0x80324E18 && m_PipelineStage == NORMAL)
{ {
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
UpdateCounters(m_RegWorkingSet,false,true); UpdateCounters(m_RegWorkingSet,false,true);
@ -306,7 +306,7 @@ void CX86RecompilerOps::PreCompileOpcode(void)
#endif #endif
} }
}*/ }*/
/* if (m_CompilePC == 0x803245CC && m_NextInstruction == NORMAL) /* if (m_CompilePC == 0x803245CC && m_PipelineStage == NORMAL)
{ {
//m_RegWorkingSet.UnMap_AllFPRs(); //m_RegWorkingSet.UnMap_AllFPRs();
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
@ -314,7 +314,7 @@ void CX86RecompilerOps::PreCompileOpcode(void)
//X86BreakPoint(__FILEW__,__LINE__); //X86BreakPoint(__FILEW__,__LINE__);
//m_RegWorkingSet.UnMap_AllFPRs(); //m_RegWorkingSet.UnMap_AllFPRs();
}*/ }*/
/*if (m_CompilePC >= 0x80179DC4 && m_CompilePC <= 0x80179DF0 && m_NextInstruction == NORMAL) /*if (m_CompilePC >= 0x80179DC4 && m_CompilePC <= 0x80179DF0 && m_PipelineStage == NORMAL)
{ {
m_RegWorkingSet.UnMap_AllFPRs(); m_RegWorkingSet.UnMap_AllFPRs();
}*/ }*/
@ -453,7 +453,7 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
static CRegInfo RegBeforeDelay; static CRegInfo RegBeforeDelay;
static bool EffectDelaySlot; static bool EffectDelaySlot;
if (m_NextInstruction == NORMAL) if (m_PipelineStage == PIPELINE_STAGE_NORMAL)
{ {
if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT) if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT)
{ {
@ -583,7 +583,7 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveConstToVariable(m_Section->m_Jump.TargetPC, &g_System->m_JumpToLocation, "System::m_JumpToLocation");
} }
else if (m_Section->m_Cont.FallThrough) else if (m_Section->m_Cont.FallThrough)
{ {
@ -591,7 +591,7 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
MoveConstToVariable(m_Section->m_Cont.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveConstToVariable(m_Section->m_Cont.TargetPC, &g_System->m_JumpToLocation, "System::m_JumpToLocation");
} }
if (m_Section->m_Jump.LinkLocation != nullptr || m_Section->m_Jump.LinkLocation2 != nullptr) if (m_Section->m_Jump.LinkLocation != nullptr || m_Section->m_Jump.LinkLocation2 != nullptr)
@ -603,7 +603,7 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
CPU_Message(" "); CPU_Message(" ");
CPU_Message(" %s:", m_Section->m_Jump.BranchLabel.c_str()); CPU_Message(" %s:", m_Section->m_Jump.BranchLabel.c_str());
LinkJump(m_Section->m_Jump); LinkJump(m_Section->m_Jump);
MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveConstToVariable(m_Section->m_Jump.TargetPC, &g_System->m_JumpToLocation, "System::m_JumpToLocation");
} }
if (m_Section->m_Cont.LinkLocation != nullptr || m_Section->m_Cont.LinkLocation2 != nullptr) if (m_Section->m_Cont.LinkLocation != nullptr || m_Section->m_Cont.LinkLocation2 != nullptr)
{ {
@ -614,7 +614,7 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
CPU_Message(" "); CPU_Message(" ");
CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str()); CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str());
LinkJump(m_Section->m_Cont); LinkJump(m_Section->m_Cont);
MoveConstToVariable(m_Section->m_Cont.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveConstToVariable(m_Section->m_Cont.TargetPC, &g_System->m_JumpToLocation, "System::m_JumpToLocation");
} }
if (DelayLinkLocation) if (DelayLinkLocation)
{ {
@ -628,9 +628,9 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
ResetX86Protection(); ResetX86Protection();
RegBeforeDelay = m_RegWorkingSet; RegBeforeDelay = m_RegWorkingSet;
} }
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT_DONE)
{ {
if (EffectDelaySlot) if (EffectDelaySlot)
{ {
@ -684,7 +684,7 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
CPU_Message(" %s:", JumpInfo->BranchLabel.c_str()); CPU_Message(" %s:", JumpInfo->BranchLabel.c_str());
LinkJump(*JumpInfo); LinkJump(*JumpInfo);
JumpInfo->FallThrough = true; JumpInfo->FallThrough = true;
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
m_RegWorkingSet = RegBeforeDelay; m_RegWorkingSet = RegBeforeDelay;
return; return;
} }
@ -721,20 +721,20 @@ void CX86RecompilerOps::Compile_Branch(BRANCH_COMPARE CompareType, BRANCH_TYPE B
} }
} }
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
else else
{ {
if (HaveDebugger()) if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_PipelineStage).c_str());
} }
} }
} }
void CX86RecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link) void CX86RecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Link)
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == PIPELINE_STAGE_NORMAL)
{ {
if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT) if (CompareType == CompareTypeCOP1BCF || CompareType == CompareTypeCOP1BCT)
{ {
@ -813,7 +813,7 @@ void CX86RecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Li
{ {
LinkJump(m_Section->m_Jump); LinkJump(m_Section->m_Jump);
MoveConstToVariable(m_Section->m_Jump.TargetPC, &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveConstToVariable(m_Section->m_Jump.TargetPC, &g_System->m_JumpToLocation, "System::m_JumpToLocation");
OverflowDelaySlot(false); OverflowDelaySlot(false);
CPU_Message(" "); CPU_Message(" ");
CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str()); CPU_Message(" %s:", m_Section->m_Cont.BranchLabel.c_str());
@ -829,14 +829,14 @@ void CX86RecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Li
} }
else else
{ {
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
if (g_System->bLinkBlocks()) if (g_System->bLinkBlocks())
{ {
m_Section->m_Jump.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
else else
{ {
@ -847,20 +847,20 @@ void CX86RecompilerOps::Compile_BranchLikely(BRANCH_COMPARE CompareType, bool Li
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
} }
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
} }
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT_DONE)
{ {
ResetX86Protection(); ResetX86Protection();
m_Section->m_Jump.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
else if (HaveDebugger()) else if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n%s\nNextInstruction = %X", __FUNCTION__, m_PipelineStage).c_str());
} }
} }
@ -2130,11 +2130,11 @@ void CX86RecompilerOps::COP1_BCT_Compare()
// Opcode functions // Opcode functions
void CX86RecompilerOps::J() void CX86RecompilerOps::J()
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == PIPELINE_STAGE_NORMAL)
{ {
if ((m_CompilePC & 0xFFC) == 0xFFC) if ((m_CompilePC & 0xFFC) == 0xFFC)
{ {
MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2), &g_System->m_JumpToLocation, "System::m_JumpToLocation");
OverflowDelaySlot(false); OverflowDelaySlot(false);
return; return;
} }
@ -2152,23 +2152,23 @@ void CX86RecompilerOps::J()
m_Section->m_Jump.FallThrough = true; m_Section->m_Jump.FallThrough = true;
m_Section->m_Jump.LinkLocation = nullptr; m_Section->m_Jump.LinkLocation = nullptr;
m_Section->m_Jump.LinkLocation2 = nullptr; m_Section->m_Jump.LinkLocation2 = nullptr;
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT_DONE)
{ {
m_Section->m_Jump.RegSet = m_RegWorkingSet; m_Section->m_Jump.RegSet = m_RegWorkingSet;
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
else if (HaveDebugger()) else if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n\nJ\nNextInstruction = %X", m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n\nJ\nNextInstruction = %X", m_PipelineStage).c_str());
} }
} }
void CX86RecompilerOps::JAL() void CX86RecompilerOps::JAL()
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == PIPELINE_STAGE_NORMAL)
{ {
Map_GPR_32bit(31, true, -1); Map_GPR_32bit(31, true, -1);
MoveVariableToX86reg(_PROGRAM_COUNTER, "_PROGRAM_COUNTER", GetMipsRegMapLo(31)); MoveVariableToX86reg(_PROGRAM_COUNTER, "_PROGRAM_COUNTER", GetMipsRegMapLo(31));
@ -2176,7 +2176,7 @@ void CX86RecompilerOps::JAL()
AddConstToX86Reg(GetMipsRegMapLo(31), (m_CompilePC + 8) & ~0xF0000000); AddConstToX86Reg(GetMipsRegMapLo(31), (m_CompilePC + 8) & ~0xF0000000);
if ((m_CompilePC & 0xFFC) == 0xFFC) if ((m_CompilePC & 0xFFC) == 0xFFC)
{ {
MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveConstToVariable((m_CompilePC & 0xF0000000) + (m_Opcode.target << 2), &g_System->m_JumpToLocation, "System::m_JumpToLocation");
OverflowDelaySlot(false); OverflowDelaySlot(false);
return; return;
} }
@ -2193,9 +2193,9 @@ void CX86RecompilerOps::JAL()
m_Section->m_Jump.FallThrough = true; m_Section->m_Jump.FallThrough = true;
m_Section->m_Jump.LinkLocation = nullptr; m_Section->m_Jump.LinkLocation = nullptr;
m_Section->m_Jump.LinkLocation2 = nullptr; m_Section->m_Jump.LinkLocation2 = nullptr;
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT_DONE)
{ {
if (m_Section->m_JumpSection) if (m_Section->m_JumpSection)
{ {
@ -2218,7 +2218,7 @@ void CX86RecompilerOps::JAL()
CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, bCheck ? CExitInfo::Normal : CExitInfo::Normal_NoSysCheck, true, nullptr); CompileExit((uint32_t)-1, (uint32_t)-1, m_RegWorkingSet, bCheck ? CExitInfo::Normal : CExitInfo::Normal_NoSysCheck, true, nullptr);
} }
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
else else
{ {
@ -4799,19 +4799,19 @@ void CX86RecompilerOps::SPECIAL_SRAV()
void CX86RecompilerOps::SPECIAL_JR() void CX86RecompilerOps::SPECIAL_JR()
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == PIPELINE_STAGE_NORMAL)
{ {
if ((m_CompilePC & 0xFFC) == 0xFFC) if ((m_CompilePC & 0xFFC) == 0xFFC)
{ {
if (IsMapped(m_Opcode.rs)) if (IsMapped(m_Opcode.rs))
{ {
MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &g_System->m_JumpToLocation, "System::m_JumpToLocation");
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
} }
else else
{ {
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), &g_System->m_JumpToLocation, "System::m_JumpToLocation");
} }
OverflowDelaySlot(true); OverflowDelaySlot(true);
return; return;
@ -4839,9 +4839,9 @@ void CX86RecompilerOps::SPECIAL_JR()
MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER"); MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), _PROGRAM_COUNTER, "PROGRAM_COUNTER");
} }
} }
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT_DONE)
{ {
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0))
{ {
@ -4868,17 +4868,17 @@ void CX86RecompilerOps::SPECIAL_JR()
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
} }
} }
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
else if (HaveDebugger()) else if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_PipelineStage).c_str());
} }
} }
void CX86RecompilerOps::SPECIAL_JALR() void CX86RecompilerOps::SPECIAL_JALR()
{ {
if (m_NextInstruction == NORMAL) if (m_PipelineStage == PIPELINE_STAGE_NORMAL)
{ {
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0) && (m_CompilePC & 0xFFC) != 0xFFC) if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0) && (m_CompilePC & 0xFFC) != 0xFFC)
{ {
@ -4902,13 +4902,13 @@ void CX86RecompilerOps::SPECIAL_JALR()
{ {
if (IsMapped(m_Opcode.rs)) if (IsMapped(m_Opcode.rs))
{ {
MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveX86regToVariable(GetMipsRegMapLo(m_Opcode.rs), &g_System->m_JumpToLocation, "System::m_JumpToLocation");
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
} }
else else
{ {
m_RegWorkingSet.WriteBackRegisters(); m_RegWorkingSet.WriteBackRegisters();
MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), &R4300iOp::m_JumpToLocation, "R4300iOp::m_JumpToLocation"); MoveX86regToVariable(Map_TempReg(x86_Any, m_Opcode.rs, false), &g_System->m_JumpToLocation, "System::m_JumpToLocation");
} }
OverflowDelaySlot(true); OverflowDelaySlot(true);
return; return;
@ -4921,9 +4921,9 @@ void CX86RecompilerOps::SPECIAL_JALR()
m_Section->m_Cont.LinkLocation = nullptr; m_Section->m_Cont.LinkLocation = nullptr;
m_Section->m_Cont.LinkLocation2 = nullptr; m_Section->m_Cont.LinkLocation2 = nullptr;
m_NextInstruction = DO_DELAY_SLOT; m_PipelineStage = PIPELINE_STAGE_DO_DELAY_SLOT;
} }
else if (m_NextInstruction == DELAY_SLOT_DONE) else if (m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT_DONE)
{ {
if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0)) if (DelaySlotEffectsCompare(m_CompilePC, m_Opcode.rs, 0))
{ {
@ -4950,18 +4950,18 @@ void CX86RecompilerOps::SPECIAL_JALR()
m_Section->GenerateSectionLinkage(); m_Section->GenerateSectionLinkage();
} }
} }
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
else if (HaveDebugger()) else if (HaveDebugger())
{ {
g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_NextInstruction).c_str()); g_Notify->DisplayError(stdstr_f("WTF\n\nBranch\nNextInstruction = %X", m_PipelineStage).c_str());
} }
} }
void CX86RecompilerOps::SPECIAL_SYSCALL() void CX86RecompilerOps::SPECIAL_SYSCALL()
{ {
CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::DoSysCall, true, nullptr); CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::DoSysCall, true, nullptr);
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
void CX86RecompilerOps::SPECIAL_MFLO() void CX86RecompilerOps::SPECIAL_MFLO()
@ -7824,7 +7824,7 @@ void CX86RecompilerOps::COP0_CO_ERET(void)
UpdateCounters(m_RegWorkingSet, true, true); UpdateCounters(m_RegWorkingSet, true, true);
CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, nullptr); CompileExit(m_CompilePC, (uint32_t)-1, m_RegWorkingSet, CExitInfo::Normal, true, nullptr);
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
// FPU options // FPU options
@ -8784,7 +8784,7 @@ void CX86RecompilerOps::UnknownOpcode()
MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); MoveConstToVariable(m_Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex");
Call_Direct((void *)R4300iOp::UnknownOpcode, "R4300iOp::UnknownOpcode"); Call_Direct((void *)R4300iOp::UnknownOpcode, "R4300iOp::UnknownOpcode");
Ret(); Ret();
if (m_NextInstruction == NORMAL) { m_NextInstruction = END_BLOCK; } if (m_PipelineStage == PIPELINE_STAGE_NORMAL) { m_PipelineStage = PIPELINE_STAGE_END_BLOCK; }
} }
void CX86RecompilerOps::ClearCachedInstructionInfo() void CX86RecompilerOps::ClearCachedInstructionInfo()
@ -8809,11 +8809,11 @@ void CX86RecompilerOps::ClearCachedInstructionInfo()
void CX86RecompilerOps::FoundMemoryBreakpoint() void CX86RecompilerOps::FoundMemoryBreakpoint()
{ {
ClearCachedInstructionInfo(); ClearCachedInstructionInfo();
MoveConstToVariable((m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT) ? 1 : 0, &memory_write_in_delayslot, "memory_write_in_delayslot"); MoveConstToVariable((m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT) ? 1 : 0, &memory_write_in_delayslot, "memory_write_in_delayslot");
Call_Direct((void *)x86MemoryBreakpoint, "x86MemoryBreakpoint"); Call_Direct((void *)x86MemoryBreakpoint, "x86MemoryBreakpoint");
MoveConstToVariable(0, &memory_breakpoint_found, "memory_breakpoint_found"); MoveConstToVariable(0, &memory_breakpoint_found, "memory_breakpoint_found");
ExitCodeBlock(); ExitCodeBlock();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
void CX86RecompilerOps::PreReadInstruction() void CX86RecompilerOps::PreReadInstruction()
@ -8838,7 +8838,7 @@ void CX86RecompilerOps::TestBreakpoint(x86Reg AddressReg, void * FunctAddress, c
{ {
m_RegWorkingSet.BeforeCallDirect(); m_RegWorkingSet.BeforeCallDirect();
MoveX86regToVariable(AddressReg, &memory_access_address, "memory_access_address"); MoveX86regToVariable(AddressReg, &memory_access_address, "memory_access_address");
MoveConstToVariable((m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT) ? 1 : 0, &memory_write_in_delayslot, "memory_write_in_delayslot"); MoveConstToVariable((m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT) ? 1 : 0, &memory_write_in_delayslot, "memory_write_in_delayslot");
Call_Direct(FunctAddress, FunctName); Call_Direct(FunctAddress, FunctName);
m_RegWorkingSet.AfterCallDirect(); m_RegWorkingSet.AfterCallDirect();
CompConstToVariable(0, &memory_breakpoint_found, "memory_breakpoint_found"); CompConstToVariable(0, &memory_breakpoint_found, "memory_breakpoint_found");
@ -8910,7 +8910,7 @@ void CX86RecompilerOps::CompileExitCode()
CPU_Message(""); CPU_Message("");
CPU_Message(" $Exit_%d", ExitIter->ID); CPU_Message(" $Exit_%d", ExitIter->ID);
SetJump32(ExitIter->JumpLoc, (uint32_t *)*g_RecompPos); SetJump32(ExitIter->JumpLoc, (uint32_t *)*g_RecompPos);
m_NextInstruction = ExitIter->NextInstruction; m_PipelineStage = ExitIter->PipelineStage;
CompileExit((uint32_t)-1, ExitIter->TargetPC, ExitIter->ExitRegSet, ExitIter->reason, true, nullptr); CompileExit((uint32_t)-1, ExitIter->TargetPC, ExitIter->ExitRegSet, ExitIter->reason, true, nullptr);
} }
} }
@ -9676,14 +9676,14 @@ void CX86RecompilerOps::SetCurrentSection(CCodeSection * section)
m_Section = section; m_Section = section;
} }
void CX86RecompilerOps::SetNextStepType(STEP_TYPE StepType) void CX86RecompilerOps::SetNextStepType(PIPELINE_STAGE StepType)
{ {
m_NextInstruction = StepType; m_PipelineStage = StepType;
} }
STEP_TYPE CX86RecompilerOps::GetNextStepType(void) PIPELINE_STAGE CX86RecompilerOps::GetNextStepType(void)
{ {
return m_NextInstruction; return m_PipelineStage;
} }
const OPCODE & CX86RecompilerOps::GetOpcode(void) const const OPCODE & CX86RecompilerOps::GetOpcode(void) const
@ -9780,7 +9780,7 @@ void CX86RecompilerOps::CompileSystemCheck(uint32_t TargetPC, const CRegInfo & R
void CX86RecompilerOps::CompileExecuteBP(void) void CX86RecompilerOps::CompileExecuteBP(void)
{ {
bool bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT; bool bDelay = m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT;
if (bDelay) if (bDelay)
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
@ -9802,12 +9802,12 @@ void CX86RecompilerOps::CompileExecuteBP(void)
} }
Call_Direct((void *)x86_compiler_Break_Point, "x86_compiler_Break_Point"); Call_Direct((void *)x86_compiler_Break_Point, "x86_compiler_Break_Point");
ExitCodeBlock(); ExitCodeBlock();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
void CX86RecompilerOps::CompileExecuteDelaySlotBP(void) void CX86RecompilerOps::CompileExecuteDelaySlotBP(void)
{ {
bool bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT; bool bDelay = m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT;
if (bDelay) if (bDelay)
{ {
g_Notify->BreakPoint(__FILE__, __LINE__); g_Notify->BreakPoint(__FILE__, __LINE__);
@ -9829,7 +9829,7 @@ void CX86RecompilerOps::CompileExecuteDelaySlotBP(void)
} }
Call_Direct((void *)x86_Break_Point_DelaySlot, "x86_Break_Point_DelaySlot"); Call_Direct((void *)x86_Break_Point_DelaySlot, "x86_Break_Point_DelaySlot");
ExitCodeBlock(); ExitCodeBlock();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
void CX86RecompilerOps::OverflowDelaySlot(bool TestTimer) void CX86RecompilerOps::OverflowDelaySlot(bool TestTimer)
@ -9850,7 +9850,7 @@ void CX86RecompilerOps::OverflowDelaySlot(bool TestTimer)
#endif #endif
} }
MoveConstToVariable(JUMP, &R4300iOp::m_NextInstruction, "R4300iOp::m_NextInstruction"); MoveConstToVariable(PIPELINE_STAGE_JUMP, &g_System->m_PipelineStage, "System->m_PipelineStage");
if (TestTimer) if (TestTimer)
{ {
@ -9878,7 +9878,7 @@ void CX86RecompilerOps::OverflowDelaySlot(bool TestTimer)
} }
ExitCodeBlock(); ExitCodeBlock();
m_NextInstruction = END_BLOCK; m_PipelineStage = PIPELINE_STAGE_END_BLOCK;
} }
void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason) void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo &ExitRegSet, CExitInfo::EXIT_REASON reason)
@ -9904,7 +9904,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
ExitInfo.TargetPC = TargetPC; ExitInfo.TargetPC = TargetPC;
ExitInfo.ExitRegSet = ExitRegSet; ExitInfo.ExitRegSet = ExitRegSet;
ExitInfo.reason = reason; ExitInfo.reason = reason;
ExitInfo.NextInstruction = m_NextInstruction; ExitInfo.PipelineStage = m_PipelineStage;
ExitInfo.JumpLoc = (uint32_t *)(*g_RecompPos - 4); ExitInfo.JumpLoc = (uint32_t *)(*g_RecompPos - 4);
m_ExitInfo.push_back(ExitInfo); m_ExitInfo.push_back(ExitInfo);
return; return;
@ -10062,7 +10062,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
break; break;
case CExitInfo::DoSysCall: case CExitInfo::DoSysCall:
{ {
bool bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT; bool bDelay = m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT;
PushImm32(bDelay ? "true" : "false", bDelay); PushImm32(bDelay ? "true" : "false", bDelay);
#ifdef _MSC_VER #ifdef _MSC_VER
MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX);
@ -10077,7 +10077,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
break; break;
case CExitInfo::COP1_Unuseable: case CExitInfo::COP1_Unuseable:
{ {
bool bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT; bool bDelay = m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT;
PushImm32("1", 1); PushImm32("1", 1);
PushImm32(bDelay ? "true" : "false", bDelay); PushImm32(bDelay ? "true" : "false", bDelay);
#ifdef _MSC_VER #ifdef _MSC_VER
@ -10098,7 +10098,7 @@ void CX86RecompilerOps::CompileExit(uint32_t JumpPC, uint32_t TargetPC, CRegInfo
case CExitInfo::TLBReadMiss: case CExitInfo::TLBReadMiss:
MoveVariableToX86reg(g_TLBLoadAddress, "g_TLBLoadAddress", x86_EDX); MoveVariableToX86reg(g_TLBLoadAddress, "g_TLBLoadAddress", x86_EDX);
Push(x86_EDX); Push(x86_EDX);
PushImm32(m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT); PushImm32(m_PipelineStage == PIPELINE_STAGE_JUMP || m_PipelineStage == PIPELINE_STAGE_DELAY_SLOT);
#ifdef _MSC_VER #ifdef _MSC_VER
MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX);
Call_Direct(AddressOf(&CRegisters::DoTLBReadMiss), "CRegisters::DoTLBReadMiss"); Call_Direct(AddressOf(&CRegisters::DoTLBReadMiss), "CRegisters::DoTLBReadMiss");

View File

@ -223,8 +223,8 @@ public:
void SetCurrentPC(uint32_t ProgramCounter); void SetCurrentPC(uint32_t ProgramCounter);
uint32_t GetCurrentPC(void); uint32_t GetCurrentPC(void);
void SetCurrentSection(CCodeSection * section); void SetCurrentSection(CCodeSection * section);
void SetNextStepType(STEP_TYPE StepType); void SetNextStepType(PIPELINE_STAGE StepType);
STEP_TYPE GetNextStepType(void); PIPELINE_STAGE GetNextStepType(void);
const OPCODE & GetOpcode(void) const; const OPCODE & GetOpcode(void) const;
void PreCompileOpcode(void); void PreCompileOpcode(void);
void PostCompileOpcode(void); void PostCompileOpcode(void);
@ -367,7 +367,7 @@ private:
void ResetMemoryStack(); void ResetMemoryStack();
EXIT_LIST m_ExitInfo; EXIT_LIST m_ExitInfo;
static STEP_TYPE m_NextInstruction; static PIPELINE_STAGE m_PipelineStage;
static uint32_t m_CompilePC; static uint32_t m_CompilePC;
static OPCODE m_Opcode; static OPCODE m_Opcode;
static CX86RegInfo m_RegWorkingSet; static CX86RegInfo m_RegWorkingSet;

View File

@ -344,7 +344,7 @@ LRESULT CDebugSymbols::OnListCacheHint(NMHDR * pNMHDR)
return 0; return 0;
} }
LRESULT CDebugSymbols::OnFilterChanged(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& /*bHandled*/) LRESULT CDebugSymbols::OnFilterChanged(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& /*bHandled*/)
{ {
if (::GetWindowTextLength(GetDlgItem(IDC_FILTER_EDIT)) == 0) if (::GetWindowTextLength(GetDlgItem(IDC_FILTER_EDIT)) == 0)
{ {

View File

@ -698,7 +698,7 @@ void CDebuggerUI::CPUStepEnded()
if (op == R4300i_JAL || ((op == R4300i_SPECIAL) && (funct == R4300i_SPECIAL_JALR) && (Opcode.rd == 31))) // JAL or JALR RA, x if (op == R4300i_JAL || ((op == R4300i_SPECIAL) && (funct == R4300i_SPECIAL_JALR) && (Opcode.rd == 31))) // JAL or JALR RA, x
{ {
m_StackTrace->PushEntry(R4300iOp::m_JumpToLocation, g_Reg->m_PROGRAM_COUNTER); m_StackTrace->PushEntry(g_System->JumpToLocation(), g_Reg->m_PROGRAM_COUNTER);
} }
else if (funct == R4300i_SPECIAL_JR && Opcode.rs == 31) // JR RA else if (funct == R4300i_SPECIAL_JR && Opcode.rs == 31) // JR RA
{ {