Merge pull request #8506 from lioncash/cache

PPCCache: Make arrays constexpr where applicable
This commit is contained in:
Léo Lam 2019-12-14 14:25:06 +01:00 committed by GitHub
commit 49fcc71565
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 87 additions and 54 deletions

View File

@ -4,7 +4,7 @@
#include "Core/PowerPC/PPCCache.h" #include "Core/PowerPC/PPCCache.h"
#include <cstring> #include <array>
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/Swap.h" #include "Common/Swap.h"
@ -15,63 +15,96 @@
namespace PowerPC namespace PowerPC
{ {
static const u32 s_plru_mask[8] = {11, 11, 19, 19, 37, 37, 69, 69}; namespace
static const u32 s_plru_value[8] = {11, 3, 17, 1, 36, 4, 64, 0};
InstructionCache::InstructionCache()
{ {
for (u32 m = 0; m < 0xff; m++) constexpr std::array<u32, 8> s_plru_mask{
11, 11, 19, 19, 37, 37, 69, 69,
};
constexpr std::array<u32, 8> s_plru_value{
11, 3, 17, 1, 36, 4, 64, 0,
};
constexpr std::array<u32, 255> s_way_from_valid = [] {
std::array<u32, 255> data{};
for (size_t m = 0; m < data.size(); m++)
{ {
u32 w = 0; u32 w = 0;
while (m & (1 << w)) while ((m & (size_t{1} << w)) != 0)
w++; w++;
way_from_valid[m] = w; data[m] = w;
} }
return data;
}();
for (u32 m = 0; m < 128; m++) constexpr std::array<u32, 128> s_way_from_plru = [] {
std::array<u32, 128> data{};
for (size_t m = 0; m < data.size(); m++)
{ {
u32 b[7]; std::array<u32, 7> b{};
for (int i = 0; i < 7; i++) for (size_t i = 0; i < b.size(); i++)
b[i] = m & (1 << i); b[i] = u32(m & (size_t{1} << i));
u32 w;
if (b[0]) u32 w = 0;
if (b[2]) if (b[0] != 0)
if (b[6]) {
if (b[2] != 0)
{
if (b[6] != 0)
w = 7; w = 7;
else else
w = 6; w = 6;
else if (b[5]) }
else if (b[5] != 0)
{
w = 5; w = 5;
}
else else
{
w = 4; w = 4;
else if (b[1]) }
if (b[4]) }
else if (b[1] != 0)
{
if (b[4] != 0)
w = 3; w = 3;
else else
w = 2; w = 2;
else if (b[3]) }
else if (b[3] != 0)
{
w = 1; w = 1;
}
else else
{
w = 0; w = 0;
way_from_plru[m] = w; }
data[m] = w;
} }
return data;
}();
} // Anonymous namespace
InstructionCache::InstructionCache()
{
} }
void InstructionCache::Reset() void InstructionCache::Reset()
{ {
memset(valid, 0, sizeof(valid)); valid.fill(0);
memset(plru, 0, sizeof(plru)); plru.fill(0);
memset(lookup_table, 0xff, sizeof(lookup_table)); lookup_table.fill(0xFF);
memset(lookup_table_ex, 0xff, sizeof(lookup_table_ex)); lookup_table_ex.fill(0xFF);
memset(lookup_table_vmem, 0xff, sizeof(lookup_table_vmem)); lookup_table_vmem.fill(0xFF);
JitInterface::ClearSafe(); JitInterface::ClearSafe();
} }
void InstructionCache::Init() void InstructionCache::Init()
{ {
memset(data, 0, sizeof(data)); data.fill({});
memset(tags, 0, sizeof(tags)); tags.fill({});
Reset(); Reset();
} }
@ -79,10 +112,12 @@ void InstructionCache::Invalidate(u32 addr)
{ {
if (!HID0.ICE) if (!HID0.ICE)
return; return;
// invalidates the whole set
u32 set = (addr >> 5) & 0x7f; // Invalidates the whole set
for (int i = 0; i < 8; i++) const u32 set = (addr >> 5) & 0x7f;
if (valid[set] & (1 << i)) for (size_t i = 0; i < 8; i++)
{
if (valid[set] & (1U << i))
{ {
if (tags[set][i] & (ICACHE_VMEM_BIT >> 12)) if (tags[set][i] & (ICACHE_VMEM_BIT >> 12))
lookup_table_vmem[((tags[set][i] << 7) | set) & 0xfffff] = 0xff; lookup_table_vmem[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
@ -91,6 +126,7 @@ void InstructionCache::Invalidate(u32 addr)
else else
lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff; lookup_table[((tags[set][i] << 7) | set) & 0xfffff] = 0xff;
} }
}
valid[set] = 0; valid[set] = 0;
JitInterface::InvalidateICache(addr & ~0x1f, 32, false); JitInterface::InvalidateICache(addr & ~0x1f, 32, false);
} }
@ -122,11 +158,11 @@ u32 InstructionCache::ReadInstruction(u32 addr)
return Memory::Read_U32(addr); return Memory::Read_U32(addr);
// select a way // select a way
if (valid[set] != 0xff) if (valid[set] != 0xff)
t = way_from_valid[valid[set]]; t = s_way_from_valid[valid[set]];
else else
t = way_from_plru[plru[set]]; t = s_way_from_plru[plru[set]];
// load // load
Memory::CopyFromEmu((u8*)data[set][t], (addr & ~0x1f), 32); Memory::CopyFromEmu(reinterpret_cast<u8*>(data[set][t].data()), (addr & ~0x1f), 32);
if (valid[set] & (1 << t)) if (valid[set] & (1 << t))
{ {
if (tags[set][t] & (ICACHE_VMEM_BIT >> 12)) if (tags[set][t] & (ICACHE_VMEM_BIT >> 12))
@ -165,8 +201,6 @@ void InstructionCache::DoState(PointerWrap& p)
p.DoArray(tags); p.DoArray(tags);
p.DoArray(plru); p.DoArray(plru);
p.DoArray(valid); p.DoArray(valid);
p.DoArray(way_from_valid);
p.DoArray(way_from_plru);
p.DoArray(lookup_table); p.DoArray(lookup_table);
p.DoArray(lookup_table_ex); p.DoArray(lookup_table_ex);
p.DoArray(lookup_table_vmem); p.DoArray(lookup_table_vmem);

View File

@ -4,33 +4,32 @@
#pragma once #pragma once
#include <array>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
class PointerWrap; class PointerWrap;
namespace PowerPC namespace PowerPC
{ {
const u32 ICACHE_SETS = 128; constexpr u32 ICACHE_SETS = 128;
const u32 ICACHE_WAYS = 8; constexpr u32 ICACHE_WAYS = 8;
// size of an instruction cache block in words // 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; constexpr u32 ICACHE_EXRAM_BIT = 0x10000000;
const u32 ICACHE_VMEM_BIT = 0x20000000; constexpr u32 ICACHE_VMEM_BIT = 0x20000000;
struct InstructionCache struct InstructionCache
{ {
u32 data[ICACHE_SETS][ICACHE_WAYS][ICACHE_BLOCK_SIZE]; std::array<std::array<std::array<u32, ICACHE_BLOCK_SIZE>, ICACHE_WAYS>, ICACHE_SETS> data;
u32 tags[ICACHE_SETS][ICACHE_WAYS]; std::array<std::array<u32, ICACHE_WAYS>, ICACHE_SETS> tags;
u32 plru[ICACHE_SETS]; std::array<u32, ICACHE_SETS> plru;
u32 valid[ICACHE_SETS]; std::array<u32, ICACHE_SETS> valid;
u32 way_from_valid[255]; std::array<u8, 1 << 20> lookup_table;
u32 way_from_plru[128]; std::array<u8, 1 << 21> lookup_table_ex;
std::array<u8, 1 << 20> lookup_table_vmem;
u8 lookup_table[1 << 20];
u8 lookup_table_ex[1 << 21];
u8 lookup_table_vmem[1 << 20];
InstructionCache(); InstructionCache();
u32 ReadInstruction(u32 addr); u32 ReadInstruction(u32 addr);

View File

@ -73,7 +73,7 @@ static Common::Event g_compressAndDumpStateSyncEvent;
static std::thread g_save_thread; static std::thread g_save_thread;
// Don't forget to increase this after doing changes on the savestate system // 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. // Maps savestate versions to Dolphin versions.
// Versions after 42 don't need to be added to this list, // Versions after 42 don't need to be added to this list,