diff --git a/Core/MIPS/IR/IRFrontend.cpp b/Core/MIPS/IR/IRFrontend.cpp index 7cd47c3d11..38d54eb497 100644 --- a/Core/MIPS/IR/IRFrontend.cpp +++ b/Core/MIPS/IR/IRFrontend.cpp @@ -349,7 +349,7 @@ void IRFrontend::CheckBreakpoint(u32 addr) { 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); + ir.Write(IROp::Breakpoint, 0, ir.AddConstant(addr)); ApplyRoundingMode(); js.hadBreakpoints = true; @@ -372,7 +372,7 @@ void IRFrontend::CheckMemoryBreakpoint(int rs, int offset) { 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, 0, rs, ir.AddConstant(offset)); + ir.Write(IROp::MemoryCheck, js.inDelaySlot ? 4 : 0, rs, ir.AddConstant(offset)); ApplyRoundingMode(); js.hadBreakpoints = true; diff --git a/Core/MIPS/IR/IRInst.cpp b/Core/MIPS/IR/IRInst.cpp index c03d1ec76f..5f9b4d53f0 100644 --- a/Core/MIPS/IR/IRInst.cpp +++ b/Core/MIPS/IR/IRInst.cpp @@ -166,8 +166,8 @@ static const IRMeta irMeta[] = { { IROp::SetPC, "SetPC", "_G" }, { IROp::SetPCConst, "SetPC", "_C" }, { IROp::CallReplacement, "CallRepl", "_C", IRFLAG_BARRIER }, - { IROp::Breakpoint, "Breakpoint", "", IRFLAG_BARRIER }, - { IROp::MemoryCheck, "MemoryCheck", "_GC", IRFLAG_BARRIER }, + { IROp::Breakpoint, "Breakpoint", "_C", IRFLAG_BARRIER }, + { IROp::MemoryCheck, "MemoryCheck", "IGC", IRFLAG_BARRIER }, { IROp::ValidateAddress8, "ValidAddr8", "_GC", IRFLAG_BARRIER }, { IROp::ValidateAddress16, "ValidAddr16", "_GC", IRFLAG_BARRIER }, diff --git a/Core/MIPS/IR/IRInterpreter.cpp b/Core/MIPS/IR/IRInterpreter.cpp index ade6d64b62..01c6f05d42 100644 --- a/Core/MIPS/IR/IRInterpreter.cpp +++ b/Core/MIPS/IR/IRInterpreter.cpp @@ -60,20 +60,30 @@ alignas(16) static const uint32_t lowBytesMask[4] = { 0x000000FF, 0x000000FF, 0x000000FF, 0x000000FF, }; -u32 RunBreakpoint(u32 pc) { +u32 IRRunBreakpoint(u32 pc) { // Should we skip this breakpoint? - if (CBreakPoints::CheckSkipFirst() == pc) + uint32_t skipFirst = CBreakPoints::CheckSkipFirst(); + if (skipFirst == pc || skipFirst == currentMIPS->pc) return 0; - CBreakPoints::ExecBreakPoint(currentMIPS->pc); + // Did we already hit one? + if (coreState != CORE_RUNNING && coreState != CORE_NEXTFRAME) + return 1; + + CBreakPoints::ExecBreakPoint(pc); return coreState != CORE_RUNNING ? 1 : 0; } -u32 RunMemCheck(u32 pc, u32 addr) { +u32 IRRunMemCheck(u32 pc, u32 addr) { // Should we skip this breakpoint? - if (CBreakPoints::CheckSkipFirst() == pc) + uint32_t skipFirst = CBreakPoints::CheckSkipFirst(); + if (skipFirst == pc || skipFirst == currentMIPS->pc) return 0; + // Did we already hit one? + if (coreState != CORE_RUNNING && coreState != CORE_NEXTFRAME) + return 1; + CBreakPoints::ExecOpMemCheck(addr, pc); return coreState != CORE_RUNNING ? 1 : 0; } @@ -1100,14 +1110,14 @@ u32 IRInterpret(MIPSState *mips, const IRInst *inst, int count) { break; case IROp::Breakpoint: - if (RunBreakpoint(mips->pc)) { + if (IRRunBreakpoint(inst->constant)) { CoreTiming::ForceCheck(); return mips->pc; } break; case IROp::MemoryCheck: - if (RunMemCheck(mips->pc, mips->r[inst->src1] + inst->constant)) { + if (IRRunMemCheck(mips->pc + inst->dest, mips->r[inst->src1] + inst->constant)) { CoreTiming::ForceCheck(); return mips->pc; } diff --git a/Core/MIPS/IR/IRInterpreter.h b/Core/MIPS/IR/IRInterpreter.h index ec2c6f270b..21e7f15dc7 100644 --- a/Core/MIPS/IR/IRInterpreter.h +++ b/Core/MIPS/IR/IRInterpreter.h @@ -20,4 +20,7 @@ inline static u32 ReverseBits32(u32 v) { return v; } +u32 IRRunBreakpoint(u32 pc); +u32 IRRunMemCheck(u32 pc, u32 addr); + u32 IRInterpret(MIPSState *ms, const IRInst *inst, int count);