CPU/Recompiler: Get rid of non-constant offsetofs

This commit is contained in:
Connor McLaughlin 2021-05-12 02:26:58 +10:00
parent 4cb8817247
commit acda42be16
5 changed files with 15 additions and 18 deletions

View file

@ -500,7 +500,7 @@ recompile:
{ {
block->recompile_count++; block->recompile_count++;
if (block->recompile_count >= RECOMPILE_COUNT_TO_FALL_BACK_TO_INTERPRETER) if (block->recompile_count >= RECOMPILE_COUNT_TO_FALL_BACK_TO_INTERPRETER&&false)
{ {
Log_PerfPrintf("Block 0x%08X has been recompiled %u times in %u frames, falling back to interpreter", Log_PerfPrintf("Block 0x%08X has been recompiled %u times in %u frames, falling back to interpreter",
block->GetPC(), block->recompile_count, frame_diff); block->GetPC(), block->recompile_count, frame_diff);

View file

@ -84,6 +84,9 @@ struct State
std::array<u8, DCACHE_SIZE> dcache = {}; std::array<u8, DCACHE_SIZE> dcache = {};
std::array<u32, ICACHE_LINES> icache_tags = {}; std::array<u32, ICACHE_LINES> icache_tags = {};
std::array<u8, ICACHE_SIZE> icache_data = {}; std::array<u8, ICACHE_SIZE> icache_data = {};
static constexpr u32 GPRRegisterOffset(u32 index) { return offsetof(State, regs.r) + (sizeof(u32) * index); }
static constexpr u32 GTERegisterOffset(u32 index) { return offsetof(State, gte_regs.r32) + (sizeof(u32) * index); }
}; };
extern State g_state; extern State g_state;

View file

@ -14,11 +14,6 @@ Log_SetChannel(CPU::Recompiler);
namespace CPU::Recompiler { namespace CPU::Recompiler {
u32 CodeGenerator::CalculateRegisterOffset(Reg reg)
{
return u32(offsetof(State, regs.r[0]) + (static_cast<u32>(reg) * sizeof(u32)));
}
bool CodeGenerator::CompileBlock(CodeBlock* block, CodeBlock::HostCodePointer* out_host_code, u32* out_host_code_size) bool CodeGenerator::CompileBlock(CodeBlock* block, CodeBlock::HostCodePointer* out_host_code, u32* out_host_code_size)
{ {
// TODO: Align code buffer. // TODO: Align code buffer.
@ -2627,7 +2622,7 @@ Value CodeGenerator::DoGTERegisterRead(u32 index)
default: default:
{ {
EmitLoadCPUStructField(value.host_reg, RegSize_32, offsetof(State, gte_regs.r32[index])); EmitLoadCPUStructField(value.host_reg, RegSize_32, State::GTERegisterOffset(index));
} }
break; break;
} }
@ -2656,7 +2651,7 @@ void CodeGenerator::DoGTERegisterWrite(u32 index, const Value& value)
{ {
// sign-extend z component of vector registers // sign-extend z component of vector registers
Value temp = ConvertValueSize(value.ViewAsSize(RegSize_16), RegSize_32, true); Value temp = ConvertValueSize(value.ViewAsSize(RegSize_16), RegSize_32, true);
EmitStoreCPUStructField(offsetof(State, gte_regs.r32[index]), temp); EmitStoreCPUStructField(State::GTERegisterOffset(index), temp);
return; return;
} }
break; break;
@ -2669,7 +2664,7 @@ void CodeGenerator::DoGTERegisterWrite(u32 index, const Value& value)
{ {
// zero-extend unsigned values // zero-extend unsigned values
Value temp = ConvertValueSize(value.ViewAsSize(RegSize_16), RegSize_32, false); Value temp = ConvertValueSize(value.ViewAsSize(RegSize_16), RegSize_32, false);
EmitStoreCPUStructField(offsetof(State, gte_regs.r32[index]), temp); EmitStoreCPUStructField(State::GTERegisterOffset(index), temp);
return; return;
} }
break; break;
@ -2680,15 +2675,15 @@ void CodeGenerator::DoGTERegisterWrite(u32 index, const Value& value)
Value temp = m_register_cache.AllocateScratch(RegSize_32); Value temp = m_register_cache.AllocateScratch(RegSize_32);
// SXY0 <- SXY1 // SXY0 <- SXY1
EmitLoadCPUStructField(temp.host_reg, RegSize_32, offsetof(State, gte_regs.r32[13])); EmitLoadCPUStructField(temp.host_reg, RegSize_32, State::GTERegisterOffset(13));
EmitStoreCPUStructField(offsetof(State, gte_regs.r32[12]), temp); EmitStoreCPUStructField(State::GTERegisterOffset(12), temp);
// SXY1 <- SXY2 // SXY1 <- SXY2
EmitLoadCPUStructField(temp.host_reg, RegSize_32, offsetof(State, gte_regs.r32[14])); EmitLoadCPUStructField(temp.host_reg, RegSize_32, State::GTERegisterOffset(14));
EmitStoreCPUStructField(offsetof(State, gte_regs.r32[13]), temp); EmitStoreCPUStructField(State::GTERegisterOffset(13), temp);
// SXY2 <- SXYP // SXY2 <- SXYP
EmitStoreCPUStructField(offsetof(State, gte_regs.r32[14]), value); EmitStoreCPUStructField(State::GTERegisterOffset(14), value);
return; return;
} }
break; break;
@ -2711,7 +2706,7 @@ void CodeGenerator::DoGTERegisterWrite(u32 index, const Value& value)
default: default:
{ {
// written as-is, 2x16 or 1x32 bits // written as-is, 2x16 or 1x32 bits
EmitStoreCPUStructField(offsetof(State, gte_regs.r32[index]), value); EmitStoreCPUStructField(State::GTERegisterOffset(index), value);
return; return;
} }
} }

View file

@ -21,7 +21,6 @@ public:
CodeGenerator(JitCodeBuffer* code_buffer); CodeGenerator(JitCodeBuffer* code_buffer);
~CodeGenerator(); ~CodeGenerator();
static u32 CalculateRegisterOffset(Reg reg);
static const char* GetHostRegName(HostReg reg, RegSize size = HostPointerSize); static const char* GetHostRegName(HostReg reg, RegSize size = HostPointerSize);
static void AlignCodeBuffer(JitCodeBuffer* code_buffer); static void AlignCodeBuffer(JitCodeBuffer* code_buffer);

View file

@ -9,13 +9,13 @@ namespace CPU::Recompiler {
void CodeGenerator::EmitLoadGuestRegister(HostReg host_reg, Reg guest_reg) void CodeGenerator::EmitLoadGuestRegister(HostReg host_reg, Reg guest_reg)
{ {
EmitLoadCPUStructField(host_reg, RegSize_32, CalculateRegisterOffset(guest_reg)); EmitLoadCPUStructField(host_reg, RegSize_32, State::GPRRegisterOffset(static_cast<u32>(guest_reg)));
} }
void CodeGenerator::EmitStoreGuestRegister(Reg guest_reg, const Value& value) void CodeGenerator::EmitStoreGuestRegister(Reg guest_reg, const Value& value)
{ {
DebugAssert(value.size == RegSize_32); DebugAssert(value.size == RegSize_32);
EmitStoreCPUStructField(CalculateRegisterOffset(guest_reg), value); EmitStoreCPUStructField(State::GPRRegisterOffset(static_cast<u32>(guest_reg)), value);
} }
void CodeGenerator::EmitStoreInterpreterLoadDelay(Reg reg, const Value& value) void CodeGenerator::EmitStoreInterpreterLoadDelay(Reg reg, const Value& value)