Merge pull request #8506 from lioncash/cache
PPCCache: Make arrays constexpr where applicable
This commit is contained in:
commit
49fcc71565
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue