CachedInterpreter: Avoid System::GetInstance() and ppcState.

This commit is contained in:
Admiral H. Curtiss 2023-03-20 21:45:09 +01:00
parent 9c0226b7e3
commit dfc14db313
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
2 changed files with 88 additions and 43 deletions

View File

@ -20,6 +20,8 @@ struct CachedInterpreter::Instruction
using CommonCallback = void (*)(UGeckoInstruction); using CommonCallback = void (*)(UGeckoInstruction);
using ConditionalCallback = bool (*)(u32); using ConditionalCallback = bool (*)(u32);
using InterpreterCallback = void (*)(Interpreter&, UGeckoInstruction); using InterpreterCallback = void (*)(Interpreter&, UGeckoInstruction);
using CachedInterpreterCallback = void (*)(CachedInterpreter&, UGeckoInstruction);
using ConditionalCachedInterpreterCallback = bool (*)(CachedInterpreter&, u32);
Instruction() {} Instruction() {}
Instruction(const CommonCallback c, UGeckoInstruction i) Instruction(const CommonCallback c, UGeckoInstruction i)
@ -37,12 +39,25 @@ struct CachedInterpreter::Instruction
{ {
} }
Instruction(const CachedInterpreterCallback c, UGeckoInstruction i)
: cached_interpreter_callback(c), data(i.hex), type(Type::CachedInterpreter)
{
}
Instruction(const ConditionalCachedInterpreterCallback c, u32 d)
: conditional_cached_interpreter_callback(c), data(d),
type(Type::ConditionalCachedInterpreter)
{
}
enum class Type enum class Type
{ {
Abort, Abort,
Common, Common,
Conditional, Conditional,
Interpreter, Interpreter,
CachedInterpreter,
ConditionalCachedInterpreter,
}; };
union union
@ -50,6 +65,8 @@ struct CachedInterpreter::Instruction
const CommonCallback common_callback = nullptr; const CommonCallback common_callback = nullptr;
const ConditionalCallback conditional_callback; const ConditionalCallback conditional_callback;
const InterpreterCallback interpreter_callback; const InterpreterCallback interpreter_callback;
const CachedInterpreterCallback cached_interpreter_callback;
const ConditionalCachedInterpreterCallback conditional_cached_interpreter_callback;
}; };
u32 data = 0; u32 data = 0;
@ -91,11 +108,12 @@ void CachedInterpreter::ExecuteOneBlock()
const u8* normal_entry = m_block_cache.Dispatch(); const u8* normal_entry = m_block_cache.Dispatch();
if (!normal_entry) if (!normal_entry)
{ {
Jit(PowerPC::ppcState.pc); Jit(m_ppc_state.pc);
return; return;
} }
const Instruction* code = reinterpret_cast<const Instruction*>(normal_entry); const Instruction* code = reinterpret_cast<const Instruction*>(normal_entry);
auto& interpreter = m_system.GetInterpreter();
for (; code->type != Instruction::Type::Abort; ++code) for (; code->type != Instruction::Type::Abort; ++code)
{ {
@ -111,8 +129,16 @@ void CachedInterpreter::ExecuteOneBlock()
break; break;
case Instruction::Type::Interpreter: case Instruction::Type::Interpreter:
code->interpreter_callback(Core::System::GetInstance().GetInterpreter(), code->interpreter_callback(interpreter, UGeckoInstruction(code->data));
UGeckoInstruction(code->data)); break;
case Instruction::Type::CachedInterpreter:
code->cached_interpreter_callback(*this, UGeckoInstruction(code->data));
break;
case Instruction::Type::ConditionalCachedInterpreter:
if (code->conditional_cached_interpreter_callback(*this, code->data))
return;
break; break;
default: default:
@ -125,9 +151,8 @@ void CachedInterpreter::ExecuteOneBlock()
void CachedInterpreter::Run() void CachedInterpreter::Run()
{ {
auto& system = Core::System::GetInstance(); auto& core_timing = m_system.GetCoreTiming();
auto& core_timing = system.GetCoreTiming(); auto& cpu = m_system.GetCPU();
auto& cpu = system.GetCPU();
const CPU::State* state_ptr = cpu.GetStatePtr(); const CPU::State* state_ptr = cpu.GetStatePtr();
while (cpu.GetState() == CPU::State::Running) while (cpu.GetState() == CPU::State::Running)
@ -139,96 +164,103 @@ void CachedInterpreter::Run()
do do
{ {
ExecuteOneBlock(); ExecuteOneBlock();
} while (PowerPC::ppcState.downcount > 0 && *state_ptr == CPU::State::Running); } while (m_ppc_state.downcount > 0 && *state_ptr == CPU::State::Running);
} }
} }
void CachedInterpreter::SingleStep() void CachedInterpreter::SingleStep()
{ {
// Enter new timing slice // Enter new timing slice
Core::System::GetInstance().GetCoreTiming().Advance(); m_system.GetCoreTiming().Advance();
ExecuteOneBlock(); ExecuteOneBlock();
} }
static void EndBlock(UGeckoInstruction data) void CachedInterpreter::EndBlock(CachedInterpreter& cached_interpreter, UGeckoInstruction data)
{ {
PowerPC::ppcState.pc = PowerPC::ppcState.npc; auto& ppc_state = cached_interpreter.m_ppc_state;
PowerPC::ppcState.downcount -= data.hex; ppc_state.pc = ppc_state.npc;
PowerPC::UpdatePerformanceMonitor(data.hex, 0, 0, PowerPC::ppcState); ppc_state.downcount -= data.hex;
PowerPC::UpdatePerformanceMonitor(data.hex, 0, 0, ppc_state);
} }
static void UpdateNumLoadStoreInstructions(UGeckoInstruction data) void CachedInterpreter::UpdateNumLoadStoreInstructions(CachedInterpreter& cached_interpreter,
UGeckoInstruction data)
{ {
PowerPC::UpdatePerformanceMonitor(0, data.hex, 0, PowerPC::ppcState); PowerPC::UpdatePerformanceMonitor(0, data.hex, 0, cached_interpreter.m_ppc_state);
} }
static void UpdateNumFloatingPointInstructions(UGeckoInstruction data) void CachedInterpreter::UpdateNumFloatingPointInstructions(CachedInterpreter& cached_interpreter,
UGeckoInstruction data)
{ {
PowerPC::UpdatePerformanceMonitor(0, 0, data.hex, PowerPC::ppcState); PowerPC::UpdatePerformanceMonitor(0, 0, data.hex, cached_interpreter.m_ppc_state);
} }
static void WritePC(UGeckoInstruction data) void CachedInterpreter::WritePC(CachedInterpreter& cached_interpreter, UGeckoInstruction data)
{ {
PowerPC::ppcState.pc = data.hex; auto& ppc_state = cached_interpreter.m_ppc_state;
PowerPC::ppcState.npc = data.hex + 4; ppc_state.pc = data.hex;
ppc_state.npc = data.hex + 4;
} }
static void WriteBrokenBlockNPC(UGeckoInstruction data) void CachedInterpreter::WriteBrokenBlockNPC(CachedInterpreter& cached_interpreter,
UGeckoInstruction data)
{ {
PowerPC::ppcState.npc = data.hex; cached_interpreter.m_ppc_state.npc = data.hex;
} }
static bool CheckFPU(u32 data) bool CachedInterpreter::CheckFPU(CachedInterpreter& cached_interpreter, u32 data)
{ {
if (!PowerPC::ppcState.msr.FP) auto& ppc_state = cached_interpreter.m_ppc_state;
if (!ppc_state.msr.FP)
{ {
PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; ppc_state.Exceptions |= EXCEPTION_FPU_UNAVAILABLE;
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
PowerPC::ppcState.downcount -= data; ppc_state.downcount -= data;
return true; return true;
} }
return false; return false;
} }
static bool CheckDSI(u32 data) bool CachedInterpreter::CheckDSI(CachedInterpreter& cached_interpreter, u32 data)
{ {
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI) auto& ppc_state = cached_interpreter.m_ppc_state;
if (ppc_state.Exceptions & EXCEPTION_DSI)
{ {
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
PowerPC::ppcState.downcount -= data; ppc_state.downcount -= data;
return true; return true;
} }
return false; return false;
} }
static bool CheckProgramException(u32 data) bool CachedInterpreter::CheckProgramException(CachedInterpreter& cached_interpreter, u32 data)
{ {
if (PowerPC::ppcState.Exceptions & EXCEPTION_PROGRAM) auto& ppc_state = cached_interpreter.m_ppc_state;
if (ppc_state.Exceptions & EXCEPTION_PROGRAM)
{ {
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
PowerPC::ppcState.downcount -= data; ppc_state.downcount -= data;
return true; return true;
} }
return false; return false;
} }
static bool CheckBreakpoint(u32 data) bool CachedInterpreter::CheckBreakpoint(CachedInterpreter& cached_interpreter, u32 data)
{ {
PowerPC::CheckBreakPoints(); PowerPC::CheckBreakPoints();
auto& system = Core::System::GetInstance(); if (cached_interpreter.m_system.GetCPU().GetState() != CPU::State::Running)
if (system.GetCPU().GetState() != CPU::State::Running)
{ {
PowerPC::ppcState.downcount -= data; cached_interpreter.m_ppc_state.downcount -= data;
return true; return true;
} }
return false; return false;
} }
static bool CheckIdle(u32 idle_pc) bool CachedInterpreter::CheckIdle(CachedInterpreter& cached_interpreter, u32 idle_pc)
{ {
if (PowerPC::ppcState.npc == idle_pc) if (cached_interpreter.m_ppc_state.npc == idle_pc)
{ {
Core::System::GetInstance().GetCoreTiming().Idle(); cached_interpreter.m_system.GetCoreTiming().Idle();
} }
return false; return false;
} }
@ -257,20 +289,20 @@ void CachedInterpreter::Jit(u32 address)
} }
const u32 nextPC = const u32 nextPC =
analyzer.Analyze(PowerPC::ppcState.pc, &code_block, &m_code_buffer, m_code_buffer.size()); analyzer.Analyze(m_ppc_state.pc, &code_block, &m_code_buffer, m_code_buffer.size());
if (code_block.m_memory_exception) if (code_block.m_memory_exception)
{ {
// Address of instruction could not be translated // Address of instruction could not be translated
PowerPC::ppcState.npc = nextPC; m_ppc_state.npc = nextPC;
PowerPC::ppcState.Exceptions |= EXCEPTION_ISI; m_ppc_state.Exceptions |= EXCEPTION_ISI;
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
WARN_LOG_FMT(POWERPC, "ISI exception at {:#010x}", nextPC); WARN_LOG_FMT(POWERPC, "ISI exception at {:#010x}", nextPC);
return; return;
} }
JitBlock* b = m_block_cache.AllocateBlock(PowerPC::ppcState.pc); JitBlock* b = m_block_cache.AllocateBlock(m_ppc_state.pc);
js.blockStart = PowerPC::ppcState.pc; js.blockStart = m_ppc_state.pc;
js.firstFPInstructionFound = false; js.firstFPInstructionFound = false;
js.fifoBytesSinceCheck = 0; js.fifoBytesSinceCheck = 0;
js.downcountAmount = 0; js.downcountAmount = 0;

View File

@ -43,6 +43,19 @@ private:
bool HandleFunctionHooking(u32 address); bool HandleFunctionHooking(u32 address);
static void EndBlock(CachedInterpreter& cached_interpreter, UGeckoInstruction data);
static void UpdateNumLoadStoreInstructions(CachedInterpreter& cached_interpreter,
UGeckoInstruction data);
static void UpdateNumFloatingPointInstructions(CachedInterpreter& cached_interpreter,
UGeckoInstruction data);
static void WritePC(CachedInterpreter& cached_interpreter, UGeckoInstruction data);
static void WriteBrokenBlockNPC(CachedInterpreter& cached_interpreter, UGeckoInstruction data);
static bool CheckFPU(CachedInterpreter& cached_interpreter, u32 data);
static bool CheckDSI(CachedInterpreter& cached_interpreter, u32 data);
static bool CheckProgramException(CachedInterpreter& cached_interpreter, u32 data);
static bool CheckBreakpoint(CachedInterpreter& cached_interpreter, u32 data);
static bool CheckIdle(CachedInterpreter& cached_interpreter, u32 idle_pc);
BlockCache m_block_cache{*this}; BlockCache m_block_cache{*this};
std::vector<Instruction> m_code; std::vector<Instruction> m_code;
}; };