diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp index 5e8c093671..85817a49e3 100644 --- a/Core/HLE/ReplaceTables.cpp +++ b/Core/HLE/ReplaceTables.cpp @@ -233,8 +233,9 @@ static int Replace_memcpy16() { bool skip = false; // Some games use memcpy on executable code. We need to flush emuhack ops. - currentMIPS->InvalidateICache(srcPtr, bytes); - if ((skipGPUReplacements & (int)GPUReplacementSkip::MEMCPY) == 0) { + if (bytes != 0) + currentMIPS->InvalidateICache(srcPtr, bytes); + if ((skipGPUReplacements & (int)GPUReplacementSkip::MEMCPY) == 0 && bytes != 0) { if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) { skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes); } @@ -305,7 +306,7 @@ static int Replace_memmove() { bool skip = false; // Some games use memcpy on executable code. We need to flush emuhack ops. - if ((skipGPUReplacements & (int)GPUReplacementSkip::MEMMOVE) == 0) { + if ((skipGPUReplacements & (int)GPUReplacementSkip::MEMMOVE) == 0 && bytes != 0) { currentMIPS->InvalidateICache(srcPtr, bytes); if (Memory::IsVRAMAddress(destPtr) || Memory::IsVRAMAddress(srcPtr)) { skip = gpu->PerformMemoryCopy(destPtr, srcPtr, bytes); diff --git a/Core/HLE/sceDmac.cpp b/Core/HLE/sceDmac.cpp index 5fba8f9b94..3735eb2a84 100644 --- a/Core/HLE/sceDmac.cpp +++ b/Core/HLE/sceDmac.cpp @@ -49,7 +49,7 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) { if (Memory::IsVRAMAddress(src) || Memory::IsVRAMAddress(dst)) { skip = gpu->PerformMemoryCopy(dst, src, size); } - if (!skip) { + if (!skip && size != 0) { currentMIPS->InvalidateICache(src, size); if (MemBlockInfoDetailed(size)) { const std::string tag = GetMemWriteTagAt("DmacMemcpy/", src, size); diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index b9d1028b48..6f18a5768e 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -392,7 +392,8 @@ int sceKernelDcacheInvalidateRange(u32 addr, int size) int sceKernelIcacheInvalidateRange(u32 addr, int size) { DEBUG_LOG(CPU, "sceKernelIcacheInvalidateRange(%08x, %i)", addr, size); - currentMIPS->InvalidateICache(addr, size); + if (size != 0) + currentMIPS->InvalidateICache(addr, size); return 0; } diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp index 4c91ffe529..3dadc4dc77 100644 --- a/Core/HLE/sceKernelInterrupt.cpp +++ b/Core/HLE/sceKernelInterrupt.cpp @@ -624,7 +624,8 @@ static 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); + if (size != 0) + currentMIPS->InvalidateICache(src, size); bool skip = false; if (Memory::IsVRAMAddress(src) || Memory::IsVRAMAddress(dst)) { diff --git a/Core/MIPS/MIPS.cpp b/Core/MIPS/MIPS.cpp index 5aeeacbbf8..9a472b08c5 100644 --- a/Core/MIPS/MIPS.cpp +++ b/Core/MIPS/MIPS.cpp @@ -366,14 +366,15 @@ void MIPSState::ProcessPendingClears() { void MIPSState::InvalidateICache(u32 address, int length) { // Only really applies to jit. std::lock_guard guard(MIPSComp::jitLock); - if (MIPSComp::jit) { - if (coreState == CORE_RUNNING || insideJit) { - pendingClears.emplace_back(address, length); - hasPendingClears = true; - CoreTiming::ForceCheck(); - } else { - MIPSComp::jit->InvalidateCacheAt(address, length); - } + if (!MIPSComp::jit || length == 0) + return; + + if (coreState == CORE_RUNNING || insideJit) { + pendingClears.emplace_back(address, length); + hasPendingClears = true; + CoreTiming::ForceCheck(); + } else { + MIPSComp::jit->InvalidateCacheAt(address, length); } }