[Project64] Handle break point in delay slot
This commit is contained in:
parent
f20dca31fd
commit
ba0124efa8
|
@ -5393,6 +5393,11 @@ void CArmRecompilerOps::CompileExecuteBP(void)
|
|||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
void CArmRecompilerOps::CompileExecuteDelaySlotBP(void)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
|
||||
CRegInfo & CArmRecompilerOps::GetRegWorkingSet(void)
|
||||
{
|
||||
return m_RegWorkingSet;
|
||||
|
|
|
@ -225,6 +225,7 @@ private:
|
|||
void CompileReadTLBMiss(ArmReg AddressReg, ArmReg LookUpReg);
|
||||
void CompileWriteTLBMiss(ArmReg AddressReg, ArmReg LookUpReg);
|
||||
void CompileExecuteBP(void);
|
||||
void CompileExecuteDelaySlotBP(void);
|
||||
|
||||
/********* Helper Functions *********/
|
||||
typedef CRegInfo::REG_STATE REG_STATE;
|
||||
|
|
|
@ -26,6 +26,50 @@ void InPermLoop();
|
|||
|
||||
bool DelaySlotEffectsCompare(uint32_t PC, uint32_t Reg1, uint32_t Reg2);
|
||||
|
||||
static bool OpHasDelaySlot(const OPCODE & Opcode)
|
||||
{
|
||||
if (Opcode.op == R4300i_J ||
|
||||
Opcode.op == R4300i_JAL ||
|
||||
Opcode.op == R4300i_BEQ ||
|
||||
Opcode.op == R4300i_BNE ||
|
||||
Opcode.op == R4300i_BLEZ ||
|
||||
Opcode.op == R4300i_BGTZ ||
|
||||
Opcode.op == R4300i_BEQL ||
|
||||
Opcode.op == R4300i_BNEL ||
|
||||
Opcode.op == R4300i_BLEZL ||
|
||||
Opcode.op == R4300i_BGTZL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else if (Opcode.op == R4300i_SPECIAL)
|
||||
{
|
||||
if (Opcode.funct == R4300i_SPECIAL_JR ||
|
||||
Opcode.funct == R4300i_SPECIAL_JALR)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (Opcode.op == R4300i_REGIMM)
|
||||
{
|
||||
if (Opcode.rt == R4300i_REGIMM_BLTZ ||
|
||||
Opcode.rt == R4300i_REGIMM_BGEZ ||
|
||||
Opcode.rt == R4300i_REGIMM_BLTZL ||
|
||||
Opcode.rt == R4300i_REGIMM_BGEZL ||
|
||||
Opcode.rt == R4300i_REGIMM_BLTZAL ||
|
||||
Opcode.rt == R4300i_REGIMM_BGEZAL ||
|
||||
Opcode.rt == R4300i_REGIMM_BLTZALL ||
|
||||
Opcode.rt == R4300i_REGIMM_BGEZALL)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (Opcode.op == R4300i_CP1 && Opcode.fmt == R4300i_COP1_BC)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool DelaySlotEffectsJump(uint32_t JumpPC)
|
||||
{
|
||||
OPCODE Command;
|
||||
|
@ -476,6 +520,12 @@ bool CCodeSection::GenerateNativeCode(uint32_t Test)
|
|||
m_BlockInfo->SetVAddrLast(m_RecompilerOps->GetCurrentPC());
|
||||
}
|
||||
|
||||
if (isDebugging() && HaveExecutionBP() && OpHasDelaySlot(Opcode) && g_Debugger->ExecutionBP(m_RecompilerOps->GetCurrentPC() + 4))
|
||||
{
|
||||
m_RecompilerOps->CompileExecuteDelaySlotBP();
|
||||
break;
|
||||
}
|
||||
|
||||
if (isDebugging() && HaveExecutionBP() && g_Debugger->ExecutionBP(m_RecompilerOps->GetCurrentPC()))
|
||||
{
|
||||
m_RecompilerOps->CompileExecuteBP();
|
||||
|
|
|
@ -223,4 +223,5 @@ public:
|
|||
virtual void PostCompileOpcode(void) = 0;
|
||||
virtual void UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false) = 0;
|
||||
virtual void CompileExecuteBP(void) = 0;
|
||||
virtual void CompileExecuteDelaySlotBP(void) = 0;
|
||||
};
|
||||
|
|
|
@ -87,6 +87,29 @@ static void x86_compiler_Break_Point()
|
|||
}
|
||||
}
|
||||
|
||||
static void x86_Break_Point_DelaySlot()
|
||||
{
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
if (g_SyncSystem)
|
||||
{
|
||||
g_System->UpdateSyncCPU(g_SyncSystem, g_System->CountPerOp());
|
||||
g_System->SyncCPU(g_SyncSystem);
|
||||
}
|
||||
if (g_Debugger->ExecutionBP(g_Reg->m_PROGRAM_COUNTER))
|
||||
{
|
||||
x86_compiler_Break_Point();
|
||||
}
|
||||
if (R4300iOp::m_NextInstruction != NORMAL)
|
||||
{
|
||||
CInterpreterCPU::ExecuteOps(g_System->CountPerOp());
|
||||
if (g_SyncSystem)
|
||||
{
|
||||
g_System->UpdateSyncCPU(g_SyncSystem, g_System->CountPerOp());
|
||||
g_System->SyncCPU(g_SyncSystem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t memory_access_address;
|
||||
static uint32_t memory_write_in_delayslot;
|
||||
static uint32_t memory_breakpoint_found = 0;
|
||||
|
@ -10060,6 +10083,32 @@ void CX86RecompilerOps::CompileExecuteBP(void)
|
|||
m_NextInstruction = END_BLOCK;
|
||||
}
|
||||
|
||||
void CX86RecompilerOps::CompileExecuteDelaySlotBP(void)
|
||||
{
|
||||
bool bDelay = m_NextInstruction == JUMP || m_NextInstruction == DELAY_SLOT;
|
||||
if (bDelay)
|
||||
{
|
||||
g_Notify->BreakPoint(__FILE__, __LINE__);
|
||||
}
|
||||
m_RegWorkingSet.WriteBackRegisters();
|
||||
|
||||
UpdateCounters(m_RegWorkingSet, true, true);
|
||||
if (g_SyncSystem)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
MoveConstToX86reg((uint32_t)g_BaseSystem, x86_ECX);
|
||||
Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem");
|
||||
#else
|
||||
PushImm32((uint32_t)g_BaseSystem);
|
||||
Call_Direct(AddressOf(&CN64System::SyncSystem), "CN64System::SyncSystem");
|
||||
AddConstToX86Reg(x86_ESP, 4);
|
||||
#endif
|
||||
}
|
||||
Call_Direct((void *)x86_Break_Point_DelaySlot, "x86_Break_Point_DelaySlot");
|
||||
ExitCodeBlock();
|
||||
m_NextInstruction = END_BLOCK;
|
||||
}
|
||||
|
||||
void CX86RecompilerOps::OverflowDelaySlot(bool TestTimer)
|
||||
{
|
||||
m_RegWorkingSet.WriteBackRegisters();
|
||||
|
|
|
@ -242,6 +242,7 @@ public:
|
|||
void UpdateCounters(CRegInfo & RegSet, bool CheckTimer, bool ClearValues = false);
|
||||
void CompileSystemCheck(uint32_t TargetPC, const CRegInfo & RegSet);
|
||||
void CompileExecuteBP(void);
|
||||
void CompileExecuteDelaySlotBP(void);
|
||||
static void ChangeDefaultRoundingModel();
|
||||
void OverflowDelaySlot(bool TestTimer);
|
||||
|
||||
|
|
Loading…
Reference in New Issue