Merge pull request #4218 from aldelaro5/debugger-stepping-fixes
Fix a bunch of debugger stepping issues.
This commit is contained in:
commit
ad1d45d4e2
|
@ -149,8 +149,6 @@ void CCodeWindow::OnHostMessage(wxCommandEvent& event)
|
||||||
|
|
||||||
case IDM_UPDATE_DISASM_DIALOG:
|
case IDM_UPDATE_DISASM_DIALOG:
|
||||||
Update();
|
Update();
|
||||||
if (codeview)
|
|
||||||
codeview->Center(PC);
|
|
||||||
if (CPU::IsStepping())
|
if (CPU::IsStepping())
|
||||||
Parent->UpdateGUI();
|
Parent->UpdateGUI();
|
||||||
if (m_RegisterWindow)
|
if (m_RegisterWindow)
|
||||||
|
@ -160,7 +158,6 @@ void CCodeWindow::OnHostMessage(wxCommandEvent& event)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IDM_UPDATE_BREAKPOINTS:
|
case IDM_UPDATE_BREAKPOINTS:
|
||||||
Update();
|
|
||||||
if (m_BreakpointWindow)
|
if (m_BreakpointWindow)
|
||||||
m_BreakpointWindow->NotifyUpdate();
|
m_BreakpointWindow->NotifyUpdate();
|
||||||
break;
|
break;
|
||||||
|
@ -296,13 +293,13 @@ void CCodeWindow::SingleStep()
|
||||||
{
|
{
|
||||||
if (CPU::IsStepping())
|
if (CPU::IsStepping())
|
||||||
{
|
{
|
||||||
|
PowerPC::CoreMode old_mode = PowerPC::GetMode();
|
||||||
|
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
|
||||||
PowerPC::breakpoints.ClearAllTemporary();
|
PowerPC::breakpoints.ClearAllTemporary();
|
||||||
JitInterface::InvalidateICache(PC, 4, true);
|
|
||||||
CPU::StepOpcode(&sync_event);
|
CPU::StepOpcode(&sync_event);
|
||||||
wxThread::Sleep(20);
|
sync_event.WaitFor(std::chrono::milliseconds(20));
|
||||||
// need a short wait here
|
PowerPC::SetMode(old_mode);
|
||||||
JumpToAddress(PC);
|
// Will get a IDM_UPDATE_DISASM_DIALOG. Don't update the GUI here.
|
||||||
Update();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -316,20 +313,23 @@ void CCodeWindow::StepOver()
|
||||||
PowerPC::breakpoints.ClearAllTemporary();
|
PowerPC::breakpoints.ClearAllTemporary();
|
||||||
PowerPC::breakpoints.Add(PC + 4, true);
|
PowerPC::breakpoints.Add(PC + 4, true);
|
||||||
CPU::EnableStepping(false);
|
CPU::EnableStepping(false);
|
||||||
JumpToAddress(PC);
|
|
||||||
Update();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SingleStep();
|
SingleStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateButtonStates();
|
|
||||||
// Update all toolbars in the aui manager
|
|
||||||
Parent->UpdateGUI();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns true on a blr or on a bclr that evaluates to true.
|
||||||
|
static bool WillInstructionReturn(UGeckoInstruction inst)
|
||||||
|
{
|
||||||
|
bool counter = (inst.BO_2 >> 2 & 1) != 0 || (CTR != 0) != ((inst.BO_2 >> 1 & 1) != 0);
|
||||||
|
bool condition = inst.BO_2 >> 4 != 0 || GetCRBit(inst.BI_2) == (inst.BO_2 >> 3 & 1);
|
||||||
|
bool isBclr = inst.OPCD_7 == 0b010011 && (inst.hex >> 1 & 0b10000) != 0;
|
||||||
|
return isBclr && counter && condition && !inst.LK_3;
|
||||||
|
}
|
||||||
|
|
||||||
void CCodeWindow::StepOut()
|
void CCodeWindow::StepOut()
|
||||||
{
|
{
|
||||||
if (CPU::IsStepping())
|
if (CPU::IsStepping())
|
||||||
|
@ -337,13 +337,16 @@ void CCodeWindow::StepOut()
|
||||||
CPU::PauseAndLock(true, false);
|
CPU::PauseAndLock(true, false);
|
||||||
PowerPC::breakpoints.ClearAllTemporary();
|
PowerPC::breakpoints.ClearAllTemporary();
|
||||||
|
|
||||||
// Keep stepping until the next blr or timeout after one second
|
// Keep stepping until the next return instruction or timeout after one second
|
||||||
u64 timeout = SystemTimers::GetTicksPerSecond();
|
u64 timeout = SystemTimers::GetTicksPerSecond();
|
||||||
u64 steps = 0;
|
u64 steps = 0;
|
||||||
PowerPC::CoreMode oldMode = PowerPC::GetMode();
|
PowerPC::CoreMode old_mode = PowerPC::GetMode();
|
||||||
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
|
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
|
||||||
UGeckoInstruction inst = PowerPC::HostRead_Instruction(PC);
|
UGeckoInstruction inst = PowerPC::HostRead_Instruction(PC);
|
||||||
while (inst.hex != 0x4e800020 && steps < timeout) // check for blr
|
// Loop until either the current instruction is a return instruction with no Link flag
|
||||||
|
// or a breakpoint is detected so it can step at the breakpoint.
|
||||||
|
while (!(WillInstructionReturn(inst)) && steps < timeout &&
|
||||||
|
!PowerPC::breakpoints.IsAddressBreakPoint(PC))
|
||||||
{
|
{
|
||||||
if (inst.LK)
|
if (inst.LK)
|
||||||
{
|
{
|
||||||
|
@ -362,15 +365,14 @@ void CCodeWindow::StepOut()
|
||||||
}
|
}
|
||||||
inst = PowerPC::HostRead_Instruction(PC);
|
inst = PowerPC::HostRead_Instruction(PC);
|
||||||
}
|
}
|
||||||
|
// If the loop stopped because of a breakpoint, we do not want to step to
|
||||||
|
// an instruction after it.
|
||||||
|
if (!PowerPC::breakpoints.IsAddressBreakPoint(PC))
|
||||||
PowerPC::SingleStep();
|
PowerPC::SingleStep();
|
||||||
PowerPC::SetMode(oldMode);
|
PowerPC::SetMode(old_mode);
|
||||||
CPU::PauseAndLock(false, false);
|
CPU::PauseAndLock(false, false);
|
||||||
|
|
||||||
JumpToAddress(PC);
|
|
||||||
Update();
|
|
||||||
Host_UpdateDisasmDialog();
|
Host_UpdateDisasmDialog();
|
||||||
|
|
||||||
UpdateButtonStates();
|
UpdateButtonStates();
|
||||||
// Update all toolbars in the aui manager
|
// Update all toolbars in the aui manager
|
||||||
Parent->UpdateGUI();
|
Parent->UpdateGUI();
|
||||||
|
@ -698,7 +700,7 @@ void CCodeWindow::Update()
|
||||||
if (!codeview)
|
if (!codeview)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
codeview->Refresh();
|
codeview->Center(PC);
|
||||||
UpdateCallstack();
|
UpdateCallstack();
|
||||||
UpdateButtonStates();
|
UpdateButtonStates();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue