From 96b01e4999a26da76a3f8aa75d2ce0a7377a7376 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 19 Jul 2015 13:04:06 -0700 Subject: [PATCH 1/3] Make sure we don't clean up proxy blocks. --- Core/CwCheat.cpp | 4 +--- Core/MIPS/JitCommon/JitBlockCache.cpp | 11 +++++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp index 165231c0fe..8ad68e148e 100644 --- a/Core/CwCheat.cpp +++ b/Core/CwCheat.cpp @@ -284,9 +284,7 @@ std::vector CWCheatEngine::GetCodesList() { //Reads the entire chea } void CWCheatEngine::InvalidateICache(u32 addr, int size) { - if (MIPSComp::jit) { - MIPSComp::jit->GetBlockCache()->InvalidateICache(addr & ~3, size); - } + currentMIPS->InvalidateICache(addr & ~3, size); } void CWCheatEngine::Run() { diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 04db18d33d..bb03c0a58b 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -566,14 +566,21 @@ void JitBlockCache::DestroyBlock(int block_num, bool invalidate) { } b->invalid = true; - if (Memory::ReadUnchecked_U32(b->originalAddress) == GetEmuHackOpForBlock(block_num).encoding) - Memory::Write_Opcode_JIT(b->originalAddress, b->originalFirstOpcode); + if (!b->IsPureProxy()) { + if (Memory::ReadUnchecked_U32(b->originalAddress) == GetEmuHackOpForBlock(block_num).encoding) + Memory::Write_Opcode_JIT(b->originalAddress, b->originalFirstOpcode); + } // It's not safe to set normalEntry to 0 here, since we use a binary search // that looks at that later to find blocks. Marking it invalid is enough. UnlinkBlock(block_num); + // Don't change the jit code when invalidating a pure proxy block. + if (b->IsPureProxy()) { + return; + } + #if defined(ARM) // Send anyone who tries to run this block back to the dispatcher. From cd842ac21f60cedfe1f49aa915f4ecdd732b80c3 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 19 Jul 2015 13:08:32 -0700 Subject: [PATCH 2/3] Validate blocklinking in icache invalidate all. Normally blocks are invalidated on entry. But when blocklinking is on, we don't validate on all entries. This fixes Tales of Rebirth crashes (#7868.) --- Core/HLE/sceKernel.cpp | 4 ++++ Core/MIPS/JitCommon/JitBlockCache.cpp | 20 ++++++++++++++++++++ Core/MIPS/JitCommon/JitBlockCache.h | 1 + 3 files changed, 25 insertions(+) diff --git a/Core/HLE/sceKernel.cpp b/Core/HLE/sceKernel.cpp index 17ee8f6db0..2f87e092bb 100644 --- a/Core/HLE/sceKernel.cpp +++ b/Core/HLE/sceKernel.cpp @@ -425,6 +425,8 @@ u32 sceKernelIcacheInvalidateAll() #ifdef LOG_CACHE NOTICE_LOG(CPU, "Icache invalidated - should clear JIT someday"); #endif + // Note that this doesn't actually fully invalidate all with such a large range. + currentMIPS->InvalidateICache(0, 0x3FFFFFFF); return 0; } @@ -435,6 +437,8 @@ u32 sceKernelIcacheClearAll() NOTICE_LOG(CPU, "Icache cleared - should clear JIT someday"); #endif DEBUG_LOG(CPU, "Icache cleared - should clear JIT someday"); + // Note that this doesn't actually fully invalidate all with such a large range. + currentMIPS->InvalidateICache(0, 0x3FFFFFFF); return 0; } diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index bb03c0a58b..30503d6e01 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -626,6 +626,11 @@ void JitBlockCache::InvalidateICache(u32 address, const u32 length) { return; } + if (pAddr == 0 && pEnd >= 0x1FFFFFFF) { + InvalidateChangedBlocks(); + return; + } + // Blocks may start and end in overlapping ways, and destroying one invalidates iterators. // So after destroying one, we start over. do { @@ -647,6 +652,21 @@ void JitBlockCache::InvalidateICache(u32 address, const u32 length) { } while (false); } +void JitBlockCache::InvalidateChangedBlocks() { + // The primary goal of this is to make sure block linking is cleared up. + for (int block_num = 0; block_num < num_blocks_; ++block_num) { + JitBlock &b = blocks_[block_num]; + if (b.invalid || b.IsPureProxy()) + continue; + + const u32 emuhack = GetEmuHackOpForBlock(block_num).encoding; + if (Memory::ReadUnchecked_U32(b.originalAddress) != emuhack) { + DEBUG_LOG(JIT, "Invalidating changed block at %08x", b.originalAddress); + DestroyBlock(block_num, true); + } + } +} + int JitBlockCache::GetBlockExitSize() { #if defined(ARM) // Will depend on the sequence found to encode the destination address. diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index 168e101018..ccd448337b 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -147,6 +147,7 @@ public: // DOES NOT WORK CORRECTLY WITH JIT INLINING void InvalidateICache(u32 address, const u32 length); + void InvalidateChangedBlocks(); void DestroyBlock(int block_num, bool invalidate); // No jit operations may be run between these calls. From 9262ddfc135f14f9c50080cae9b9c12f43b5f0da Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sun, 19 Jul 2015 13:25:50 -0700 Subject: [PATCH 3/3] Avoid any possible shifts by 32. --- Core/MIPS/ARM/ArmCompALU.cpp | 2 +- Core/MIPS/ARM64/Arm64CompALU.cpp | 3 +-- Core/MIPS/MIPSInt.cpp | 7 ++++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/MIPS/ARM/ArmCompALU.cpp b/Core/MIPS/ARM/ArmCompALU.cpp index 0fe3d7c87b..6232044290 100644 --- a/Core/MIPS/ARM/ArmCompALU.cpp +++ b/Core/MIPS/ARM/ArmCompALU.cpp @@ -533,7 +533,7 @@ namespace MIPSComp int pos = _POS; int size = _SIZE + 1; - u32 mask = (1 << size) - 1; + u32 mask = 0xFFFFFFFFUL >> (32 - size); // Don't change $zr. if (rt == 0) diff --git a/Core/MIPS/ARM64/Arm64CompALU.cpp b/Core/MIPS/ARM64/Arm64CompALU.cpp index 0e891e164d..bcbfca5bda 100644 --- a/Core/MIPS/ARM64/Arm64CompALU.cpp +++ b/Core/MIPS/ARM64/Arm64CompALU.cpp @@ -431,8 +431,7 @@ void Arm64Jit::Comp_Special3(MIPSOpcode op) { int pos = _POS; int size = _SIZE + 1; - // Workaround for a compiler bug. - u32 mask = size == 32 ? 0xFFFFFFFF : (1 << size) - 1; + u32 mask = 0xFFFFFFFFUL >> (32 - size); // Don't change $zr. if (rt == 0) diff --git a/Core/MIPS/MIPSInt.cpp b/Core/MIPS/MIPSInt.cpp index e246901752..60ce72b299 100644 --- a/Core/MIPS/MIPSInt.cpp +++ b/Core/MIPS/MIPSInt.cpp @@ -866,14 +866,15 @@ namespace MIPSInt case 0x0: //ext { int size = _SIZE + 1; - R(rt) = (R(rs) >> pos) & ((1<> (32 - size); + R(rt) = (R(rs) >> pos) & sourcemask; } break; case 0x4: //ins { int size = (_SIZE + 1) - pos; - int sourcemask = (1 << size) - 1; - int destmask = sourcemask << pos; + u32 sourcemask = 0xFFFFFFFFUL >> (32 - size); + u32 destmask = sourcemask << pos; R(rt) = (R(rt) & ~destmask) | ((R(rs)&sourcemask) << pos); } break;