From 09b9d2ad814ad4d86f377debea8ab3abe4c19ea2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 5 Jul 2014 16:25:16 -0700 Subject: [PATCH] Keep track of ranges that have emuhack ops. So that we can invalidate them smarter. --- Core/MIPS/JitCommon/JitBlockCache.cpp | 35 ++++++++++++++++++++++++++- Core/MIPS/JitCommon/JitBlockCache.h | 10 ++++++++ Core/MIPS/x86/Jit.cpp | 5 ---- Core/MIPS/x86/Jit.h | 6 ++++- Core/MemMap.h | 1 + Core/MemMapFunctions.cpp | 4 +++ 6 files changed, 54 insertions(+), 7 deletions(-) diff --git a/Core/MIPS/JitCommon/JitBlockCache.cpp b/Core/MIPS/JitCommon/JitBlockCache.cpp index 958a26b29a..e0e42cbbc4 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.cpp +++ b/Core/MIPS/JitCommon/JitBlockCache.cpp @@ -23,6 +23,7 @@ // locating performance issues. #include +#include #include "Common.h" @@ -124,6 +125,10 @@ void JitBlockCache::Clear() { block_map_.clear(); proxyBlockIndices_.clear(); num_blocks_ = 0; + + blockMemRanges_[JITBLOCK_RANGE_SCRATCH] = std::make_pair(0xFFFFFFFF, 0x00000000); + blockMemRanges_[JITBLOCK_RANGE_RAMBOTTOM] = std::make_pair(0xFFFFFFFF, 0x00000000); + blockMemRanges_[JITBLOCK_RANGE_RAMTOP] = std::make_pair(0xFFFFFFFF, 0x00000000); } void JitBlockCache::Reset() { @@ -198,6 +203,11 @@ void JitBlockCache::ProxyBlock(u32 rootAddress, u32 startAddress, u32 size, cons num_blocks_++; //commit the current block } +static void ExpandRange(std::pair &range, u32 newStart, u32 newEnd) { + range.first = std::min(range.first, newStart); + range.second = std::max(range.second, newEnd); +} + void JitBlockCache::FinalizeBlock(int block_num, bool block_link) { JitBlock &b = blocks_[block_num]; @@ -209,17 +219,31 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link) { // Yeah, this'll work fine for PSP too I think. u32 pAddr = b.originalAddress & 0x1FFFFFFF; + u32 latestExit = 0; block_map_[std::make_pair(pAddr + 4 * b.originalSize - 1, pAddr)] = block_num; if (block_link) { for (int i = 0; i < MAX_JIT_BLOCK_EXITS; i++) { - if (b.exitAddress[i] != INVALID_EXIT) + if (b.exitAddress[i] != INVALID_EXIT) { links_to_.insert(std::pair(b.exitAddress[i], block_num)); + latestExit = std::max(latestExit, b.exitAddress[i]); + } } LinkBlock(block_num); LinkBlockExits(block_num); } + if (Memory::IsScratchpadAddress(b.originalAddress)) { + ExpandRange(blockMemRanges_[JITBLOCK_RANGE_SCRATCH], b.originalAddress, latestExit); + } + const u32 halfUserMemory = (PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase()) / 2; + if (b.originalAddress < PSP_GetUserMemoryBase() + halfUserMemory) { + ExpandRange(blockMemRanges_[JITBLOCK_RANGE_RAMBOTTOM], b.originalAddress, latestExit); + } + if (latestExit > PSP_GetUserMemoryBase() + halfUserMemory) { + ExpandRange(blockMemRanges_[JITBLOCK_RANGE_RAMTOP], b.originalAddress, latestExit); + } + #if defined USE_OPROFILE && USE_OPROFILE char buf[100]; sprintf(buf, "EmuCode%x", b.originalAddress); @@ -242,6 +266,15 @@ void JitBlockCache::FinalizeBlock(int block_num, bool block_link) { #endif } +bool JitBlockCache::RangeMayHaveEmuHacks(u32 start, u32 end) const { + for (int i = 0; i < JITBLOCK_RANGE_COUNT; ++i) { + if (end >= blockMemRanges_[i].first && start <= blockMemRanges_[i].second) { + return true; + } + } + return false; +} + static int binary_search(JitBlock blocks_[], const u8 *baseoff, int imin, int imax) { while (imin < imax) { int imid = (imin + imax) / 2; diff --git a/Core/MIPS/JitCommon/JitBlockCache.h b/Core/MIPS/JitCommon/JitBlockCache.h index c1ff175964..5bb5461b22 100644 --- a/Core/MIPS/JitCommon/JitBlockCache.h +++ b/Core/MIPS/JitCommon/JitBlockCache.h @@ -128,6 +128,8 @@ public: MIPSOpcode GetOriginalFirstOp(int block_num); + bool RangeMayHaveEmuHacks(u32 start, u32 end) const; + // DOES NOT WORK CORRECTLY WITH JIT INLINING void InvalidateICache(u32 address, const u32 length); void DestroyBlock(int block_num, bool invalidate); @@ -155,6 +157,14 @@ private: std::multimap links_to_; std::map, u32> block_map_; // (end_addr, start_addr) -> number + enum { + JITBLOCK_RANGE_SCRATCH = 0, + JITBLOCK_RANGE_RAMBOTTOM = 1, + JITBLOCK_RANGE_RAMTOP = 2, + JITBLOCK_RANGE_COUNT = 3, + }; + std::pair blockMemRanges_[3]; + enum { MAX_NUM_BLOCKS = 65536*2 }; diff --git a/Core/MIPS/x86/Jit.cpp b/Core/MIPS/x86/Jit.cpp index e907b56af8..fd716bce68 100644 --- a/Core/MIPS/x86/Jit.cpp +++ b/Core/MIPS/x86/Jit.cpp @@ -222,11 +222,6 @@ void Jit::InvalidateCache() blocks.Clear(); } -void Jit::InvalidateCacheAt(u32 em_address, int length) -{ - blocks.InvalidateICache(em_address, length); -} - void Jit::CompileDelaySlot(int flags, RegCacheState *state) { const u32 addr = js.compilerPC + 4; diff --git a/Core/MIPS/x86/Jit.h b/Core/MIPS/x86/Jit.h index c210ef6fc6..81ffcd42ab 100644 --- a/Core/MIPS/x86/Jit.h +++ b/Core/MIPS/x86/Jit.h @@ -169,7 +169,11 @@ public: void ClearCache(); void InvalidateCache(); - void InvalidateCacheAt(u32 em_address, int length = 4); + inline void InvalidateCacheAt(u32 em_address, int length = 4) { + if (blocks.RangeMayHaveEmuHacks(em_address, em_address + length)) { + blocks.InvalidateICache(em_address, length); + } + } private: void GetStateAndFlushAll(RegCacheState &state); diff --git a/Core/MemMap.h b/Core/MemMap.h index 830a6a77b1..07a829be53 100644 --- a/Core/MemMap.h +++ b/Core/MemMap.h @@ -239,6 +239,7 @@ inline void Write_Float(float f, u32 address) u8* GetPointer(const u32 address); bool IsRAMAddress(const u32 address); bool IsVRAMAddress(const u32 address); +bool IsScratchpadAddress(const u32 address); inline const char* GetCharPointer(const u32 address) { return (const char *)GetPointer(address); diff --git a/Core/MemMapFunctions.cpp b/Core/MemMapFunctions.cpp index a2e92d9634..bb04c3899e 100644 --- a/Core/MemMapFunctions.cpp +++ b/Core/MemMapFunctions.cpp @@ -159,6 +159,10 @@ bool IsVRAMAddress(const u32 address) { return ((address & 0x3F800000) == 0x04000000); } +bool IsScratchpadAddress(const u32 address) { + return (address & 0xBFFF0000) == 0x00010000; +} + u8 Read_U8(const u32 _Address) { u8 _var = 0;