diff --git a/Core/MIPS/x86/CompVFPU.cpp b/Core/MIPS/x86/CompVFPU.cpp index 383638fc67..32a859d19b 100644 --- a/Core/MIPS/x86/CompVFPU.cpp +++ b/Core/MIPS/x86/CompVFPU.cpp @@ -158,6 +158,7 @@ void Jit::Comp_SVQ(u32 op) fpr.MapRegsV(vregs, V_Quad, MAP_DIRTY | MAP_NOINIT); JitSafeMem safe(this, rs, imm); + safe.SetFar(); OpArg src; if (safe.PrepareRead(src)) { @@ -191,6 +192,7 @@ void Jit::Comp_SVQ(u32 op) fpr.MapRegsV(vregs, V_Quad, 0); JitSafeMem safe(this, rs, imm); + safe.SetFar(); OpArg dest; if (safe.PrepareWrite(dest)) { diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index f486a4a53d..d252420b94 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -305,6 +305,14 @@ bool Jit::CheckJitBreakpoint(u32 addr, int downcountOffset) Jit::JitSafeMem::JitSafeMem(Jit *jit, int raddr, s32 offset) : jit_(jit), raddr_(raddr), offset_(offset), needsCheck_(false), needsSkip_(false) { + // This makes it more instructions, so let's play it safe and say we need a far jump. + far_ = !g_Config.bIgnoreBadMemAccess; +} + +void Jit::JitSafeMem::SetFar() +{ + _dbg_assert_msg_(JIT, !needsSkip_, "Sorry, you need to call SetFar() earlier."); + far_ = true; } bool Jit::JitSafeMem::PrepareWrite(OpArg &dest) @@ -420,7 +428,7 @@ OpArg Jit::JitSafeMem::PrepareMemoryOpArg() void Jit::JitSafeMem::PrepareSlowAccess() { // Skip the fast path (which the caller wrote just now.) - skip_ = jit_->J(); + skip_ = jit_->J(far_); needsSkip_ = true; jit_->SetJumpTarget(tooLow_); jit_->SetJumpTarget(tooHigh_); diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index 25b3d24cac..84ad6974d6 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -201,14 +201,16 @@ private: // Emit code for a slow read call, and returns true if result is in EAX. bool PrepareSlowRead(void *safeFunc); + // Cleans up final code for the memory access. + void Finish(); + + // Use this before anything else if you're gonna use the below. + void SetFar(); // WARNING: Only works for non-GPR. Do not use for reads into GPR. OpArg NextFastAddress(int suboffset); // WARNING: Only works for non-GPR. Do not use for reads into GPR. void NextSlowRead(void *safeFunc, int suboffset); - // Cleans up final code for the memory access. - void Finish(); - private: OpArg PrepareMemoryOpArg(); void PrepareSlowAccess(); @@ -218,6 +220,7 @@ private: s32 offset_; bool needsCheck_; bool needsSkip_; + bool far_; X64Reg xaddr_; FixupBranch tooLow_, tooHigh_, skip_; const u8 *safe_;