diff --git a/Source/Core/Core/PowerPC/PPCCache.cpp b/Source/Core/Core/PowerPC/PPCCache.cpp index 9207ea5f72..b70575c04a 100644 --- a/Source/Core/Core/PowerPC/PPCCache.cpp +++ b/Source/Core/Core/PowerPC/PPCCache.cpp @@ -204,13 +204,53 @@ u32 InstructionCache::ReadInstruction(u32 addr) void InstructionCache::DoState(PointerWrap& p) { + if (p.IsReadMode()) + { + // Clear valid parts of the lookup tables (this is done instead of using fill(0xff) to avoid + // loading the entire 4MB of tables into cache) + for (u32 set = 0; set < ICACHE_SETS; set++) + { + for (u32 way = 0; way < ICACHE_WAYS; way++) + { + if ((valid[set] & (1 << way)) != 0) + { + const u32 addr = (tags[set][way] << 12) | (set << 5); + if (addr & ICACHE_VMEM_BIT) + lookup_table_vmem[(addr >> 5) & 0xfffff] = 0xff; + else if (addr & ICACHE_EXRAM_BIT) + lookup_table_ex[(addr >> 5) & 0x1fffff] = 0xff; + else + lookup_table[(addr >> 5) & 0xfffff] = 0xff; + } + } + } + } + p.DoArray(data); p.DoArray(tags); p.DoArray(plru); p.DoArray(valid); - p.DoArray(lookup_table); - p.DoArray(lookup_table_ex); - p.DoArray(lookup_table_vmem); + + if (p.IsReadMode()) + { + // Recompute lookup tables + for (u32 set = 0; set < ICACHE_SETS; set++) + { + for (u32 way = 0; way < ICACHE_WAYS; way++) + { + if ((valid[set] & (1 << way)) != 0) + { + const u32 addr = (tags[set][way] << 12) | (set << 5); + if (addr & ICACHE_VMEM_BIT) + lookup_table_vmem[(addr >> 5) & 0xfffff] = way; + else if (addr & ICACHE_EXRAM_BIT) + lookup_table_ex[(addr >> 5) & 0x1fffff] = way; + else + lookup_table[(addr >> 5) & 0xfffff] = way; + } + } + } + } } void InstructionCache::RefreshConfig() diff --git a/Source/Core/Core/PowerPC/PPCCache.h b/Source/Core/Core/PowerPC/PPCCache.h index 431bc10c41..4b9906ea42 100644 --- a/Source/Core/Core/PowerPC/PPCCache.h +++ b/Source/Core/Core/PowerPC/PPCCache.h @@ -27,6 +27,8 @@ struct InstructionCache std::array plru{}; std::array valid{}; + // Note: This is only for performance purposes; this same data could be computed at runtime + // from the tags and valid fields (and that's how it's done on the actual cache) std::array lookup_table{}; std::array lookup_table_ex{}; std::array lookup_table_vmem{}; diff --git a/Source/Core/Core/State.cpp b/Source/Core/Core/State.cpp index c0ab42a64b..9457ea259a 100644 --- a/Source/Core/Core/State.cpp +++ b/Source/Core/Core/State.cpp @@ -74,7 +74,7 @@ static std::recursive_mutex g_save_thread_mutex; static std::thread g_save_thread; // Don't forget to increase this after doing changes on the savestate system -constexpr u32 STATE_VERSION = 146; // Last changed in PR 10883 +constexpr u32 STATE_VERSION = 147; // Last changed in PR 10935 // Maps savestate versions to Dolphin versions. // Versions after 42 don't need to be added to this list,