Interpreter: Move global state into class, move instance to System.
This commit is contained in:
parent
919182eda2
commit
3d67c11b91
|
@ -109,7 +109,8 @@ void CachedInterpreter::ExecuteOneBlock()
|
|||
break;
|
||||
|
||||
case Instruction::Type::Interpreter:
|
||||
code->interpreter_callback(*Interpreter::getInstance(), UGeckoInstruction(code->data));
|
||||
code->interpreter_callback(Core::System::GetInstance().GetInterpreter(),
|
||||
UGeckoInstruction(code->data));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -27,13 +27,6 @@
|
|||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "Core/System.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
u32 last_pc;
|
||||
}
|
||||
|
||||
bool Interpreter::m_end_block;
|
||||
|
||||
namespace
|
||||
{
|
||||
// Determines whether or not the given instruction is one where its execution
|
||||
|
@ -63,13 +56,20 @@ bool IsInvalidPairedSingleExecution(UGeckoInstruction inst)
|
|||
return HID2(PowerPC::ppcState).PSE && !HID2(PowerPC::ppcState).LSQE &&
|
||||
IsPairedSingleQuantizedNonIndexedInstruction(inst);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void UpdatePC()
|
||||
void Interpreter::UpdatePC()
|
||||
{
|
||||
last_pc = PowerPC::ppcState.pc;
|
||||
m_last_pc = PowerPC::ppcState.pc;
|
||||
PowerPC::ppcState.pc = PowerPC::ppcState.npc;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
Interpreter::Interpreter(Core::System& system, PowerPC::PowerPCState& ppc_state)
|
||||
: m_system(system), m_ppc_state(ppc_state)
|
||||
{
|
||||
}
|
||||
|
||||
Interpreter::~Interpreter() = default;
|
||||
|
||||
void Interpreter::Init()
|
||||
{
|
||||
|
@ -80,9 +80,7 @@ void Interpreter::Shutdown()
|
|||
{
|
||||
}
|
||||
|
||||
static bool s_start_trace = false;
|
||||
|
||||
static void Trace(const UGeckoInstruction& inst)
|
||||
void Interpreter::Trace(const UGeckoInstruction& inst)
|
||||
{
|
||||
std::string regs;
|
||||
for (size_t i = 0; i < std::size(PowerPC::ppcState.gpr); i++)
|
||||
|
@ -109,8 +107,8 @@ static void Trace(const UGeckoInstruction& inst)
|
|||
|
||||
bool Interpreter::HandleFunctionHooking(u32 address)
|
||||
{
|
||||
return HLE::ReplaceFunctionIfPossible(address, [](u32 hook_index, HLE::HookType type) {
|
||||
HLEFunction(*Interpreter::getInstance(), hook_index);
|
||||
return HLE::ReplaceFunctionIfPossible(address, [this](u32 hook_index, HLE::HookType type) {
|
||||
HLEFunction(*this, hook_index);
|
||||
return type != HLE::HookType::Start;
|
||||
});
|
||||
}
|
||||
|
@ -135,14 +133,14 @@ int Interpreter::SingleStepInner()
|
|||
// if ((PowerPC::ppcState.pc & 0x00FFFFFF) >= 0x000AB54C &&
|
||||
// (PowerPC::ppcState.pc & 0x00FFFFFF) <= 0x000AB624)
|
||||
// {
|
||||
// s_start_trace = true;
|
||||
// m_start_trace = true;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// s_start_trace = false;
|
||||
// m_start_trace = false;
|
||||
// }
|
||||
|
||||
if (s_start_trace)
|
||||
if (m_start_trace)
|
||||
{
|
||||
Trace(m_prev_inst);
|
||||
}
|
||||
|
@ -156,7 +154,7 @@ int Interpreter::SingleStepInner()
|
|||
}
|
||||
else if (PowerPC::ppcState.msr.FP)
|
||||
{
|
||||
RunInterpreterOp(*Interpreter::getInstance(), m_prev_inst);
|
||||
RunInterpreterOp(*this, m_prev_inst);
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
CheckExceptions();
|
||||
|
@ -172,7 +170,7 @@ int Interpreter::SingleStepInner()
|
|||
}
|
||||
else
|
||||
{
|
||||
RunInterpreterOp(*Interpreter::getInstance(), m_prev_inst);
|
||||
RunInterpreterOp(*this, m_prev_inst);
|
||||
if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0)
|
||||
{
|
||||
CheckExceptions();
|
||||
|
@ -319,6 +317,7 @@ void Interpreter::unknown_instruction(Interpreter& interpreter, UGeckoInstructio
|
|||
auto& system = Core::System::GetInstance();
|
||||
Core::CPUThreadGuard guard(system);
|
||||
|
||||
const u32 last_pc = interpreter.m_last_pc;
|
||||
const u32 opcode = PowerPC::HostRead_U32(guard, last_pc);
|
||||
const std::string disasm = Common::GekkoDisassembler::Disassemble(opcode, last_pc);
|
||||
NOTICE_LOG_FMT(POWERPC, "Last PC = {:08x} : {}", last_pc, disasm);
|
||||
|
@ -360,9 +359,3 @@ const char* Interpreter::GetName() const
|
|||
return "Interpreter32";
|
||||
#endif
|
||||
}
|
||||
|
||||
Interpreter* Interpreter::getInstance()
|
||||
{
|
||||
static Interpreter instance;
|
||||
return &instance;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,25 @@
|
|||
#include "Core/PowerPC/CPUCoreBase.h"
|
||||
#include "Core/PowerPC/Gekko.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
class System;
|
||||
}
|
||||
namespace PowerPC
|
||||
{
|
||||
struct PowerPCState;
|
||||
}
|
||||
|
||||
class Interpreter : public CPUCoreBase
|
||||
{
|
||||
public:
|
||||
Interpreter(Core::System& system, PowerPC::PowerPCState& ppc_state);
|
||||
Interpreter(const Interpreter&) = delete;
|
||||
Interpreter(Interpreter&&) = delete;
|
||||
Interpreter& operator=(const Interpreter&) = delete;
|
||||
Interpreter& operator=(Interpreter&&) = delete;
|
||||
~Interpreter();
|
||||
|
||||
void Init() override;
|
||||
void Shutdown() override;
|
||||
void SingleStep() override;
|
||||
|
@ -266,9 +282,6 @@ public:
|
|||
static Instruction GetInterpreterOp(UGeckoInstruction inst);
|
||||
static void RunInterpreterOp(Interpreter& interpreter, UGeckoInstruction inst);
|
||||
|
||||
// singleton
|
||||
static Interpreter* getInstance();
|
||||
|
||||
static void RunTable4(Interpreter& interpreter, UGeckoInstruction inst);
|
||||
static void RunTable19(Interpreter& interpreter, UGeckoInstruction inst);
|
||||
static void RunTable31(Interpreter& interpreter, UGeckoInstruction inst);
|
||||
|
@ -280,7 +293,7 @@ public:
|
|||
private:
|
||||
void CheckExceptions();
|
||||
|
||||
static bool HandleFunctionHooking(u32 address);
|
||||
bool HandleFunctionHooking(u32 address);
|
||||
|
||||
// flag helper
|
||||
static void Helper_UpdateCR0(u32 value);
|
||||
|
@ -290,7 +303,15 @@ private:
|
|||
static void Helper_FloatCompareOrdered(UGeckoInstruction inst, double a, double b);
|
||||
static void Helper_FloatCompareUnordered(UGeckoInstruction inst, double a, double b);
|
||||
|
||||
UGeckoInstruction m_prev_inst{};
|
||||
void UpdatePC();
|
||||
|
||||
static bool m_end_block;
|
||||
void Trace(const UGeckoInstruction& inst);
|
||||
|
||||
Core::System& m_system;
|
||||
PowerPC::PowerPCState& m_ppc_state;
|
||||
|
||||
UGeckoInstruction m_prev_inst{};
|
||||
u32 m_last_pc = 0;
|
||||
bool m_end_block = false;
|
||||
bool m_start_trace = false;
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
else
|
||||
PowerPC::ppcState.npc = PowerPC::ppcState.pc + address;
|
||||
|
||||
m_end_block = true;
|
||||
interpreter.m_end_block = true;
|
||||
}
|
||||
|
||||
// bcx - ugly, straight from PPC manual equations :)
|
||||
|
@ -54,7 +54,7 @@ void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
PowerPC::ppcState.npc = PowerPC::ppcState.pc + address;
|
||||
}
|
||||
|
||||
m_end_block = true;
|
||||
interpreter.m_end_block = true;
|
||||
}
|
||||
|
||||
void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -72,7 +72,7 @@ void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
|
||||
}
|
||||
|
||||
m_end_block = true;
|
||||
interpreter.m_end_block = true;
|
||||
}
|
||||
|
||||
void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
|
@ -91,12 +91,12 @@ void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4;
|
||||
}
|
||||
|
||||
m_end_block = true;
|
||||
interpreter.m_end_block = true;
|
||||
}
|
||||
|
||||
void Interpreter::HLEFunction(Interpreter& interpreter, UGeckoInstruction inst)
|
||||
{
|
||||
m_end_block = true;
|
||||
interpreter.m_end_block = true;
|
||||
|
||||
ASSERT(Core::IsCPUThread());
|
||||
Core::CPUThreadGuard guard(Core::System::GetInstance());
|
||||
|
@ -126,7 +126,7 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
// else
|
||||
// set NPC to saved offset and resume
|
||||
PowerPC::ppcState.npc = SRR0(PowerPC::ppcState);
|
||||
m_end_block = true;
|
||||
interpreter.m_end_block = true;
|
||||
}
|
||||
|
||||
// sc isn't really used for anything important in GameCube games (just for a write barrier) so we
|
||||
|
@ -136,5 +136,5 @@ void Interpreter::sc(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
|
||||
PowerPC::CheckExceptions();
|
||||
m_end_block = true;
|
||||
interpreter.m_end_block = true;
|
||||
}
|
||||
|
|
|
@ -137,7 +137,7 @@ void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
GenerateProgramException(ProgramExceptionCause::Trap);
|
||||
PowerPC::CheckExceptions();
|
||||
m_end_block = true; // Dunno about this
|
||||
interpreter.m_end_block = true; // Dunno about this
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -353,7 +353,7 @@ void Interpreter::tw(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
{
|
||||
GenerateProgramException(ProgramExceptionCause::Trap);
|
||||
PowerPC::CheckExceptions();
|
||||
m_end_block = true; // Dunno about this
|
||||
interpreter.m_end_block = true; // Dunno about this
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst)
|
|||
CheckFPExceptions(PowerPC::ppcState.fpscr);
|
||||
|
||||
PowerPC::CheckExceptions();
|
||||
m_end_block = true;
|
||||
interpreter.m_end_block = true;
|
||||
}
|
||||
|
||||
// Segment registers. MMU control.
|
||||
|
|
|
@ -344,7 +344,7 @@ void Jit64::FallBackToInterpreter(UGeckoInstruction inst)
|
|||
|
||||
Interpreter::Instruction instr = Interpreter::GetInterpreterOp(inst);
|
||||
ABI_PushRegistersAndAdjustStack({}, 0);
|
||||
ABI_CallFunctionPC(instr, Interpreter::getInstance(), inst.hex);
|
||||
ABI_CallFunctionPC(instr, &Core::System::GetInstance().GetInterpreter(), inst.hex);
|
||||
ABI_PopRegistersAndAdjustStack({}, 0);
|
||||
|
||||
// If the instruction wrote to any registers which were marked as discarded,
|
||||
|
|
|
@ -199,7 +199,7 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst)
|
|||
|
||||
Interpreter::Instruction instr = Interpreter::GetInterpreterOp(inst);
|
||||
MOVP2R(ARM64Reg::X8, instr);
|
||||
MOVP2R(ARM64Reg::W0, Interpreter::getInstance());
|
||||
MOVP2R(ARM64Reg::W0, &Core::System::GetInstance().GetInterpreter());
|
||||
MOVI2R(ARM64Reg::W1, inst.hex);
|
||||
BLR(ARM64Reg::X8);
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ PowerPCState ppcState;
|
|||
|
||||
static CPUCoreBase* s_cpu_core_base = nullptr;
|
||||
static bool s_cpu_core_base_is_injected = false;
|
||||
Interpreter* const s_interpreter = Interpreter::getInstance();
|
||||
static CoreMode s_mode = CoreMode::Interpreter;
|
||||
|
||||
BreakPoints breakpoints;
|
||||
|
@ -220,12 +219,13 @@ static void InitializeCPUCore(CPUCore cpu_core)
|
|||
{
|
||||
// We initialize the interpreter because
|
||||
// it is used on boot and code window independently.
|
||||
s_interpreter->Init();
|
||||
auto& interpreter = Core::System::GetInstance().GetInterpreter();
|
||||
interpreter.Init();
|
||||
|
||||
switch (cpu_core)
|
||||
{
|
||||
case CPUCore::Interpreter:
|
||||
s_cpu_core_base = s_interpreter;
|
||||
s_cpu_core_base = &interpreter;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -239,7 +239,7 @@ static void InitializeCPUCore(CPUCore cpu_core)
|
|||
break;
|
||||
}
|
||||
|
||||
s_mode = s_cpu_core_base == s_interpreter ? CoreMode::Interpreter : CoreMode::JIT;
|
||||
s_mode = s_cpu_core_base == &interpreter ? CoreMode::Interpreter : CoreMode::JIT;
|
||||
}
|
||||
|
||||
const std::vector<CPUCore>& AvailableCPUCores()
|
||||
|
@ -316,7 +316,8 @@ void Shutdown()
|
|||
{
|
||||
InjectExternalCPUCore(nullptr);
|
||||
JitInterface::Shutdown();
|
||||
s_interpreter->Shutdown();
|
||||
auto& interpreter = Core::System::GetInstance().GetInterpreter();
|
||||
interpreter.Shutdown();
|
||||
s_cpu_core_base = nullptr;
|
||||
}
|
||||
|
||||
|
@ -327,17 +328,19 @@ CoreMode GetMode()
|
|||
|
||||
static void ApplyMode()
|
||||
{
|
||||
auto& interpreter = Core::System::GetInstance().GetInterpreter();
|
||||
|
||||
switch (s_mode)
|
||||
{
|
||||
case CoreMode::Interpreter: // Switching from JIT to interpreter
|
||||
s_cpu_core_base = s_interpreter;
|
||||
s_cpu_core_base = &interpreter;
|
||||
break;
|
||||
|
||||
case CoreMode::JIT: // Switching from interpreter to JIT.
|
||||
// Don't really need to do much. It'll work, the cache will refill itself.
|
||||
s_cpu_core_base = JitInterface::GetCore();
|
||||
if (!s_cpu_core_base) // Has a chance to not get a working JIT core if one isn't active on host
|
||||
s_cpu_core_base = s_interpreter;
|
||||
s_cpu_core_base = &interpreter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "Core/HW/SI/SI.h"
|
||||
#include "Core/HW/Sram.h"
|
||||
#include "Core/HW/VideoInterface.h"
|
||||
#include "Core/PowerPC/Interpreter/Interpreter.h"
|
||||
#include "Core/PowerPC/PowerPC.h"
|
||||
#include "IOS/USB/Emulated/Skylander.h"
|
||||
#include "VideoCommon/CommandProcessor.h"
|
||||
|
@ -39,7 +40,7 @@ struct System::Impl
|
|||
: m_audio_interface(system), m_core_timing(system), m_dsp(system), m_dvd_interface(system),
|
||||
m_dvd_thread(system), m_expansion_interface(system), m_gp_fifo(system), m_memory(system),
|
||||
m_ppc_state(PowerPC::ppcState), m_processor_interface(system), m_serial_interface(system),
|
||||
m_video_interface(system)
|
||||
m_video_interface(system), m_interpreter(system, m_ppc_state)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -70,6 +71,7 @@ struct System::Impl
|
|||
Sram m_sram;
|
||||
VertexShaderManager m_vertex_shader_manager;
|
||||
VideoInterface::VideoInterfaceManager m_video_interface;
|
||||
Interpreter m_interpreter;
|
||||
};
|
||||
|
||||
System::System() : m_impl{std::make_unique<Impl>(*this)}
|
||||
|
@ -175,6 +177,11 @@ HSP::HSPManager& System::GetHSP() const
|
|||
return m_impl->m_hsp;
|
||||
}
|
||||
|
||||
Interpreter& System::GetInterpreter() const
|
||||
{
|
||||
return m_impl->m_interpreter;
|
||||
}
|
||||
|
||||
IOS::HLE::USB::SkylanderPortal& System::GetSkylanderPortal() const
|
||||
{
|
||||
return m_impl->m_skylander_portal;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <memory>
|
||||
|
||||
class GeometryShaderManager;
|
||||
class Interpreter;
|
||||
class PixelShaderManager;
|
||||
class SoundStream;
|
||||
struct Sram;
|
||||
|
@ -131,6 +132,7 @@ public:
|
|||
GeometryShaderManager& GetGeometryShaderManager() const;
|
||||
GPFifo::GPFifoManager& GetGPFifo() const;
|
||||
HSP::HSPManager& GetHSP() const;
|
||||
Interpreter& GetInterpreter() const;
|
||||
IOS::HLE::USB::SkylanderPortal& GetSkylanderPortal() const;
|
||||
Memory::MemoryManager& GetMemory() const;
|
||||
MemoryInterface::MemoryInterfaceManager& GetMemoryInterface() const;
|
||||
|
|
Loading…
Reference in New Issue