diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp index 551142e173..80e74f5a5c 100644 --- a/Source/Core/Core/PowerPC/PPCCache.cpp +++ b/Source/Core/Core/PowerPC/PPCCache.cpp @@ -4,7 +4,7 @@ #include "Core/PowerPC/PPCCache.h" -#include +#include #include "Common/ChunkFile.h" #include "Common/Swap.h" @@ -15,63 +15,96 @@ namespace PowerPC { -static const u32 s_plru_mask[8] = {11, 11, 19, 19, 37, 37, 69, 69}; -static const u32 s_plru_value[8] = {11, 3, 17, 1, 36, 4, 64, 0}; - -InstructionCache::InstructionCache() +namespace { - for (u32 m = 0; m < 0xff; m++) +constexpr std::array s_plru_mask{ + 11, 11, 19, 19, 37, 37, 69, 69, +}; +constexpr std::array s_plru_value{ + 11, 3, 17, 1, 36, 4, 64, 0, +}; + +constexpr std::array s_way_from_valid = [] { + std::array data{}; + for (size_t m = 0; m < data.size(); m++) { u32 w = 0; - while (m & (1 << w)) + while ((m & (size_t{1} << w)) != 0) w++; - way_from_valid[m] = w; + data[m] = w; } + return data; +}(); - for (u32 m = 0; m < 128; m++) +constexpr std::array s_way_from_plru = [] { + std::array data{}; + + for (size_t m = 0; m < data.size(); m++) { - u32 b[7]; - for (int i = 0; i < 7; i++) - b[i] = m & (1 << i); - u32 w; - if (b[0]) - if (b[2]) - if (b[6]) + std::array b{}; + for (size_t i = 0; i < b.size(); i++) + b[i] = u32(m & (size_t{1} << i)); + + u32 w = 0; + if (b[0] != 0) + { + if (b[2] != 0) + { + if (b[6] != 0) w = 7; else w = 6; - else if (b[5]) + } + else if (b[5] != 0) + { w = 5; + } else + { w = 4; - else if (b[1]) - if (b[4]) + } + } + else if (b[1] != 0) + { + if (b[4] != 0) w = 3; else w = 2; - else if (b[3]) + } + else if (b[3] != 0) + { w = 1; + } else + { w = 0; - way_from_plru[m] = w; + } + + data[m] = w; } + + return data; +}(); +} // Anonymous namespace + +InstructionCache::InstructionCache() +{ } void InstructionCache::Reset() { - memset(valid, 0, sizeof(valid)); - memset(plru, 0, sizeof(plru)); - memset(lookup_table, 0xff, sizeof(lookup_table)); - memset(lookup_table_ex, 0xff, sizeof(lookup_table_ex)); - memset(lookup_table_vmem, 0xff, sizeof(lookup_table_vmem)); + valid.fill(0); + plru.fill(0); + lookup_table.fill(0xFF); + lookup_table_ex.fill(0xFF); + lookup_table_vmem.fill(0xFF); JitInterface::ClearSafe(); } void InstructionCache::Init() { - memset(data, 0, sizeof(data)); - memset(tags, 0, sizeof(tags)); - + data.fill({}); + tags.fill({}); Reset(); } @@ -79,10 +112,12 @@ void InstructionCache::Invalidate(u32 addr) { if (!HID0.ICE) return; - // invalidates the whole set - u32 set = (addr >> 5) & 0x7f; - for (int i = 0; i < 8; i++) - if (valid[set] & (1 << i)) + + // Invalidates the whole set + const u32 set = (addr >> 5) & 0x7f; + for (size_t i = 0; i < 8; i++) + { + if (valid[set] & (1U << i)) { if (tags[set][i] & (ICACHE_VMEM_BIT >> 12)) lookup_table_vmem[((tags[set][i] << 7) | set) & 0xfffff] = 0xff; @@ -91,6 +126,7 @@ void InstructionCache::Invalidate(u32 addr) else lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff; } + } valid[set] = 0; JitInterface::InvalidateICache(addr & ~0x1f, 32, false); } @@ -122,11 +158,11 @@ u32 InstructionCache::ReadInstruction(u32 addr) return Memory::Read_U32(addr); // select a way if (valid[set] != 0xff) - t = way_from_valid[valid[set]]; + t = s_way_from_valid[valid[set]]; else - t = way_from_plru[plru[set]]; + t = s_way_from_plru[plru[set]]; // load - Memory::CopyFromEmu((u8*)data[set][t], (addr & ~0x1f), 32); + Memory::CopyFromEmu(reinterpret_cast(data[set][t].data()), (addr & ~0x1f), 32); if (valid[set] & (1 << t)) { if (tags[set][t] & (ICACHE_VMEM_BIT >> 12)) @@ -165,8 +201,6 @@ void InstructionCache::DoState(PointerWrap& p) p.DoArray(tags); p.DoArray(plru); p.DoArray(valid); - p.DoArray(way_from_valid); - p.DoArray(way_from_plru); p.DoArray(lookup_table); p.DoArray(lookup_table_ex); p.DoArray(lookup_table_vmem); diff --git a/Source/Core/Core/PowerPC/PPCCache.h b/Source/Core/Core/PowerPC/PPCCache.h index b13dc15284..d5220dbde3 100644 --- a/Source/Core/Core/PowerPC/PPCCache.h +++ b/Source/Core/Core/PowerPC/PPCCache.h @@ -4,33 +4,32 @@ #pragma once +#include + #include "Common/CommonTypes.h" class PointerWrap; namespace PowerPC { -const u32 ICACHE_SETS = 128; -const u32 ICACHE_WAYS = 8; +constexpr u32 ICACHE_SETS = 128; +constexpr u32 ICACHE_WAYS = 8; // size of an instruction cache block in words -const u32 ICACHE_BLOCK_SIZE = 8; +constexpr u32 ICACHE_BLOCK_SIZE = 8; -const u32 ICACHE_EXRAM_BIT = 0x10000000; -const u32 ICACHE_VMEM_BIT = 0x20000000; +constexpr u32 ICACHE_EXRAM_BIT = 0x10000000; +constexpr u32 ICACHE_VMEM_BIT = 0x20000000; struct InstructionCache { - u32 data[ICACHE_SETS][ICACHE_WAYS][ICACHE_BLOCK_SIZE]; - u32 tags[ICACHE_SETS][ICACHE_WAYS]; - u32 plru[ICACHE_SETS]; - u32 valid[ICACHE_SETS]; + std::array, ICACHE_WAYS>, ICACHE_SETS> data; + std::array, ICACHE_SETS> tags; + std::array plru; + std::array valid; - u32 way_from_valid[255]; - u32 way_from_plru[128]; - - u8 lookup_table[1 << 20]; - u8 lookup_table_ex[1 << 21]; - u8 lookup_table_vmem[1 << 20]; + std::array lookup_table; + std::array lookup_table_ex; + std::array lookup_table_vmem; InstructionCache(); u32 ReadInstruction(u32 addr); diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index 329c1052da..93f0b33318 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -73,7 +73,7 @@ static Common::Event g_compressAndDumpStateSyncEvent; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -static const u32 STATE_VERSION = 112; // Last changed in PR 8444 +constexpr u32 STATE_VERSION = 113; // Last changed in PR 8506 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list,