diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 5367bb6f22..4bff4240ad 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -107,6 +107,9 @@ static int Replace_memcpy() { u32 srcPtr = PARAM(1); u32 bytes = PARAM(2); bool skip = false; + + // Some games use memcpy on executable code. We need to flush emuhack ops. + currentMIPS->InvalidateICache(srcPtr, bytes); if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) { skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes); } @@ -140,6 +143,9 @@ static int Replace_memcpy16() { u32 srcPtr = PARAM(1); u32 bytes = PARAM(2) * 16; bool skip = false; + + // Some games use memcpy on executable code. We need to flush emuhack ops. + currentMIPS->InvalidateICache(srcPtr, bytes); if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) { skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes); } @@ -195,6 +201,9 @@ static int Replace_memmove() { u32 srcPtr = PARAM(1); u32 bytes = PARAM(2); bool skip = false; + + // Some games use memcpy on executable code. We need to flush emuhack ops. + currentMIPS->InvalidateICache(srcPtr, bytes); if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) { skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes); } diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 18dddc29cd..5cc0661728 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -623,6 +623,9 @@ u32 sceKernelMemcpy(u32 dst, u32 src, u32 size) { DEBUG_LOG(SCEKERNEL, "sceKernelMemcpy(dest=%08x, src=%08x, size=%i)", dst, src, size); + // Some games copy from executable code. We need to flush emuhack ops. + currentMIPS->InvalidateICache(src, size); + bool skip = false; if (Memory::IsVRAMAddress(src) || Memory::IsVRAMAddress(dst)) { skip = gpu->PerformMemoryCopy(dst, src, size); diff --git a/Core/MIPS/x86/CompBranch.cpp b/Core/MIPS/x86/CompBranch.cpp index 3849c58ffe..2a2db6a442 100644 --- a/Core/MIPS/x86/CompBranch.cpp +++ b/Core/MIPS/x86/CompBranch.cpp @@ -528,7 +528,7 @@ void Jit::Comp_Jump(MIPSOpcode op) { // Might be a stubbed address or something? if (!Memory::IsValidAddress(targetAddr)) { if (js.nextExit == 0) { - ERROR_LOG_REPORT(JIT, "Jump to invalid address: %08x", targetAddr); + ERROR_LOG_REPORT(JIT, "Jump to invalid address: %08x PC %08x LR %08x", targetAddr, js.compilerPC, currentMIPS->r[MIPS_REG_RA]); } else { js.compiling = false; } diff --git a/Core/MIPS/x86/JitSafeMem.cpp b/Core/MIPS/x86/JitSafeMem.cpp index 670af75d9f..086ac7a5c9 100644 --- a/Core/MIPS/x86/JitSafeMem.cpp +++ b/Core/MIPS/x86/JitSafeMem.cpp @@ -239,6 +239,9 @@ void JitSafeMem::DoSlowWrite(const void *safeFunc, const OpArg src, int suboffse if (!src.IsSimpleReg(EDX)) { jit_->MOV(32, R(EDX), src); } + if (!g_Config.bIgnoreBadMemAccess) { + jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC)); + } // This is a special jit-ABI'd function. jit_->CALL(safeFunc); #ifdef _M_IX86 @@ -266,6 +269,9 @@ bool JitSafeMem::PrepareSlowRead(const void *safeFunc) jit_->AND(32, R(EAX), Imm32(alignMask_)); } + if (!g_Config.bIgnoreBadMemAccess) { + jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC)); + } // This is a special jit-ABI'd function. jit_->CALL(safeFunc); needsCheck_ = true; @@ -297,6 +303,9 @@ void JitSafeMem::NextSlowRead(const void *safeFunc, int suboffset) jit_->AND(32, R(EAX), Imm32(alignMask_)); } + if (!g_Config.bIgnoreBadMemAccess) { + jit_->MOV(32, M(&jit_->mips_->pc), Imm32(jit_->js.compilerPC)); + } // This is a special jit-ABI'd function. jit_->CALL(safeFunc); } diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index 285ae2a5df..a2e92d9634 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -88,7 +88,8 @@ inline void ReadFromHardware(T &var, const u32 address) // More RAM (remasters, etc.) var = *((const T*)GetPointerUnchecked(address)); } else { - if (g_Config.bJit) { + // In jit, we only flush PC when bIgnoreBadMemAccess is off. + if (g_Config.bJit && g_Config.bIgnoreBadMemAccess) { WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x", address); } else { WARN_LOG(MEMMAP, "ReadFromHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]); @@ -124,7 +125,8 @@ inline void WriteToHardware(u32 address, const T data) // More RAM (remasters, etc.) *(T*)GetPointerUnchecked(address) = data; } else { - if (g_Config.bJit) { + // In jit, we only flush PC when bIgnoreBadMemAccess is off. + if (g_Config.bJit && g_Config.bIgnoreBadMemAccess) { WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x", address); } else { WARN_LOG(MEMMAP, "WriteToHardware: Invalid address %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);