diff --git a/Source/Core/Common/Src/BreakPoints.cpp b/Source/Core/Common/Src/BreakPoints.cpp index 45a0b52daf..9164312f82 100644 --- a/Source/Core/Common/Src/BreakPoints.cpp +++ b/Source/Core/Common/Src/BreakPoints.cpp @@ -19,6 +19,7 @@ #include "DebugInterface.h" #include "BreakPoints.h" #include +#include "..\..\Core\Src\PowerPC\JitCommon\JitBase.h" bool BreakPoints::IsAddressBreakPoint(u32 _iAddress) { @@ -70,7 +71,11 @@ void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) void BreakPoints::Add(const TBreakPoint& bp) { if (!IsAddressBreakPoint(bp.iAddress)) + { m_BreakPoints.push_back(bp); + if (jit) + jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); + } } void BreakPoints::Add(u32 em_address, bool temp) @@ -83,21 +88,35 @@ void BreakPoints::Add(u32 em_address, bool temp) pt.iAddress = em_address; m_BreakPoints.push_back(pt); + + if (jit) + jit->GetBlockCache()->InvalidateICache(em_address, 4); } } -void BreakPoints::Remove(u32 _iAddress) +void BreakPoints::Remove(u32 em_address) { for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) { - if (i->iAddress == _iAddress) + if (i->iAddress == em_address) { m_BreakPoints.erase(i); + if (jit) + jit->GetBlockCache()->InvalidateICache(em_address, 4); return; } } } +void BreakPoints::Clear() +{ + for (TBreakPoints::iterator i = m_BreakPoints.begin(); i != m_BreakPoints.end(); ++i) + { + if (jit) + jit->GetBlockCache()->InvalidateICache(i->iAddress, 4); + m_BreakPoints.erase(i); + } +} MemChecks::TMemChecksStr MemChecks::GetStrings() const { diff --git a/Source/Core/Common/Src/BreakPoints.h b/Source/Core/Common/Src/BreakPoints.h index a97452cde6..c742f812a7 100644 --- a/Source/Core/Common/Src/BreakPoints.h +++ b/Source/Core/Common/Src/BreakPoints.h @@ -78,7 +78,7 @@ public: // Remove Breakpoint void Remove(u32 _iAddress); - void Clear() { m_BreakPoints.clear(); }; + void Clear(); void DeleteByAddress(u32 _Address); diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp index 1506170b2b..cb9f66b7d4 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit.cpp @@ -415,9 +415,8 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc if (Core::g_CoreStartupParameter.bEnableDebugging) { - // Comment out the following to disable breakpoints (speed-up) - blockSize = 1; - broken_block = true; + if (GetState() == CPU_STEPPING) + blockSize = 1; Trace(); } @@ -597,6 +596,20 @@ const u8* Jit64::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc SetJumpTarget(clearInt); } + if (Core::g_CoreStartupParameter.bEnableDebugging && breakpoints.IsAddressBreakPoint(ops[i].address) && GetState() != CPU_STEPPING) + { + MOV(32, M(&PC), Imm32(ops[i].address)); + ABI_CallFunction(reinterpret_cast(&PowerPC::CheckBreakPoints)); + TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); + + FixupBranch noBreakpoint = J_CC(CC_Z); + gpr.Flush(FLUSH_ALL); + fpr.Flush(FLUSH_ALL); + + WriteExit(ops[i].address, 0); + SetJumpTarget(noBreakpoint); + } + Jit64Tables::CompileInstruction(ops[i]); if (js.memcheck && (opinfo->flags & FL_LOADSTORE)) diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp index afab21b30e..7c3e7f0810 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.cpp @@ -1269,7 +1269,8 @@ static const unsigned alwaysUsedList[] = { Store16, Store32, StoreSingle, StoreDouble, StorePaired, StoreFReg, FDCmpCR, BlockStart, BlockEnd, IdleBranch, BranchCond, BranchUncond, ShortIdleLoop, SystemCall, InterpreterBranch, RFIExit, FPExceptionCheckStart, - FPExceptionCheckEnd, ISIException, ExtExceptionCheck, Int3, Tramp, Nop + FPExceptionCheckEnd, ISIException, ExtExceptionCheck, BreakPointCheck, + Int3, Tramp, Nop }; static const unsigned extra8RegList[] = { LoadGReg, LoadCR, LoadGQR, LoadFReg, LoadFRegDENToZero, diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h index 284cbe6538..f41742b01c 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR.h @@ -168,7 +168,7 @@ enum Opcode { // used for exception checking, at least until someone // has a better idea of integrating it FPExceptionCheckStart, FPExceptionCheckEnd, - ISIException,ExtExceptionCheck, + ISIException, ExtExceptionCheck, BreakPointCheck, // "Opcode" representing a register too far away to // reference directly; this is a size optimization Tramp, @@ -414,6 +414,9 @@ public: InstLoc EmitExtExceptionCheck(InstLoc pc) { return EmitUOp(ExtExceptionCheck, pc); } + InstLoc EmitBreakPointCheck(InstLoc pc) { + return EmitUOp(BreakPointCheck, pc); + } InstLoc EmitRFIExit() { return FoldZeroOp(RFIExit, 0); } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp index f82e34b5b1..743eaf2030 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/IR_X86.cpp @@ -763,6 +763,7 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak case FPExceptionCheckEnd: case ISIException: case ExtExceptionCheck: + case BreakPointCheck: case Int3: case Tramp: // No liveness effects @@ -1943,6 +1944,17 @@ static void DoWriteCode(IRBuilder* ibuild, JitIL* Jit, bool UseProfile, bool Mak Jit->SetJumpTarget(clearInt); break; } + case BreakPointCheck: { + unsigned InstLoc = ibuild->GetImmValue(getOp1(I)); + + Jit->MOV(32, M(&PC), Imm32(InstLoc)); + Jit->ABI_CallFunction(reinterpret_cast(&PowerPC::CheckBreakPoints)); + Jit->TEST(32, M((void*)PowerPC::GetStatePtr()), Imm32(0xFFFFFFFF)); + FixupBranch noBreakpoint = Jit->J_CC(CC_Z); + Jit->WriteExit(InstLoc, 0); + Jit->SetJumpTarget(noBreakpoint); + break; + } case Int3: { Jit->INT3(); break; diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp index 96afff1613..7694722bb5 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL.cpp @@ -523,8 +523,8 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc if (Core::g_CoreStartupParameter.bEnableDebugging) { - // Comment out the following to disable breakpoints (speed-up) - blockSize = 1; + if (GetState() == CPU_STEPPING) + blockSize = 1; Trace(); } @@ -653,6 +653,11 @@ const u8* JitIL::DoJit(u32 em_address, PPCAnalyst::CodeBuffer *code_buf, JitBloc { ibuild.EmitExtExceptionCheck(ibuild.EmitIntConst(ops[i].address)); } + + if (Core::g_CoreStartupParameter.bEnableDebugging && breakpoints.IsAddressBreakPoint(ops[i].address) && GetState() != CPU_STEPPING) + { + ibuild.EmitBreakPointCheck(ibuild.EmitIntConst(ops[i].address)); + } JitILTables::CompileInstruction(ops[i]); diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp index bccb218fd9..46096450e7 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitCache.cpp @@ -417,6 +417,24 @@ bool JitBlock::ContainsAddress(u32 em_address) std::map, u32>::iterator it1 = block_map.lower_bound(std::make_pair(address, 0)), it2 = it1, it; while (it2 != block_map.end() && it2->first.second < address + length) { +#ifdef JIT_UNLIMITED_ICACHE + JitBlock &b = blocks[it2->second]; + if (b.originalAddress & JIT_ICACHE_VMEM_BIT) + { + u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK; + memset(iCacheVMEM + cacheaddr, JIT_ICACHE_INVALID_BYTE, length); + } + else if (b.originalAddress & JIT_ICACHE_EXRAM_BIT) + { + u32 cacheaddr = b.originalAddress & JIT_ICACHEEX_MASK; + memset(iCacheEx + cacheaddr, JIT_ICACHE_INVALID_BYTE, length); + } + else + { + u32 cacheaddr = b.originalAddress & JIT_ICACHE_MASK; + memset(iCache + cacheaddr, JIT_ICACHE_INVALID_BYTE, length); + } +#endif DestroyBlock(it2->second, true); it2++; }