From 919182eda262a9c827dcb99fab4827116999353c Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Thu, 16 Mar 2023 22:43:27 +0100 Subject: [PATCH 01/10] Interpreter: Pass Interpreter to CPU instruction functions. --- .../CachedInterpreter/CachedInterpreter.cpp | 12 + .../Core/PowerPC/Interpreter/Interpreter.cpp | 8 +- .../Core/PowerPC/Interpreter/Interpreter.h | 464 +++++++++--------- .../Interpreter/Interpreter_Branch.cpp | 14 +- .../Interpreter/Interpreter_FloatingPoint.cpp | 56 +-- .../Interpreter/Interpreter_Integer.cpp | 106 ++-- .../Interpreter/Interpreter_LoadStore.cpp | 144 +++--- .../Interpreter_LoadStorePaired.cpp | 16 +- .../Interpreter/Interpreter_Paired.cpp | 58 +-- .../Interpreter_SystemRegisters.cpp | 58 +-- .../Interpreter/Interpreter_Tables.cpp | 24 +- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 2 +- Source/Core/Core/PowerPC/JitArm64/Jit.cpp | 3 +- 13 files changed, 489 insertions(+), 476 deletions(-) diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index d85f8ece18..7b89fbf5a6 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -19,6 +19,7 @@ struct CachedInterpreter::Instruction { using CommonCallback = void (*)(UGeckoInstruction); using ConditionalCallback = bool (*)(u32); + using InterpreterCallback = void (*)(Interpreter&, UGeckoInstruction); Instruction() {} Instruction(const CommonCallback c, UGeckoInstruction i) @@ -31,17 +32,24 @@ struct CachedInterpreter::Instruction { } + Instruction(const InterpreterCallback c, UGeckoInstruction i) + : interpreter_callback(c), data(i.hex), type(Type::Interpreter) + { + } + enum class Type { Abort, Common, Conditional, + Interpreter, }; union { const CommonCallback common_callback = nullptr; const ConditionalCallback conditional_callback; + const InterpreterCallback interpreter_callback; }; u32 data = 0; @@ -100,6 +108,10 @@ void CachedInterpreter::ExecuteOneBlock() return; break; + case Instruction::Type::Interpreter: + code->interpreter_callback(*Interpreter::getInstance(), UGeckoInstruction(code->data)); + break; + default: ERROR_LOG_FMT(POWERPC, "Unknown CachedInterpreter Instruction: {}", static_cast(code->type)); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index 319f29c186..977c6cefad 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -110,7 +110,7 @@ static void Trace(const UGeckoInstruction& inst) bool Interpreter::HandleFunctionHooking(u32 address) { return HLE::ReplaceFunctionIfPossible(address, [](u32 hook_index, HLE::HookType type) { - HLEFunction(hook_index); + HLEFunction(*Interpreter::getInstance(), hook_index); return type != HLE::HookType::Start; }); } @@ -156,7 +156,7 @@ int Interpreter::SingleStepInner() } else if (PowerPC::ppcState.msr.FP) { - RunInterpreterOp(m_prev_inst); + RunInterpreterOp(*Interpreter::getInstance(), m_prev_inst); if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) { CheckExceptions(); @@ -172,7 +172,7 @@ int Interpreter::SingleStepInner() } else { - RunInterpreterOp(m_prev_inst); + RunInterpreterOp(*Interpreter::getInstance(), m_prev_inst); if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) { CheckExceptions(); @@ -313,7 +313,7 @@ void Interpreter::Run() } } -void Interpreter::unknown_instruction(UGeckoInstruction inst) +void Interpreter::unknown_instruction(Interpreter& interpreter, UGeckoInstruction inst) { ASSERT(Core::IsCPUThread()); auto& system = Core::System::GetInstance(); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h index 0dd01fa3c7..ae2e87bff4 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h @@ -21,259 +21,259 @@ public: void ClearCache() override; const char* GetName() const override; - static void unknown_instruction(UGeckoInstruction inst); + static void unknown_instruction(Interpreter& interpreter, UGeckoInstruction inst); // Branch Instructions - static void bx(UGeckoInstruction inst); - static void bcx(UGeckoInstruction inst); - static void bcctrx(UGeckoInstruction inst); - static void bclrx(UGeckoInstruction inst); - static void HLEFunction(UGeckoInstruction inst); + static void bx(Interpreter& interpreter, UGeckoInstruction inst); + static void bcx(Interpreter& interpreter, UGeckoInstruction inst); + static void bcctrx(Interpreter& interpreter, UGeckoInstruction inst); + static void bclrx(Interpreter& interpreter, UGeckoInstruction inst); + static void HLEFunction(Interpreter& interpreter, UGeckoInstruction inst); // Syscall Instruction - static void sc(UGeckoInstruction inst); + static void sc(Interpreter& interpreter, UGeckoInstruction inst); // Floating Point Instructions - static void faddsx(UGeckoInstruction inst); - static void fdivsx(UGeckoInstruction inst); - static void fmaddsx(UGeckoInstruction inst); - static void fmsubsx(UGeckoInstruction inst); - static void fmulsx(UGeckoInstruction inst); - static void fnmaddsx(UGeckoInstruction inst); - static void fnmsubsx(UGeckoInstruction inst); - static void fresx(UGeckoInstruction inst); - static void fsubsx(UGeckoInstruction inst); - static void fabsx(UGeckoInstruction inst); - static void fcmpo(UGeckoInstruction inst); - static void fcmpu(UGeckoInstruction inst); - static void fctiwx(UGeckoInstruction inst); - static void fctiwzx(UGeckoInstruction inst); - static void fmrx(UGeckoInstruction inst); - static void fnabsx(UGeckoInstruction inst); - static void fnegx(UGeckoInstruction inst); - static void frspx(UGeckoInstruction inst); - static void faddx(UGeckoInstruction inst); - static void fdivx(UGeckoInstruction inst); - static void fmaddx(UGeckoInstruction inst); - static void fmsubx(UGeckoInstruction inst); - static void fmulx(UGeckoInstruction inst); - static void fnmaddx(UGeckoInstruction inst); - static void fnmsubx(UGeckoInstruction inst); - static void frsqrtex(UGeckoInstruction inst); - static void fselx(UGeckoInstruction inst); - static void fsubx(UGeckoInstruction inst); + static void faddsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fdivsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fmaddsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fmsubsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fmulsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fnmaddsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fnmsubsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fresx(Interpreter& interpreter, UGeckoInstruction inst); + static void fsubsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fabsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fcmpo(Interpreter& interpreter, UGeckoInstruction inst); + static void fcmpu(Interpreter& interpreter, UGeckoInstruction inst); + static void fctiwx(Interpreter& interpreter, UGeckoInstruction inst); + static void fctiwzx(Interpreter& interpreter, UGeckoInstruction inst); + static void fmrx(Interpreter& interpreter, UGeckoInstruction inst); + static void fnabsx(Interpreter& interpreter, UGeckoInstruction inst); + static void fnegx(Interpreter& interpreter, UGeckoInstruction inst); + static void frspx(Interpreter& interpreter, UGeckoInstruction inst); + static void faddx(Interpreter& interpreter, UGeckoInstruction inst); + static void fdivx(Interpreter& interpreter, UGeckoInstruction inst); + static void fmaddx(Interpreter& interpreter, UGeckoInstruction inst); + static void fmsubx(Interpreter& interpreter, UGeckoInstruction inst); + static void fmulx(Interpreter& interpreter, UGeckoInstruction inst); + static void fnmaddx(Interpreter& interpreter, UGeckoInstruction inst); + static void fnmsubx(Interpreter& interpreter, UGeckoInstruction inst); + static void frsqrtex(Interpreter& interpreter, UGeckoInstruction inst); + static void fselx(Interpreter& interpreter, UGeckoInstruction inst); + static void fsubx(Interpreter& interpreter, UGeckoInstruction inst); // Integer Instructions - static void addi(UGeckoInstruction inst); - static void addic(UGeckoInstruction inst); - static void addic_rc(UGeckoInstruction inst); - static void addis(UGeckoInstruction inst); - static void andi_rc(UGeckoInstruction inst); - static void andis_rc(UGeckoInstruction inst); - static void cmpi(UGeckoInstruction inst); - static void cmpli(UGeckoInstruction inst); - static void mulli(UGeckoInstruction inst); - static void ori(UGeckoInstruction inst); - static void oris(UGeckoInstruction inst); - static void subfic(UGeckoInstruction inst); - static void twi(UGeckoInstruction inst); - static void xori(UGeckoInstruction inst); - static void xoris(UGeckoInstruction inst); - static void rlwimix(UGeckoInstruction inst); - static void rlwinmx(UGeckoInstruction inst); - static void rlwnmx(UGeckoInstruction inst); - static void andx(UGeckoInstruction inst); - static void andcx(UGeckoInstruction inst); - static void cmp(UGeckoInstruction inst); - static void cmpl(UGeckoInstruction inst); - static void cntlzwx(UGeckoInstruction inst); - static void eqvx(UGeckoInstruction inst); - static void extsbx(UGeckoInstruction inst); - static void extshx(UGeckoInstruction inst); - static void nandx(UGeckoInstruction inst); - static void norx(UGeckoInstruction inst); - static void orx(UGeckoInstruction inst); - static void orcx(UGeckoInstruction inst); - static void slwx(UGeckoInstruction inst); - static void srawx(UGeckoInstruction inst); - static void srawix(UGeckoInstruction inst); - static void srwx(UGeckoInstruction inst); - static void tw(UGeckoInstruction inst); - static void xorx(UGeckoInstruction inst); - static void addx(UGeckoInstruction inst); - static void addcx(UGeckoInstruction inst); - static void addex(UGeckoInstruction inst); - static void addmex(UGeckoInstruction inst); - static void addzex(UGeckoInstruction inst); - static void divwx(UGeckoInstruction inst); - static void divwux(UGeckoInstruction inst); - static void mulhwx(UGeckoInstruction inst); - static void mulhwux(UGeckoInstruction inst); - static void mullwx(UGeckoInstruction inst); - static void negx(UGeckoInstruction inst); - static void subfx(UGeckoInstruction inst); - static void subfcx(UGeckoInstruction inst); - static void subfex(UGeckoInstruction inst); - static void subfmex(UGeckoInstruction inst); - static void subfzex(UGeckoInstruction inst); + static void addi(Interpreter& interpreter, UGeckoInstruction inst); + static void addic(Interpreter& interpreter, UGeckoInstruction inst); + static void addic_rc(Interpreter& interpreter, UGeckoInstruction inst); + static void addis(Interpreter& interpreter, UGeckoInstruction inst); + static void andi_rc(Interpreter& interpreter, UGeckoInstruction inst); + static void andis_rc(Interpreter& interpreter, UGeckoInstruction inst); + static void cmpi(Interpreter& interpreter, UGeckoInstruction inst); + static void cmpli(Interpreter& interpreter, UGeckoInstruction inst); + static void mulli(Interpreter& interpreter, UGeckoInstruction inst); + static void ori(Interpreter& interpreter, UGeckoInstruction inst); + static void oris(Interpreter& interpreter, UGeckoInstruction inst); + static void subfic(Interpreter& interpreter, UGeckoInstruction inst); + static void twi(Interpreter& interpreter, UGeckoInstruction inst); + static void xori(Interpreter& interpreter, UGeckoInstruction inst); + static void xoris(Interpreter& interpreter, UGeckoInstruction inst); + static void rlwimix(Interpreter& interpreter, UGeckoInstruction inst); + static void rlwinmx(Interpreter& interpreter, UGeckoInstruction inst); + static void rlwnmx(Interpreter& interpreter, UGeckoInstruction inst); + static void andx(Interpreter& interpreter, UGeckoInstruction inst); + static void andcx(Interpreter& interpreter, UGeckoInstruction inst); + static void cmp(Interpreter& interpreter, UGeckoInstruction inst); + static void cmpl(Interpreter& interpreter, UGeckoInstruction inst); + static void cntlzwx(Interpreter& interpreter, UGeckoInstruction inst); + static void eqvx(Interpreter& interpreter, UGeckoInstruction inst); + static void extsbx(Interpreter& interpreter, UGeckoInstruction inst); + static void extshx(Interpreter& interpreter, UGeckoInstruction inst); + static void nandx(Interpreter& interpreter, UGeckoInstruction inst); + static void norx(Interpreter& interpreter, UGeckoInstruction inst); + static void orx(Interpreter& interpreter, UGeckoInstruction inst); + static void orcx(Interpreter& interpreter, UGeckoInstruction inst); + static void slwx(Interpreter& interpreter, UGeckoInstruction inst); + static void srawx(Interpreter& interpreter, UGeckoInstruction inst); + static void srawix(Interpreter& interpreter, UGeckoInstruction inst); + static void srwx(Interpreter& interpreter, UGeckoInstruction inst); + static void tw(Interpreter& interpreter, UGeckoInstruction inst); + static void xorx(Interpreter& interpreter, UGeckoInstruction inst); + static void addx(Interpreter& interpreter, UGeckoInstruction inst); + static void addcx(Interpreter& interpreter, UGeckoInstruction inst); + static void addex(Interpreter& interpreter, UGeckoInstruction inst); + static void addmex(Interpreter& interpreter, UGeckoInstruction inst); + static void addzex(Interpreter& interpreter, UGeckoInstruction inst); + static void divwx(Interpreter& interpreter, UGeckoInstruction inst); + static void divwux(Interpreter& interpreter, UGeckoInstruction inst); + static void mulhwx(Interpreter& interpreter, UGeckoInstruction inst); + static void mulhwux(Interpreter& interpreter, UGeckoInstruction inst); + static void mullwx(Interpreter& interpreter, UGeckoInstruction inst); + static void negx(Interpreter& interpreter, UGeckoInstruction inst); + static void subfx(Interpreter& interpreter, UGeckoInstruction inst); + static void subfcx(Interpreter& interpreter, UGeckoInstruction inst); + static void subfex(Interpreter& interpreter, UGeckoInstruction inst); + static void subfmex(Interpreter& interpreter, UGeckoInstruction inst); + static void subfzex(Interpreter& interpreter, UGeckoInstruction inst); // Load/Store Instructions - static void lbz(UGeckoInstruction inst); - static void lbzu(UGeckoInstruction inst); - static void lfd(UGeckoInstruction inst); - static void lfdu(UGeckoInstruction inst); - static void lfs(UGeckoInstruction inst); - static void lfsu(UGeckoInstruction inst); - static void lha(UGeckoInstruction inst); - static void lhau(UGeckoInstruction inst); - static void lhz(UGeckoInstruction inst); - static void lhzu(UGeckoInstruction inst); - static void lmw(UGeckoInstruction inst); - static void lwz(UGeckoInstruction inst); - static void lwzu(UGeckoInstruction inst); - static void stb(UGeckoInstruction inst); - static void stbu(UGeckoInstruction inst); - static void stfd(UGeckoInstruction inst); - static void stfdu(UGeckoInstruction inst); - static void stfs(UGeckoInstruction inst); - static void stfsu(UGeckoInstruction inst); - static void sth(UGeckoInstruction inst); - static void sthu(UGeckoInstruction inst); - static void stmw(UGeckoInstruction inst); - static void stw(UGeckoInstruction inst); - static void stwu(UGeckoInstruction inst); - static void dcba(UGeckoInstruction inst); - static void dcbf(UGeckoInstruction inst); - static void dcbi(UGeckoInstruction inst); - static void dcbst(UGeckoInstruction inst); - static void dcbt(UGeckoInstruction inst); - static void dcbtst(UGeckoInstruction inst); - static void dcbz(UGeckoInstruction inst); - static void eciwx(UGeckoInstruction inst); - static void ecowx(UGeckoInstruction inst); - static void eieio(UGeckoInstruction inst); - static void icbi(UGeckoInstruction inst); - static void lbzux(UGeckoInstruction inst); - static void lbzx(UGeckoInstruction inst); - static void lfdux(UGeckoInstruction inst); - static void lfdx(UGeckoInstruction inst); - static void lfsux(UGeckoInstruction inst); - static void lfsx(UGeckoInstruction inst); - static void lhaux(UGeckoInstruction inst); - static void lhax(UGeckoInstruction inst); - static void lhbrx(UGeckoInstruction inst); - static void lhzux(UGeckoInstruction inst); - static void lhzx(UGeckoInstruction inst); - static void lswi(UGeckoInstruction inst); - static void lswx(UGeckoInstruction inst); - static void lwarx(UGeckoInstruction inst); - static void lwbrx(UGeckoInstruction inst); - static void lwzux(UGeckoInstruction inst); - static void lwzx(UGeckoInstruction inst); - static void stbux(UGeckoInstruction inst); - static void stbx(UGeckoInstruction inst); - static void stfdux(UGeckoInstruction inst); - static void stfdx(UGeckoInstruction inst); - static void stfiwx(UGeckoInstruction inst); - static void stfsux(UGeckoInstruction inst); - static void stfsx(UGeckoInstruction inst); - static void sthbrx(UGeckoInstruction inst); - static void sthux(UGeckoInstruction inst); - static void sthx(UGeckoInstruction inst); - static void stswi(UGeckoInstruction inst); - static void stswx(UGeckoInstruction inst); - static void stwbrx(UGeckoInstruction inst); - static void stwcxd(UGeckoInstruction inst); - static void stwux(UGeckoInstruction inst); - static void stwx(UGeckoInstruction inst); - static void tlbie(UGeckoInstruction inst); - static void tlbsync(UGeckoInstruction inst); + static void lbz(Interpreter& interpreter, UGeckoInstruction inst); + static void lbzu(Interpreter& interpreter, UGeckoInstruction inst); + static void lfd(Interpreter& interpreter, UGeckoInstruction inst); + static void lfdu(Interpreter& interpreter, UGeckoInstruction inst); + static void lfs(Interpreter& interpreter, UGeckoInstruction inst); + static void lfsu(Interpreter& interpreter, UGeckoInstruction inst); + static void lha(Interpreter& interpreter, UGeckoInstruction inst); + static void lhau(Interpreter& interpreter, UGeckoInstruction inst); + static void lhz(Interpreter& interpreter, UGeckoInstruction inst); + static void lhzu(Interpreter& interpreter, UGeckoInstruction inst); + static void lmw(Interpreter& interpreter, UGeckoInstruction inst); + static void lwz(Interpreter& interpreter, UGeckoInstruction inst); + static void lwzu(Interpreter& interpreter, UGeckoInstruction inst); + static void stb(Interpreter& interpreter, UGeckoInstruction inst); + static void stbu(Interpreter& interpreter, UGeckoInstruction inst); + static void stfd(Interpreter& interpreter, UGeckoInstruction inst); + static void stfdu(Interpreter& interpreter, UGeckoInstruction inst); + static void stfs(Interpreter& interpreter, UGeckoInstruction inst); + static void stfsu(Interpreter& interpreter, UGeckoInstruction inst); + static void sth(Interpreter& interpreter, UGeckoInstruction inst); + static void sthu(Interpreter& interpreter, UGeckoInstruction inst); + static void stmw(Interpreter& interpreter, UGeckoInstruction inst); + static void stw(Interpreter& interpreter, UGeckoInstruction inst); + static void stwu(Interpreter& interpreter, UGeckoInstruction inst); + static void dcba(Interpreter& interpreter, UGeckoInstruction inst); + static void dcbf(Interpreter& interpreter, UGeckoInstruction inst); + static void dcbi(Interpreter& interpreter, UGeckoInstruction inst); + static void dcbst(Interpreter& interpreter, UGeckoInstruction inst); + static void dcbt(Interpreter& interpreter, UGeckoInstruction inst); + static void dcbtst(Interpreter& interpreter, UGeckoInstruction inst); + static void dcbz(Interpreter& interpreter, UGeckoInstruction inst); + static void eciwx(Interpreter& interpreter, UGeckoInstruction inst); + static void ecowx(Interpreter& interpreter, UGeckoInstruction inst); + static void eieio(Interpreter& interpreter, UGeckoInstruction inst); + static void icbi(Interpreter& interpreter, UGeckoInstruction inst); + static void lbzux(Interpreter& interpreter, UGeckoInstruction inst); + static void lbzx(Interpreter& interpreter, UGeckoInstruction inst); + static void lfdux(Interpreter& interpreter, UGeckoInstruction inst); + static void lfdx(Interpreter& interpreter, UGeckoInstruction inst); + static void lfsux(Interpreter& interpreter, UGeckoInstruction inst); + static void lfsx(Interpreter& interpreter, UGeckoInstruction inst); + static void lhaux(Interpreter& interpreter, UGeckoInstruction inst); + static void lhax(Interpreter& interpreter, UGeckoInstruction inst); + static void lhbrx(Interpreter& interpreter, UGeckoInstruction inst); + static void lhzux(Interpreter& interpreter, UGeckoInstruction inst); + static void lhzx(Interpreter& interpreter, UGeckoInstruction inst); + static void lswi(Interpreter& interpreter, UGeckoInstruction inst); + static void lswx(Interpreter& interpreter, UGeckoInstruction inst); + static void lwarx(Interpreter& interpreter, UGeckoInstruction inst); + static void lwbrx(Interpreter& interpreter, UGeckoInstruction inst); + static void lwzux(Interpreter& interpreter, UGeckoInstruction inst); + static void lwzx(Interpreter& interpreter, UGeckoInstruction inst); + static void stbux(Interpreter& interpreter, UGeckoInstruction inst); + static void stbx(Interpreter& interpreter, UGeckoInstruction inst); + static void stfdux(Interpreter& interpreter, UGeckoInstruction inst); + static void stfdx(Interpreter& interpreter, UGeckoInstruction inst); + static void stfiwx(Interpreter& interpreter, UGeckoInstruction inst); + static void stfsux(Interpreter& interpreter, UGeckoInstruction inst); + static void stfsx(Interpreter& interpreter, UGeckoInstruction inst); + static void sthbrx(Interpreter& interpreter, UGeckoInstruction inst); + static void sthux(Interpreter& interpreter, UGeckoInstruction inst); + static void sthx(Interpreter& interpreter, UGeckoInstruction inst); + static void stswi(Interpreter& interpreter, UGeckoInstruction inst); + static void stswx(Interpreter& interpreter, UGeckoInstruction inst); + static void stwbrx(Interpreter& interpreter, UGeckoInstruction inst); + static void stwcxd(Interpreter& interpreter, UGeckoInstruction inst); + static void stwux(Interpreter& interpreter, UGeckoInstruction inst); + static void stwx(Interpreter& interpreter, UGeckoInstruction inst); + static void tlbie(Interpreter& interpreter, UGeckoInstruction inst); + static void tlbsync(Interpreter& interpreter, UGeckoInstruction inst); // Paired Instructions - static void psq_l(UGeckoInstruction inst); - static void psq_lu(UGeckoInstruction inst); - static void psq_st(UGeckoInstruction inst); - static void psq_stu(UGeckoInstruction inst); - static void psq_lx(UGeckoInstruction inst); - static void psq_stx(UGeckoInstruction inst); - static void psq_lux(UGeckoInstruction inst); - static void psq_stux(UGeckoInstruction inst); - static void ps_div(UGeckoInstruction inst); - static void ps_sub(UGeckoInstruction inst); - static void ps_add(UGeckoInstruction inst); - static void ps_sel(UGeckoInstruction inst); - static void ps_res(UGeckoInstruction inst); - static void ps_mul(UGeckoInstruction inst); - static void ps_rsqrte(UGeckoInstruction inst); - static void ps_msub(UGeckoInstruction inst); - static void ps_madd(UGeckoInstruction inst); - static void ps_nmsub(UGeckoInstruction inst); - static void ps_nmadd(UGeckoInstruction inst); - static void ps_neg(UGeckoInstruction inst); - static void ps_mr(UGeckoInstruction inst); - static void ps_nabs(UGeckoInstruction inst); - static void ps_abs(UGeckoInstruction inst); - static void ps_sum0(UGeckoInstruction inst); - static void ps_sum1(UGeckoInstruction inst); - static void ps_muls0(UGeckoInstruction inst); - static void ps_muls1(UGeckoInstruction inst); - static void ps_madds0(UGeckoInstruction inst); - static void ps_madds1(UGeckoInstruction inst); - static void ps_cmpu0(UGeckoInstruction inst); - static void ps_cmpo0(UGeckoInstruction inst); - static void ps_cmpu1(UGeckoInstruction inst); - static void ps_cmpo1(UGeckoInstruction inst); - static void ps_merge00(UGeckoInstruction inst); - static void ps_merge01(UGeckoInstruction inst); - static void ps_merge10(UGeckoInstruction inst); - static void ps_merge11(UGeckoInstruction inst); - static void dcbz_l(UGeckoInstruction inst); + static void psq_l(Interpreter& interpreter, UGeckoInstruction inst); + static void psq_lu(Interpreter& interpreter, UGeckoInstruction inst); + static void psq_st(Interpreter& interpreter, UGeckoInstruction inst); + static void psq_stu(Interpreter& interpreter, UGeckoInstruction inst); + static void psq_lx(Interpreter& interpreter, UGeckoInstruction inst); + static void psq_stx(Interpreter& interpreter, UGeckoInstruction inst); + static void psq_lux(Interpreter& interpreter, UGeckoInstruction inst); + static void psq_stux(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_div(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_sub(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_add(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_sel(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_res(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_mul(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_rsqrte(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_msub(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_madd(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_nmsub(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_nmadd(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_neg(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_mr(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_nabs(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_abs(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_sum0(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_sum1(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_muls0(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_muls1(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_madds0(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_madds1(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_cmpu0(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_cmpo0(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_cmpu1(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_cmpo1(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_merge00(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_merge01(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_merge10(Interpreter& interpreter, UGeckoInstruction inst); + static void ps_merge11(Interpreter& interpreter, UGeckoInstruction inst); + static void dcbz_l(Interpreter& interpreter, UGeckoInstruction inst); // System Registers Instructions - static void mcrfs(UGeckoInstruction inst); - static void mffsx(UGeckoInstruction inst); - static void mtfsb0x(UGeckoInstruction inst); - static void mtfsb1x(UGeckoInstruction inst); - static void mtfsfix(UGeckoInstruction inst); - static void mtfsfx(UGeckoInstruction inst); - static void mcrxr(UGeckoInstruction inst); - static void mfcr(UGeckoInstruction inst); - static void mfmsr(UGeckoInstruction inst); - static void mfsr(UGeckoInstruction inst); - static void mfsrin(UGeckoInstruction inst); - static void mtmsr(UGeckoInstruction inst); - static void mtsr(UGeckoInstruction inst); - static void mtsrin(UGeckoInstruction inst); - static void mfspr(UGeckoInstruction inst); - static void mftb(UGeckoInstruction inst); - static void mtcrf(UGeckoInstruction inst); - static void mtspr(UGeckoInstruction inst); - static void crand(UGeckoInstruction inst); - static void crandc(UGeckoInstruction inst); - static void creqv(UGeckoInstruction inst); - static void crnand(UGeckoInstruction inst); - static void crnor(UGeckoInstruction inst); - static void cror(UGeckoInstruction inst); - static void crorc(UGeckoInstruction inst); - static void crxor(UGeckoInstruction inst); - static void mcrf(UGeckoInstruction inst); - static void rfi(UGeckoInstruction inst); - static void sync(UGeckoInstruction inst); - static void isync(UGeckoInstruction inst); + static void mcrfs(Interpreter& interpreter, UGeckoInstruction inst); + static void mffsx(Interpreter& interpreter, UGeckoInstruction inst); + static void mtfsb0x(Interpreter& interpreter, UGeckoInstruction inst); + static void mtfsb1x(Interpreter& interpreter, UGeckoInstruction inst); + static void mtfsfix(Interpreter& interpreter, UGeckoInstruction inst); + static void mtfsfx(Interpreter& interpreter, UGeckoInstruction inst); + static void mcrxr(Interpreter& interpreter, UGeckoInstruction inst); + static void mfcr(Interpreter& interpreter, UGeckoInstruction inst); + static void mfmsr(Interpreter& interpreter, UGeckoInstruction inst); + static void mfsr(Interpreter& interpreter, UGeckoInstruction inst); + static void mfsrin(Interpreter& interpreter, UGeckoInstruction inst); + static void mtmsr(Interpreter& interpreter, UGeckoInstruction inst); + static void mtsr(Interpreter& interpreter, UGeckoInstruction inst); + static void mtsrin(Interpreter& interpreter, UGeckoInstruction inst); + static void mfspr(Interpreter& interpreter, UGeckoInstruction inst); + static void mftb(Interpreter& interpreter, UGeckoInstruction inst); + static void mtcrf(Interpreter& interpreter, UGeckoInstruction inst); + static void mtspr(Interpreter& interpreter, UGeckoInstruction inst); + static void crand(Interpreter& interpreter, UGeckoInstruction inst); + static void crandc(Interpreter& interpreter, UGeckoInstruction inst); + static void creqv(Interpreter& interpreter, UGeckoInstruction inst); + static void crnand(Interpreter& interpreter, UGeckoInstruction inst); + static void crnor(Interpreter& interpreter, UGeckoInstruction inst); + static void cror(Interpreter& interpreter, UGeckoInstruction inst); + static void crorc(Interpreter& interpreter, UGeckoInstruction inst); + static void crxor(Interpreter& interpreter, UGeckoInstruction inst); + static void mcrf(Interpreter& interpreter, UGeckoInstruction inst); + static void rfi(Interpreter& interpreter, UGeckoInstruction inst); + static void sync(Interpreter& interpreter, UGeckoInstruction inst); + static void isync(Interpreter& interpreter, UGeckoInstruction inst); - using Instruction = void (*)(UGeckoInstruction inst); + using Instruction = void (*)(Interpreter& interpreter, UGeckoInstruction inst); static Instruction GetInterpreterOp(UGeckoInstruction inst); - static void RunInterpreterOp(UGeckoInstruction inst); + static void RunInterpreterOp(Interpreter& interpreter, UGeckoInstruction inst); // singleton static Interpreter* getInstance(); - static void RunTable4(UGeckoInstruction inst); - static void RunTable19(UGeckoInstruction inst); - static void RunTable31(UGeckoInstruction inst); - static void RunTable59(UGeckoInstruction inst); - static void RunTable63(UGeckoInstruction inst); + static void RunTable4(Interpreter& interpreter, UGeckoInstruction inst); + static void RunTable19(Interpreter& interpreter, UGeckoInstruction inst); + static void RunTable31(Interpreter& interpreter, UGeckoInstruction inst); + static void RunTable59(Interpreter& interpreter, UGeckoInstruction inst); + static void RunTable63(Interpreter& interpreter, UGeckoInstruction inst); static u32 Helper_Carry(u32 value1, u32 value2); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index 39c1165a5c..e2fba4a931 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -12,7 +12,7 @@ #include "Core/PowerPC/PowerPC.h" #include "Core/System.h" -void Interpreter::bx(UGeckoInstruction inst) +void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst) { if (inst.LK) LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4; @@ -28,7 +28,7 @@ void Interpreter::bx(UGeckoInstruction inst) } // bcx - ugly, straight from PPC manual equations :) -void Interpreter::bcx(UGeckoInstruction inst) +void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst) { if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) CTR(PowerPC::ppcState)--; @@ -57,7 +57,7 @@ void Interpreter::bcx(UGeckoInstruction inst) m_end_block = true; } -void Interpreter::bcctrx(UGeckoInstruction inst) +void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst) { DEBUG_ASSERT_MSG(POWERPC, (inst.BO_2 & BO_DONT_DECREMENT_FLAG) != 0, "bcctrx with decrement and test CTR option is invalid!"); @@ -75,7 +75,7 @@ void Interpreter::bcctrx(UGeckoInstruction inst) m_end_block = true; } -void Interpreter::bclrx(UGeckoInstruction inst) +void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst) { if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0) CTR(PowerPC::ppcState)--; @@ -94,7 +94,7 @@ void Interpreter::bclrx(UGeckoInstruction inst) m_end_block = true; } -void Interpreter::HLEFunction(UGeckoInstruction inst) +void Interpreter::HLEFunction(Interpreter& interpreter, UGeckoInstruction inst) { m_end_block = true; @@ -104,7 +104,7 @@ void Interpreter::HLEFunction(UGeckoInstruction inst) HLE::Execute(guard, PowerPC::ppcState.pc, inst.hex); } -void Interpreter::rfi(UGeckoInstruction inst) +void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -132,7 +132,7 @@ void Interpreter::rfi(UGeckoInstruction inst) // sc isn't really used for anything important in GameCube games (just for a write barrier) so we // really don't have to emulate it. // We do it anyway, though :P -void Interpreter::sc(UGeckoInstruction inst) +void Interpreter::sc(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL; PowerPC::CheckExceptions(); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index 9f5c78e76b..b3301af738 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -209,7 +209,7 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa PowerPC::ppcState.cr.SetField(inst.CRFD, compare_value); } -void Interpreter::fcmpo(UGeckoInstruction inst) +void Interpreter::fcmpo(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -217,7 +217,7 @@ void Interpreter::fcmpo(UGeckoInstruction inst) Helper_FloatCompareOrdered(inst, a.PS0AsDouble(), b.PS0AsDouble()); } -void Interpreter::fcmpu(UGeckoInstruction inst) +void Interpreter::fcmpu(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -225,17 +225,17 @@ void Interpreter::fcmpu(UGeckoInstruction inst) Helper_FloatCompareUnordered(inst, a.PS0AsDouble(), b.PS0AsDouble()); } -void Interpreter::fctiwx(UGeckoInstruction inst) +void Interpreter::fctiwx(Interpreter& interpreter, UGeckoInstruction inst) { ConvertToInteger(inst, static_cast(PowerPC::ppcState.fpscr.RN.Value())); } -void Interpreter::fctiwzx(UGeckoInstruction inst) +void Interpreter::fctiwzx(Interpreter& interpreter, UGeckoInstruction inst) { ConvertToInteger(inst, RoundingMode::TowardsZero); } -void Interpreter::fmrx(UGeckoInstruction inst) +void Interpreter::fmrx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.ps[inst.FD].SetPS0(PowerPC::ppcState.ps[inst.FB].PS0AsU64()); @@ -244,7 +244,7 @@ void Interpreter::fmrx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fabsx(UGeckoInstruction inst) +void Interpreter::fabsx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.ps[inst.FD].SetPS0(fabs(PowerPC::ppcState.ps[inst.FB].PS0AsDouble())); @@ -253,7 +253,7 @@ void Interpreter::fabsx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fnabsx(UGeckoInstruction inst) +void Interpreter::fnabsx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.ps[inst.FD].SetPS0(PowerPC::ppcState.ps[inst.FB].PS0AsU64() | (UINT64_C(1) << 63)); @@ -263,7 +263,7 @@ void Interpreter::fnabsx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fnegx(UGeckoInstruction inst) +void Interpreter::fnegx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.ps[inst.FD].SetPS0(PowerPC::ppcState.ps[inst.FB].PS0AsU64() ^ (UINT64_C(1) << 63)); @@ -273,7 +273,7 @@ void Interpreter::fnegx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fselx(UGeckoInstruction inst) +void Interpreter::fselx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -290,7 +290,7 @@ void Interpreter::fselx(UGeckoInstruction inst) // !!! warning !!! // PS1 must be set to the value of PS0 or DragonballZ will be f**ked up // PS1 is said to be undefined -void Interpreter::frspx(UGeckoInstruction inst) // round to single +void Interpreter::frspx(Interpreter& interpreter, UGeckoInstruction inst) // round to single { const double b = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); const float rounded = ForceSingle(PowerPC::ppcState.fpscr, b); @@ -322,7 +322,7 @@ void Interpreter::frspx(UGeckoInstruction inst) // round to single PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fmulx(UGeckoInstruction inst) +void Interpreter::fmulx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& c = PowerPC::ppcState.ps[inst.FC]; @@ -342,7 +342,7 @@ void Interpreter::fmulx(UGeckoInstruction inst) if (inst.Rc) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fmulsx(UGeckoInstruction inst) +void Interpreter::fmulsx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& c = PowerPC::ppcState.ps[inst.FC]; @@ -364,7 +364,7 @@ void Interpreter::fmulsx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fmaddx(UGeckoInstruction inst) +void Interpreter::fmaddx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -383,7 +383,7 @@ void Interpreter::fmaddx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fmaddsx(UGeckoInstruction inst) +void Interpreter::fmaddsx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -407,7 +407,7 @@ void Interpreter::fmaddsx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::faddx(UGeckoInstruction inst) +void Interpreter::faddx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -424,7 +424,7 @@ void Interpreter::faddx(UGeckoInstruction inst) if (inst.Rc) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::faddsx(UGeckoInstruction inst) +void Interpreter::faddsx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -442,7 +442,7 @@ void Interpreter::faddsx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fdivx(UGeckoInstruction inst) +void Interpreter::fdivx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -462,7 +462,7 @@ void Interpreter::fdivx(UGeckoInstruction inst) if (inst.Rc) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fdivsx(UGeckoInstruction inst) +void Interpreter::fdivsx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -483,7 +483,7 @@ void Interpreter::fdivsx(UGeckoInstruction inst) } // Single precision only. -void Interpreter::fresx(UGeckoInstruction inst) +void Interpreter::fresx(Interpreter& interpreter, UGeckoInstruction inst) { const double b = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); @@ -521,7 +521,7 @@ void Interpreter::fresx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::frsqrtex(UGeckoInstruction inst) +void Interpreter::frsqrtex(Interpreter& interpreter, UGeckoInstruction inst) { const double b = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); @@ -567,7 +567,7 @@ void Interpreter::frsqrtex(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fmsubx(UGeckoInstruction inst) +void Interpreter::fmsubx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -587,7 +587,7 @@ void Interpreter::fmsubx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fmsubsx(UGeckoInstruction inst) +void Interpreter::fmsubsx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -608,7 +608,7 @@ void Interpreter::fmsubsx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fnmaddx(UGeckoInstruction inst) +void Interpreter::fnmaddx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -630,7 +630,7 @@ void Interpreter::fnmaddx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fnmaddsx(UGeckoInstruction inst) +void Interpreter::fnmaddsx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -653,7 +653,7 @@ void Interpreter::fnmaddsx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fnmsubx(UGeckoInstruction inst) +void Interpreter::fnmsubx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -675,7 +675,7 @@ void Interpreter::fnmsubx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fnmsubsx(UGeckoInstruction inst) +void Interpreter::fnmsubsx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -698,7 +698,7 @@ void Interpreter::fnmsubsx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fsubx(UGeckoInstruction inst) +void Interpreter::fsubx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -716,7 +716,7 @@ void Interpreter::fsubx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::fsubsx(UGeckoInstruction inst) +void Interpreter::fsubsx(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index 3349d1448a..7f3a4c1827 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -26,7 +26,7 @@ u32 Interpreter::Helper_Carry(u32 value1, u32 value2) return value2 > (~value1); } -void Interpreter::addi(UGeckoInstruction inst) +void Interpreter::addi(Interpreter& interpreter, UGeckoInstruction inst) { if (inst.RA) PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_16); @@ -34,7 +34,7 @@ void Interpreter::addi(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RD] = u32(inst.SIMM_16); } -void Interpreter::addic(UGeckoInstruction inst) +void Interpreter::addic(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.gpr[inst.RA]; const u32 imm = u32(s32{inst.SIMM_16}); @@ -43,13 +43,13 @@ void Interpreter::addic(UGeckoInstruction inst) PowerPC::ppcState.SetCarry(Helper_Carry(a, imm)); } -void Interpreter::addic_rc(UGeckoInstruction inst) +void Interpreter::addic_rc(Interpreter& interpreter, UGeckoInstruction inst) { - addic(inst); + addic(interpreter, inst); Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); } -void Interpreter::addis(UGeckoInstruction inst) +void Interpreter::addis(Interpreter& interpreter, UGeckoInstruction inst) { if (inst.RA) PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_16 << 16); @@ -57,13 +57,13 @@ void Interpreter::addis(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RD] = u32(inst.SIMM_16 << 16); } -void Interpreter::andi_rc(UGeckoInstruction inst) +void Interpreter::andi_rc(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & inst.UIMM; Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::andis_rc(UGeckoInstruction inst) +void Interpreter::andis_rc(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & (u32{inst.UIMM} << 16); Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); @@ -87,36 +87,36 @@ void Interpreter::Helper_IntCompare(UGeckoInstruction inst, T a, T b) PowerPC::ppcState.cr.SetField(inst.CRFD, cr_field); } -void Interpreter::cmpi(UGeckoInstruction inst) +void Interpreter::cmpi(Interpreter& interpreter, UGeckoInstruction inst) { const s32 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); const s32 b = inst.SIMM_16; Helper_IntCompare(inst, a, b); } -void Interpreter::cmpli(UGeckoInstruction inst) +void Interpreter::cmpli(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.gpr[inst.RA]; const u32 b = inst.UIMM; Helper_IntCompare(inst, a, b); } -void Interpreter::mulli(UGeckoInstruction inst) +void Interpreter::mulli(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RD] = u32(s32(PowerPC::ppcState.gpr[inst.RA]) * inst.SIMM_16); } -void Interpreter::ori(UGeckoInstruction inst) +void Interpreter::ori(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | inst.UIMM; } -void Interpreter::oris(UGeckoInstruction inst) +void Interpreter::oris(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | (u32{inst.UIMM} << 16); } -void Interpreter::subfic(UGeckoInstruction inst) +void Interpreter::subfic(Interpreter& interpreter, UGeckoInstruction inst) { const s32 immediate = inst.SIMM_16; PowerPC::ppcState.gpr[inst.RD] = u32(immediate - s32(PowerPC::ppcState.gpr[inst.RA])); @@ -124,7 +124,7 @@ void Interpreter::subfic(UGeckoInstruction inst) (Helper_Carry(0 - PowerPC::ppcState.gpr[inst.RA], u32(immediate)))); } -void Interpreter::twi(UGeckoInstruction inst) +void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst) { const s32 a = s32(PowerPC::ppcState.gpr[inst.RA]); const s32 b = inst.SIMM_16; @@ -141,17 +141,17 @@ void Interpreter::twi(UGeckoInstruction inst) } } -void Interpreter::xori(UGeckoInstruction inst) +void Interpreter::xori(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ inst.UIMM; } -void Interpreter::xoris(UGeckoInstruction inst) +void Interpreter::xoris(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ (u32{inst.UIMM} << 16); } -void Interpreter::rlwimix(UGeckoInstruction inst) +void Interpreter::rlwimix(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); PowerPC::ppcState.gpr[inst.RA] = (PowerPC::ppcState.gpr[inst.RA] & ~mask) | @@ -161,7 +161,7 @@ void Interpreter::rlwimix(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::rlwinmx(UGeckoInstruction inst) +void Interpreter::rlwinmx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); PowerPC::ppcState.gpr[inst.RA] = std::rotl(PowerPC::ppcState.gpr[inst.RS], inst.SH) & mask; @@ -170,7 +170,7 @@ void Interpreter::rlwinmx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::rlwnmx(UGeckoInstruction inst) +void Interpreter::rlwnmx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); PowerPC::ppcState.gpr[inst.RA] = @@ -180,7 +180,7 @@ void Interpreter::rlwnmx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::andx(UGeckoInstruction inst) +void Interpreter::andx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & PowerPC::ppcState.gpr[inst.RB]; @@ -188,7 +188,7 @@ void Interpreter::andx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::andcx(UGeckoInstruction inst) +void Interpreter::andcx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & ~PowerPC::ppcState.gpr[inst.RB]; @@ -196,21 +196,21 @@ void Interpreter::andcx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::cmp(UGeckoInstruction inst) +void Interpreter::cmp(Interpreter& interpreter, UGeckoInstruction inst) { const s32 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); const s32 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); Helper_IntCompare(inst, a, b); } -void Interpreter::cmpl(UGeckoInstruction inst) +void Interpreter::cmpl(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.gpr[inst.RA]; const u32 b = PowerPC::ppcState.gpr[inst.RB]; Helper_IntCompare(inst, a, b); } -void Interpreter::cntlzwx(UGeckoInstruction inst) +void Interpreter::cntlzwx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = u32(std::countl_zero(PowerPC::ppcState.gpr[inst.RS])); @@ -218,7 +218,7 @@ void Interpreter::cntlzwx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::eqvx(UGeckoInstruction inst) +void Interpreter::eqvx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = ~(PowerPC::ppcState.gpr[inst.RS] ^ PowerPC::ppcState.gpr[inst.RB]); @@ -227,7 +227,7 @@ void Interpreter::eqvx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::extsbx(UGeckoInstruction inst) +void Interpreter::extsbx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = u32(s32(s8(PowerPC::ppcState.gpr[inst.RS]))); @@ -235,7 +235,7 @@ void Interpreter::extsbx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::extshx(UGeckoInstruction inst) +void Interpreter::extshx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = u32(s32(s16(PowerPC::ppcState.gpr[inst.RS]))); @@ -243,7 +243,7 @@ void Interpreter::extshx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::nandx(UGeckoInstruction inst) +void Interpreter::nandx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = ~(PowerPC::ppcState.gpr[inst.RS] & PowerPC::ppcState.gpr[inst.RB]); @@ -252,7 +252,7 @@ void Interpreter::nandx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::norx(UGeckoInstruction inst) +void Interpreter::norx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = ~(PowerPC::ppcState.gpr[inst.RS] | PowerPC::ppcState.gpr[inst.RB]); @@ -261,7 +261,7 @@ void Interpreter::norx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::orx(UGeckoInstruction inst) +void Interpreter::orx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | PowerPC::ppcState.gpr[inst.RB]; @@ -269,7 +269,7 @@ void Interpreter::orx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::orcx(UGeckoInstruction inst) +void Interpreter::orcx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | (~PowerPC::ppcState.gpr[inst.RB]); @@ -278,7 +278,7 @@ void Interpreter::orcx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::slwx(UGeckoInstruction inst) +void Interpreter::slwx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 amount = PowerPC::ppcState.gpr[inst.RB]; PowerPC::ppcState.gpr[inst.RA] = @@ -288,7 +288,7 @@ void Interpreter::slwx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::srawx(UGeckoInstruction inst) +void Interpreter::srawx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 rb = PowerPC::ppcState.gpr[inst.RB]; @@ -318,7 +318,7 @@ void Interpreter::srawx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::srawix(UGeckoInstruction inst) +void Interpreter::srawix(Interpreter& interpreter, UGeckoInstruction inst) { const u32 amount = inst.SH; const s32 rrs = s32(PowerPC::ppcState.gpr[inst.RS]); @@ -330,7 +330,7 @@ void Interpreter::srawix(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::srwx(UGeckoInstruction inst) +void Interpreter::srwx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 amount = PowerPC::ppcState.gpr[inst.RB]; PowerPC::ppcState.gpr[inst.RA] = @@ -340,7 +340,7 @@ void Interpreter::srwx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); } -void Interpreter::tw(UGeckoInstruction inst) +void Interpreter::tw(Interpreter& interpreter, UGeckoInstruction inst) { const s32 a = s32(PowerPC::ppcState.gpr[inst.RA]); const s32 b = s32(PowerPC::ppcState.gpr[inst.RB]); @@ -357,7 +357,7 @@ void Interpreter::tw(UGeckoInstruction inst) } } -void Interpreter::xorx(UGeckoInstruction inst) +void Interpreter::xorx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ PowerPC::ppcState.gpr[inst.RB]; @@ -372,7 +372,7 @@ static bool HasAddOverflowed(u32 x, u32 y, u32 result) return (((x ^ result) & (y ^ result)) >> 31) != 0; } -void Interpreter::addx(UGeckoInstruction inst) +void Interpreter::addx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.gpr[inst.RA]; const u32 b = PowerPC::ppcState.gpr[inst.RB]; @@ -387,7 +387,7 @@ void Interpreter::addx(UGeckoInstruction inst) Helper_UpdateCR0(result); } -void Interpreter::addcx(UGeckoInstruction inst) +void Interpreter::addcx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.gpr[inst.RA]; const u32 b = PowerPC::ppcState.gpr[inst.RB]; @@ -403,7 +403,7 @@ void Interpreter::addcx(UGeckoInstruction inst) Helper_UpdateCR0(result); } -void Interpreter::addex(UGeckoInstruction inst) +void Interpreter::addex(Interpreter& interpreter, UGeckoInstruction inst) { const u32 carry = PowerPC::ppcState.GetCarry(); const u32 a = PowerPC::ppcState.gpr[inst.RA]; @@ -420,7 +420,7 @@ void Interpreter::addex(UGeckoInstruction inst) Helper_UpdateCR0(result); } -void Interpreter::addmex(UGeckoInstruction inst) +void Interpreter::addmex(Interpreter& interpreter, UGeckoInstruction inst) { const u32 carry = PowerPC::ppcState.GetCarry(); const u32 a = PowerPC::ppcState.gpr[inst.RA]; @@ -437,7 +437,7 @@ void Interpreter::addmex(UGeckoInstruction inst) Helper_UpdateCR0(result); } -void Interpreter::addzex(UGeckoInstruction inst) +void Interpreter::addzex(Interpreter& interpreter, UGeckoInstruction inst) { const u32 carry = PowerPC::ppcState.GetCarry(); const u32 a = PowerPC::ppcState.gpr[inst.RA]; @@ -453,7 +453,7 @@ void Interpreter::addzex(UGeckoInstruction inst) Helper_UpdateCR0(result); } -void Interpreter::divwx(UGeckoInstruction inst) +void Interpreter::divwx(Interpreter& interpreter, UGeckoInstruction inst) { const auto a = s32(PowerPC::ppcState.gpr[inst.RA]); const auto b = s32(PowerPC::ppcState.gpr[inst.RB]); @@ -478,7 +478,7 @@ void Interpreter::divwx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); } -void Interpreter::divwux(UGeckoInstruction inst) +void Interpreter::divwux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.gpr[inst.RA]; const u32 b = PowerPC::ppcState.gpr[inst.RB]; @@ -500,7 +500,7 @@ void Interpreter::divwux(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); } -void Interpreter::mulhwx(UGeckoInstruction inst) +void Interpreter::mulhwx(Interpreter& interpreter, UGeckoInstruction inst) { const s64 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); const s64 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); @@ -512,7 +512,7 @@ void Interpreter::mulhwx(UGeckoInstruction inst) Helper_UpdateCR0(d); } -void Interpreter::mulhwux(UGeckoInstruction inst) +void Interpreter::mulhwux(Interpreter& interpreter, UGeckoInstruction inst) { const u64 a = PowerPC::ppcState.gpr[inst.RA]; const u64 b = PowerPC::ppcState.gpr[inst.RB]; @@ -524,7 +524,7 @@ void Interpreter::mulhwux(UGeckoInstruction inst) Helper_UpdateCR0(d); } -void Interpreter::mullwx(UGeckoInstruction inst) +void Interpreter::mullwx(Interpreter& interpreter, UGeckoInstruction inst) { const s64 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); const s64 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); @@ -539,7 +539,7 @@ void Interpreter::mullwx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); } -void Interpreter::negx(UGeckoInstruction inst) +void Interpreter::negx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.gpr[inst.RA]; @@ -552,7 +552,7 @@ void Interpreter::negx(UGeckoInstruction inst) Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); } -void Interpreter::subfx(UGeckoInstruction inst) +void Interpreter::subfx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; const u32 b = PowerPC::ppcState.gpr[inst.RB]; @@ -567,7 +567,7 @@ void Interpreter::subfx(UGeckoInstruction inst) Helper_UpdateCR0(result); } -void Interpreter::subfcx(UGeckoInstruction inst) +void Interpreter::subfcx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; const u32 b = PowerPC::ppcState.gpr[inst.RB]; @@ -583,7 +583,7 @@ void Interpreter::subfcx(UGeckoInstruction inst) Helper_UpdateCR0(result); } -void Interpreter::subfex(UGeckoInstruction inst) +void Interpreter::subfex(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; const u32 b = PowerPC::ppcState.gpr[inst.RB]; @@ -601,7 +601,7 @@ void Interpreter::subfex(UGeckoInstruction inst) } // sub from minus one -void Interpreter::subfmex(UGeckoInstruction inst) +void Interpreter::subfmex(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; const u32 b = 0xFFFFFFFF; @@ -619,7 +619,7 @@ void Interpreter::subfmex(UGeckoInstruction inst) } // sub from zero -void Interpreter::subfzex(UGeckoInstruction inst) +void Interpreter::subfzex(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; const u32 carry = PowerPC::ppcState.GetCarry(); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index 85c93389e6..b81f8908ad 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -37,7 +37,7 @@ static u32 Helper_Get_EA_UX(const PowerPC::PowerPCState& ppcs, const UGeckoInstr return (ppcs.gpr[inst.RA] + ppcs.gpr[inst.RB]); } -void Interpreter::lbz(UGeckoInstruction inst) +void Interpreter::lbz(Interpreter& interpreter, UGeckoInstruction inst) { const u32 temp = PowerPC::Read_U8(Helper_Get_EA(PowerPC::ppcState, inst)); @@ -45,7 +45,7 @@ void Interpreter::lbz(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RD] = temp; } -void Interpreter::lbzu(UGeckoInstruction inst) +void Interpreter::lbzu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U8(address); @@ -57,7 +57,7 @@ void Interpreter::lbzu(UGeckoInstruction inst) } } -void Interpreter::lfd(UGeckoInstruction inst) +void Interpreter::lfd(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); @@ -73,7 +73,7 @@ void Interpreter::lfd(UGeckoInstruction inst) PowerPC::ppcState.ps[inst.FD].SetPS0(temp); } -void Interpreter::lfdu(UGeckoInstruction inst) +void Interpreter::lfdu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); @@ -92,7 +92,7 @@ void Interpreter::lfdu(UGeckoInstruction inst) } } -void Interpreter::lfdux(UGeckoInstruction inst) +void Interpreter::lfdux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); @@ -111,7 +111,7 @@ void Interpreter::lfdux(UGeckoInstruction inst) } } -void Interpreter::lfdx(UGeckoInstruction inst) +void Interpreter::lfdx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -127,7 +127,7 @@ void Interpreter::lfdx(UGeckoInstruction inst) PowerPC::ppcState.ps[inst.FD].SetPS0(temp); } -void Interpreter::lfs(UGeckoInstruction inst) +void Interpreter::lfs(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); @@ -146,7 +146,7 @@ void Interpreter::lfs(UGeckoInstruction inst) } } -void Interpreter::lfsu(UGeckoInstruction inst) +void Interpreter::lfsu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); @@ -166,7 +166,7 @@ void Interpreter::lfsu(UGeckoInstruction inst) } } -void Interpreter::lfsux(UGeckoInstruction inst) +void Interpreter::lfsux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); @@ -186,7 +186,7 @@ void Interpreter::lfsux(UGeckoInstruction inst) } } -void Interpreter::lfsx(UGeckoInstruction inst) +void Interpreter::lfsx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -205,7 +205,7 @@ void Interpreter::lfsx(UGeckoInstruction inst) } } -void Interpreter::lha(UGeckoInstruction inst) +void Interpreter::lha(Interpreter& interpreter, UGeckoInstruction inst) { const u32 temp = u32(s32(s16(PowerPC::Read_U16(Helper_Get_EA(PowerPC::ppcState, inst))))); @@ -215,7 +215,7 @@ void Interpreter::lha(UGeckoInstruction inst) } } -void Interpreter::lhau(UGeckoInstruction inst) +void Interpreter::lhau(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); const u32 temp = u32(s32(s16(PowerPC::Read_U16(address)))); @@ -227,7 +227,7 @@ void Interpreter::lhau(UGeckoInstruction inst) } } -void Interpreter::lhz(UGeckoInstruction inst) +void Interpreter::lhz(Interpreter& interpreter, UGeckoInstruction inst) { const u32 temp = PowerPC::Read_U16(Helper_Get_EA(PowerPC::ppcState, inst)); @@ -237,7 +237,7 @@ void Interpreter::lhz(UGeckoInstruction inst) } } -void Interpreter::lhzu(UGeckoInstruction inst) +void Interpreter::lhzu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U16(address); @@ -250,7 +250,7 @@ void Interpreter::lhzu(UGeckoInstruction inst) } // FIXME: lmw should do a total rollback if a DSI occurs -void Interpreter::lmw(UGeckoInstruction inst) +void Interpreter::lmw(Interpreter& interpreter, UGeckoInstruction inst) { u32 address = Helper_Get_EA(PowerPC::ppcState, inst); @@ -278,7 +278,7 @@ void Interpreter::lmw(UGeckoInstruction inst) } // FIXME: stmw should do a total rollback if a DSI occurs -void Interpreter::stmw(UGeckoInstruction inst) +void Interpreter::stmw(Interpreter& interpreter, UGeckoInstruction inst) { u32 address = Helper_Get_EA(PowerPC::ppcState, inst); @@ -300,7 +300,7 @@ void Interpreter::stmw(UGeckoInstruction inst) } } -void Interpreter::lwz(UGeckoInstruction inst) +void Interpreter::lwz(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U32(address); @@ -311,7 +311,7 @@ void Interpreter::lwz(UGeckoInstruction inst) } } -void Interpreter::lwzu(UGeckoInstruction inst) +void Interpreter::lwzu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U32(address); @@ -323,12 +323,12 @@ void Interpreter::lwzu(UGeckoInstruction inst) } } -void Interpreter::stb(UGeckoInstruction inst) +void Interpreter::stb(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::Write_U8(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA(PowerPC::ppcState, inst)); } -void Interpreter::stbu(UGeckoInstruction inst) +void Interpreter::stbu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); @@ -339,7 +339,7 @@ void Interpreter::stbu(UGeckoInstruction inst) } } -void Interpreter::stfd(UGeckoInstruction inst) +void Interpreter::stfd(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); @@ -352,7 +352,7 @@ void Interpreter::stfd(UGeckoInstruction inst) PowerPC::Write_U64(PowerPC::ppcState.ps[inst.FS].PS0AsU64(), address); } -void Interpreter::stfdu(UGeckoInstruction inst) +void Interpreter::stfdu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); @@ -369,7 +369,7 @@ void Interpreter::stfdu(UGeckoInstruction inst) } } -void Interpreter::stfs(UGeckoInstruction inst) +void Interpreter::stfs(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); @@ -382,7 +382,7 @@ void Interpreter::stfs(UGeckoInstruction inst) PowerPC::Write_U32(ConvertToSingle(PowerPC::ppcState.ps[inst.FS].PS0AsU64()), address); } -void Interpreter::stfsu(UGeckoInstruction inst) +void Interpreter::stfsu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); @@ -399,12 +399,12 @@ void Interpreter::stfsu(UGeckoInstruction inst) } } -void Interpreter::sth(UGeckoInstruction inst) +void Interpreter::sth(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::Write_U16(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA(PowerPC::ppcState, inst)); } -void Interpreter::sthu(UGeckoInstruction inst) +void Interpreter::sthu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); @@ -415,12 +415,12 @@ void Interpreter::sthu(UGeckoInstruction inst) } } -void Interpreter::stw(UGeckoInstruction inst) +void Interpreter::stw(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA(PowerPC::ppcState, inst)); } -void Interpreter::stwu(UGeckoInstruction inst) +void Interpreter::stwu(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); @@ -431,12 +431,12 @@ void Interpreter::stwu(UGeckoInstruction inst) } } -void Interpreter::dcba(UGeckoInstruction inst) +void Interpreter::dcba(Interpreter& interpreter, UGeckoInstruction inst) { ASSERT_MSG(POWERPC, 0, "dcba - Not implemented - not a Gekko instruction"); } -void Interpreter::dcbf(UGeckoInstruction inst) +void Interpreter::dcbf(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); if (!PowerPC::ppcState.m_enable_dcache) @@ -451,7 +451,7 @@ void Interpreter::dcbf(UGeckoInstruction inst) PowerPC::FlushDCacheLine(address); } -void Interpreter::dcbi(UGeckoInstruction inst) +void Interpreter::dcbi(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -472,7 +472,7 @@ void Interpreter::dcbi(UGeckoInstruction inst) PowerPC::InvalidateDCacheLine(address); } -void Interpreter::dcbst(UGeckoInstruction inst) +void Interpreter::dcbst(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); if (!PowerPC::ppcState.m_enable_dcache) @@ -491,15 +491,15 @@ void Interpreter::dcbst(UGeckoInstruction inst) // data cache. But the CPU is never guaranteed to do this fetch, and in practice it's not more // performant to emulate it. -void Interpreter::dcbt(UGeckoInstruction inst) +void Interpreter::dcbt(Interpreter& interpreter, UGeckoInstruction inst) { } -void Interpreter::dcbtst(UGeckoInstruction inst) +void Interpreter::dcbtst(Interpreter& interpreter, UGeckoInstruction inst) { } -void Interpreter::dcbz(UGeckoInstruction inst) +void Interpreter::dcbz(Interpreter& interpreter, UGeckoInstruction inst) { const u32 dcbz_addr = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -523,7 +523,7 @@ void Interpreter::dcbz(UGeckoInstruction inst) PowerPC::ClearDCacheLine(dcbz_addr & (~31)); } -void Interpreter::dcbz_l(UGeckoInstruction inst) +void Interpreter::dcbz_l(Interpreter& interpreter, UGeckoInstruction inst) { if (!HID2(PowerPC::ppcState).LCE) { @@ -544,7 +544,7 @@ void Interpreter::dcbz_l(UGeckoInstruction inst) // eciwx/ecowx technically should access the specified device // We just do it instantly from ppc...and hey, it works! :D -void Interpreter::eciwx(UGeckoInstruction inst) +void Interpreter::eciwx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -563,7 +563,7 @@ void Interpreter::eciwx(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RD] = PowerPC::Read_U32(EA); } -void Interpreter::ecowx(UGeckoInstruction inst) +void Interpreter::ecowx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -582,7 +582,7 @@ void Interpreter::ecowx(UGeckoInstruction inst) PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], EA); } -void Interpreter::eieio(UGeckoInstruction inst) +void Interpreter::eieio(Interpreter& interpreter, UGeckoInstruction inst) { // Basically ensures that loads/stores before this instruction // have completed (in order) before executing the next op. @@ -590,14 +590,14 @@ void Interpreter::eieio(UGeckoInstruction inst) // But (at least in interpreter) we do everything realtime anyways. } -void Interpreter::icbi(UGeckoInstruction inst) +void Interpreter::icbi(Interpreter& interpreter, UGeckoInstruction inst) { // TODO: Raise DSI if translation fails (except for direct-store segments). const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); PowerPC::ppcState.iCache.Invalidate(address); } -void Interpreter::lbzux(UGeckoInstruction inst) +void Interpreter::lbzux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U8(address); @@ -609,7 +609,7 @@ void Interpreter::lbzux(UGeckoInstruction inst) } } -void Interpreter::lbzx(UGeckoInstruction inst) +void Interpreter::lbzx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 temp = PowerPC::Read_U8(Helper_Get_EA_X(PowerPC::ppcState, inst)); @@ -619,7 +619,7 @@ void Interpreter::lbzx(UGeckoInstruction inst) } } -void Interpreter::lhaux(UGeckoInstruction inst) +void Interpreter::lhaux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); const s32 temp = s32{s16(PowerPC::Read_U16(address))}; @@ -631,7 +631,7 @@ void Interpreter::lhaux(UGeckoInstruction inst) } } -void Interpreter::lhax(UGeckoInstruction inst) +void Interpreter::lhax(Interpreter& interpreter, UGeckoInstruction inst) { const s32 temp = s32{s16(PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst)))}; @@ -641,7 +641,7 @@ void Interpreter::lhax(UGeckoInstruction inst) } } -void Interpreter::lhbrx(UGeckoInstruction inst) +void Interpreter::lhbrx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 temp = Common::swap16(PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst))); @@ -651,7 +651,7 @@ void Interpreter::lhbrx(UGeckoInstruction inst) } } -void Interpreter::lhzux(UGeckoInstruction inst) +void Interpreter::lhzux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U16(address); @@ -663,7 +663,7 @@ void Interpreter::lhzux(UGeckoInstruction inst) } } -void Interpreter::lhzx(UGeckoInstruction inst) +void Interpreter::lhzx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 temp = PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst)); @@ -674,7 +674,7 @@ void Interpreter::lhzx(UGeckoInstruction inst) } // FIXME: Should rollback if a DSI occurs -void Interpreter::lswx(UGeckoInstruction inst) +void Interpreter::lswx(Interpreter& interpreter, UGeckoInstruction inst) { u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -706,7 +706,7 @@ void Interpreter::lswx(UGeckoInstruction inst) } } -void Interpreter::lwbrx(UGeckoInstruction inst) +void Interpreter::lwbrx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 temp = Common::swap32(PowerPC::Read_U32(Helper_Get_EA_X(PowerPC::ppcState, inst))); @@ -716,7 +716,7 @@ void Interpreter::lwbrx(UGeckoInstruction inst) } } -void Interpreter::lwzux(UGeckoInstruction inst) +void Interpreter::lwzux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U32(address); @@ -728,7 +728,7 @@ void Interpreter::lwzux(UGeckoInstruction inst) } } -void Interpreter::lwzx(UGeckoInstruction inst) +void Interpreter::lwzx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); const u32 temp = PowerPC::Read_U32(address); @@ -739,7 +739,7 @@ void Interpreter::lwzx(UGeckoInstruction inst) } } -void Interpreter::stbux(UGeckoInstruction inst) +void Interpreter::stbux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); @@ -750,12 +750,12 @@ void Interpreter::stbux(UGeckoInstruction inst) } } -void Interpreter::stbx(UGeckoInstruction inst) +void Interpreter::stbx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::Write_U8(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA_X(PowerPC::ppcState, inst)); } -void Interpreter::stfdux(UGeckoInstruction inst) +void Interpreter::stfdux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); @@ -772,7 +772,7 @@ void Interpreter::stfdux(UGeckoInstruction inst) } } -void Interpreter::stfdx(UGeckoInstruction inst) +void Interpreter::stfdx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -786,7 +786,7 @@ void Interpreter::stfdx(UGeckoInstruction inst) } // Stores Floating points into Integers indeXed -void Interpreter::stfiwx(UGeckoInstruction inst) +void Interpreter::stfiwx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -799,7 +799,7 @@ void Interpreter::stfiwx(UGeckoInstruction inst) PowerPC::Write_U32(PowerPC::ppcState.ps[inst.FS].PS0AsU32(), address); } -void Interpreter::stfsux(UGeckoInstruction inst) +void Interpreter::stfsux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); @@ -816,7 +816,7 @@ void Interpreter::stfsux(UGeckoInstruction inst) } } -void Interpreter::stfsx(UGeckoInstruction inst) +void Interpreter::stfsx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -829,12 +829,12 @@ void Interpreter::stfsx(UGeckoInstruction inst) PowerPC::Write_U32(ConvertToSingle(PowerPC::ppcState.ps[inst.FS].PS0AsU64()), address); } -void Interpreter::sthbrx(UGeckoInstruction inst) +void Interpreter::sthbrx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::Write_U16_Swap(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA_X(PowerPC::ppcState, inst)); } -void Interpreter::sthux(UGeckoInstruction inst) +void Interpreter::sthux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); @@ -845,14 +845,14 @@ void Interpreter::sthux(UGeckoInstruction inst) } } -void Interpreter::sthx(UGeckoInstruction inst) +void Interpreter::sthx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::Write_U16(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA_X(PowerPC::ppcState, inst)); } // lswi - bizarro string instruction // FIXME: Should rollback if a DSI occurs -void Interpreter::lswi(UGeckoInstruction inst) +void Interpreter::lswi(Interpreter& interpreter, UGeckoInstruction inst) { u32 EA = 0; if (inst.RA != 0) @@ -899,7 +899,7 @@ void Interpreter::lswi(UGeckoInstruction inst) // todo : optimize ? // stswi - bizarro string instruction // FIXME: Should rollback if a DSI occurs -void Interpreter::stswi(UGeckoInstruction inst) +void Interpreter::stswi(Interpreter& interpreter, UGeckoInstruction inst) { u32 EA = 0; if (inst.RA != 0) @@ -939,7 +939,7 @@ void Interpreter::stswi(UGeckoInstruction inst) } // TODO: is this right? is it DSI interruptible? -void Interpreter::stswx(UGeckoInstruction inst) +void Interpreter::stswx(Interpreter& interpreter, UGeckoInstruction inst) { u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -968,7 +968,7 @@ void Interpreter::stswx(UGeckoInstruction inst) } } -void Interpreter::stwbrx(UGeckoInstruction inst) +void Interpreter::stwbrx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -978,7 +978,7 @@ void Interpreter::stwbrx(UGeckoInstruction inst) // The following two instructions are for SMP communications. On a single // CPU, they cannot fail unless an interrupt happens in between. -void Interpreter::lwarx(UGeckoInstruction inst) +void Interpreter::lwarx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -999,7 +999,7 @@ void Interpreter::lwarx(UGeckoInstruction inst) } // Stores Word Conditional indeXed -void Interpreter::stwcxd(UGeckoInstruction inst) +void Interpreter::stwcxd(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); @@ -1026,7 +1026,7 @@ void Interpreter::stwcxd(UGeckoInstruction inst) PowerPC::ppcState.cr.SetField(0, PowerPC::ppcState.GetXER_SO()); } -void Interpreter::stwux(UGeckoInstruction inst) +void Interpreter::stwux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); @@ -1037,19 +1037,19 @@ void Interpreter::stwux(UGeckoInstruction inst) } } -void Interpreter::stwx(UGeckoInstruction inst) +void Interpreter::stwx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], address); } -void Interpreter::sync(UGeckoInstruction inst) +void Interpreter::sync(Interpreter& interpreter, UGeckoInstruction inst) { // ignored } -void Interpreter::tlbie(UGeckoInstruction inst) +void Interpreter::tlbie(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -1063,7 +1063,7 @@ void Interpreter::tlbie(UGeckoInstruction inst) PowerPC::InvalidateTLBEntry(address); } -void Interpreter::tlbsync(UGeckoInstruction inst) +void Interpreter::tlbsync(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp index b701617680..074746f27c 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp @@ -308,7 +308,7 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI, ppcs->ps[instRD].SetBoth(ps0, ps1); } -void Interpreter::psq_l(UGeckoInstruction inst) +void Interpreter::psq_l(Interpreter& interpreter, UGeckoInstruction inst) { if (HID2(PowerPC::ppcState).LSQE == 0) { @@ -320,7 +320,7 @@ void Interpreter::psq_l(UGeckoInstruction inst) Helper_Dequantize(&PowerPC::ppcState, EA, inst.I, inst.RD, inst.W); } -void Interpreter::psq_lu(UGeckoInstruction inst) +void Interpreter::psq_lu(Interpreter& interpreter, UGeckoInstruction inst) { if (HID2(PowerPC::ppcState).LSQE == 0) { @@ -339,7 +339,7 @@ void Interpreter::psq_lu(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RA] = EA; } -void Interpreter::psq_st(UGeckoInstruction inst) +void Interpreter::psq_st(Interpreter& interpreter, UGeckoInstruction inst) { if (HID2(PowerPC::ppcState).LSQE == 0) { @@ -351,7 +351,7 @@ void Interpreter::psq_st(UGeckoInstruction inst) Helper_Quantize(&PowerPC::ppcState, EA, inst.I, inst.RS, inst.W); } -void Interpreter::psq_stu(UGeckoInstruction inst) +void Interpreter::psq_stu(Interpreter& interpreter, UGeckoInstruction inst) { if (HID2(PowerPC::ppcState).LSQE == 0) { @@ -370,21 +370,21 @@ void Interpreter::psq_stu(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RA] = EA; } -void Interpreter::psq_lx(UGeckoInstruction inst) +void Interpreter::psq_lx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]) : PowerPC::ppcState.gpr[inst.RB]; Helper_Dequantize(&PowerPC::ppcState, EA, inst.Ix, inst.RD, inst.Wx); } -void Interpreter::psq_stx(UGeckoInstruction inst) +void Interpreter::psq_stx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]) : PowerPC::ppcState.gpr[inst.RB]; Helper_Quantize(&PowerPC::ppcState, EA, inst.Ix, inst.RS, inst.Wx); } -void Interpreter::psq_lux(UGeckoInstruction inst) +void Interpreter::psq_lux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 EA = PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]; Helper_Dequantize(&PowerPC::ppcState, EA, inst.Ix, inst.RD, inst.Wx); @@ -397,7 +397,7 @@ void Interpreter::psq_lux(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RA] = EA; } -void Interpreter::psq_stux(UGeckoInstruction inst) +void Interpreter::psq_stux(Interpreter& interpreter, UGeckoInstruction inst) { const u32 EA = PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]; Helper_Quantize(&PowerPC::ppcState, EA, inst.Ix, inst.RS, inst.Wx); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index b11c9f97ea..aa9048cc29 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -11,7 +11,7 @@ #include "Core/PowerPC/PowerPC.h" // These "binary instructions" do not alter FPSCR. -void Interpreter::ps_sel(UGeckoInstruction inst) +void Interpreter::ps_sel(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -25,7 +25,7 @@ void Interpreter::ps_sel(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_neg(UGeckoInstruction inst) +void Interpreter::ps_neg(Interpreter& interpreter, UGeckoInstruction inst) { const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -36,7 +36,7 @@ void Interpreter::ps_neg(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_mr(UGeckoInstruction inst) +void Interpreter::ps_mr(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.ps[inst.FD] = PowerPC::ppcState.ps[inst.FB]; @@ -44,7 +44,7 @@ void Interpreter::ps_mr(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_nabs(UGeckoInstruction inst) +void Interpreter::ps_nabs(Interpreter& interpreter, UGeckoInstruction inst) { const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -55,7 +55,7 @@ void Interpreter::ps_nabs(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_abs(UGeckoInstruction inst) +void Interpreter::ps_abs(Interpreter& interpreter, UGeckoInstruction inst) { const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -67,7 +67,7 @@ void Interpreter::ps_abs(UGeckoInstruction inst) } // These are just moves, double is OK. -void Interpreter::ps_merge00(UGeckoInstruction inst) +void Interpreter::ps_merge00(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -78,7 +78,7 @@ void Interpreter::ps_merge00(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_merge01(UGeckoInstruction inst) +void Interpreter::ps_merge01(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -89,7 +89,7 @@ void Interpreter::ps_merge01(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_merge10(UGeckoInstruction inst) +void Interpreter::ps_merge10(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -100,7 +100,7 @@ void Interpreter::ps_merge10(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_merge11(UGeckoInstruction inst) +void Interpreter::ps_merge11(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -112,7 +112,7 @@ void Interpreter::ps_merge11(UGeckoInstruction inst) } // From here on, the real deal. -void Interpreter::ps_div(UGeckoInstruction inst) +void Interpreter::ps_div(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -131,7 +131,7 @@ void Interpreter::ps_div(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_res(UGeckoInstruction inst) +void Interpreter::ps_res(Interpreter& interpreter, UGeckoInstruction inst) { // this code is based on the real hardware tests const double a = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); @@ -159,7 +159,7 @@ void Interpreter::ps_res(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_rsqrte(UGeckoInstruction inst) +void Interpreter::ps_rsqrte(Interpreter& interpreter, UGeckoInstruction inst) { const double ps0 = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); const double ps1 = PowerPC::ppcState.ps[inst.FB].PS1AsDouble(); @@ -194,7 +194,7 @@ void Interpreter::ps_rsqrte(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_sub(UGeckoInstruction inst) +void Interpreter::ps_sub(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -213,7 +213,7 @@ void Interpreter::ps_sub(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_add(UGeckoInstruction inst) +void Interpreter::ps_add(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -232,7 +232,7 @@ void Interpreter::ps_add(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_mul(UGeckoInstruction inst) +void Interpreter::ps_mul(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& c = PowerPC::ppcState.ps[inst.FC]; @@ -252,7 +252,7 @@ void Interpreter::ps_mul(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_msub(UGeckoInstruction inst) +void Interpreter::ps_msub(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -275,7 +275,7 @@ void Interpreter::ps_msub(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_madd(UGeckoInstruction inst) +void Interpreter::ps_madd(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -298,7 +298,7 @@ void Interpreter::ps_madd(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_nmsub(UGeckoInstruction inst) +void Interpreter::ps_nmsub(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -324,7 +324,7 @@ void Interpreter::ps_nmsub(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_nmadd(UGeckoInstruction inst) +void Interpreter::ps_nmadd(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -350,7 +350,7 @@ void Interpreter::ps_nmadd(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_sum0(UGeckoInstruction inst) +void Interpreter::ps_sum0(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -368,7 +368,7 @@ void Interpreter::ps_sum0(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_sum1(UGeckoInstruction inst) +void Interpreter::ps_sum1(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -386,7 +386,7 @@ void Interpreter::ps_sum1(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_muls0(UGeckoInstruction inst) +void Interpreter::ps_muls0(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& c = PowerPC::ppcState.ps[inst.FC]; @@ -404,7 +404,7 @@ void Interpreter::ps_muls0(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_muls1(UGeckoInstruction inst) +void Interpreter::ps_muls1(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& c = PowerPC::ppcState.ps[inst.FC]; @@ -422,7 +422,7 @@ void Interpreter::ps_muls1(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_madds0(UGeckoInstruction inst) +void Interpreter::ps_madds0(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -443,7 +443,7 @@ void Interpreter::ps_madds0(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_madds1(UGeckoInstruction inst) +void Interpreter::ps_madds1(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -464,7 +464,7 @@ void Interpreter::ps_madds1(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::ps_cmpu0(UGeckoInstruction inst) +void Interpreter::ps_cmpu0(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -472,7 +472,7 @@ void Interpreter::ps_cmpu0(UGeckoInstruction inst) Helper_FloatCompareUnordered(inst, a.PS0AsDouble(), b.PS0AsDouble()); } -void Interpreter::ps_cmpo0(UGeckoInstruction inst) +void Interpreter::ps_cmpo0(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -480,7 +480,7 @@ void Interpreter::ps_cmpo0(UGeckoInstruction inst) Helper_FloatCompareOrdered(inst, a.PS0AsDouble(), b.PS0AsDouble()); } -void Interpreter::ps_cmpu1(UGeckoInstruction inst) +void Interpreter::ps_cmpu1(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; @@ -488,7 +488,7 @@ void Interpreter::ps_cmpu1(UGeckoInstruction inst) Helper_FloatCompareUnordered(inst, a.PS1AsDouble(), b.PS1AsDouble()); } -void Interpreter::ps_cmpo1(UGeckoInstruction inst) +void Interpreter::ps_cmpo1(Interpreter& interpreter, UGeckoInstruction inst) { const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index f5bae2e719..3d00d01b29 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -32,7 +32,7 @@ static void FPSCRUpdated(UReg_FPSCR* fpscr) PowerPC::RoundingModeUpdated(); } -void Interpreter::mtfsb0x(UGeckoInstruction inst) +void Interpreter::mtfsb0x(Interpreter& interpreter, UGeckoInstruction inst) { u32 b = 0x80000000 >> inst.CRBD; @@ -44,7 +44,7 @@ void Interpreter::mtfsb0x(UGeckoInstruction inst) } // This instruction can affect FX -void Interpreter::mtfsb1x(UGeckoInstruction inst) +void Interpreter::mtfsb1x(Interpreter& interpreter, UGeckoInstruction inst) { const u32 bit = inst.CRBD; const u32 b = 0x80000000 >> bit; @@ -60,7 +60,7 @@ void Interpreter::mtfsb1x(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::mtfsfix(UGeckoInstruction inst) +void Interpreter::mtfsfix(Interpreter& interpreter, UGeckoInstruction inst) { const u32 field = inst.CRFD; const u32 pre_shifted_mask = 0xF0000000; @@ -75,7 +75,7 @@ void Interpreter::mtfsfix(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::mtfsfx(UGeckoInstruction inst) +void Interpreter::mtfsfx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 fm = inst.FM; u32 m = 0; @@ -93,19 +93,19 @@ void Interpreter::mtfsfx(UGeckoInstruction inst) PowerPC::ppcState.UpdateCR1(); } -void Interpreter::mcrxr(UGeckoInstruction inst) +void Interpreter::mcrxr(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.cr.SetField(inst.CRFD, PowerPC::ppcState.GetXER().Hex >> 28); PowerPC::ppcState.xer_ca = 0; PowerPC::ppcState.xer_so_ov = 0; } -void Interpreter::mfcr(UGeckoInstruction inst) +void Interpreter::mfcr(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.cr.Get(); } -void Interpreter::mtcrf(UGeckoInstruction inst) +void Interpreter::mtcrf(Interpreter& interpreter, UGeckoInstruction inst) { const u32 crm = inst.CRM; if (crm == 0xFF) @@ -127,7 +127,7 @@ void Interpreter::mtcrf(UGeckoInstruction inst) } } -void Interpreter::mfmsr(UGeckoInstruction inst) +void Interpreter::mfmsr(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -138,7 +138,7 @@ void Interpreter::mfmsr(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.msr.Hex; } -void Interpreter::mfsr(UGeckoInstruction inst) +void Interpreter::mfsr(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -149,7 +149,7 @@ void Interpreter::mfsr(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.sr[inst.SR]; } -void Interpreter::mfsrin(UGeckoInstruction inst) +void Interpreter::mfsrin(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -161,7 +161,7 @@ void Interpreter::mfsrin(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.sr[index]; } -void Interpreter::mtmsr(UGeckoInstruction inst) +void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -180,7 +180,7 @@ void Interpreter::mtmsr(UGeckoInstruction inst) // Segment registers. MMU control. -void Interpreter::mtsr(UGeckoInstruction inst) +void Interpreter::mtsr(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -193,7 +193,7 @@ void Interpreter::mtsr(UGeckoInstruction inst) PowerPC::ppcState.SetSR(index, value); } -void Interpreter::mtsrin(UGeckoInstruction inst) +void Interpreter::mtsrin(Interpreter& interpreter, UGeckoInstruction inst) { if (PowerPC::ppcState.msr.PR) { @@ -206,14 +206,14 @@ void Interpreter::mtsrin(UGeckoInstruction inst) PowerPC::ppcState.SetSR(index, value); } -void Interpreter::mftb(UGeckoInstruction inst) +void Interpreter::mftb(Interpreter& interpreter, UGeckoInstruction inst) { [[maybe_unused]] const u32 index = (inst.TBR >> 5) | ((inst.TBR & 0x1F) << 5); DEBUG_ASSERT_MSG(POWERPC, (index == SPR_TL) || (index == SPR_TU), "Invalid mftb"); - mfspr(inst); + mfspr(interpreter, inst); } -void Interpreter::mfspr(UGeckoInstruction inst) +void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst) { const u32 index = ((inst.SPR & 0x1F) << 5) + ((inst.SPR >> 5) & 0x1F); @@ -284,7 +284,7 @@ void Interpreter::mfspr(UGeckoInstruction inst) PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.spr[index]; } -void Interpreter::mtspr(UGeckoInstruction inst) +void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) { const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F); @@ -513,7 +513,7 @@ void Interpreter::mtspr(UGeckoInstruction inst) } } -void Interpreter::crand(UGeckoInstruction inst) +void Interpreter::crand(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); @@ -521,7 +521,7 @@ void Interpreter::crand(UGeckoInstruction inst) PowerPC::ppcState.cr.SetBit(inst.CRBD, a & b); } -void Interpreter::crandc(UGeckoInstruction inst) +void Interpreter::crandc(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); @@ -529,7 +529,7 @@ void Interpreter::crandc(UGeckoInstruction inst) PowerPC::ppcState.cr.SetBit(inst.CRBD, a & (1 ^ b)); } -void Interpreter::creqv(UGeckoInstruction inst) +void Interpreter::creqv(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); @@ -537,7 +537,7 @@ void Interpreter::creqv(UGeckoInstruction inst) PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a ^ b)); } -void Interpreter::crnand(UGeckoInstruction inst) +void Interpreter::crnand(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); @@ -545,7 +545,7 @@ void Interpreter::crnand(UGeckoInstruction inst) PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a & b)); } -void Interpreter::crnor(UGeckoInstruction inst) +void Interpreter::crnor(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); @@ -553,7 +553,7 @@ void Interpreter::crnor(UGeckoInstruction inst) PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a | b)); } -void Interpreter::cror(UGeckoInstruction inst) +void Interpreter::cror(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); @@ -561,7 +561,7 @@ void Interpreter::cror(UGeckoInstruction inst) PowerPC::ppcState.cr.SetBit(inst.CRBD, a | b); } -void Interpreter::crorc(UGeckoInstruction inst) +void Interpreter::crorc(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); @@ -569,7 +569,7 @@ void Interpreter::crorc(UGeckoInstruction inst) PowerPC::ppcState.cr.SetBit(inst.CRBD, a | (1 ^ b)); } -void Interpreter::crxor(UGeckoInstruction inst) +void Interpreter::crxor(Interpreter& interpreter, UGeckoInstruction inst) { const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); @@ -577,20 +577,20 @@ void Interpreter::crxor(UGeckoInstruction inst) PowerPC::ppcState.cr.SetBit(inst.CRBD, a ^ b); } -void Interpreter::mcrf(UGeckoInstruction inst) +void Interpreter::mcrf(Interpreter& interpreter, UGeckoInstruction inst) { const u32 cr_f = PowerPC::ppcState.cr.GetField(inst.CRFS); PowerPC::ppcState.cr.SetField(inst.CRFD, cr_f); } -void Interpreter::isync(UGeckoInstruction inst) +void Interpreter::isync(Interpreter& interpreter, UGeckoInstruction inst) { // shouldn't do anything } // the following commands read from FPSCR -void Interpreter::mcrfs(UGeckoInstruction inst) +void Interpreter::mcrfs(Interpreter& interpreter, UGeckoInstruction inst) { const u32 shift = 4 * (7 - inst.CRFS); const u32 fpflags = (PowerPC::ppcState.fpscr.Hex >> shift) & 0xF; @@ -602,7 +602,7 @@ void Interpreter::mcrfs(UGeckoInstruction inst) PowerPC::ppcState.cr.SetField(inst.CRFD, fpflags); } -void Interpreter::mffsx(UGeckoInstruction inst) +void Interpreter::mffsx(Interpreter& interpreter, UGeckoInstruction inst) { PowerPC::ppcState.ps[inst.FD].SetPS0(UINT64_C(0xFFF8000000000000) | PowerPC::ppcState.fpscr.Hex); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp index f85c5570e9..44ac712896 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Tables.cpp @@ -468,29 +468,29 @@ Interpreter::Instruction Interpreter::GetInterpreterOp(UGeckoInstruction inst) return result; } -void Interpreter::RunInterpreterOp(UGeckoInstruction inst) +void Interpreter::RunInterpreterOp(Interpreter& interpreter, UGeckoInstruction inst) { // Will handle subtables using RunTable4 etc. - s_interpreter_op_table[inst.OPCD](inst); + s_interpreter_op_table[inst.OPCD](interpreter, inst); } -void Interpreter::RunTable4(UGeckoInstruction inst) +void Interpreter::RunTable4(Interpreter& interpreter, UGeckoInstruction inst) { - s_interpreter_op_table4[inst.SUBOP10](inst); + s_interpreter_op_table4[inst.SUBOP10](interpreter, inst); } -void Interpreter::RunTable19(UGeckoInstruction inst) +void Interpreter::RunTable19(Interpreter& interpreter, UGeckoInstruction inst) { - s_interpreter_op_table19[inst.SUBOP10](inst); + s_interpreter_op_table19[inst.SUBOP10](interpreter, inst); } -void Interpreter::RunTable31(UGeckoInstruction inst) +void Interpreter::RunTable31(Interpreter& interpreter, UGeckoInstruction inst) { - s_interpreter_op_table31[inst.SUBOP10](inst); + s_interpreter_op_table31[inst.SUBOP10](interpreter, inst); } -void Interpreter::RunTable59(UGeckoInstruction inst) +void Interpreter::RunTable59(Interpreter& interpreter, UGeckoInstruction inst) { - s_interpreter_op_table59[inst.SUBOP5](inst); + s_interpreter_op_table59[inst.SUBOP5](interpreter, inst); } -void Interpreter::RunTable63(UGeckoInstruction inst) +void Interpreter::RunTable63(Interpreter& interpreter, UGeckoInstruction inst) { - s_interpreter_op_table63[inst.SUBOP10](inst); + s_interpreter_op_table63[inst.SUBOP10](interpreter, inst); } diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 6d287a9a5c..3a97cf3711 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -344,7 +344,7 @@ void Jit64::FallBackToInterpreter(UGeckoInstruction inst) Interpreter::Instruction instr = Interpreter::GetInterpreterOp(inst); ABI_PushRegistersAndAdjustStack({}, 0); - ABI_CallFunctionC(instr, inst.hex); + ABI_CallFunctionPC(instr, Interpreter::getInstance(), inst.hex); ABI_PopRegistersAndAdjustStack({}, 0); // If the instruction wrote to any registers which were marked as discarded, diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 57fa29e2e3..65e454b21a 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -199,7 +199,8 @@ void JitArm64::FallBackToInterpreter(UGeckoInstruction inst) Interpreter::Instruction instr = Interpreter::GetInterpreterOp(inst); MOVP2R(ARM64Reg::X8, instr); - MOVI2R(ARM64Reg::W0, inst.hex); + MOVP2R(ARM64Reg::W0, Interpreter::getInstance()); + MOVI2R(ARM64Reg::W1, inst.hex); BLR(ARM64Reg::X8); // If the instruction wrote to any registers which were marked as discarded, From 3d67c11b919c134dfa0af8a92b6a9c006755012f Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 00:24:22 +0100 Subject: [PATCH 02/10] Interpreter: Move global state into class, move instance to System. --- .../CachedInterpreter/CachedInterpreter.cpp | 3 +- .../Core/PowerPC/Interpreter/Interpreter.cpp | 45 ++++++++----------- .../Core/PowerPC/Interpreter/Interpreter.h | 33 +++++++++++--- .../Interpreter/Interpreter_Branch.cpp | 14 +++--- .../Interpreter/Interpreter_Integer.cpp | 4 +- .../Interpreter_SystemRegisters.cpp | 2 +- Source/Core/Core/PowerPC/Jit64/Jit.cpp | 2 +- Source/Core/Core/PowerPC/JitArm64/Jit.cpp | 2 +- Source/Core/Core/PowerPC/PowerPC.cpp | 17 ++++--- Source/Core/Core/System.cpp | 9 +++- Source/Core/Core/System.h | 2 + 11 files changed, 80 insertions(+), 53 deletions(-) diff --git a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp index 7b89fbf5a6..86f971d173 100644 --- a/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp +++ b/Source/Core/Core/PowerPC/CachedInterpreter/CachedInterpreter.cpp @@ -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: diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index 977c6cefad..4f2b3a89bd 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -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; -} diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h index ae2e87bff4..88dac22031 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h @@ -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; }; diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index e2fba4a931..09d696076d 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -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; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index 7f3a4c1827..b5bc42d234 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -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 } } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 3d00d01b29..4e171f087d 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -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. diff --git a/Source/Core/Core/PowerPC/Jit64/Jit.cpp b/Source/Core/Core/PowerPC/Jit64/Jit.cpp index 3a97cf3711..73e0dd3601 100644 --- a/Source/Core/Core/PowerPC/Jit64/Jit.cpp +++ b/Source/Core/Core/PowerPC/Jit64/Jit.cpp @@ -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, diff --git a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp index 65e454b21a..51c775f66d 100644 --- a/Source/Core/Core/PowerPC/JitArm64/Jit.cpp +++ b/Source/Core/Core/PowerPC/JitArm64/Jit.cpp @@ -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); diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index 2d8f201b30..c2b763b684 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -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& 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; } } diff --git a/Source/Core/Core/System.cpp b/Source/Core/Core/System.cpp index 788a4834b9..0a1a0eb77f 100644 --- a/Source/Core/Core/System.cpp +++ b/Source/Core/Core/System.cpp @@ -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(*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; diff --git a/Source/Core/Core/System.h b/Source/Core/Core/System.h index d49819a1aa..e1c7b9a5b8 100644 --- a/Source/Core/Core/System.h +++ b/Source/Core/Core/System.h @@ -6,6 +6,7 @@ #include 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; From 68ab623764af534bb5f3e898ad3acc22846c625a Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 00:30:01 +0100 Subject: [PATCH 03/10] Interpreter: Avoid ppcState global (Interpreter.cpp). --- .../Core/PowerPC/Interpreter/Interpreter.cpp | 94 +++++++++---------- .../Core/PowerPC/Interpreter/Interpreter.h | 1 + 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index 4f2b3a89bd..a4740cdb41 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -42,26 +42,26 @@ bool IsPairedSingleInstruction(UGeckoInstruction inst) { return inst.OPCD == 4 || IsPairedSingleQuantizedNonIndexedInstruction(inst); } +} // namespace // Checks if a given instruction would be illegal to execute if it's a paired single instruction. // // Paired single instructions are illegal to execute if HID2.PSE is not set. // It's also illegal to execute psq_l, psq_lu, psq_st, and psq_stu if HID2.PSE is enabled, // but HID2.LSQE is not set. -bool IsInvalidPairedSingleExecution(UGeckoInstruction inst) +bool Interpreter::IsInvalidPairedSingleExecution(UGeckoInstruction inst) { - if (!HID2(PowerPC::ppcState).PSE && IsPairedSingleInstruction(inst)) + if (!HID2(m_ppc_state).PSE && IsPairedSingleInstruction(inst)) return true; - return HID2(PowerPC::ppcState).PSE && !HID2(PowerPC::ppcState).LSQE && + return HID2(m_ppc_state).PSE && !HID2(m_ppc_state).LSQE && IsPairedSingleQuantizedNonIndexedInstruction(inst); } -} // namespace void Interpreter::UpdatePC() { - m_last_pc = PowerPC::ppcState.pc; - PowerPC::ppcState.pc = PowerPC::ppcState.npc; + m_last_pc = m_ppc_state.pc; + m_ppc_state.pc = m_ppc_state.npc; } Interpreter::Interpreter(Core::System& system, PowerPC::PowerPCState& ppc_state) @@ -83,26 +83,25 @@ void Interpreter::Shutdown() void Interpreter::Trace(const UGeckoInstruction& inst) { std::string regs; - for (size_t i = 0; i < std::size(PowerPC::ppcState.gpr); i++) + for (size_t i = 0; i < std::size(m_ppc_state.gpr); i++) { - regs += fmt::format("r{:02d}: {:08x} ", i, PowerPC::ppcState.gpr[i]); + regs += fmt::format("r{:02d}: {:08x} ", i, m_ppc_state.gpr[i]); } std::string fregs; - for (size_t i = 0; i < std::size(PowerPC::ppcState.ps); i++) + for (size_t i = 0; i < std::size(m_ppc_state.ps); i++) { - const auto& ps = PowerPC::ppcState.ps[i]; + const auto& ps = m_ppc_state.ps[i]; fregs += fmt::format("f{:02d}: {:08x} {:08x} ", i, ps.PS0AsU64(), ps.PS1AsU64()); } - const std::string ppc_inst = - Common::GekkoDisassembler::Disassemble(inst.hex, PowerPC::ppcState.pc); + const std::string ppc_inst = Common::GekkoDisassembler::Disassemble(inst.hex, m_ppc_state.pc); DEBUG_LOG_FMT(POWERPC, "INTER PC: {:08x} SRR0: {:08x} SRR1: {:08x} CRval: {:016x} " "FPSCR: {:08x} MSR: {:08x} LR: {:08x} {} {:08x} {}", - PowerPC::ppcState.pc, SRR0(PowerPC::ppcState), SRR1(PowerPC::ppcState), - PowerPC::ppcState.cr.fields[0], PowerPC::ppcState.fpscr.Hex, - PowerPC::ppcState.msr.Hex, PowerPC::ppcState.spr[8], regs, inst.hex, ppc_inst); + m_ppc_state.pc, SRR0(m_ppc_state), SRR1(m_ppc_state), m_ppc_state.cr.fields[0], + m_ppc_state.fpscr.Hex, m_ppc_state.msr.Hex, m_ppc_state.spr[8], regs, inst.hex, + ppc_inst); } bool Interpreter::HandleFunctionHooking(u32 address) @@ -115,7 +114,7 @@ bool Interpreter::HandleFunctionHooking(u32 address) int Interpreter::SingleStepInner() { - if (HandleFunctionHooking(PowerPC::ppcState.pc)) + if (HandleFunctionHooking(m_ppc_state.pc)) { UpdatePC(); // TODO: Does it make sense to use m_prev_inst here? @@ -124,14 +123,14 @@ int Interpreter::SingleStepInner() return PPCTables::GetOpInfo(m_prev_inst)->num_cycles; } - PowerPC::ppcState.npc = PowerPC::ppcState.pc + sizeof(UGeckoInstruction); - m_prev_inst.hex = PowerPC::Read_Opcode(PowerPC::ppcState.pc); + m_ppc_state.npc = m_ppc_state.pc + sizeof(UGeckoInstruction); + m_prev_inst.hex = PowerPC::Read_Opcode(m_ppc_state.pc); const GekkoOPInfo* opinfo = PPCTables::GetOpInfo(m_prev_inst); // Uncomment to trace the interpreter - // if ((PowerPC::ppcState.pc & 0x00FFFFFF) >= 0x000AB54C && - // (PowerPC::ppcState.pc & 0x00FFFFFF) <= 0x000AB624) + // if ((m_ppc_state.pc & 0x00FFFFFF) >= 0x000AB54C && + // (m_ppc_state.pc & 0x00FFFFFF) <= 0x000AB624) // { // m_start_trace = true; // } @@ -152,10 +151,10 @@ int Interpreter::SingleStepInner() GenerateProgramException(ProgramExceptionCause::IllegalInstruction); CheckExceptions(); } - else if (PowerPC::ppcState.msr.FP) + else if (m_ppc_state.msr.FP) { RunInterpreterOp(*this, m_prev_inst); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((m_ppc_state.Exceptions & EXCEPTION_DSI) != 0) { CheckExceptions(); } @@ -165,13 +164,13 @@ int Interpreter::SingleStepInner() // check if we have to generate a FPU unavailable exception or a program exception. if ((opinfo->flags & FL_USE_FPU) != 0) { - PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; + m_ppc_state.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; CheckExceptions(); } else { RunInterpreterOp(*this, m_prev_inst); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((m_ppc_state.Exceptions & EXCEPTION_DSI) != 0) { CheckExceptions(); } @@ -187,13 +186,13 @@ int Interpreter::SingleStepInner() UpdatePC(); PowerPC::UpdatePerformanceMonitor(opinfo->num_cycles, (opinfo->flags & FL_LOADSTORE) != 0, - (opinfo->flags & FL_USE_FPU) != 0, PowerPC::ppcState); + (opinfo->flags & FL_USE_FPU) != 0, m_ppc_state); return opinfo->num_cycles; } void Interpreter::SingleStep() { - auto& core_timing = Core::System::GetInstance().GetCoreTiming(); + auto& core_timing = m_system.GetCoreTiming(); auto& core_timing_globals = core_timing.GetGlobals(); // Declare start of new slice @@ -203,12 +202,12 @@ void Interpreter::SingleStep() // The interpreter ignores instruction timing information outside the 'fast runloop'. core_timing_globals.slice_length = 1; - PowerPC::ppcState.downcount = 0; + m_ppc_state.downcount = 0; - if (PowerPC::ppcState.Exceptions != 0) + if (m_ppc_state.Exceptions != 0) { PowerPC::CheckExceptions(); - PowerPC::ppcState.pc = PowerPC::ppcState.npc; + m_ppc_state.pc = m_ppc_state.npc; } } @@ -223,9 +222,8 @@ constexpr u32 s_show_steps = 300; // FastRun - inspired by GCemu (to imitate the JIT so that they can be compared). void Interpreter::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(); while (cpu.GetState() == CPU::State::Running) { // CoreTiming Advance() ends the previous slice and declares the start of the next @@ -237,27 +235,27 @@ void Interpreter::Run() if (Config::Get(Config::MAIN_ENABLE_DEBUGGING)) { #ifdef SHOW_HISTORY - s_pc_block_vec.push_back(PowerPC::ppcState.pc); + s_pc_block_vec.push_back(m_ppc_state.pc); if (s_pc_block_vec.size() > s_show_blocks) s_pc_block_vec.erase(s_pc_block_vec.begin()); #endif // Debugging friendly version of inner loop. Tries to do the timing as similarly to the // JIT as possible. Does not take into account that some instructions take multiple cycles. - while (PowerPC::ppcState.downcount > 0) + while (m_ppc_state.downcount > 0) { m_end_block = false; int cycles = 0; while (!m_end_block) { #ifdef SHOW_HISTORY - s_pc_vec.push_back(PowerPC::ppcState.pc); + s_pc_vec.push_back(m_ppc_state.pc); if (s_pc_vec.size() > s_show_steps) s_pc_vec.erase(s_pc_vec.begin()); #endif // 2: check for breakpoint - if (PowerPC::breakpoints.IsAddressBreakPoint(PowerPC::ppcState.pc)) + if (PowerPC::breakpoints.IsAddressBreakPoint(m_ppc_state.pc)) { #ifdef SHOW_HISTORY NOTICE_LOG_FMT(POWERPC, "----------------------------"); @@ -278,25 +276,25 @@ void Interpreter::Run() NOTICE_LOG_FMT(POWERPC, "PC: {:#010x}", s_pc_vec[j]); } #endif - INFO_LOG_FMT(POWERPC, "Hit Breakpoint - {:08x}", PowerPC::ppcState.pc); + INFO_LOG_FMT(POWERPC, "Hit Breakpoint - {:08x}", m_ppc_state.pc); cpu.Break(); if (GDBStub::IsActive()) GDBStub::TakeControl(); - if (PowerPC::breakpoints.IsTempBreakPoint(PowerPC::ppcState.pc)) - PowerPC::breakpoints.Remove(PowerPC::ppcState.pc); + if (PowerPC::breakpoints.IsTempBreakPoint(m_ppc_state.pc)) + PowerPC::breakpoints.Remove(m_ppc_state.pc); Host_UpdateDisasmDialog(); return; } cycles += SingleStepInner(); } - PowerPC::ppcState.downcount -= cycles; + m_ppc_state.downcount -= cycles; } } else { // "fast" version of inner loop. well, it's not so fast. - while (PowerPC::ppcState.downcount > 0) + while (m_ppc_state.downcount > 0) { m_end_block = false; @@ -305,7 +303,7 @@ void Interpreter::Run() { cycles += SingleStepInner(); } - PowerPC::ppcState.downcount -= cycles; + m_ppc_state.downcount -= cycles; } } } @@ -314,7 +312,7 @@ void Interpreter::Run() void Interpreter::unknown_instruction(Interpreter& interpreter, UGeckoInstruction inst) { ASSERT(Core::IsCPUThread()); - auto& system = Core::System::GetInstance(); + auto& system = interpreter.m_system; Core::CPUThreadGuard guard(system); const u32 last_pc = interpreter.m_last_pc; @@ -323,19 +321,21 @@ void Interpreter::unknown_instruction(Interpreter& interpreter, UGeckoInstructio NOTICE_LOG_FMT(POWERPC, "Last PC = {:08x} : {}", last_pc, disasm); Dolphin_Debugger::PrintCallstack(system, guard, Common::Log::LogType::POWERPC, Common::Log::LogLevel::LNOTICE); + + const auto& ppc_state = interpreter.m_ppc_state; NOTICE_LOG_FMT( POWERPC, "\nIntCPU: Unknown instruction {:08x} at PC = {:08x} last_PC = {:08x} LR = {:08x}\n", - inst.hex, PowerPC::ppcState.pc, last_pc, LR(PowerPC::ppcState)); + inst.hex, ppc_state.pc, last_pc, LR(ppc_state)); for (int i = 0; i < 32; i += 4) { NOTICE_LOG_FMT(POWERPC, "r{}: {:#010x} r{}: {:#010x} r{}: {:#010x} r{}: {:#010x}", i, - PowerPC::ppcState.gpr[i], i + 1, PowerPC::ppcState.gpr[i + 1], i + 2, - PowerPC::ppcState.gpr[i + 2], i + 3, PowerPC::ppcState.gpr[i + 3]); + ppc_state.gpr[i], i + 1, ppc_state.gpr[i + 1], i + 2, ppc_state.gpr[i + 2], + i + 3, ppc_state.gpr[i + 3]); } ASSERT_MSG(POWERPC, 0, "\nIntCPU: Unknown instruction {:08x} at PC = {:08x} last_PC = {:08x} LR = {:08x}\n", - inst.hex, PowerPC::ppcState.pc, last_pc, LR(PowerPC::ppcState)); + inst.hex, ppc_state.pc, last_pc, LR(ppc_state)); if (system.IsPauseOnPanicMode()) system.GetCPU().Break(); } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h index 88dac22031..81b15efc90 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h @@ -304,6 +304,7 @@ private: static void Helper_FloatCompareUnordered(UGeckoInstruction inst, double a, double b); void UpdatePC(); + bool IsInvalidPairedSingleExecution(UGeckoInstruction inst); void Trace(const UGeckoInstruction& inst); From d4ca591e02b371b6335cbec7b5cbfb79a029bf41 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 00:36:08 +0100 Subject: [PATCH 04/10] Interpreter: Avoid ppcState global (Interpreter_Branch.cpp). --- .../Interpreter/Interpreter_Branch.cpp | 64 +++++++++++-------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index 09d696076d..c36f9c30e3 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -14,15 +14,17 @@ void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; + if (inst.LK) - LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4; + LR(ppc_state) = ppc_state.pc + 4; const auto address = u32(SignExt26(inst.LI << 2)); if (inst.AA) - PowerPC::ppcState.npc = address; + ppc_state.npc = address; else - PowerPC::ppcState.npc = PowerPC::ppcState.pc + address; + ppc_state.npc = ppc_state.pc + address; interpreter.m_end_block = true; } @@ -30,28 +32,29 @@ void Interpreter::bx(Interpreter& interpreter, UGeckoInstruction inst) // bcx - ugly, straight from PPC manual equations :) void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; + if ((inst.BO & BO_DONT_DECREMENT_FLAG) == 0) - CTR(PowerPC::ppcState)--; + CTR(ppc_state)--; const bool true_false = ((inst.BO >> 3) & 1) != 0; const bool only_counter_check = ((inst.BO >> 4) & 1) != 0; const bool only_condition_check = ((inst.BO >> 2) & 1) != 0; - const u32 ctr_check = ((CTR(PowerPC::ppcState) != 0) ^ (inst.BO >> 1)) & 1; + const u32 ctr_check = ((CTR(ppc_state) != 0) ^ (inst.BO >> 1)) & 1; const bool counter = only_condition_check || ctr_check != 0; - const bool condition = - only_counter_check || (PowerPC::ppcState.cr.GetBit(inst.BI) == u32(true_false)); + const bool condition = only_counter_check || (ppc_state.cr.GetBit(inst.BI) == u32(true_false)); if (counter && condition) { if (inst.LK) - LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4; + LR(ppc_state) = ppc_state.pc + 4; const auto address = u32(SignExt16(s16(inst.BD << 2))); if (inst.AA) - PowerPC::ppcState.npc = address; + ppc_state.npc = address; else - PowerPC::ppcState.npc = PowerPC::ppcState.pc + address; + ppc_state.npc = ppc_state.pc + address; } interpreter.m_end_block = true; @@ -59,17 +62,19 @@ void Interpreter::bcx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; + DEBUG_ASSERT_MSG(POWERPC, (inst.BO_2 & BO_DONT_DECREMENT_FLAG) != 0, "bcctrx with decrement and test CTR option is invalid!"); const u32 condition = - ((inst.BO_2 >> 4) | (PowerPC::ppcState.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1; + ((inst.BO_2 >> 4) | (ppc_state.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1; if (condition != 0) { - PowerPC::ppcState.npc = CTR(PowerPC::ppcState) & (~3); + ppc_state.npc = CTR(ppc_state) & (~3); if (inst.LK_3) - LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4; + LR(ppc_state) = ppc_state.pc + 4; } interpreter.m_end_block = true; @@ -77,18 +82,20 @@ void Interpreter::bcctrx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::bclrx(Interpreter& interpreter, UGeckoInstruction inst) { - if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0) - CTR(PowerPC::ppcState)--; + auto& ppc_state = interpreter.m_ppc_state; - const u32 counter = ((inst.BO_2 >> 2) | ((CTR(PowerPC::ppcState) != 0) ^ (inst.BO_2 >> 1))) & 1; + if ((inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0) + CTR(ppc_state)--; + + const u32 counter = ((inst.BO_2 >> 2) | ((CTR(ppc_state) != 0) ^ (inst.BO_2 >> 1))) & 1; const u32 condition = - ((inst.BO_2 >> 4) | (PowerPC::ppcState.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1; + ((inst.BO_2 >> 4) | (ppc_state.cr.GetBit(inst.BI_2) == ((inst.BO_2 >> 3) & 1))) & 1; if ((counter & condition) != 0) { - PowerPC::ppcState.npc = LR(PowerPC::ppcState) & (~3); + ppc_state.npc = LR(ppc_state) & (~3); if (inst.LK_3) - LR(PowerPC::ppcState) = PowerPC::ppcState.pc + 4; + LR(ppc_state) = ppc_state.pc + 4; } interpreter.m_end_block = true; @@ -99,14 +106,16 @@ void Interpreter::HLEFunction(Interpreter& interpreter, UGeckoInstruction inst) interpreter.m_end_block = true; ASSERT(Core::IsCPUThread()); - Core::CPUThreadGuard guard(Core::System::GetInstance()); + Core::CPUThreadGuard guard(interpreter.m_system); - HLE::Execute(guard, PowerPC::ppcState.pc, inst.hex); + HLE::Execute(guard, interpreter.m_ppc_state.pc, inst.hex); } void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; @@ -115,17 +124,16 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst) // Restore saved bits from SRR1 to MSR. // Gecko/Broadway can save more bits than explicitly defined in ppc spec const u32 mask = 0x87C0FFFF; - PowerPC::ppcState.msr.Hex = - (PowerPC::ppcState.msr.Hex & ~mask) | (SRR1(PowerPC::ppcState) & mask); + ppc_state.msr.Hex = (ppc_state.msr.Hex & ~mask) | (SRR1(ppc_state) & mask); // MSR[13] is set to 0. - PowerPC::ppcState.msr.Hex &= 0xFFFBFFFF; + ppc_state.msr.Hex &= 0xFFFBFFFF; // Here we should check if there are pending exceptions, and if their corresponding enable bits // are set // if above is true, we'd do: // PowerPC::CheckExceptions(); // else // set NPC to saved offset and resume - PowerPC::ppcState.npc = SRR0(PowerPC::ppcState); + ppc_state.npc = SRR0(ppc_state); interpreter.m_end_block = true; } @@ -134,7 +142,9 @@ void Interpreter::rfi(Interpreter& interpreter, UGeckoInstruction inst) // We do it anyway, though :P void Interpreter::sc(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL; + auto& ppc_state = interpreter.m_ppc_state; + + ppc_state.Exceptions |= EXCEPTION_SYSCALL; PowerPC::CheckExceptions(); interpreter.m_end_block = true; } From 2ce86a890a20d7960c8537f16b339a22d86ad9d3 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 01:03:13 +0100 Subject: [PATCH 05/10] Interpreter: Avoid ppcState global (Interpreter_FloatingPoint.cpp). --- .../Core/PowerPC/Interpreter/Interpreter.h | 6 +- .../Interpreter/Interpreter_FloatingPoint.cpp | 494 +++++++++--------- .../Interpreter/Interpreter_Paired.cpp | 8 +- 3 files changed, 267 insertions(+), 241 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h index 81b15efc90..98c245b3ca 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h @@ -300,8 +300,10 @@ private: template static void Helper_IntCompare(UGeckoInstruction inst, T a, T b); - static void Helper_FloatCompareOrdered(UGeckoInstruction inst, double a, double b); - static void Helper_FloatCompareUnordered(UGeckoInstruction inst, double a, double b); + static void Helper_FloatCompareOrdered(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, + double a, double b); + static void Helper_FloatCompareUnordered(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, + double a, double b); void UpdatePC(); bool IsInvalidPairedSingleExecution(UGeckoInstruction inst); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index b3301af738..4679624996 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -35,33 +35,34 @@ void SetFI(UReg_FPSCR* fpscr, u32 FI) // Note that the convert to integer operation is defined // in Appendix C.4.2 in PowerPC Microprocessor Family: // The Programming Environments Manual for 32 and 64-bit Microprocessors -void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode) +void ConvertToInteger(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, + RoundingMode rounding_mode) { - const double b = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); + const double b = ppc_state.ps[inst.FB].PS0AsDouble(); u32 value; bool exception_occurred = false; if (std::isnan(b)) { if (Common::IsSNAN(b)) - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN); + SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); value = 0x80000000; - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXCVI); + SetFPException(&ppc_state.fpscr, FPSCR_VXCVI); exception_occurred = true; } else if (b > static_cast(0x7fffffff)) { // Positive large operand or +inf value = 0x7fffffff; - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXCVI); + SetFPException(&ppc_state.fpscr, FPSCR_VXCVI); exception_occurred = true; } else if (b < -static_cast(0x80000000)) { // Negative large operand or -inf value = 0x80000000; - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXCVI); + SetFPException(&ppc_state.fpscr, FPSCR_VXCVI); exception_occurred = true; } else @@ -103,22 +104,22 @@ void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode) const double di = i; if (di == b) { - PowerPC::ppcState.fpscr.ClearFIFR(); + ppc_state.fpscr.ClearFIFR(); } else { // Also sets FPSCR[XX] - SetFI(&PowerPC::ppcState.fpscr, 1); - PowerPC::ppcState.fpscr.FR = fabs(di) > fabs(b); + SetFI(&ppc_state.fpscr, 1); + ppc_state.fpscr.FR = fabs(di) > fabs(b); } } if (exception_occurred) { - PowerPC::ppcState.fpscr.ClearFIFR(); + ppc_state.fpscr.ClearFIFR(); } - if (!exception_occurred || PowerPC::ppcState.fpscr.VE == 0) + if (!exception_occurred || ppc_state.fpscr.VE == 0) { // Based on HW tests // FPRF is not affected @@ -126,15 +127,16 @@ void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode) if (value == 0 && std::signbit(b)) result |= 0x100000000ull; - PowerPC::ppcState.ps[inst.FD].SetPS0(result); + ppc_state.ps[inst.FD].SetPS0(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } } // Anonymous namespace -void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction inst, double fa, double fb) +void Interpreter::Helper_FloatCompareOrdered(PowerPC::PowerPCState& ppc_state, + UGeckoInstruction inst, double fa, double fb) { FPCC compare_result; @@ -143,15 +145,15 @@ void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction inst, double fa, compare_result = FPCC::FU; if (Common::IsSNAN(fa) || Common::IsSNAN(fb)) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN); - if (PowerPC::ppcState.fpscr.VE == 0) + SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); + if (ppc_state.fpscr.VE == 0) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXVC); + SetFPException(&ppc_state.fpscr, FPSCR_VXVC); } } else // QNaN { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXVC); + SetFPException(&ppc_state.fpscr, FPSCR_VXVC); } } else if (fa < fb) @@ -170,12 +172,13 @@ void Interpreter::Helper_FloatCompareOrdered(UGeckoInstruction inst, double fa, const u32 compare_value = static_cast(compare_result); // Clear and set the FPCC bits accordingly. - PowerPC::ppcState.fpscr.FPRF = (PowerPC::ppcState.fpscr.FPRF & ~FPCC_MASK) | compare_value; + ppc_state.fpscr.FPRF = (ppc_state.fpscr.FPRF & ~FPCC_MASK) | compare_value; - PowerPC::ppcState.cr.SetField(inst.CRFD, compare_value); + ppc_state.cr.SetField(inst.CRFD, compare_value); } -void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa, double fb) +void Interpreter::Helper_FloatCompareUnordered(PowerPC::PowerPCState& ppc_state, + UGeckoInstruction inst, double fa, double fb) { FPCC compare_result; @@ -185,7 +188,7 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa if (Common::IsSNAN(fa) || Common::IsSNAN(fb)) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN); + SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); } } else if (fa < fb) @@ -204,87 +207,93 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction inst, double fa const u32 compare_value = static_cast(compare_result); // Clear and set the FPCC bits accordingly. - PowerPC::ppcState.fpscr.FPRF = (PowerPC::ppcState.fpscr.FPRF & ~FPCC_MASK) | compare_value; + ppc_state.fpscr.FPRF = (ppc_state.fpscr.FPRF & ~FPCC_MASK) | compare_value; - PowerPC::ppcState.cr.SetField(inst.CRFD, compare_value); + ppc_state.cr.SetField(inst.CRFD, compare_value); } void Interpreter::fcmpo(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - Helper_FloatCompareOrdered(inst, a.PS0AsDouble(), b.PS0AsDouble()); + Helper_FloatCompareOrdered(ppc_state, inst, a.PS0AsDouble(), b.PS0AsDouble()); } void Interpreter::fcmpu(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - Helper_FloatCompareUnordered(inst, a.PS0AsDouble(), b.PS0AsDouble()); + Helper_FloatCompareUnordered(ppc_state, inst, a.PS0AsDouble(), b.PS0AsDouble()); } void Interpreter::fctiwx(Interpreter& interpreter, UGeckoInstruction inst) { - ConvertToInteger(inst, static_cast(PowerPC::ppcState.fpscr.RN.Value())); + auto& ppc_state = interpreter.m_ppc_state; + ConvertToInteger(ppc_state, inst, static_cast(ppc_state.fpscr.RN.Value())); } void Interpreter::fctiwzx(Interpreter& interpreter, UGeckoInstruction inst) { - ConvertToInteger(inst, RoundingMode::TowardsZero); + auto& ppc_state = interpreter.m_ppc_state; + ConvertToInteger(ppc_state, inst, RoundingMode::TowardsZero); } void Interpreter::fmrx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.ps[inst.FD].SetPS0(PowerPC::ppcState.ps[inst.FB].PS0AsU64()); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.ps[inst.FD].SetPS0(ppc_state.ps[inst.FB].PS0AsU64()); // This is a binary instruction. Does not alter FPSCR if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fabsx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.ps[inst.FD].SetPS0(fabs(PowerPC::ppcState.ps[inst.FB].PS0AsDouble())); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.ps[inst.FD].SetPS0(fabs(ppc_state.ps[inst.FB].PS0AsDouble())); // This is a binary instruction. Does not alter FPSCR if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fnabsx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.ps[inst.FD].SetPS0(PowerPC::ppcState.ps[inst.FB].PS0AsU64() | - (UINT64_C(1) << 63)); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.ps[inst.FD].SetPS0(ppc_state.ps[inst.FB].PS0AsU64() | (UINT64_C(1) << 63)); // This is a binary instruction. Does not alter FPSCR if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fnegx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.ps[inst.FD].SetPS0(PowerPC::ppcState.ps[inst.FB].PS0AsU64() ^ - (UINT64_C(1) << 63)); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.ps[inst.FD].SetPS0(ppc_state.ps[inst.FB].PS0AsU64() ^ (UINT64_C(1) << 63)); // This is a binary instruction. Does not alter FPSCR if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fselx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; - PowerPC::ppcState.ps[inst.FD].SetPS0((a.PS0AsDouble() >= -0.0) ? c.PS0AsDouble() : - b.PS0AsDouble()); + ppc_state.ps[inst.FD].SetPS0((a.PS0AsDouble() >= -0.0) ? c.PS0AsDouble() : b.PS0AsDouble()); // This is a binary instruction. Does not alter FPSCR if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } // !!! warning !!! @@ -292,444 +301,459 @@ void Interpreter::fselx(Interpreter& interpreter, UGeckoInstruction inst) // PS1 is said to be undefined void Interpreter::frspx(Interpreter& interpreter, UGeckoInstruction inst) // round to single { - const double b = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); - const float rounded = ForceSingle(PowerPC::ppcState.fpscr, b); + auto& ppc_state = interpreter.m_ppc_state; + const double b = ppc_state.ps[inst.FB].PS0AsDouble(); + const float rounded = ForceSingle(ppc_state.fpscr, b); if (std::isnan(b)) { const bool is_snan = Common::IsSNAN(b); if (is_snan) - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN); + SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); - if (!is_snan || PowerPC::ppcState.fpscr.VE == 0) + if (!is_snan || ppc_state.fpscr.VE == 0) { - PowerPC::ppcState.ps[inst.FD].Fill(rounded); - PowerPC::ppcState.UpdateFPRFSingle(rounded); + ppc_state.ps[inst.FD].Fill(rounded); + ppc_state.UpdateFPRFSingle(rounded); } - PowerPC::ppcState.fpscr.ClearFIFR(); + ppc_state.fpscr.ClearFIFR(); } else { - SetFI(&PowerPC::ppcState.fpscr, b != rounded); - PowerPC::ppcState.fpscr.FR = fabs(rounded) > fabs(b); - PowerPC::ppcState.UpdateFPRFSingle(rounded); - PowerPC::ppcState.ps[inst.FD].Fill(rounded); + SetFI(&ppc_state.fpscr, b != rounded); + ppc_state.fpscr.FR = fabs(rounded) > fabs(b); + ppc_state.UpdateFPRFSingle(rounded); + ppc_state.ps[inst.FD].Fill(rounded); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fmulx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& c = ppc_state.ps[inst.FC]; - const FPResult product = NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble()); + const FPResult product = NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) { - const double result = ForceDouble(PowerPC::ppcState.fpscr, product.value); + const double result = ForceDouble(ppc_state.fpscr, product.value); - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.fpscr.FI = 0; // are these flags important? - PowerPC::ppcState.fpscr.FR = 0; - PowerPC::ppcState.UpdateFPRFDouble(result); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.fpscr.FI = 0; // are these flags important? + ppc_state.fpscr.FR = 0; + ppc_state.UpdateFPRFDouble(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fmulsx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& c = ppc_state.ps[inst.FC]; const double c_value = Force25Bit(c.PS0AsDouble()); - const FPResult d_value = NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value); + const FPResult d_value = NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c_value); - if (PowerPC::ppcState.fpscr.VE == 0 || d_value.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || d_value.HasNoInvalidExceptions()) { - const float result = ForceSingle(PowerPC::ppcState.fpscr, d_value.value); + const float result = ForceSingle(ppc_state.fpscr, d_value.value); - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.fpscr.FI = 0; - PowerPC::ppcState.fpscr.FR = 0; - PowerPC::ppcState.UpdateFPRFSingle(result); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.fpscr.FI = 0; + ppc_state.fpscr.FR = 0; + ppc_state.UpdateFPRFSingle(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fmaddx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const FPResult product = - NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); + NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) { - const double result = ForceDouble(PowerPC::ppcState.fpscr, product.value); - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.UpdateFPRFDouble(result); + const double result = ForceDouble(ppc_state.fpscr, product.value); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.UpdateFPRFDouble(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fmaddsx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c_value = Force25Bit(c.PS0AsDouble()); - const FPResult d_value = - NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); + const FPResult d_value = NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || d_value.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || d_value.HasNoInvalidExceptions()) { - const float result = ForceSingle(PowerPC::ppcState.fpscr, d_value.value); + const float result = ForceSingle(ppc_state.fpscr, d_value.value); - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.fpscr.FI = d_value.value != result; - PowerPC::ppcState.fpscr.FR = 0; - PowerPC::ppcState.UpdateFPRFSingle(result); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.fpscr.FI = d_value.value != result; + ppc_state.fpscr.FR = 0; + ppc_state.UpdateFPRFSingle(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::faddx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const FPResult sum = NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); + const FPResult sum = NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || sum.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || sum.HasNoInvalidExceptions()) { - const double result = ForceDouble(PowerPC::ppcState.fpscr, sum.value); - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.UpdateFPRFDouble(result); + const double result = ForceDouble(ppc_state.fpscr, sum.value); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.UpdateFPRFDouble(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::faddsx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const FPResult sum = NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); + const FPResult sum = NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || sum.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || sum.HasNoInvalidExceptions()) { - const float result = ForceSingle(PowerPC::ppcState.fpscr, sum.value); - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.UpdateFPRFSingle(result); + const float result = ForceSingle(ppc_state.fpscr, sum.value); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.UpdateFPRFSingle(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fdivx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const FPResult quotient = NI_div(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); - const bool not_divide_by_zero = PowerPC::ppcState.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX; - const bool not_invalid = PowerPC::ppcState.fpscr.VE == 0 || quotient.HasNoInvalidExceptions(); + const FPResult quotient = NI_div(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); + const bool not_divide_by_zero = ppc_state.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX; + const bool not_invalid = ppc_state.fpscr.VE == 0 || quotient.HasNoInvalidExceptions(); if (not_divide_by_zero && not_invalid) { - const double result = ForceDouble(PowerPC::ppcState.fpscr, quotient.value); - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.UpdateFPRFDouble(result); + const double result = ForceDouble(ppc_state.fpscr, quotient.value); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.UpdateFPRFDouble(result); } // FR,FI,OX,UX??? if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fdivsx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const FPResult quotient = NI_div(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); - const bool not_divide_by_zero = PowerPC::ppcState.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX; - const bool not_invalid = PowerPC::ppcState.fpscr.VE == 0 || quotient.HasNoInvalidExceptions(); + const FPResult quotient = NI_div(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); + const bool not_divide_by_zero = ppc_state.fpscr.ZE == 0 || quotient.exception != FPSCR_ZX; + const bool not_invalid = ppc_state.fpscr.VE == 0 || quotient.HasNoInvalidExceptions(); if (not_divide_by_zero && not_invalid) { - const float result = ForceSingle(PowerPC::ppcState.fpscr, quotient.value); - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.UpdateFPRFSingle(result); + const float result = ForceSingle(ppc_state.fpscr, quotient.value); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.UpdateFPRFSingle(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } // Single precision only. void Interpreter::fresx(Interpreter& interpreter, UGeckoInstruction inst) { - const double b = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); + auto& ppc_state = interpreter.m_ppc_state; + const double b = ppc_state.ps[inst.FB].PS0AsDouble(); - const auto compute_result = [inst](double value) { + const auto compute_result = [&ppc_state, inst](double value) { const double result = Common::ApproximateReciprocal(value); - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.UpdateFPRFSingle(float(result)); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.UpdateFPRFSingle(float(result)); }; if (b == 0.0) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_ZX); - PowerPC::ppcState.fpscr.ClearFIFR(); + SetFPException(&ppc_state.fpscr, FPSCR_ZX); + ppc_state.fpscr.ClearFIFR(); - if (PowerPC::ppcState.fpscr.ZE == 0) + if (ppc_state.fpscr.ZE == 0) compute_result(b); } else if (Common::IsSNAN(b)) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN); - PowerPC::ppcState.fpscr.ClearFIFR(); + SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); + ppc_state.fpscr.ClearFIFR(); - if (PowerPC::ppcState.fpscr.VE == 0) + if (ppc_state.fpscr.VE == 0) compute_result(b); } else { if (std::isnan(b) || std::isinf(b)) - PowerPC::ppcState.fpscr.ClearFIFR(); + ppc_state.fpscr.ClearFIFR(); compute_result(b); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::frsqrtex(Interpreter& interpreter, UGeckoInstruction inst) { - const double b = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); + auto& ppc_state = interpreter.m_ppc_state; + const double b = ppc_state.ps[inst.FB].PS0AsDouble(); - const auto compute_result = [inst](double value) { + const auto compute_result = [&ppc_state, inst](double value) { const double result = Common::ApproximateReciprocalSquareRoot(value); - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.UpdateFPRFDouble(result); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.UpdateFPRFDouble(result); }; if (b < 0.0) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSQRT); - PowerPC::ppcState.fpscr.ClearFIFR(); + SetFPException(&ppc_state.fpscr, FPSCR_VXSQRT); + ppc_state.fpscr.ClearFIFR(); - if (PowerPC::ppcState.fpscr.VE == 0) + if (ppc_state.fpscr.VE == 0) compute_result(b); } else if (b == 0.0) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_ZX); - PowerPC::ppcState.fpscr.ClearFIFR(); + SetFPException(&ppc_state.fpscr, FPSCR_ZX); + ppc_state.fpscr.ClearFIFR(); - if (PowerPC::ppcState.fpscr.ZE == 0) + if (ppc_state.fpscr.ZE == 0) compute_result(b); } else if (Common::IsSNAN(b)) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN); - PowerPC::ppcState.fpscr.ClearFIFR(); + SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); + ppc_state.fpscr.ClearFIFR(); - if (PowerPC::ppcState.fpscr.VE == 0) + if (ppc_state.fpscr.VE == 0) compute_result(b); } else { if (std::isnan(b) || std::isinf(b)) - PowerPC::ppcState.fpscr.ClearFIFR(); + ppc_state.fpscr.ClearFIFR(); compute_result(b); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fmsubx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const FPResult product = - NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); + NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) { - const double result = ForceDouble(PowerPC::ppcState.fpscr, product.value); - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.UpdateFPRFDouble(result); + const double result = ForceDouble(ppc_state.fpscr, product.value); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.UpdateFPRFDouble(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fmsubsx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c_value = Force25Bit(c.PS0AsDouble()); - const FPResult product = - NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); + const FPResult product = NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) { - const float result = ForceSingle(PowerPC::ppcState.fpscr, product.value); - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.UpdateFPRFSingle(result); + const float result = ForceSingle(ppc_state.fpscr, product.value); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.UpdateFPRFSingle(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fnmaddx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const FPResult product = - NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); + NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) { - const double tmp = ForceDouble(PowerPC::ppcState.fpscr, product.value); + const double tmp = ForceDouble(ppc_state.fpscr, product.value); const double result = std::isnan(tmp) ? tmp : -tmp; - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.UpdateFPRFDouble(result); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.UpdateFPRFDouble(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fnmaddsx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c_value = Force25Bit(c.PS0AsDouble()); - const FPResult product = - NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); + const FPResult product = NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) { - const float tmp = ForceSingle(PowerPC::ppcState.fpscr, product.value); + const float tmp = ForceSingle(ppc_state.fpscr, product.value); const float result = std::isnan(tmp) ? tmp : -tmp; - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.UpdateFPRFSingle(result); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.UpdateFPRFSingle(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fnmsubx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const FPResult product = - NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); + NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c.PS0AsDouble(), b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) { - const double tmp = ForceDouble(PowerPC::ppcState.fpscr, product.value); + const double tmp = ForceDouble(ppc_state.fpscr, product.value); const double result = std::isnan(tmp) ? tmp : -tmp; - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.UpdateFPRFDouble(result); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.UpdateFPRFDouble(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fnmsubsx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c_value = Force25Bit(c.PS0AsDouble()); - const FPResult product = - NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); + const FPResult product = NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c_value, b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || product.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || product.HasNoInvalidExceptions()) { - const float tmp = ForceSingle(PowerPC::ppcState.fpscr, product.value); + const float tmp = ForceSingle(ppc_state.fpscr, product.value); const float result = std::isnan(tmp) ? tmp : -tmp; - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.UpdateFPRFSingle(result); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.UpdateFPRFSingle(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fsubx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const FPResult difference = NI_sub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); + const FPResult difference = NI_sub(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || difference.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || difference.HasNoInvalidExceptions()) { - const double result = ForceDouble(PowerPC::ppcState.fpscr, difference.value); - PowerPC::ppcState.ps[inst.FD].SetPS0(result); - PowerPC::ppcState.UpdateFPRFDouble(result); + const double result = ForceDouble(ppc_state.fpscr, difference.value); + ppc_state.ps[inst.FD].SetPS0(result); + ppc_state.UpdateFPRFDouble(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::fsubsx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const FPResult difference = NI_sub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); + const FPResult difference = NI_sub(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()); - if (PowerPC::ppcState.fpscr.VE == 0 || difference.HasNoInvalidExceptions()) + if (ppc_state.fpscr.VE == 0 || difference.HasNoInvalidExceptions()) { - const float result = ForceSingle(PowerPC::ppcState.fpscr, difference.value); - PowerPC::ppcState.ps[inst.FD].Fill(result); - PowerPC::ppcState.UpdateFPRFSingle(result); + const float result = ForceSingle(ppc_state.fpscr, difference.value); + ppc_state.ps[inst.FD].Fill(result); + ppc_state.UpdateFPRFSingle(result); } if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index aa9048cc29..73941474c4 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -469,7 +469,7 @@ void Interpreter::ps_cmpu0(Interpreter& interpreter, UGeckoInstruction inst) const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; - Helper_FloatCompareUnordered(inst, a.PS0AsDouble(), b.PS0AsDouble()); + Helper_FloatCompareUnordered(PowerPC::ppcState, inst, a.PS0AsDouble(), b.PS0AsDouble()); } void Interpreter::ps_cmpo0(Interpreter& interpreter, UGeckoInstruction inst) @@ -477,7 +477,7 @@ void Interpreter::ps_cmpo0(Interpreter& interpreter, UGeckoInstruction inst) const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; - Helper_FloatCompareOrdered(inst, a.PS0AsDouble(), b.PS0AsDouble()); + Helper_FloatCompareOrdered(PowerPC::ppcState, inst, a.PS0AsDouble(), b.PS0AsDouble()); } void Interpreter::ps_cmpu1(Interpreter& interpreter, UGeckoInstruction inst) @@ -485,7 +485,7 @@ void Interpreter::ps_cmpu1(Interpreter& interpreter, UGeckoInstruction inst) const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; - Helper_FloatCompareUnordered(inst, a.PS1AsDouble(), b.PS1AsDouble()); + Helper_FloatCompareUnordered(PowerPC::ppcState, inst, a.PS1AsDouble(), b.PS1AsDouble()); } void Interpreter::ps_cmpo1(Interpreter& interpreter, UGeckoInstruction inst) @@ -493,5 +493,5 @@ void Interpreter::ps_cmpo1(Interpreter& interpreter, UGeckoInstruction inst) const auto& a = PowerPC::ppcState.ps[inst.FA]; const auto& b = PowerPC::ppcState.ps[inst.FB]; - Helper_FloatCompareOrdered(inst, a.PS1AsDouble(), b.PS1AsDouble()); + Helper_FloatCompareOrdered(PowerPC::ppcState, inst, a.PS1AsDouble(), b.PS1AsDouble()); } From 8b133498867776053ade901d394e89d67659b790 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 01:20:54 +0100 Subject: [PATCH 06/10] Interpreter: Avoid ppcState global (Interpreter_Integer.cpp). --- .../Core/PowerPC/Interpreter/Interpreter.h | 4 +- .../Interpreter/Interpreter_Integer.cpp | 416 ++++++++++-------- 2 files changed, 233 insertions(+), 187 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h index 98c245b3ca..686557461f 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h @@ -296,10 +296,10 @@ private: bool HandleFunctionHooking(u32 address); // flag helper - static void Helper_UpdateCR0(u32 value); + static void Helper_UpdateCR0(PowerPC::PowerPCState& ppc_state, u32 value); template - static void Helper_IntCompare(UGeckoInstruction inst, T a, T b); + static void Helper_IntCompare(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, T a, T b); static void Helper_FloatCompareOrdered(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, double a, double b); static void Helper_FloatCompareUnordered(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index b5bc42d234..006110a4e2 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -11,14 +11,14 @@ #include "Core/PowerPC/Interpreter/ExceptionUtils.h" #include "Core/PowerPC/PowerPC.h" -void Interpreter::Helper_UpdateCR0(u32 value) +void Interpreter::Helper_UpdateCR0(PowerPC::PowerPCState& ppc_state, u32 value) { const s64 sign_extended = s64{s32(value)}; u64 cr_val = u64(sign_extended); cr_val = (cr_val & ~(1ULL << PowerPC::CR_EMU_SO_BIT)) | - (u64{PowerPC::ppcState.GetXER_SO()} << PowerPC::CR_EMU_SO_BIT); + (u64{ppc_state.GetXER_SO()} << PowerPC::CR_EMU_SO_BIT); - PowerPC::ppcState.cr.fields[0] = cr_val; + ppc_state.cr.fields[0] = cr_val; } u32 Interpreter::Helper_Carry(u32 value1, u32 value2) @@ -28,49 +28,56 @@ u32 Interpreter::Helper_Carry(u32 value1, u32 value2) void Interpreter::addi(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; if (inst.RA) - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_16); + ppc_state.gpr[inst.RD] = ppc_state.gpr[inst.RA] + u32(inst.SIMM_16); else - PowerPC::ppcState.gpr[inst.RD] = u32(inst.SIMM_16); + ppc_state.gpr[inst.RD] = u32(inst.SIMM_16); } void Interpreter::addic(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; const u32 imm = u32(s32{inst.SIMM_16}); - PowerPC::ppcState.gpr[inst.RD] = a + imm; - PowerPC::ppcState.SetCarry(Helper_Carry(a, imm)); + ppc_state.gpr[inst.RD] = a + imm; + ppc_state.SetCarry(Helper_Carry(a, imm)); } void Interpreter::addic_rc(Interpreter& interpreter, UGeckoInstruction inst) { addic(interpreter, inst); - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + auto& ppc_state = interpreter.m_ppc_state; + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::addis(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; if (inst.RA) - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_16 << 16); + ppc_state.gpr[inst.RD] = ppc_state.gpr[inst.RA] + u32(inst.SIMM_16 << 16); else - PowerPC::ppcState.gpr[inst.RD] = u32(inst.SIMM_16 << 16); + ppc_state.gpr[inst.RD] = u32(inst.SIMM_16 << 16); } void Interpreter::andi_rc(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & inst.UIMM; - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] & inst.UIMM; + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::andis_rc(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & (u32{inst.UIMM} << 16); - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] & (u32{inst.UIMM} << 16); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } template -void Interpreter::Helper_IntCompare(UGeckoInstruction inst, T a, T b) +void Interpreter::Helper_IntCompare(PowerPC::PowerPCState& ppc_state, UGeckoInstruction inst, T a, + T b) { u32 cr_field; @@ -81,52 +88,59 @@ void Interpreter::Helper_IntCompare(UGeckoInstruction inst, T a, T b) else cr_field = PowerPC::CR_EQ; - if (PowerPC::ppcState.GetXER_SO()) + if (ppc_state.GetXER_SO()) cr_field |= PowerPC::CR_SO; - PowerPC::ppcState.cr.SetField(inst.CRFD, cr_field); + ppc_state.cr.SetField(inst.CRFD, cr_field); } void Interpreter::cmpi(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); + auto& ppc_state = interpreter.m_ppc_state; + const s32 a = static_cast(ppc_state.gpr[inst.RA]); const s32 b = inst.SIMM_16; - Helper_IntCompare(inst, a, b); + Helper_IntCompare(ppc_state, inst, a, b); } void Interpreter::cmpli(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; const u32 b = inst.UIMM; - Helper_IntCompare(inst, a, b); + Helper_IntCompare(ppc_state, inst, a, b); } void Interpreter::mulli(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RD] = u32(s32(PowerPC::ppcState.gpr[inst.RA]) * inst.SIMM_16); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RD] = u32(s32(ppc_state.gpr[inst.RA]) * inst.SIMM_16); } void Interpreter::ori(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | inst.UIMM; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] | inst.UIMM; } void Interpreter::oris(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | (u32{inst.UIMM} << 16); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] | (u32{inst.UIMM} << 16); } void Interpreter::subfic(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const s32 immediate = inst.SIMM_16; - PowerPC::ppcState.gpr[inst.RD] = u32(immediate - s32(PowerPC::ppcState.gpr[inst.RA])); - PowerPC::ppcState.SetCarry((PowerPC::ppcState.gpr[inst.RA] == 0) || - (Helper_Carry(0 - PowerPC::ppcState.gpr[inst.RA], u32(immediate)))); + ppc_state.gpr[inst.RD] = u32(immediate - s32(ppc_state.gpr[inst.RA])); + ppc_state.SetCarry((ppc_state.gpr[inst.RA] == 0) || + (Helper_Carry(0 - ppc_state.gpr[inst.RA], u32(immediate)))); } void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 a = s32(PowerPC::ppcState.gpr[inst.RA]); + auto& ppc_state = interpreter.m_ppc_state; + const s32 a = s32(ppc_state.gpr[inst.RA]); const s32 b = inst.SIMM_16; const u32 TO = inst.TO; @@ -143,207 +157,222 @@ void Interpreter::twi(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::xori(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ inst.UIMM; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] ^ inst.UIMM; } void Interpreter::xoris(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ (u32{inst.UIMM} << 16); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] ^ (u32{inst.UIMM} << 16); } void Interpreter::rlwimix(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); - PowerPC::ppcState.gpr[inst.RA] = (PowerPC::ppcState.gpr[inst.RA] & ~mask) | - (std::rotl(PowerPC::ppcState.gpr[inst.RS], inst.SH) & mask); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = + (ppc_state.gpr[inst.RA] & ~mask) | (std::rotl(ppc_state.gpr[inst.RS], inst.SH) & mask); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::rlwinmx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); - PowerPC::ppcState.gpr[inst.RA] = std::rotl(PowerPC::ppcState.gpr[inst.RS], inst.SH) & mask; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = std::rotl(ppc_state.gpr[inst.RS], inst.SH) & mask; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::rlwnmx(Interpreter& interpreter, UGeckoInstruction inst) { const u32 mask = MakeRotationMask(inst.MB, inst.ME); - PowerPC::ppcState.gpr[inst.RA] = - std::rotl(PowerPC::ppcState.gpr[inst.RS], PowerPC::ppcState.gpr[inst.RB] & 0x1F) & mask; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = std::rotl(ppc_state.gpr[inst.RS], ppc_state.gpr[inst.RB] & 0x1F) & mask; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::andx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] & ppc_state.gpr[inst.RB]; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::andcx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] & ~PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] & ~ppc_state.gpr[inst.RB]; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::cmp(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); - const s32 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); - Helper_IntCompare(inst, a, b); + auto& ppc_state = interpreter.m_ppc_state; + const s32 a = static_cast(ppc_state.gpr[inst.RA]); + const s32 b = static_cast(ppc_state.gpr[inst.RB]); + Helper_IntCompare(ppc_state, inst, a, b); } void Interpreter::cmpl(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; - Helper_IntCompare(inst, a, b); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; + Helper_IntCompare(ppc_state, inst, a, b); } void Interpreter::cntlzwx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = u32(std::countl_zero(PowerPC::ppcState.gpr[inst.RS])); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = u32(std::countl_zero(ppc_state.gpr[inst.RS])); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::eqvx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = - ~(PowerPC::ppcState.gpr[inst.RS] ^ PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ~(ppc_state.gpr[inst.RS] ^ ppc_state.gpr[inst.RB]); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::extsbx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = u32(s32(s8(PowerPC::ppcState.gpr[inst.RS]))); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = u32(s32(s8(ppc_state.gpr[inst.RS]))); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::extshx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = u32(s32(s16(PowerPC::ppcState.gpr[inst.RS]))); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = u32(s32(s16(ppc_state.gpr[inst.RS]))); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::nandx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = - ~(PowerPC::ppcState.gpr[inst.RS] & PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ~(ppc_state.gpr[inst.RS] & ppc_state.gpr[inst.RB]); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::norx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = - ~(PowerPC::ppcState.gpr[inst.RS] | PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ~(ppc_state.gpr[inst.RS] | ppc_state.gpr[inst.RB]); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::orx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] | PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] | ppc_state.gpr[inst.RB]; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::orcx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = - PowerPC::ppcState.gpr[inst.RS] | (~PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] | (~ppc_state.gpr[inst.RB]); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::slwx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 amount = PowerPC::ppcState.gpr[inst.RB]; - PowerPC::ppcState.gpr[inst.RA] = - (amount & 0x20) != 0 ? 0 : PowerPC::ppcState.gpr[inst.RS] << (amount & 0x1f); + auto& ppc_state = interpreter.m_ppc_state; + const u32 amount = ppc_state.gpr[inst.RB]; + ppc_state.gpr[inst.RA] = (amount & 0x20) != 0 ? 0 : ppc_state.gpr[inst.RS] << (amount & 0x1f); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::srawx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 rb = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 rb = ppc_state.gpr[inst.RB]; if ((rb & 0x20) != 0) { - if ((PowerPC::ppcState.gpr[inst.RS] & 0x80000000) != 0) + if ((ppc_state.gpr[inst.RS] & 0x80000000) != 0) { - PowerPC::ppcState.gpr[inst.RA] = 0xFFFFFFFF; - PowerPC::ppcState.SetCarry(1); + ppc_state.gpr[inst.RA] = 0xFFFFFFFF; + ppc_state.SetCarry(1); } else { - PowerPC::ppcState.gpr[inst.RA] = 0x00000000; - PowerPC::ppcState.SetCarry(0); + ppc_state.gpr[inst.RA] = 0x00000000; + ppc_state.SetCarry(0); } } else { const u32 amount = rb & 0x1f; - const s32 rrs = s32(PowerPC::ppcState.gpr[inst.RS]); - PowerPC::ppcState.gpr[inst.RA] = u32(rrs >> amount); + const s32 rrs = s32(ppc_state.gpr[inst.RS]); + ppc_state.gpr[inst.RA] = u32(rrs >> amount); - PowerPC::ppcState.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0); + ppc_state.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0); } if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::srawix(Interpreter& interpreter, UGeckoInstruction inst) { const u32 amount = inst.SH; - const s32 rrs = s32(PowerPC::ppcState.gpr[inst.RS]); + auto& ppc_state = interpreter.m_ppc_state; + const s32 rrs = s32(ppc_state.gpr[inst.RS]); - PowerPC::ppcState.gpr[inst.RA] = u32(rrs >> amount); - PowerPC::ppcState.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0); + ppc_state.gpr[inst.RA] = u32(rrs >> amount); + ppc_state.SetCarry(rrs < 0 && amount > 0 && (u32(rrs) << (32 - amount)) != 0); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::srwx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 amount = PowerPC::ppcState.gpr[inst.RB]; - PowerPC::ppcState.gpr[inst.RA] = - (amount & 0x20) != 0 ? 0 : (PowerPC::ppcState.gpr[inst.RS] >> (amount & 0x1f)); + auto& ppc_state = interpreter.m_ppc_state; + const u32 amount = ppc_state.gpr[inst.RB]; + ppc_state.gpr[inst.RA] = (amount & 0x20) != 0 ? 0 : (ppc_state.gpr[inst.RS] >> (amount & 0x1f)); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } void Interpreter::tw(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 a = s32(PowerPC::ppcState.gpr[inst.RA]); - const s32 b = s32(PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + const s32 a = s32(ppc_state.gpr[inst.RA]); + const s32 b = s32(ppc_state.gpr[inst.RB]); const u32 TO = inst.TO; DEBUG_LOG_FMT(POWERPC, "tw rA {:x} rB {:x} TO {:x}", a, b, TO); @@ -359,10 +388,11 @@ void Interpreter::tw(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::xorx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RA] = PowerPC::ppcState.gpr[inst.RS] ^ PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RA] = ppc_state.gpr[inst.RS] ^ ppc_state.gpr[inst.RB]; if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RA]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RA]); } static bool HasAddOverflowed(u32 x, u32 y, u32 result) @@ -374,263 +404,279 @@ static bool HasAddOverflowed(u32 x, u32 y, u32 result) void Interpreter::addx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b; - PowerPC::ppcState.gpr[inst.RD] = result; + ppc_state.gpr[inst.RD] = result; if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::addcx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, b)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, b)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::addex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 carry = PowerPC::ppcState.GetCarry(); - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 carry = ppc_state.GetCarry(); + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry))); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry))); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::addmex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 carry = PowerPC::ppcState.GetCarry(); - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 carry = ppc_state.GetCarry(); + const u32 a = ppc_state.gpr[inst.RA]; const u32 b = 0xFFFFFFFF; const u32 result = a + b + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, carry - 1)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, carry - 1)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::addzex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 carry = PowerPC::ppcState.GetCarry(); - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 carry = ppc_state.GetCarry(); + const u32 a = ppc_state.gpr[inst.RA]; const u32 result = a + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, carry)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, carry)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, 0, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, 0, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::divwx(Interpreter& interpreter, UGeckoInstruction inst) { - const auto a = s32(PowerPC::ppcState.gpr[inst.RA]); - const auto b = s32(PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + const auto a = s32(ppc_state.gpr[inst.RA]); + const auto b = s32(ppc_state.gpr[inst.RB]); const bool overflow = b == 0 || (static_cast(a) == 0x80000000 && b == -1); if (overflow) { if (a < 0) - PowerPC::ppcState.gpr[inst.RD] = UINT32_MAX; + ppc_state.gpr[inst.RD] = UINT32_MAX; else - PowerPC::ppcState.gpr[inst.RD] = 0; + ppc_state.gpr[inst.RD] = 0; } else { - PowerPC::ppcState.gpr[inst.RD] = static_cast(a / b); + ppc_state.gpr[inst.RD] = static_cast(a / b); } if (inst.OE) - PowerPC::ppcState.SetXER_OV(overflow); + ppc_state.SetXER_OV(overflow); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::divwux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const bool overflow = b == 0; if (overflow) { - PowerPC::ppcState.gpr[inst.RD] = 0; + ppc_state.gpr[inst.RD] = 0; } else { - PowerPC::ppcState.gpr[inst.RD] = a / b; + ppc_state.gpr[inst.RD] = a / b; } if (inst.OE) - PowerPC::ppcState.SetXER_OV(overflow); + ppc_state.SetXER_OV(overflow); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::mulhwx(Interpreter& interpreter, UGeckoInstruction inst) { - const s64 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); - const s64 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + const s64 a = static_cast(ppc_state.gpr[inst.RA]); + const s64 b = static_cast(ppc_state.gpr[inst.RB]); const u32 d = static_cast((a * b) >> 32); - PowerPC::ppcState.gpr[inst.RD] = d; + ppc_state.gpr[inst.RD] = d; if (inst.Rc) - Helper_UpdateCR0(d); + Helper_UpdateCR0(ppc_state, d); } void Interpreter::mulhwux(Interpreter& interpreter, UGeckoInstruction inst) { - const u64 a = PowerPC::ppcState.gpr[inst.RA]; - const u64 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u64 a = ppc_state.gpr[inst.RA]; + const u64 b = ppc_state.gpr[inst.RB]; const u32 d = static_cast((a * b) >> 32); - PowerPC::ppcState.gpr[inst.RD] = d; + ppc_state.gpr[inst.RD] = d; if (inst.Rc) - Helper_UpdateCR0(d); + Helper_UpdateCR0(ppc_state, d); } void Interpreter::mullwx(Interpreter& interpreter, UGeckoInstruction inst) { - const s64 a = static_cast(PowerPC::ppcState.gpr[inst.RA]); - const s64 b = static_cast(PowerPC::ppcState.gpr[inst.RB]); + auto& ppc_state = interpreter.m_ppc_state; + const s64 a = static_cast(ppc_state.gpr[inst.RA]); + const s64 b = static_cast(ppc_state.gpr[inst.RB]); const s64 result = a * b; - PowerPC::ppcState.gpr[inst.RD] = static_cast(result); + ppc_state.gpr[inst.RD] = static_cast(result); if (inst.OE) - PowerPC::ppcState.SetXER_OV(result < -0x80000000LL || result > 0x7FFFFFFFLL); + ppc_state.SetXER_OV(result < -0x80000000LL || result > 0x7FFFFFFFLL); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::negx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.gpr[inst.RA]; - PowerPC::ppcState.gpr[inst.RD] = (~a) + 1; + ppc_state.gpr[inst.RD] = (~a) + 1; if (inst.OE) - PowerPC::ppcState.SetXER_OV(a == 0x80000000); + ppc_state.SetXER_OV(a == 0x80000000); if (inst.Rc) - Helper_UpdateCR0(PowerPC::ppcState.gpr[inst.RD]); + Helper_UpdateCR0(ppc_state, ppc_state.gpr[inst.RD]); } void Interpreter::subfx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b + 1; - PowerPC::ppcState.gpr[inst.RD] = result; + ppc_state.gpr[inst.RD] = result; if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::subfcx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; const u32 result = a + b + 1; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(a == 0xFFFFFFFF || Helper_Carry(b, a + 1)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(a == 0xFFFFFFFF || Helper_Carry(b, a + 1)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } void Interpreter::subfex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; - const u32 b = PowerPC::ppcState.gpr[inst.RB]; - const u32 carry = PowerPC::ppcState.GetCarry(); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; + const u32 b = ppc_state.gpr[inst.RB]; + const u32 carry = ppc_state.GetCarry(); const u32 result = a + b + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, b) || Helper_Carry(a + b, carry)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, b) || Helper_Carry(a + b, carry)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } // sub from minus one void Interpreter::subfmex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; const u32 b = 0xFFFFFFFF; - const u32 carry = PowerPC::ppcState.GetCarry(); + const u32 carry = ppc_state.GetCarry(); const u32 result = a + b + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, carry - 1)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, carry - 1)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, b, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, b, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } // sub from zero void Interpreter::subfzex(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = ~PowerPC::ppcState.gpr[inst.RA]; - const u32 carry = PowerPC::ppcState.GetCarry(); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ~ppc_state.gpr[inst.RA]; + const u32 carry = ppc_state.GetCarry(); const u32 result = a + carry; - PowerPC::ppcState.gpr[inst.RD] = result; - PowerPC::ppcState.SetCarry(Helper_Carry(a, carry)); + ppc_state.gpr[inst.RD] = result; + ppc_state.SetCarry(Helper_Carry(a, carry)); if (inst.OE) - PowerPC::ppcState.SetXER_OV(HasAddOverflowed(a, 0, result)); + ppc_state.SetXER_OV(HasAddOverflowed(a, 0, result)); if (inst.Rc) - Helper_UpdateCR0(result); + Helper_UpdateCR0(ppc_state, result); } From 9af8410e4c01fb2c5e6930c3728b2267122bedb6 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 01:33:45 +0100 Subject: [PATCH 07/10] Interpreter: Avoid ppcState global (Interpreter_LoadStore.cpp). --- .../Interpreter/Interpreter_LoadStore.cpp | 495 ++++++++++-------- 1 file changed, 281 insertions(+), 214 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index b81f8908ad..1decfd5f8e 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -39,27 +39,30 @@ static u32 Helper_Get_EA_UX(const PowerPC::PowerPCState& ppcs, const UGeckoInstr void Interpreter::lbz(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 temp = PowerPC::Read_U8(Helper_Get_EA(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + const u32 temp = PowerPC::Read_U8(Helper_Get_EA(ppc_state, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) - PowerPC::ppcState.gpr[inst.RD] = temp; + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) + ppc_state.gpr[inst.RD] = temp; } void Interpreter::lbzu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); const u32 temp = PowerPC::Read_U8(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lfd(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA(ppc_state, inst); if ((address & 0b11) != 0) { @@ -69,13 +72,14 @@ void Interpreter::lfd(Interpreter& interpreter, UGeckoInstruction inst) const u64 temp = PowerPC::Read_U64(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) - PowerPC::ppcState.ps[inst.FD].SetPS0(temp); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) + ppc_state.ps[inst.FD].SetPS0(temp); } void Interpreter::lfdu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); if ((address & 0b11) != 0) { @@ -85,16 +89,17 @@ void Interpreter::lfdu(Interpreter& interpreter, UGeckoInstruction inst) const u64 temp = PowerPC::Read_U64(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.ps[inst.FD].SetPS0(temp); - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.ps[inst.FD].SetPS0(temp); + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lfdux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); if ((address & 0b11) != 0) { @@ -104,16 +109,17 @@ void Interpreter::lfdux(Interpreter& interpreter, UGeckoInstruction inst) const u64 temp = PowerPC::Read_U64(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.ps[inst.FD].SetPS0(temp); - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.ps[inst.FD].SetPS0(temp); + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lfdx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); if ((address & 0b11) != 0) { @@ -123,13 +129,14 @@ void Interpreter::lfdx(Interpreter& interpreter, UGeckoInstruction inst) const u64 temp = PowerPC::Read_U64(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) - PowerPC::ppcState.ps[inst.FD].SetPS0(temp); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) + ppc_state.ps[inst.FD].SetPS0(temp); } void Interpreter::lfs(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA(ppc_state, inst); if ((address & 0b11) != 0) { @@ -139,16 +146,17 @@ void Interpreter::lfs(Interpreter& interpreter, UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { const u64 value = ConvertToDouble(temp); - PowerPC::ppcState.ps[inst.FD].Fill(value); + ppc_state.ps[inst.FD].Fill(value); } } void Interpreter::lfsu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); if ((address & 0b11) != 0) { @@ -158,17 +166,18 @@ void Interpreter::lfsu(Interpreter& interpreter, UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { const u64 value = ConvertToDouble(temp); - PowerPC::ppcState.ps[inst.FD].Fill(value); - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.ps[inst.FD].Fill(value); + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lfsux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); if ((address & 0b11) != 0) { @@ -178,17 +187,18 @@ void Interpreter::lfsux(Interpreter& interpreter, UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { const u64 value = ConvertToDouble(temp); - PowerPC::ppcState.ps[inst.FD].Fill(value); - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.ps[inst.FD].Fill(value); + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lfsx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); if ((address & 0b11) != 0) { @@ -198,63 +208,68 @@ void Interpreter::lfsx(Interpreter& interpreter, UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { const u64 value = ConvertToDouble(temp); - PowerPC::ppcState.ps[inst.FD].Fill(value); + ppc_state.ps[inst.FD].Fill(value); } } void Interpreter::lha(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 temp = u32(s32(s16(PowerPC::Read_U16(Helper_Get_EA(PowerPC::ppcState, inst))))); + auto& ppc_state = interpreter.m_ppc_state; + const u32 temp = u32(s32(s16(PowerPC::Read_U16(Helper_Get_EA(ppc_state, inst))))); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RD] = temp; } } void Interpreter::lhau(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); const u32 temp = u32(s32(s16(PowerPC::Read_U16(address)))); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lhz(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 temp = PowerPC::Read_U16(Helper_Get_EA(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + const u32 temp = PowerPC::Read_U16(Helper_Get_EA(ppc_state, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RD] = temp; } } void Interpreter::lhzu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); const u32 temp = PowerPC::Read_U16(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RA] = address; } } // FIXME: lmw should do a total rollback if a DSI occurs void Interpreter::lmw(Interpreter& interpreter, UGeckoInstruction inst) { - u32 address = Helper_Get_EA(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + u32 address = Helper_Get_EA(ppc_state, inst); - if ((address & 0b11) != 0 || PowerPC::ppcState.msr.LE) + if ((address & 0b11) != 0 || ppc_state.msr.LE) { GenerateAlignmentException(address); return; @@ -264,7 +279,7 @@ void Interpreter::lmw(Interpreter& interpreter, UGeckoInstruction inst) { const u32 temp_reg = PowerPC::Read_U32(address); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { PanicAlertFmt("DSI exception in lmw"); NOTICE_LOG_FMT(POWERPC, "DSI exception in lmw"); @@ -272,7 +287,7 @@ void Interpreter::lmw(Interpreter& interpreter, UGeckoInstruction inst) } else { - PowerPC::ppcState.gpr[i] = temp_reg; + ppc_state.gpr[i] = temp_reg; } } } @@ -280,9 +295,10 @@ void Interpreter::lmw(Interpreter& interpreter, UGeckoInstruction inst) // FIXME: stmw should do a total rollback if a DSI occurs void Interpreter::stmw(Interpreter& interpreter, UGeckoInstruction inst) { - u32 address = Helper_Get_EA(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + u32 address = Helper_Get_EA(ppc_state, inst); - if ((address & 0b11) != 0 || PowerPC::ppcState.msr.LE) + if ((address & 0b11) != 0 || ppc_state.msr.LE) { GenerateAlignmentException(address); return; @@ -290,8 +306,8 @@ void Interpreter::stmw(Interpreter& interpreter, UGeckoInstruction inst) for (u32 i = inst.RS; i <= 31; i++, address += 4) { - PowerPC::Write_U32(PowerPC::ppcState.gpr[i], address); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + PowerPC::Write_U32(ppc_state.gpr[i], address); + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { PanicAlertFmt("DSI exception in stmw"); NOTICE_LOG_FMT(POWERPC, "DSI exception in stmw"); @@ -302,46 +318,51 @@ void Interpreter::stmw(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::lwz(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA(ppc_state, inst); const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RD] = temp; } } void Interpreter::lwzu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::stb(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::Write_U8(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + PowerPC::Write_U8(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst)); } void Interpreter::stbu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); - PowerPC::Write_U8(PowerPC::ppcState.gpr[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U8(ppc_state.gpr[inst.RS], address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::stfd(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA(ppc_state, inst); if ((address & 0b11) != 0) { @@ -349,12 +370,13 @@ void Interpreter::stfd(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U64(PowerPC::ppcState.ps[inst.FS].PS0AsU64(), address); + PowerPC::Write_U64(ppc_state.ps[inst.FS].PS0AsU64(), address); } void Interpreter::stfdu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); if ((address & 0b11) != 0) { @@ -362,16 +384,17 @@ void Interpreter::stfdu(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U64(PowerPC::ppcState.ps[inst.FS].PS0AsU64(), address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U64(ppc_state.ps[inst.FS].PS0AsU64(), address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::stfs(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA(ppc_state, inst); if ((address & 0b11) != 0) { @@ -379,12 +402,13 @@ void Interpreter::stfs(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U32(ConvertToSingle(PowerPC::ppcState.ps[inst.FS].PS0AsU64()), address); + PowerPC::Write_U32(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address); } void Interpreter::stfsu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); if ((address & 0b11) != 0) { @@ -392,42 +416,46 @@ void Interpreter::stfsu(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U32(ConvertToSingle(PowerPC::ppcState.ps[inst.FS].PS0AsU64()), address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U32(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::sth(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::Write_U16(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + PowerPC::Write_U16(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst)); } void Interpreter::sthu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); - PowerPC::Write_U16(PowerPC::ppcState.gpr[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U16(ppc_state.gpr[inst.RS], address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::stw(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + PowerPC::Write_U32(ppc_state.gpr[inst.RS], Helper_Get_EA(ppc_state, inst)); } void Interpreter::stwu(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_U(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_U(ppc_state, inst); - PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U32(ppc_state.gpr[inst.RS], address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } @@ -438,8 +466,9 @@ void Interpreter::dcba(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::dcbf(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); - if (!PowerPC::ppcState.m_enable_dcache) + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); + if (!ppc_state.m_enable_dcache) { // Invalidate the JIT cache here as a heuristic to compensate for // the lack of precise L1 icache emulation in the JIT. (Portable software @@ -453,14 +482,15 @@ void Interpreter::dcbf(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::dcbi(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); - if (!PowerPC::ppcState.m_enable_dcache) + const u32 address = Helper_Get_EA_X(ppc_state, inst); + if (!ppc_state.m_enable_dcache) { // Invalidate the JIT cache here as a heuristic to compensate for // the lack of precise L1 icache emulation in the JIT. (Portable software @@ -474,8 +504,9 @@ void Interpreter::dcbi(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::dcbst(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); - if (!PowerPC::ppcState.m_enable_dcache) + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); + if (!ppc_state.m_enable_dcache) { // Invalidate the JIT cache here as a heuristic to compensate for // the lack of precise L1 icache emulation in the JIT. (Portable software @@ -501,15 +532,16 @@ void Interpreter::dcbtst(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::dcbz(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 dcbz_addr = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 dcbz_addr = Helper_Get_EA_X(ppc_state, inst); - if (!HID0(PowerPC::ppcState).DCE) + if (!HID0(ppc_state).DCE) { GenerateAlignmentException(dcbz_addr); return; } - if (!PowerPC::ppcState.m_enable_dcache) + if (!ppc_state.m_enable_dcache) { // Hack to stop dcbz/dcbi over low MEM1 trashing memory. This is not needed if data cache // emulation is enabled. @@ -525,15 +557,16 @@ void Interpreter::dcbz(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::dcbz_l(Interpreter& interpreter, UGeckoInstruction inst) { - if (!HID2(PowerPC::ppcState).LCE) + auto& ppc_state = interpreter.m_ppc_state; + if (!HID2(ppc_state).LCE) { GenerateProgramException(ProgramExceptionCause::IllegalInstruction); return; } - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + const u32 address = Helper_Get_EA_X(ppc_state, inst); - if (!HID0(PowerPC::ppcState).DCE) + if (!HID0(ppc_state).DCE) { GenerateAlignmentException(address); return; @@ -546,9 +579,10 @@ void Interpreter::dcbz_l(Interpreter& interpreter, UGeckoInstruction inst) // We just do it instantly from ppc...and hey, it works! :D void Interpreter::eciwx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 EA = Helper_Get_EA_X(ppc_state, inst); - if ((PowerPC::ppcState.spr[SPR_EAR] & 0x80000000) == 0) + if ((ppc_state.spr[SPR_EAR] & 0x80000000) == 0) { GenerateDSIException(EA); return; @@ -560,14 +594,15 @@ void Interpreter::eciwx(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::ppcState.gpr[inst.RD] = PowerPC::Read_U32(EA); + ppc_state.gpr[inst.RD] = PowerPC::Read_U32(EA); } void Interpreter::ecowx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 EA = Helper_Get_EA_X(ppc_state, inst); - if ((PowerPC::ppcState.spr[SPR_EAR] & 0x80000000) == 0) + if ((ppc_state.spr[SPR_EAR] & 0x80000000) == 0) { GenerateDSIException(EA); return; @@ -579,7 +614,7 @@ void Interpreter::ecowx(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], EA); + PowerPC::Write_U32(ppc_state.gpr[inst.RS], EA); } void Interpreter::eieio(Interpreter& interpreter, UGeckoInstruction inst) @@ -593,114 +628,123 @@ void Interpreter::eieio(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::icbi(Interpreter& interpreter, UGeckoInstruction inst) { // TODO: Raise DSI if translation fails (except for direct-store segments). - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); - PowerPC::ppcState.iCache.Invalidate(address); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); + ppc_state.iCache.Invalidate(address); } void Interpreter::lbzux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); const u32 temp = PowerPC::Read_U8(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lbzx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 temp = PowerPC::Read_U8(Helper_Get_EA_X(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + const u32 temp = PowerPC::Read_U8(Helper_Get_EA_X(ppc_state, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RD] = temp; } } void Interpreter::lhaux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); const s32 temp = s32{s16(PowerPC::Read_U16(address))}; - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = u32(temp); - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RD] = u32(temp); + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lhax(Interpreter& interpreter, UGeckoInstruction inst) { - const s32 temp = s32{s16(PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst)))}; + auto& ppc_state = interpreter.m_ppc_state; + const s32 temp = s32{s16(PowerPC::Read_U16(Helper_Get_EA_X(ppc_state, inst)))}; - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = u32(temp); + ppc_state.gpr[inst.RD] = u32(temp); } } void Interpreter::lhbrx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 temp = Common::swap16(PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst))); + auto& ppc_state = interpreter.m_ppc_state; + const u32 temp = Common::swap16(PowerPC::Read_U16(Helper_Get_EA_X(ppc_state, inst))); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RD] = temp; } } void Interpreter::lhzux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); const u32 temp = PowerPC::Read_U16(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lhzx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 temp = PowerPC::Read_U16(Helper_Get_EA_X(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + const u32 temp = PowerPC::Read_U16(Helper_Get_EA_X(ppc_state, inst)); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RD] = temp; } } // FIXME: Should rollback if a DSI occurs void Interpreter::lswx(Interpreter& interpreter, UGeckoInstruction inst) { - u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + u32 EA = Helper_Get_EA_X(ppc_state, inst); - if (PowerPC::ppcState.msr.LE) + if (ppc_state.msr.LE) { GenerateAlignmentException(EA); return; } // Confirmed by hardware test that the zero case doesn't zero gpr[r] - for (u32 n = 0; n < static_cast(PowerPC::ppcState.xer_stringctrl); n++) + for (u32 n = 0; n < static_cast(ppc_state.xer_stringctrl); n++) { const u32 reg = (inst.RD + (n >> 2)) & 0x1f; const u32 offset = (n & 3) << 3; if ((n & 0b11) == 0) - PowerPC::ppcState.gpr[reg] = 0; + ppc_state.gpr[reg] = 0; const u32 temp_value = PowerPC::Read_U8(EA) << (24 - offset); // Not64 (Homebrew N64 Emulator for Wii) triggers the following case. - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { NOTICE_LOG_FMT(POWERPC, "DSI exception in lswx"); return; } - PowerPC::ppcState.gpr[reg] |= temp_value; + ppc_state.gpr[reg] |= temp_value; EA++; } @@ -708,56 +752,62 @@ void Interpreter::lswx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::lwbrx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 temp = Common::swap32(PowerPC::Read_U32(Helper_Get_EA_X(PowerPC::ppcState, inst))); + auto& ppc_state = interpreter.m_ppc_state; + const u32 temp = Common::swap32(PowerPC::Read_U32(Helper_Get_EA_X(ppc_state, inst))); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RD] = temp; } } void Interpreter::lwzux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::lwzx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; + ppc_state.gpr[inst.RD] = temp; } } void Interpreter::stbux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); - PowerPC::Write_U8(PowerPC::ppcState.gpr[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U8(ppc_state.gpr[inst.RS], address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::stbx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::Write_U8(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA_X(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + PowerPC::Write_U8(ppc_state.gpr[inst.RS], Helper_Get_EA_X(ppc_state, inst)); } void Interpreter::stfdux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); if ((address & 0b11) != 0) { @@ -765,16 +815,17 @@ void Interpreter::stfdux(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U64(PowerPC::ppcState.ps[inst.FS].PS0AsU64(), address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U64(ppc_state.ps[inst.FS].PS0AsU64(), address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::stfdx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); if ((address & 0b11) != 0) { @@ -782,13 +833,14 @@ void Interpreter::stfdx(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U64(PowerPC::ppcState.ps[inst.FS].PS0AsU64(), address); + PowerPC::Write_U64(ppc_state.ps[inst.FS].PS0AsU64(), address); } // Stores Floating points into Integers indeXed void Interpreter::stfiwx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); if ((address & 0b11) != 0) { @@ -796,12 +848,13 @@ void Interpreter::stfiwx(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U32(PowerPC::ppcState.ps[inst.FS].PS0AsU32(), address); + PowerPC::Write_U32(ppc_state.ps[inst.FS].PS0AsU32(), address); } void Interpreter::stfsux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); if ((address & 0b11) != 0) { @@ -809,16 +862,17 @@ void Interpreter::stfsux(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U32(ConvertToSingle(PowerPC::ppcState.ps[inst.FS].PS0AsU64()), address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U32(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::stfsx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); if ((address & 0b11) != 0) { @@ -826,39 +880,43 @@ void Interpreter::stfsx(Interpreter& interpreter, UGeckoInstruction inst) return; } - PowerPC::Write_U32(ConvertToSingle(PowerPC::ppcState.ps[inst.FS].PS0AsU64()), address); + PowerPC::Write_U32(ConvertToSingle(ppc_state.ps[inst.FS].PS0AsU64()), address); } void Interpreter::sthbrx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::Write_U16_Swap(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA_X(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + PowerPC::Write_U16_Swap(ppc_state.gpr[inst.RS], Helper_Get_EA_X(ppc_state, inst)); } void Interpreter::sthux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); - PowerPC::Write_U16(PowerPC::ppcState.gpr[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U16(ppc_state.gpr[inst.RS], address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::sthx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::Write_U16(PowerPC::ppcState.gpr[inst.RS], Helper_Get_EA_X(PowerPC::ppcState, inst)); + auto& ppc_state = interpreter.m_ppc_state; + PowerPC::Write_U16(ppc_state.gpr[inst.RS], Helper_Get_EA_X(ppc_state, inst)); } // lswi - bizarro string instruction // FIXME: Should rollback if a DSI occurs void Interpreter::lswi(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; u32 EA = 0; if (inst.RA != 0) - EA = PowerPC::ppcState.gpr[inst.RA]; + EA = ppc_state.gpr[inst.RA]; - if (PowerPC::ppcState.msr.LE) + if (ppc_state.msr.LE) { GenerateAlignmentException(EA); return; @@ -876,17 +934,17 @@ void Interpreter::lswi(Interpreter& interpreter, UGeckoInstruction inst) { r++; r &= 31; - PowerPC::ppcState.gpr[r] = 0; + ppc_state.gpr[r] = 0; } const u32 temp_value = PowerPC::Read_U8(EA) << (24 - i); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { PanicAlertFmt("DSI exception in lsw."); return; } - PowerPC::ppcState.gpr[r] |= temp_value; + ppc_state.gpr[r] |= temp_value; i += 8; if (i == 32) @@ -901,11 +959,12 @@ void Interpreter::lswi(Interpreter& interpreter, UGeckoInstruction inst) // FIXME: Should rollback if a DSI occurs void Interpreter::stswi(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; u32 EA = 0; if (inst.RA != 0) - EA = PowerPC::ppcState.gpr[inst.RA]; + EA = ppc_state.gpr[inst.RA]; - if (PowerPC::ppcState.msr.LE) + if (ppc_state.msr.LE) { GenerateAlignmentException(EA); return; @@ -924,8 +983,8 @@ void Interpreter::stswi(Interpreter& interpreter, UGeckoInstruction inst) r++; r &= 31; } - PowerPC::Write_U8((PowerPC::ppcState.gpr[r] >> (24 - i)) & 0xFF, EA); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + PowerPC::Write_U8((ppc_state.gpr[r] >> (24 - i)) & 0xFF, EA); + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { return; } @@ -941,21 +1000,22 @@ void Interpreter::stswi(Interpreter& interpreter, UGeckoInstruction inst) // TODO: is this right? is it DSI interruptible? void Interpreter::stswx(Interpreter& interpreter, UGeckoInstruction inst) { - u32 EA = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + u32 EA = Helper_Get_EA_X(ppc_state, inst); - if (PowerPC::ppcState.msr.LE) + if (ppc_state.msr.LE) { GenerateAlignmentException(EA); return; } - u32 n = u8(PowerPC::ppcState.xer_stringctrl); + u32 n = u8(ppc_state.xer_stringctrl); u32 r = inst.RS; u32 i = 0; while (n > 0) { - PowerPC::Write_U8((PowerPC::ppcState.gpr[r] >> (24 - i)) & 0xFF, EA); + PowerPC::Write_U8((ppc_state.gpr[r] >> (24 - i)) & 0xFF, EA); EA++; n--; @@ -970,9 +1030,10 @@ void Interpreter::stswx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::stwbrx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); - PowerPC::Write_U32_Swap(PowerPC::ppcState.gpr[inst.RS], address); + PowerPC::Write_U32_Swap(ppc_state.gpr[inst.RS], address); } // The following two instructions are for SMP communications. On a single @@ -980,7 +1041,8 @@ void Interpreter::stwbrx(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::lwarx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); if ((address & 0b11) != 0) { @@ -990,18 +1052,19 @@ void Interpreter::lwarx(Interpreter& interpreter, UGeckoInstruction inst) const u32 temp = PowerPC::Read_U32(address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RD] = temp; - PowerPC::ppcState.reserve = true; - PowerPC::ppcState.reserve_address = address; + ppc_state.gpr[inst.RD] = temp; + ppc_state.reserve = true; + ppc_state.reserve_address = address; } } // Stores Word Conditional indeXed void Interpreter::stwcxd(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); if ((address & 0b11) != 0) { @@ -1009,39 +1072,41 @@ void Interpreter::stwcxd(Interpreter& interpreter, UGeckoInstruction inst) return; } - if (PowerPC::ppcState.reserve) + if (ppc_state.reserve) { - if (address == PowerPC::ppcState.reserve_address) + if (address == ppc_state.reserve_address) { - PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U32(ppc_state.gpr[inst.RS], address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.reserve = false; - PowerPC::ppcState.cr.SetField(0, 2 | PowerPC::ppcState.GetXER_SO()); + ppc_state.reserve = false; + ppc_state.cr.SetField(0, 2 | ppc_state.GetXER_SO()); return; } } } - PowerPC::ppcState.cr.SetField(0, PowerPC::ppcState.GetXER_SO()); + ppc_state.cr.SetField(0, ppc_state.GetXER_SO()); } void Interpreter::stwux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_UX(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_UX(ppc_state, inst); - PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], address); - if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) + PowerPC::Write_U32(ppc_state.gpr[inst.RS], address); + if (!(ppc_state.Exceptions & EXCEPTION_DSI)) { - PowerPC::ppcState.gpr[inst.RA] = address; + ppc_state.gpr[inst.RA] = address; } } void Interpreter::stwx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 address = Helper_Get_EA_X(PowerPC::ppcState, inst); + auto& ppc_state = interpreter.m_ppc_state; + const u32 address = Helper_Get_EA_X(ppc_state, inst); - PowerPC::Write_U32(PowerPC::ppcState.gpr[inst.RS], address); + PowerPC::Write_U32(ppc_state.gpr[inst.RS], address); } void Interpreter::sync(Interpreter& interpreter, UGeckoInstruction inst) @@ -1051,21 +1116,23 @@ void Interpreter::sync(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::tlbie(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } // Invalidate TLB entry - const u32 address = PowerPC::ppcState.gpr[inst.RB]; + const u32 address = ppc_state.gpr[inst.RB]; PowerPC::InvalidateTLBEntry(address); } void Interpreter::tlbsync(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); } From 514a7af4732fd656b0d19b0d9352a225db84e4fc Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 01:34:53 +0100 Subject: [PATCH 08/10] Interpreter: Avoid ppcState global (Interpreter_LoadStorePaired.cpp). --- .../Interpreter_LoadStorePaired.cpp | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp index 074746f27c..cd6ade87c6 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp @@ -310,102 +310,110 @@ static void Helper_Dequantize(PowerPC::PowerPCState* ppcs, u32 addr, u32 instI, void Interpreter::psq_l(Interpreter& interpreter, UGeckoInstruction inst) { - if (HID2(PowerPC::ppcState).LSQE == 0) + auto& ppc_state = interpreter.m_ppc_state; + if (HID2(ppc_state).LSQE == 0) { GenerateProgramException(ProgramExceptionCause::IllegalInstruction); return; } - const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12); - Helper_Dequantize(&PowerPC::ppcState, EA, inst.I, inst.RD, inst.W); + const u32 EA = inst.RA ? (ppc_state.gpr[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12); + Helper_Dequantize(&ppc_state, EA, inst.I, inst.RD, inst.W); } void Interpreter::psq_lu(Interpreter& interpreter, UGeckoInstruction inst) { - if (HID2(PowerPC::ppcState).LSQE == 0) + auto& ppc_state = interpreter.m_ppc_state; + if (HID2(ppc_state).LSQE == 0) { GenerateProgramException(ProgramExceptionCause::IllegalInstruction); return; } - const u32 EA = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_12); - Helper_Dequantize(&PowerPC::ppcState, EA, inst.I, inst.RD, inst.W); + const u32 EA = ppc_state.gpr[inst.RA] + u32(inst.SIMM_12); + Helper_Dequantize(&ppc_state, EA, inst.I, inst.RD, inst.W); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { return; } - PowerPC::ppcState.gpr[inst.RA] = EA; + ppc_state.gpr[inst.RA] = EA; } void Interpreter::psq_st(Interpreter& interpreter, UGeckoInstruction inst) { - if (HID2(PowerPC::ppcState).LSQE == 0) + auto& ppc_state = interpreter.m_ppc_state; + if (HID2(ppc_state).LSQE == 0) { GenerateProgramException(ProgramExceptionCause::IllegalInstruction); return; } - const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12); - Helper_Quantize(&PowerPC::ppcState, EA, inst.I, inst.RS, inst.W); + const u32 EA = inst.RA ? (ppc_state.gpr[inst.RA] + u32(inst.SIMM_12)) : u32(inst.SIMM_12); + Helper_Quantize(&ppc_state, EA, inst.I, inst.RS, inst.W); } void Interpreter::psq_stu(Interpreter& interpreter, UGeckoInstruction inst) { - if (HID2(PowerPC::ppcState).LSQE == 0) + auto& ppc_state = interpreter.m_ppc_state; + if (HID2(ppc_state).LSQE == 0) { GenerateProgramException(ProgramExceptionCause::IllegalInstruction); return; } - const u32 EA = PowerPC::ppcState.gpr[inst.RA] + u32(inst.SIMM_12); - Helper_Quantize(&PowerPC::ppcState, EA, inst.I, inst.RS, inst.W); + const u32 EA = ppc_state.gpr[inst.RA] + u32(inst.SIMM_12); + Helper_Quantize(&ppc_state, EA, inst.I, inst.RS, inst.W); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { return; } - PowerPC::ppcState.gpr[inst.RA] = EA; + ppc_state.gpr[inst.RA] = EA; } void Interpreter::psq_lx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]) : - PowerPC::ppcState.gpr[inst.RB]; - Helper_Dequantize(&PowerPC::ppcState, EA, inst.Ix, inst.RD, inst.Wx); + auto& ppc_state = interpreter.m_ppc_state; + const u32 EA = + inst.RA ? (ppc_state.gpr[inst.RA] + ppc_state.gpr[inst.RB]) : ppc_state.gpr[inst.RB]; + Helper_Dequantize(&ppc_state, EA, inst.Ix, inst.RD, inst.Wx); } void Interpreter::psq_stx(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 EA = inst.RA ? (PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]) : - PowerPC::ppcState.gpr[inst.RB]; - Helper_Quantize(&PowerPC::ppcState, EA, inst.Ix, inst.RS, inst.Wx); + auto& ppc_state = interpreter.m_ppc_state; + const u32 EA = + inst.RA ? (ppc_state.gpr[inst.RA] + ppc_state.gpr[inst.RB]) : ppc_state.gpr[inst.RB]; + Helper_Quantize(&ppc_state, EA, inst.Ix, inst.RS, inst.Wx); } void Interpreter::psq_lux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 EA = PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]; - Helper_Dequantize(&PowerPC::ppcState, EA, inst.Ix, inst.RD, inst.Wx); + auto& ppc_state = interpreter.m_ppc_state; + const u32 EA = ppc_state.gpr[inst.RA] + ppc_state.gpr[inst.RB]; + Helper_Dequantize(&ppc_state, EA, inst.Ix, inst.RD, inst.Wx); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { return; } - PowerPC::ppcState.gpr[inst.RA] = EA; + ppc_state.gpr[inst.RA] = EA; } void Interpreter::psq_stux(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 EA = PowerPC::ppcState.gpr[inst.RA] + PowerPC::ppcState.gpr[inst.RB]; - Helper_Quantize(&PowerPC::ppcState, EA, inst.Ix, inst.RS, inst.Wx); + auto& ppc_state = interpreter.m_ppc_state; + const u32 EA = ppc_state.gpr[inst.RA] + ppc_state.gpr[inst.RB]; + Helper_Quantize(&ppc_state, EA, inst.Ix, inst.RS, inst.Wx); - if ((PowerPC::ppcState.Exceptions & EXCEPTION_DSI) != 0) + if ((ppc_state.Exceptions & EXCEPTION_DSI) != 0) { return; } - PowerPC::ppcState.gpr[inst.RA] = EA; + ppc_state.gpr[inst.RA] = EA; } From c582aad0c75c0c143b3251b6c6056006eaedd102 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 01:36:50 +0100 Subject: [PATCH 09/10] Interpreter: Avoid ppcState global (Interpreter_Paired.cpp). --- .../Interpreter/Interpreter_Paired.cpp | 456 +++++++++--------- 1 file changed, 231 insertions(+), 225 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index 73941474c4..93c66f4aa1 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -13,485 +13,491 @@ // These "binary instructions" do not alter FPSCR. void Interpreter::ps_sel(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; - PowerPC::ppcState.ps[inst.FD].SetBoth(a.PS0AsDouble() >= -0.0 ? c.PS0AsDouble() : b.PS0AsDouble(), - a.PS1AsDouble() >= -0.0 ? c.PS1AsDouble() : - b.PS1AsDouble()); + ppc_state.ps[inst.FD].SetBoth(a.PS0AsDouble() >= -0.0 ? c.PS0AsDouble() : b.PS0AsDouble(), + a.PS1AsDouble() >= -0.0 ? c.PS1AsDouble() : b.PS1AsDouble()); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_neg(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& b = ppc_state.ps[inst.FB]; - PowerPC::ppcState.ps[inst.FD].SetBoth(b.PS0AsU64() ^ (UINT64_C(1) << 63), - b.PS1AsU64() ^ (UINT64_C(1) << 63)); + ppc_state.ps[inst.FD].SetBoth(b.PS0AsU64() ^ (UINT64_C(1) << 63), + b.PS1AsU64() ^ (UINT64_C(1) << 63)); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_mr(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.ps[inst.FD] = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.ps[inst.FD] = ppc_state.ps[inst.FB]; if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_nabs(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& b = ppc_state.ps[inst.FB]; - PowerPC::ppcState.ps[inst.FD].SetBoth(b.PS0AsU64() | (UINT64_C(1) << 63), - b.PS1AsU64() | (UINT64_C(1) << 63)); + ppc_state.ps[inst.FD].SetBoth(b.PS0AsU64() | (UINT64_C(1) << 63), + b.PS1AsU64() | (UINT64_C(1) << 63)); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_abs(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& b = ppc_state.ps[inst.FB]; - PowerPC::ppcState.ps[inst.FD].SetBoth(b.PS0AsU64() & ~(UINT64_C(1) << 63), - b.PS1AsU64() & ~(UINT64_C(1) << 63)); + ppc_state.ps[inst.FD].SetBoth(b.PS0AsU64() & ~(UINT64_C(1) << 63), + b.PS1AsU64() & ~(UINT64_C(1) << 63)); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } // These are just moves, double is OK. void Interpreter::ps_merge00(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - PowerPC::ppcState.ps[inst.FD].SetBoth(a.PS0AsDouble(), b.PS0AsDouble()); + ppc_state.ps[inst.FD].SetBoth(a.PS0AsDouble(), b.PS0AsDouble()); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_merge01(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - PowerPC::ppcState.ps[inst.FD].SetBoth(a.PS0AsDouble(), b.PS1AsDouble()); + ppc_state.ps[inst.FD].SetBoth(a.PS0AsDouble(), b.PS1AsDouble()); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_merge10(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - PowerPC::ppcState.ps[inst.FD].SetBoth(a.PS1AsDouble(), b.PS0AsDouble()); + ppc_state.ps[inst.FD].SetBoth(a.PS1AsDouble(), b.PS0AsDouble()); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_merge11(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - PowerPC::ppcState.ps[inst.FD].SetBoth(a.PS1AsDouble(), b.PS1AsDouble()); + ppc_state.ps[inst.FD].SetBoth(a.PS1AsDouble(), b.PS1AsDouble()); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } // From here on, the real deal. void Interpreter::ps_div(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const float ps0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_div(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); - const float ps1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_div(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); + const float ps0 = ForceSingle(ppc_state.fpscr, + NI_div(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); + const float ps1 = ForceSingle(ppc_state.fpscr, + NI_div(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_res(Interpreter& interpreter, UGeckoInstruction inst) { // this code is based on the real hardware tests - const double a = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); - const double b = PowerPC::ppcState.ps[inst.FB].PS1AsDouble(); + auto& ppc_state = interpreter.m_ppc_state; + const double a = ppc_state.ps[inst.FB].PS0AsDouble(); + const double b = ppc_state.ps[inst.FB].PS1AsDouble(); if (a == 0.0 || b == 0.0) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_ZX); - PowerPC::ppcState.fpscr.ClearFIFR(); + SetFPException(&ppc_state.fpscr, FPSCR_ZX); + ppc_state.fpscr.ClearFIFR(); } if (std::isnan(a) || std::isinf(a) || std::isnan(b) || std::isinf(b)) - PowerPC::ppcState.fpscr.ClearFIFR(); + ppc_state.fpscr.ClearFIFR(); if (Common::IsSNAN(a) || Common::IsSNAN(b)) - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN); + SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); const double ps0 = Common::ApproximateReciprocal(a); const double ps1 = Common::ApproximateReciprocal(b); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(float(ps0)); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(float(ps0)); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_rsqrte(Interpreter& interpreter, UGeckoInstruction inst) { - const double ps0 = PowerPC::ppcState.ps[inst.FB].PS0AsDouble(); - const double ps1 = PowerPC::ppcState.ps[inst.FB].PS1AsDouble(); + auto& ppc_state = interpreter.m_ppc_state; + const double ps0 = ppc_state.ps[inst.FB].PS0AsDouble(); + const double ps1 = ppc_state.ps[inst.FB].PS1AsDouble(); if (ps0 == 0.0 || ps1 == 0.0) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_ZX); - PowerPC::ppcState.fpscr.ClearFIFR(); + SetFPException(&ppc_state.fpscr, FPSCR_ZX); + ppc_state.fpscr.ClearFIFR(); } if (ps0 < 0.0 || ps1 < 0.0) { - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSQRT); - PowerPC::ppcState.fpscr.ClearFIFR(); + SetFPException(&ppc_state.fpscr, FPSCR_VXSQRT); + ppc_state.fpscr.ClearFIFR(); } if (std::isnan(ps0) || std::isinf(ps0) || std::isnan(ps1) || std::isinf(ps1)) - PowerPC::ppcState.fpscr.ClearFIFR(); + ppc_state.fpscr.ClearFIFR(); if (Common::IsSNAN(ps0) || Common::IsSNAN(ps1)) - SetFPException(&PowerPC::ppcState.fpscr, FPSCR_VXSNAN); + SetFPException(&ppc_state.fpscr, FPSCR_VXSNAN); - const float dst_ps0 = - ForceSingle(PowerPC::ppcState.fpscr, Common::ApproximateReciprocalSquareRoot(ps0)); - const float dst_ps1 = - ForceSingle(PowerPC::ppcState.fpscr, Common::ApproximateReciprocalSquareRoot(ps1)); + const float dst_ps0 = ForceSingle(ppc_state.fpscr, Common::ApproximateReciprocalSquareRoot(ps0)); + const float dst_ps1 = ForceSingle(ppc_state.fpscr, Common::ApproximateReciprocalSquareRoot(ps1)); - PowerPC::ppcState.ps[inst.FD].SetBoth(dst_ps0, dst_ps1); - PowerPC::ppcState.UpdateFPRFSingle(dst_ps0); + ppc_state.ps[inst.FD].SetBoth(dst_ps0, dst_ps1); + ppc_state.UpdateFPRFSingle(dst_ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_sub(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const float ps0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_sub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); - const float ps1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_sub(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); + const float ps0 = ForceSingle(ppc_state.fpscr, + NI_sub(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); + const float ps1 = ForceSingle(ppc_state.fpscr, + NI_sub(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_add(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - const float ps0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); - const float ps1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_add(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); + const float ps0 = ForceSingle(ppc_state.fpscr, + NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS0AsDouble()).value); + const float ps1 = ForceSingle(ppc_state.fpscr, + NI_add(&ppc_state.fpscr, a.PS1AsDouble(), b.PS1AsDouble()).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_mul(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& c = ppc_state.ps[inst.FC]; const double c0 = Force25Bit(c.PS0AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble()); - const float ps0 = ForceSingle(PowerPC::ppcState.fpscr, - NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0).value); - const float ps1 = ForceSingle(PowerPC::ppcState.fpscr, - NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1).value); + const float ps0 = + ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c0).value); + const float ps1 = + ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c1).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_msub(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c0 = Force25Bit(c.PS0AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble()); - const float ps0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); - const float ps1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_msub(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); + const float ps0 = ForceSingle( + ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); + const float ps1 = ForceSingle( + ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_madd(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c0 = Force25Bit(c.PS0AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble()); - const float ps0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); - const float ps1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); + const float ps0 = ForceSingle( + ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); + const float ps1 = ForceSingle( + ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_nmsub(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c0 = Force25Bit(c.PS0AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble()); - const float tmp0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_msub(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); - const float tmp1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_msub(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); + const float tmp0 = ForceSingle( + ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); + const float tmp1 = ForceSingle( + ppc_state.fpscr, NI_msub(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); const float ps0 = std::isnan(tmp0) ? tmp0 : -tmp0; const float ps1 = std::isnan(tmp1) ? tmp1 : -tmp1; - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_nmadd(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c0 = Force25Bit(c.PS0AsDouble()); const double c1 = Force25Bit(c.PS1AsDouble()); - const float tmp0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); - const float tmp1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); + const float tmp0 = ForceSingle( + ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); + const float tmp1 = ForceSingle( + ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); const float ps0 = std::isnan(tmp0) ? tmp0 : -tmp0; const float ps1 = std::isnan(tmp1) ? tmp1 : -tmp1; - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_sum0(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; - const float ps0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value); - const float ps1 = ForceSingle(PowerPC::ppcState.fpscr, c.PS1AsDouble()); + const float ps0 = ForceSingle(ppc_state.fpscr, + NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value); + const float ps1 = ForceSingle(ppc_state.fpscr, c.PS1AsDouble()); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_sum1(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; - const float ps0 = ForceSingle(PowerPC::ppcState.fpscr, c.PS0AsDouble()); - const float ps1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_add(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value); + const float ps0 = ForceSingle(ppc_state.fpscr, c.PS0AsDouble()); + const float ps1 = ForceSingle(ppc_state.fpscr, + NI_add(&ppc_state.fpscr, a.PS0AsDouble(), b.PS1AsDouble()).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps1); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps1); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_muls0(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& c = ppc_state.ps[inst.FC]; const double c0 = Force25Bit(c.PS0AsDouble()); - const float ps0 = ForceSingle(PowerPC::ppcState.fpscr, - NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0).value); - const float ps1 = ForceSingle(PowerPC::ppcState.fpscr, - NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c0).value); + const float ps0 = + ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c0).value); + const float ps1 = + ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c0).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_muls1(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& c = ppc_state.ps[inst.FC]; const double c1 = Force25Bit(c.PS1AsDouble()); - const float ps0 = ForceSingle(PowerPC::ppcState.fpscr, - NI_mul(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c1).value); - const float ps1 = ForceSingle(PowerPC::ppcState.fpscr, - NI_mul(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1).value); + const float ps0 = + ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS0AsDouble(), c1).value); + const float ps1 = + ForceSingle(ppc_state.fpscr, NI_mul(&ppc_state.fpscr, a.PS1AsDouble(), c1).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_madds0(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c0 = Force25Bit(c.PS0AsDouble()); - const float ps0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); - const float ps1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c0, b.PS1AsDouble()).value); + const float ps0 = ForceSingle( + ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c0, b.PS0AsDouble()).value); + const float ps1 = ForceSingle( + ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c0, b.PS1AsDouble()).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_madds1(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; - const auto& c = PowerPC::ppcState.ps[inst.FC]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; + const auto& c = ppc_state.ps[inst.FC]; const double c1 = Force25Bit(c.PS1AsDouble()); - const float ps0 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_madd(&PowerPC::ppcState.fpscr, a.PS0AsDouble(), c1, b.PS0AsDouble()).value); - const float ps1 = - ForceSingle(PowerPC::ppcState.fpscr, - NI_madd(&PowerPC::ppcState.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); + const float ps0 = ForceSingle( + ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS0AsDouble(), c1, b.PS0AsDouble()).value); + const float ps1 = ForceSingle( + ppc_state.fpscr, NI_madd(&ppc_state.fpscr, a.PS1AsDouble(), c1, b.PS1AsDouble()).value); - PowerPC::ppcState.ps[inst.FD].SetBoth(ps0, ps1); - PowerPC::ppcState.UpdateFPRFSingle(ps0); + ppc_state.ps[inst.FD].SetBoth(ps0, ps1); + ppc_state.UpdateFPRFSingle(ps0); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::ps_cmpu0(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - Helper_FloatCompareUnordered(PowerPC::ppcState, inst, a.PS0AsDouble(), b.PS0AsDouble()); + Helper_FloatCompareUnordered(ppc_state, inst, a.PS0AsDouble(), b.PS0AsDouble()); } void Interpreter::ps_cmpo0(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - Helper_FloatCompareOrdered(PowerPC::ppcState, inst, a.PS0AsDouble(), b.PS0AsDouble()); + Helper_FloatCompareOrdered(ppc_state, inst, a.PS0AsDouble(), b.PS0AsDouble()); } void Interpreter::ps_cmpu1(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - Helper_FloatCompareUnordered(PowerPC::ppcState, inst, a.PS1AsDouble(), b.PS1AsDouble()); + Helper_FloatCompareUnordered(ppc_state, inst, a.PS1AsDouble(), b.PS1AsDouble()); } void Interpreter::ps_cmpo1(Interpreter& interpreter, UGeckoInstruction inst) { - const auto& a = PowerPC::ppcState.ps[inst.FA]; - const auto& b = PowerPC::ppcState.ps[inst.FB]; + auto& ppc_state = interpreter.m_ppc_state; + const auto& a = ppc_state.ps[inst.FA]; + const auto& b = ppc_state.ps[inst.FB]; - Helper_FloatCompareOrdered(PowerPC::ppcState, inst, a.PS1AsDouble(), b.PS1AsDouble()); + Helper_FloatCompareOrdered(ppc_state, inst, a.PS1AsDouble(), b.PS1AsDouble()); } From 454d2fd9abd1da94a829a31642e5fe1744be7635 Mon Sep 17 00:00:00 2001 From: "Admiral H. Curtiss" Date: Fri, 17 Mar 2023 01:39:16 +0100 Subject: [PATCH 10/10] Interpreter: Avoid ppcState global (Interpreter_SystemRegisters.cpp). --- .../Interpreter_SystemRegisters.cpp | 268 ++++++++++-------- 1 file changed, 144 insertions(+), 124 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 4e171f087d..09ebbfbca4 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -34,49 +34,53 @@ static void FPSCRUpdated(UReg_FPSCR* fpscr) void Interpreter::mtfsb0x(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; u32 b = 0x80000000 >> inst.CRBD; - PowerPC::ppcState.fpscr.Hex &= ~b; - FPSCRUpdated(&PowerPC::ppcState.fpscr); + ppc_state.fpscr.Hex &= ~b; + FPSCRUpdated(&ppc_state.fpscr); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } // This instruction can affect FX void Interpreter::mtfsb1x(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const u32 bit = inst.CRBD; const u32 b = 0x80000000 >> bit; if ((b & FPSCR_ANY_X) != 0) - SetFPException(&PowerPC::ppcState.fpscr, b); + SetFPException(&ppc_state.fpscr, b); else - PowerPC::ppcState.fpscr |= b; + ppc_state.fpscr |= b; - FPSCRUpdated(&PowerPC::ppcState.fpscr); + FPSCRUpdated(&ppc_state.fpscr); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::mtfsfix(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const u32 field = inst.CRFD; const u32 pre_shifted_mask = 0xF0000000; const u32 mask = (pre_shifted_mask >> (4 * field)); const u32 imm = (inst.hex << 16) & pre_shifted_mask; - PowerPC::ppcState.fpscr = (PowerPC::ppcState.fpscr.Hex & ~mask) | (imm >> (4 * field)); + ppc_state.fpscr = (ppc_state.fpscr.Hex & ~mask) | (imm >> (4 * field)); - FPSCRUpdated(&PowerPC::ppcState.fpscr); + FPSCRUpdated(&ppc_state.fpscr); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::mtfsfx(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const u32 fm = inst.FM; u32 m = 0; for (u32 i = 0; i < 8; i++) @@ -85,32 +89,35 @@ void Interpreter::mtfsfx(Interpreter& interpreter, UGeckoInstruction inst) m |= (0xFU << (i * 4)); } - PowerPC::ppcState.fpscr = (PowerPC::ppcState.fpscr.Hex & ~m) | - (static_cast(PowerPC::ppcState.ps[inst.FB].PS0AsU64()) & m); - FPSCRUpdated(&PowerPC::ppcState.fpscr); + ppc_state.fpscr = + (ppc_state.fpscr.Hex & ~m) | (static_cast(ppc_state.ps[inst.FB].PS0AsU64()) & m); + FPSCRUpdated(&ppc_state.fpscr); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); } void Interpreter::mcrxr(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.cr.SetField(inst.CRFD, PowerPC::ppcState.GetXER().Hex >> 28); - PowerPC::ppcState.xer_ca = 0; - PowerPC::ppcState.xer_so_ov = 0; + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.cr.SetField(inst.CRFD, ppc_state.GetXER().Hex >> 28); + ppc_state.xer_ca = 0; + ppc_state.xer_so_ov = 0; } void Interpreter::mfcr(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.cr.Get(); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.gpr[inst.RD] = ppc_state.cr.Get(); } void Interpreter::mtcrf(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const u32 crm = inst.CRM; if (crm == 0xFF) { - PowerPC::ppcState.cr.Set(PowerPC::ppcState.gpr[inst.RS]); + ppc_state.cr.Set(ppc_state.gpr[inst.RS]); } else { @@ -122,57 +129,60 @@ void Interpreter::mtcrf(Interpreter& interpreter, UGeckoInstruction inst) mask |= 0xFU << (i * 4); } - PowerPC::ppcState.cr.Set((PowerPC::ppcState.cr.Get() & ~mask) | - (PowerPC::ppcState.gpr[inst.RS] & mask)); + ppc_state.cr.Set((ppc_state.cr.Get() & ~mask) | (ppc_state.gpr[inst.RS] & mask)); } } void Interpreter::mfmsr(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.msr.Hex; + ppc_state.gpr[inst.RD] = ppc_state.msr.Hex; } void Interpreter::mfsr(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.sr[inst.SR]; + ppc_state.gpr[inst.RD] = ppc_state.sr[inst.SR]; } void Interpreter::mfsrin(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } - const u32 index = (PowerPC::ppcState.gpr[inst.RB] >> 28) & 0xF; - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.sr[index]; + const u32 index = (ppc_state.gpr[inst.RB] >> 28) & 0xF; + ppc_state.gpr[inst.RD] = ppc_state.sr[index]; } void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } - PowerPC::ppcState.msr.Hex = PowerPC::ppcState.gpr[inst.RS]; + ppc_state.msr.Hex = ppc_state.gpr[inst.RS]; // FE0/FE1 may have been set - CheckFPExceptions(PowerPC::ppcState.fpscr); + CheckFPExceptions(ppc_state.fpscr); PowerPC::CheckExceptions(); interpreter.m_end_block = true; @@ -182,28 +192,30 @@ void Interpreter::mtmsr(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::mtsr(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } const u32 index = inst.SR; - const u32 value = PowerPC::ppcState.gpr[inst.RS]; - PowerPC::ppcState.SetSR(index, value); + const u32 value = ppc_state.gpr[inst.RS]; + ppc_state.SetSR(index, value); } void Interpreter::mtsrin(Interpreter& interpreter, UGeckoInstruction inst) { - if (PowerPC::ppcState.msr.PR) + auto& ppc_state = interpreter.m_ppc_state; + if (ppc_state.msr.PR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } - const u32 index = (PowerPC::ppcState.gpr[inst.RB] >> 28) & 0xF; - const u32 value = PowerPC::ppcState.gpr[inst.RS]; - PowerPC::ppcState.SetSR(index, value); + const u32 index = (ppc_state.gpr[inst.RB] >> 28) & 0xF; + const u32 value = ppc_state.gpr[inst.RS]; + ppc_state.SetSR(index, value); } void Interpreter::mftb(Interpreter& interpreter, UGeckoInstruction inst) @@ -215,10 +227,11 @@ void Interpreter::mftb(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const u32 index = ((inst.SPR & 0x1F) << 5) + ((inst.SPR >> 5) & 0x1F); // XER, LR, CTR, and timebase halves are the only ones available in user mode. - if (PowerPC::ppcState.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR && + if (ppc_state.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR && index != SPR_TL && index != SPR_TU) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); @@ -228,9 +241,9 @@ void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst) switch (index) { case SPR_DEC: - if ((PowerPC::ppcState.spr[index] & 0x80000000) == 0) // We are still decrementing + if ((ppc_state.spr[index] & 0x80000000) == 0) // We are still decrementing { - PowerPC::ppcState.spr[index] = SystemTimers::GetFakeDecrementer(); + ppc_state.spr[index] = SystemTimers::GetFakeDecrementer(); } break; @@ -248,55 +261,56 @@ void Interpreter::mfspr(Interpreter& interpreter, UGeckoInstruction inst) // Currently, we always treat the buffer as not empty, as the exact behavior is unclear // (and games that use display lists will hang if the bit doesn't eventually become zero). if (Core::System::GetInstance().GetGPFifo().IsBNE()) - PowerPC::ppcState.spr[index] |= 1; + ppc_state.spr[index] |= 1; else - PowerPC::ppcState.spr[index] &= ~1; + ppc_state.spr[index] &= ~1; } break; case SPR_XER: - PowerPC::ppcState.spr[index] = PowerPC::ppcState.GetXER().Hex; + ppc_state.spr[index] = ppc_state.GetXER().Hex; break; case SPR_UPMC1: - PowerPC::ppcState.spr[index] = PowerPC::ppcState.spr[SPR_PMC1]; + ppc_state.spr[index] = ppc_state.spr[SPR_PMC1]; break; case SPR_UPMC2: - PowerPC::ppcState.spr[index] = PowerPC::ppcState.spr[SPR_PMC2]; + ppc_state.spr[index] = ppc_state.spr[SPR_PMC2]; break; case SPR_UPMC3: - PowerPC::ppcState.spr[index] = PowerPC::ppcState.spr[SPR_PMC3]; + ppc_state.spr[index] = ppc_state.spr[SPR_PMC3]; break; case SPR_UPMC4: - PowerPC::ppcState.spr[index] = PowerPC::ppcState.spr[SPR_PMC4]; + ppc_state.spr[index] = ppc_state.spr[SPR_PMC4]; break; case SPR_IABR: // A strange quirk: reading back this register on hardware will always have the TE (Translation // enabled) bit set to 0 (despite the bit appearing to function normally when set). This does // not apply to the DABR. - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.spr[index] & ~1; + ppc_state.gpr[inst.RD] = ppc_state.spr[index] & ~1; return; } - PowerPC::ppcState.gpr[inst.RD] = PowerPC::ppcState.spr[index]; + ppc_state.gpr[inst.RD] = ppc_state.spr[index]; } void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const u32 index = (inst.SPRU << 5) | (inst.SPRL & 0x1F); // XER, LR, and CTR are the only ones available to be written to in user mode - if (PowerPC::ppcState.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR) + if (ppc_state.msr.PR && index != SPR_XER && index != SPR_LR && index != SPR_CTR) { GenerateProgramException(ProgramExceptionCause::PrivilegedInstruction); return; } - const u32 old_value = PowerPC::ppcState.spr[index]; - PowerPC::ppcState.spr[index] = PowerPC::ppcState.gpr[inst.RD]; + const u32 old_value = ppc_state.spr[index]; + ppc_state.spr[index] = ppc_state.gpr[inst.RD]; // Our DMA emulation is highly inaccurate - instead of properly emulating the queue // and so on, we simply make all DMA:s complete instantaneously. @@ -309,41 +323,39 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) break; case SPR_TL_W: - TL(PowerPC::ppcState) = PowerPC::ppcState.gpr[inst.RD]; + TL(ppc_state) = ppc_state.gpr[inst.RD]; SystemTimers::TimeBaseSet(); break; case SPR_TU_W: - TU(PowerPC::ppcState) = PowerPC::ppcState.gpr[inst.RD]; + TU(ppc_state) = ppc_state.gpr[inst.RD]; SystemTimers::TimeBaseSet(); break; case SPR_PVR: // PVR is a read-only register so maintain its value. - PowerPC::ppcState.spr[index] = old_value; + ppc_state.spr[index] = old_value; break; case SPR_HID0: // HID0 { UReg_HID0 old_hid0; old_hid0.Hex = old_value; - if (HID0(PowerPC::ppcState).ICE != old_hid0.ICE) + if (HID0(ppc_state).ICE != old_hid0.ICE) { - INFO_LOG_FMT(POWERPC, "Instruction Cache Enable (HID0.ICE) = {}", - HID0(PowerPC::ppcState).ICE); + INFO_LOG_FMT(POWERPC, "Instruction Cache Enable (HID0.ICE) = {}", HID0(ppc_state).ICE); } - if (HID0(PowerPC::ppcState).ILOCK != old_hid0.ILOCK) + if (HID0(ppc_state).ILOCK != old_hid0.ILOCK) { - INFO_LOG_FMT(POWERPC, "Instruction Cache Lock (HID0.ILOCK) = {}", - HID0(PowerPC::ppcState).ILOCK); + INFO_LOG_FMT(POWERPC, "Instruction Cache Lock (HID0.ILOCK) = {}", HID0(ppc_state).ILOCK); } - if (HID0(PowerPC::ppcState).ICFI) + if (HID0(ppc_state).ICFI) { - HID0(PowerPC::ppcState).ICFI = 0; - INFO_LOG_FMT(POWERPC, "Flush Instruction Cache! ICE={}", HID0(PowerPC::ppcState).ICE); + HID0(ppc_state).ICFI = 0; + INFO_LOG_FMT(POWERPC, "Flush Instruction Cache! ICE={}", HID0(ppc_state).ICE); // this is rather slow // most games do it only once during initialization - PowerPC::ppcState.iCache.Reset(); + ppc_state.iCache.Reset(); } } break; @@ -352,7 +364,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) // Despite being documented as a read-only register, it actually isn't. Bits // 0-4 (27-31 from a little endian perspective) are modifiable. The rest are not // affected, as those bits are reserved and ignore writes to them. - PowerPC::ppcState.spr[index] &= 0xF8000000; + ppc_state.spr[index] &= 0xF8000000; break; case SPR_HID2: @@ -360,23 +372,22 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) // TODO: emulate locked cache and DMA bits. // Only the lower half of the register (upper half from a little endian perspective) // is modifiable, except for the DMAQL field. - PowerPC::ppcState.spr[index] = - (PowerPC::ppcState.spr[index] & 0xF0FF0000) | (old_value & 0x0F000000); + ppc_state.spr[index] = (ppc_state.spr[index] & 0xF0FF0000) | (old_value & 0x0F000000); break; case SPR_HID4: - if (old_value != PowerPC::ppcState.spr[index]) + if (old_value != ppc_state.spr[index]) { - INFO_LOG_FMT(POWERPC, "HID4 updated {:x} {:x}", old_value, PowerPC::ppcState.spr[index]); + INFO_LOG_FMT(POWERPC, "HID4 updated {:x} {:x}", old_value, ppc_state.spr[index]); PowerPC::IBATUpdated(); PowerPC::DBATUpdated(); } break; case SPR_WPAR: - ASSERT_MSG(POWERPC, PowerPC::ppcState.spr[SPR_WPAR] == GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS, + ASSERT_MSG(POWERPC, ppc_state.spr[SPR_WPAR] == GPFifo::GATHER_PIPE_PHYSICAL_ADDRESS, "Gather pipe changed to unexpected address {:08x} @ PC {:08x}", - PowerPC::ppcState.spr[SPR_WPAR], PowerPC::ppcState.pc); + ppc_state.spr[SPR_WPAR], ppc_state.pc); Core::System::GetInstance().GetGPFifo().ResetGatherPipe(); break; @@ -394,20 +405,20 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) case SPR_DMAL: // Locked cache<->Memory DMA // Total fake, we ignore that DMAs take time. - if (DMAL(PowerPC::ppcState).DMA_T) + if (DMAL(ppc_state).DMA_T) { - const u32 mem_address = DMAU(PowerPC::ppcState).MEM_ADDR << 5; - const u32 cache_address = DMAL(PowerPC::ppcState).LC_ADDR << 5; - u32 length = ((DMAU(PowerPC::ppcState).DMA_LEN_U << 2) | DMAL(PowerPC::ppcState).DMA_LEN_L); + const u32 mem_address = DMAU(ppc_state).MEM_ADDR << 5; + const u32 cache_address = DMAL(ppc_state).LC_ADDR << 5; + u32 length = ((DMAU(ppc_state).DMA_LEN_U << 2) | DMAL(ppc_state).DMA_LEN_L); if (length == 0) length = 128; - if (DMAL(PowerPC::ppcState).DMA_LD) + if (DMAL(ppc_state).DMA_LD) PowerPC::DMA_MemoryToLC(cache_address, mem_address, length); else PowerPC::DMA_LCToMemory(mem_address, cache_address, length); } - DMAL(PowerPC::ppcState).DMA_T = 0; + DMAL(ppc_state).DMA_T = 0; break; case SPR_L2CR: @@ -415,10 +426,10 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) case SPR_DEC: // Top bit from 0 to 1 - if ((old_value >> 31) == 0 && (PowerPC::ppcState.gpr[inst.RD] >> 31) != 0) + if ((old_value >> 31) == 0 && (ppc_state.gpr[inst.RD] >> 31) != 0) { INFO_LOG_FMT(POWERPC, "Software triggered Decrementer exception"); - PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER; + ppc_state.Exceptions |= EXCEPTION_DECREMENTER; } SystemTimers::DecrementerSet(); break; @@ -429,7 +440,7 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) break; case SPR_XER: - PowerPC::ppcState.SetXER(UReg_XER{PowerPC::ppcState.spr[index]}); + ppc_state.SetXER(UReg_XER{ppc_state.spr[index]}); break; case SPR_DBAT0L: @@ -448,10 +459,9 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) case SPR_DBAT6U: case SPR_DBAT7L: case SPR_DBAT7U: - if (old_value != PowerPC::ppcState.spr[index]) + if (old_value != ppc_state.spr[index]) { - INFO_LOG_FMT(POWERPC, "DBAT updated {} {:x} {:x}", index, old_value, - PowerPC::ppcState.spr[index]); + INFO_LOG_FMT(POWERPC, "DBAT updated {} {:x} {:x}", index, old_value, ppc_state.spr[index]); PowerPC::DBATUpdated(); } break; @@ -472,10 +482,9 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) case SPR_IBAT6U: case SPR_IBAT7L: case SPR_IBAT7U: - if (old_value != PowerPC::ppcState.spr[index]) + if (old_value != ppc_state.spr[index]) { - INFO_LOG_FMT(POWERPC, "IBAT updated {} {:x} {:x}", index, old_value, - PowerPC::ppcState.spr[index]); + INFO_LOG_FMT(POWERPC, "IBAT updated {} {:x} {:x}", index, old_value, ppc_state.spr[index]); PowerPC::IBATUpdated(); } break; @@ -491,8 +500,8 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) // TODO: Support thermal interrupts when enabled. constexpr u32 SIMULATED_TEMP = 42; // °C - auto UpdateThermalReg = [](UReg_THRM12* reg) { - if (!THRM3(PowerPC::ppcState).E || !reg->V) + auto UpdateThermalReg = [&ppc_state](UReg_THRM12* reg) { + if (!THRM3(ppc_state).E || !reg->V) { reg->TIV = 0; } @@ -506,8 +515,8 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) } }; - UpdateThermalReg(&THRM1(PowerPC::ppcState)); - UpdateThermalReg(&THRM2(PowerPC::ppcState)); + UpdateThermalReg(&THRM1(ppc_state)); + UpdateThermalReg(&THRM2(ppc_state)); break; } } @@ -515,72 +524,81 @@ void Interpreter::mtspr(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::crand(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); - const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.cr.GetBit(inst.CRBA); + const u32 b = ppc_state.cr.GetBit(inst.CRBB); - PowerPC::ppcState.cr.SetBit(inst.CRBD, a & b); + ppc_state.cr.SetBit(inst.CRBD, a & b); } void Interpreter::crandc(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); - const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.cr.GetBit(inst.CRBA); + const u32 b = ppc_state.cr.GetBit(inst.CRBB); - PowerPC::ppcState.cr.SetBit(inst.CRBD, a & (1 ^ b)); + ppc_state.cr.SetBit(inst.CRBD, a & (1 ^ b)); } void Interpreter::creqv(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); - const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.cr.GetBit(inst.CRBA); + const u32 b = ppc_state.cr.GetBit(inst.CRBB); - PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a ^ b)); + ppc_state.cr.SetBit(inst.CRBD, 1 ^ (a ^ b)); } void Interpreter::crnand(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); - const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.cr.GetBit(inst.CRBA); + const u32 b = ppc_state.cr.GetBit(inst.CRBB); - PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a & b)); + ppc_state.cr.SetBit(inst.CRBD, 1 ^ (a & b)); } void Interpreter::crnor(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); - const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.cr.GetBit(inst.CRBA); + const u32 b = ppc_state.cr.GetBit(inst.CRBB); - PowerPC::ppcState.cr.SetBit(inst.CRBD, 1 ^ (a | b)); + ppc_state.cr.SetBit(inst.CRBD, 1 ^ (a | b)); } void Interpreter::cror(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); - const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.cr.GetBit(inst.CRBA); + const u32 b = ppc_state.cr.GetBit(inst.CRBB); - PowerPC::ppcState.cr.SetBit(inst.CRBD, a | b); + ppc_state.cr.SetBit(inst.CRBD, a | b); } void Interpreter::crorc(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); - const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.cr.GetBit(inst.CRBA); + const u32 b = ppc_state.cr.GetBit(inst.CRBB); - PowerPC::ppcState.cr.SetBit(inst.CRBD, a | (1 ^ b)); + ppc_state.cr.SetBit(inst.CRBD, a | (1 ^ b)); } void Interpreter::crxor(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 a = PowerPC::ppcState.cr.GetBit(inst.CRBA); - const u32 b = PowerPC::ppcState.cr.GetBit(inst.CRBB); + auto& ppc_state = interpreter.m_ppc_state; + const u32 a = ppc_state.cr.GetBit(inst.CRBA); + const u32 b = ppc_state.cr.GetBit(inst.CRBB); - PowerPC::ppcState.cr.SetBit(inst.CRBD, a ^ b); + ppc_state.cr.SetBit(inst.CRBD, a ^ b); } void Interpreter::mcrf(Interpreter& interpreter, UGeckoInstruction inst) { - const u32 cr_f = PowerPC::ppcState.cr.GetField(inst.CRFS); - PowerPC::ppcState.cr.SetField(inst.CRFD, cr_f); + auto& ppc_state = interpreter.m_ppc_state; + const u32 cr_f = ppc_state.cr.GetField(inst.CRFS); + ppc_state.cr.SetField(inst.CRFD, cr_f); } void Interpreter::isync(Interpreter& interpreter, UGeckoInstruction inst) @@ -592,20 +610,22 @@ void Interpreter::isync(Interpreter& interpreter, UGeckoInstruction inst) void Interpreter::mcrfs(Interpreter& interpreter, UGeckoInstruction inst) { + auto& ppc_state = interpreter.m_ppc_state; const u32 shift = 4 * (7 - inst.CRFS); - const u32 fpflags = (PowerPC::ppcState.fpscr.Hex >> shift) & 0xF; + const u32 fpflags = (ppc_state.fpscr.Hex >> shift) & 0xF; // If any exception bits were read, clear them - PowerPC::ppcState.fpscr.Hex &= ~((0xF << shift) & (FPSCR_FX | FPSCR_ANY_X)); - FPSCRUpdated(&PowerPC::ppcState.fpscr); + ppc_state.fpscr.Hex &= ~((0xF << shift) & (FPSCR_FX | FPSCR_ANY_X)); + FPSCRUpdated(&ppc_state.fpscr); - PowerPC::ppcState.cr.SetField(inst.CRFD, fpflags); + ppc_state.cr.SetField(inst.CRFD, fpflags); } void Interpreter::mffsx(Interpreter& interpreter, UGeckoInstruction inst) { - PowerPC::ppcState.ps[inst.FD].SetPS0(UINT64_C(0xFFF8000000000000) | PowerPC::ppcState.fpscr.Hex); + auto& ppc_state = interpreter.m_ppc_state; + ppc_state.ps[inst.FD].SetPS0(UINT64_C(0xFFF8000000000000) | ppc_state.fpscr.Hex); if (inst.Rc) - PowerPC::ppcState.UpdateCR1(); + ppc_state.UpdateCR1(); }