[Project64] Handle break point in delay slot

This commit is contained in:
zilmar 2018-07-30 06:07:45 +10:00
parent f20dca31fd
commit ba0124efa8
6 changed files with 107 additions and 0 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -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;
};

View File

@ -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();

View File

@ -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);