Skip to content

Commit

Permalink
irjit: Fix likely delay slot breakpoints.
Browse files Browse the repository at this point in the history
  • Loading branch information
unknownbrackets committed Sep 3, 2023
1 parent e1a1f56 commit 259734b
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Core/Debugger/Breakpoints.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ BreakAction CBreakPoints::ExecBreakPoint(u32 addr) {
std::unique_lock<std::mutex> guard(breakPointsMutex_);
size_t bp = FindBreakpoint(addr, false);
if (bp != INVALID_BREAKPOINT) {
BreakPoint info = breakPoints_[bp];
const BreakPoint &info = breakPoints_[bp];
guard.unlock();

if (info.hasCond) {
Expand Down
44 changes: 32 additions & 12 deletions Core/MIPS/IR/IRFrontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -340,13 +340,24 @@ void IRFrontend::CheckBreakpoint(u32 addr) {
if (CBreakPoints::IsAddressBreakPoint(addr)) {
FlushAll();

if (GetCompilerPC() != js.blockStart)
ir.Write(IROp::SetPCConst, 0, ir.AddConstant(GetCompilerPC()));

RestoreRoundingMode();
ir.Write(IROp::SetPCConst, 0, ir.AddConstant(GetCompilerPC()));
// 0 because we normally execute before increasing.
// TODO: In likely branches, downcount will be incorrect.
int downcountOffset = js.inDelaySlot && js.downcountAmount >= 2 ? -2 : 0;
// At this point, downcount HAS the delay slot, but not the instruction itself.
int downcountOffset = 0;
if (js.inDelaySlot) {
MIPSOpcode branchOp = Memory::Read_Opcode_JIT(GetCompilerPC());
MIPSOpcode delayOp = Memory::Read_Opcode_JIT(addr);
downcountOffset = -MIPSGetInstructionCycleEstimate(delayOp);
if ((MIPSGetInfo(branchOp) & LIKELY) != 0) {
// Okay, we're in a likely branch. Also negate the branch cycles.
downcountOffset += -MIPSGetInstructionCycleEstimate(branchOp);
}
}
int downcountAmount = js.downcountAmount + downcountOffset;
ir.Write(IROp::Downcount, 0, ir.AddConstant(downcountAmount));
if (downcountAmount != 0)
ir.Write(IROp::Downcount, 0, ir.AddConstant(downcountAmount));
// Note that this means downcount can't be metadata on the block.
js.downcountAmount = -downcountOffset;
ir.Write(IROp::Breakpoint, 0, ir.AddConstant(addr));
Expand All @@ -360,16 +371,25 @@ void IRFrontend::CheckMemoryBreakpoint(int rs, int offset) {
if (CBreakPoints::HasMemChecks()) {
FlushAll();

if (GetCompilerPC() != js.blockStart)
ir.Write(IROp::SetPCConst, 0, ir.AddConstant(GetCompilerPC()));

RestoreRoundingMode();
ir.Write(IROp::SetPCConst, 0, ir.AddConstant(GetCompilerPC()));
// 0 because we normally execute before increasing.
int downcountOffset = js.inDelaySlot ? -2 : -1;
// TODO: In likely branches, downcount will be incorrect. This might make resume fail.
if (js.downcountAmount == 0) {
downcountOffset = 0;
// At this point, downcount HAS the delay slot, but not the instruction itself.
int downcountOffset = 0;
if (js.inDelaySlot) {
// We assume delay slot in compilerPC + 4.
MIPSOpcode branchOp = Memory::Read_Opcode_JIT(GetCompilerPC());
MIPSOpcode delayOp = Memory::Read_Opcode_JIT(GetCompilerPC() + 4);
downcountOffset = -MIPSGetInstructionCycleEstimate(delayOp);
if ((MIPSGetInfo(branchOp) & LIKELY) != 0) {
// Okay, we're in a likely branch. Also negate the branch cycles.
downcountOffset += -MIPSGetInstructionCycleEstimate(branchOp);
}
}
int downcountAmount = js.downcountAmount + downcountOffset;
ir.Write(IROp::Downcount, 0, ir.AddConstant(downcountAmount));
if (downcountAmount != 0)
ir.Write(IROp::Downcount, 0, ir.AddConstant(downcountAmount));
// Note that this means downcount can't be metadata on the block.
js.downcountAmount = -downcountOffset;
ir.Write(IROp::MemoryCheck, js.inDelaySlot ? 4 : 0, rs, ir.AddConstant(offset));
Expand Down
2 changes: 1 addition & 1 deletion Core/MIPS/IR/IRInterpreter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) {
break;

case IROp::Downcount:
mips->downcount -= inst->constant;
mips->downcount -= (int)inst->constant;
break;

case IROp::SetPC:
Expand Down

0 comments on commit 259734b

Please sign in to comment.