Skip to content

Commit

Permalink
Merge pull request #11677 from AdmiralCurtiss/deglobal-jit
Browse files Browse the repository at this point in the history
Avoid System::GetInstance() and ppcState global in Jit64 and CachedInterpreter.
  • Loading branch information
AdmiralCurtiss committed Mar 25, 2023
2 parents 51f668a + fc394bd commit 6b44947
Show file tree
Hide file tree
Showing 29 changed files with 292 additions and 184 deletions.
122 changes: 78 additions & 44 deletions Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp
Expand Up @@ -20,6 +20,8 @@ struct CachedInterpreter::Instruction
using CommonCallback = void (*)(UGeckoInstruction);
using ConditionalCallback = bool (*)(u32);
using InterpreterCallback = void (*)(Interpreter&, UGeckoInstruction);
using CachedInterpreterCallback = void (*)(CachedInterpreter&, UGeckoInstruction);
using ConditionalCachedInterpreterCallback = bool (*)(CachedInterpreter&, u32);

Instruction() {}
Instruction(const CommonCallback c, UGeckoInstruction i)
Expand All @@ -37,26 +39,43 @@ 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
{
Abort,
Common,
Conditional,
Interpreter,
CachedInterpreter,
ConditionalCachedInterpreter,
};

union
{
const CommonCallback common_callback = nullptr;
const ConditionalCallback conditional_callback;
const InterpreterCallback interpreter_callback;
const CachedInterpreterCallback cached_interpreter_callback;
const ConditionalCachedInterpreterCallback conditional_cached_interpreter_callback;
};

u32 data = 0;
Type type = Type::Abort;
};

CachedInterpreter::CachedInterpreter() = default;
CachedInterpreter::CachedInterpreter(Core::System& system) : JitBase(system)
{
}

CachedInterpreter::~CachedInterpreter() = default;

Expand Down Expand Up @@ -89,11 +108,12 @@ void CachedInterpreter::ExecuteOneBlock()
const u8* normal_entry = m_block_cache.Dispatch();
if (!normal_entry)
{
Jit(PowerPC::ppcState.pc);
Jit(m_ppc_state.pc);
return;
}

const Instruction* code = reinterpret_cast<const Instruction*>(normal_entry);
auto& interpreter = m_system.GetInterpreter();

for (; code->type != Instruction::Type::Abort; ++code)
{
Expand All @@ -109,8 +129,16 @@ void CachedInterpreter::ExecuteOneBlock()
break;

case Instruction::Type::Interpreter:
code->interpreter_callback(Core::System::GetInstance().GetInterpreter(),
UGeckoInstruction(code->data));
code->interpreter_callback(interpreter, 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;

default:
Expand All @@ -123,9 +151,8 @@ void CachedInterpreter::ExecuteOneBlock()

void CachedInterpreter::Run()
{
auto& system = Core::System::GetInstance();
auto& core_timing = system.GetCoreTiming();
auto& cpu = system.GetCPU();
auto& core_timing = m_system.GetCoreTiming();
auto& cpu = m_system.GetCPU();

const CPU::State* state_ptr = cpu.GetStatePtr();
while (cpu.GetState() == CPU::State::Running)
Expand All @@ -137,96 +164,103 @@ void CachedInterpreter::Run()
do
{
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()
{
// Enter new timing slice
Core::System::GetInstance().GetCoreTiming().Advance();
m_system.GetCoreTiming().Advance();
ExecuteOneBlock();
}

static void EndBlock(UGeckoInstruction data)
void CachedInterpreter::EndBlock(CachedInterpreter& cached_interpreter, UGeckoInstruction data)
{
PowerPC::ppcState.pc = PowerPC::ppcState.npc;
PowerPC::ppcState.downcount -= data.hex;
PowerPC::UpdatePerformanceMonitor(data.hex, 0, 0, PowerPC::ppcState);
auto& ppc_state = cached_interpreter.m_ppc_state;
ppc_state.pc = ppc_state.npc;
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;
PowerPC::ppcState.npc = data.hex + 4;
auto& ppc_state = cached_interpreter.m_ppc_state;
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::ppcState.downcount -= data;
ppc_state.downcount -= data;
return true;
}
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::ppcState.downcount -= data;
ppc_state.downcount -= data;
return true;
}
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::ppcState.downcount -= data;
ppc_state.downcount -= data;
return true;
}
return false;
}

static bool CheckBreakpoint(u32 data)
bool CachedInterpreter::CheckBreakpoint(CachedInterpreter& cached_interpreter, u32 data)
{
PowerPC::CheckBreakPoints();
auto& system = Core::System::GetInstance();
if (system.GetCPU().GetState() != CPU::State::Running)
if (cached_interpreter.m_system.GetCPU().GetState() != CPU::State::Running)
{
PowerPC::ppcState.downcount -= data;
cached_interpreter.m_ppc_state.downcount -= data;
return true;
}
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;
}
Expand Down Expand Up @@ -255,20 +289,20 @@ void CachedInterpreter::Jit(u32 address)
}

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)
{
// Address of instruction could not be translated
PowerPC::ppcState.npc = nextPC;
PowerPC::ppcState.Exceptions |= EXCEPTION_ISI;
m_ppc_state.npc = nextPC;
m_ppc_state.Exceptions |= EXCEPTION_ISI;
PowerPC::CheckExceptions();
WARN_LOG_FMT(POWERPC, "ISI exception at {:#010x}", nextPC);
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.fifoBytesSinceCheck = 0;
js.downcountAmount = 0;
Expand Down
19 changes: 18 additions & 1 deletion Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.h
Expand Up @@ -13,7 +13,11 @@
class CachedInterpreter : public JitBase
{
public:
CachedInterpreter();
explicit CachedInterpreter(Core::System& system);
CachedInterpreter(const CachedInterpreter&) = delete;
CachedInterpreter(CachedInterpreter&&) = delete;
CachedInterpreter& operator=(const CachedInterpreter&) = delete;
CachedInterpreter& operator=(CachedInterpreter&&) = delete;
~CachedInterpreter();

void Init() override;
Expand All @@ -39,6 +43,19 @@ class CachedInterpreter : public JitBase

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};
std::vector<Instruction> m_code;
};

0 comments on commit 6b44947

Please sign in to comment.