From 811d94222217fadecdd54d5b7fc16b584d52f11a Mon Sep 17 00:00:00 2001 From: TheLordScruffy Date: Sat, 7 Jan 2023 07:30:42 -0500 Subject: [PATCH] Improve PPCCache lookup table --- Source/Core/Core/PowerPC/PPCCache.cpp | 37 ++++++++++++++------------- Source/Core/Core/PowerPC/PPCCache.h | 6 +++++ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp index b13793522e..d56d77927c 100644 --- a/Source/Core/Core/PowerPC/PPCCache.cpp +++ b/Source/Core/Core/PowerPC/PPCCache.cpp @@ -168,11 +168,11 @@ void Cache::Invalidate(u32 addr) if (valid[set] & (1U << way)) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table_vmem[(addrs[set][way] >> 5) & 0xfffff] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[((addrs[set][way] >> 5) & 0x1fff80) | set] = 0xff; + lookup_table_ex[(addrs[set][way] >> 5) & 0x1fffff] = 0xff; else - lookup_table[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table[(addrs[set][way] >> 5) & 0xfffff] = 0xff; valid[set] &= ~(1U << way); modified[set] &= ~(1U << way); @@ -195,11 +195,11 @@ void Cache::Flush(u32 addr) memory.CopyToEmu((addr & ~0x1f), reinterpret_cast(data[set][way].data()), 32); if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table_vmem[(addrs[set][way] >> 5) & 0xfffff] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[((addrs[set][way] >> 5) & 0x1fff80) | set] = 0xff; + lookup_table_ex[(addrs[set][way] >> 5) & 0x1fffff] = 0xff; else - lookup_table[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table[(addrs[set][way] >> 5) & 0xfffff] = 0xff; valid[set] &= ~(1U << way); modified[set] &= ~(1U << way); @@ -249,11 +249,11 @@ std::pair Cache::GetCache(u32 addr, bool locked) memory.CopyToEmu(addrs[set][way], reinterpret_cast(data[set][way].data()), 32); if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table_vmem[(addrs[set][way] >> 5) & 0xfffff] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[((addrs[set][way] >> 5) & 0x1fff80) | set] = 0xff; + lookup_table_ex[(addrs[set][way] >> 5) & 0x1fffff] = 0xff; else - lookup_table[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table[(addrs[set][way] >> 5) & 0xfffff] = 0xff; } // load @@ -265,6 +265,7 @@ std::pair Cache::GetCache(u32 addr, bool locked) lookup_table_ex[(addr >> 5) & 0x1fffff] = way; else lookup_table[(addr >> 5) & 0xfffff] = way; + addrs[set][way] = addr; valid[set] |= (1 << way); modified[set] &= ~(1 << way); @@ -351,11 +352,11 @@ void Cache::DoState(PointerWrap& p) if ((valid[set] & (1 << way)) != 0) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table_vmem[(addrs[set][way] >> 5) & 0xfffff] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[((addrs[set][way] >> 5) & 0x1fff80) | set] = 0xff; + lookup_table_ex[(addrs[set][way] >> 5) & 0x1fffff] = 0xff; else - lookup_table[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table[(addrs[set][way] >> 5) & 0xfffff] = 0xff; } } } @@ -377,11 +378,11 @@ void Cache::DoState(PointerWrap& p) if ((valid[set] & (1 << way)) != 0) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table_vmem[(addrs[set][way] >> 5) & 0xfffff] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[((addrs[set][way] >> 5) & 0x1fff80) | set] = 0xff; + lookup_table_ex[(addrs[set][way] >> 5) & 0x1fffff] = 0xff; else - lookup_table[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table[(addrs[set][way] >> 5) & 0xfffff] = 0xff; } } } @@ -413,11 +414,11 @@ void InstructionCache::Invalidate(u32 addr) if (valid[set] & (1U << way)) { if (addrs[set][way] & CACHE_VMEM_BIT) - lookup_table_vmem[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table_vmem[(addrs[set][way] >> 5) & 0xfffff] = 0xff; else if (addrs[set][way] & CACHE_EXRAM_BIT) - lookup_table_ex[((addrs[set][way] >> 5) & 0x1fff80) | set] = 0xff; + lookup_table_ex[(addrs[set][way] >> 5) & 0x1fffff] = 0xff; else - lookup_table[((addrs[set][way] >> 5) & 0xfff80) | set] = 0xff; + lookup_table[(addrs[set][way] >> 5) & 0xfffff] = 0xff; } } valid[set] = 0; diff --git a/Source/Core/Core/PowerPC/PPCCache.h b/Source/Core/Core/PowerPC/PPCCache.h index 6e0d1dc33e..b39cc3d8e6 100644 --- a/Source/Core/Core/PowerPC/PPCCache.h +++ b/Source/Core/Core/PowerPC/PPCCache.h @@ -23,7 +23,13 @@ constexpr u32 CACHE_VMEM_BIT = 0x20000000; struct Cache { std::array, CACHE_WAYS>, CACHE_SETS> data{}; + + // Stores the 32-byte aligned address of the start of each cache block. This consists of the cache + // set and tag. Real hardware only needs to store the tag, but also including the set simplifies + // debugging and getting the actual address in the cache, without changing behavior (as the set + // portion of the address is by definition the same for all addresses in a set). std::array, CACHE_SETS> addrs{}; + std::array plru{}; std::array valid{}; std::array modified{};