diff --git a/Source/Core/Core/Src/PowerPC/CPUCoreBase.h b/Source/Core/Core/Src/PowerPC/CPUCoreBase.h new file mode 100644 index 0000000000..efd8a29059 --- /dev/null +++ b/Source/Core/Core/Src/PowerPC/CPUCoreBase.h @@ -0,0 +1,32 @@ +// Copyright (C) 2010 Dolphin Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official SVN repository and contact information can be found at +// http://code.google.com/p/dolphin-emu/ + +#ifndef _CPUCOREBASE_H +#define _CPUCOREBASE_H + +class CPUCoreBase +{ +public: + virtual void Init() = 0; + virtual void Shutdown() = 0; + virtual void ClearCache() = 0; + virtual void Run() = 0; + virtual void SingleStep() = 0; + virtual const char *GetName() = 0; +}; + +#endif diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp index b5815d4e8a..12103fc701 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.cpp @@ -31,36 +31,33 @@ namespace { u32 last_pc; } +bool Interpreter::m_EndBlock; + // function tables +Interpreter::_interpreterInstruction Interpreter::m_opTable[64]; +Interpreter::_interpreterInstruction Interpreter::m_opTable4[1024]; +Interpreter::_interpreterInstruction Interpreter::m_opTable19[1024]; +Interpreter::_interpreterInstruction Interpreter::m_opTable31[1024]; +Interpreter::_interpreterInstruction Interpreter::m_opTable59[32]; +Interpreter::_interpreterInstruction Interpreter::m_opTable63[1024]; -namespace Interpreter +void Interpreter::RunTable4(UGeckoInstruction _inst) {m_opTable4 [_inst.SUBOP10](_inst);} +void Interpreter::RunTable19(UGeckoInstruction _inst) {m_opTable19[_inst.SUBOP10](_inst);} +void Interpreter::RunTable31(UGeckoInstruction _inst) {m_opTable31[_inst.SUBOP10](_inst);} +void Interpreter::RunTable59(UGeckoInstruction _inst) {m_opTable59[_inst.SUBOP5 ](_inst);} +void Interpreter::RunTable63(UGeckoInstruction _inst) {m_opTable63[_inst.SUBOP10](_inst);} + +void Interpreter::Init() { -// cpu register to keep the code readable -u32 *m_GPR = PowerPC::ppcState.gpr; -bool m_EndBlock = false; + g_bReserve = false; + m_EndBlock = false; +} -_interpreterInstruction m_opTable[64]; -_interpreterInstruction m_opTable4[1024]; -_interpreterInstruction m_opTable19[1024]; -_interpreterInstruction m_opTable31[1024]; -_interpreterInstruction m_opTable59[32]; -_interpreterInstruction m_opTable63[1024]; - -void RunTable4(UGeckoInstruction _inst) {m_opTable4 [_inst.SUBOP10](_inst);} -void RunTable19(UGeckoInstruction _inst) {m_opTable19[_inst.SUBOP10](_inst);} -void RunTable31(UGeckoInstruction _inst) {m_opTable31[_inst.SUBOP10](_inst);} -void RunTable59(UGeckoInstruction _inst) {m_opTable59[_inst.SUBOP5 ](_inst);} -void RunTable63(UGeckoInstruction _inst) {m_opTable63[_inst.SUBOP10](_inst);} - -void Init() +void Interpreter::Shutdown() { } -void Shutdown() -{ -} - -void patches() +static void patches() { /* if (Memory::Read_U16(0x90000880) == 0x130b) { @@ -77,7 +74,7 @@ void patches() }*/ } -void SingleStepInner(void) +void Interpreter::SingleStepInner(void) { static UGeckoInstruction instCode; @@ -135,7 +132,7 @@ void SingleStepInner(void) patches(); } -void SingleStep() +void Interpreter::SingleStep() { SingleStepInner(); @@ -159,7 +156,7 @@ int ShowSteps = 300; #endif // FastRun - inspired by GCemu (to imitate the JIT so that they can be compared). -void Run() +void Interpreter::Run() { while (!PowerPC::GetState()) { @@ -244,7 +241,7 @@ void Run() } } -void unknown_instruction(UGeckoInstruction _inst) +void Interpreter::unknown_instruction(UGeckoInstruction _inst) { if (_inst.hex != 0) { @@ -257,4 +254,18 @@ void unknown_instruction(UGeckoInstruction _inst) } -} // namespace +void Interpreter::ClearCache() +{ + // Do nothing. +} + +const char *Interpreter::GetName() +{ + return "Interpreter"; +} + +Interpreter *Interpreter::getInstance() +{ + static Interpreter instance; + return &instance; +} diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.h b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.h index 76eb67947e..1f5bd966a1 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.h +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter.h @@ -20,15 +20,19 @@ #include "../Gekko.h" #include "../PowerPC.h" +#include "../CPUCoreBase.h" -namespace Interpreter +class Interpreter : public CPUCoreBase { +public: void Init(); void Shutdown(); void Reset(); void SingleStep(); void SingleStepInner(); void Run(); + void ClearCache(); + const char *GetName(); typedef void (*_interpreterInstruction)(UGeckoInstruction instCode); @@ -36,288 +40,302 @@ namespace Interpreter void Log(); - // pointer to the CPU-Regs to keep the code cleaner - extern u32* m_GPR; - extern bool m_EndBlock; + // to keep the code cleaner + #define m_GPR (PowerPC::ppcState.gpr) + static bool m_EndBlock; - void unknown_instruction(UGeckoInstruction _inst); + static void unknown_instruction(UGeckoInstruction _inst); // Branch Instructions - void bx(UGeckoInstruction _inst); - void bcx(UGeckoInstruction _inst); - void bcctrx(UGeckoInstruction _inst); - void bclrx(UGeckoInstruction _inst); - void HLEFunction(UGeckoInstruction _inst); - void CompiledBlock(UGeckoInstruction _inst); + 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 CompiledBlock(UGeckoInstruction _inst); // Syscall Instruction - void sc(UGeckoInstruction _inst); + static void sc(UGeckoInstruction _inst); // Floating Point Instructions - void faddsx(UGeckoInstruction _inst); - void fdivsx(UGeckoInstruction _inst); - void fmaddsx(UGeckoInstruction _inst); - void fmsubsx(UGeckoInstruction _inst); - void fmulsx(UGeckoInstruction _inst); - void fnmaddsx(UGeckoInstruction _inst); - void fnmsubsx(UGeckoInstruction _inst); - void fresx(UGeckoInstruction _inst); -// void fsqrtsx(UGeckoInstruction _inst); - void fsubsx(UGeckoInstruction _inst); - void fabsx(UGeckoInstruction _inst); - void fcmpo(UGeckoInstruction _inst); - void fcmpu(UGeckoInstruction _inst); - void fctiwx(UGeckoInstruction _inst); - void fctiwzx(UGeckoInstruction _inst); - void fmrx(UGeckoInstruction _inst); - void fnabsx(UGeckoInstruction _inst); - void fnegx(UGeckoInstruction _inst); - void frspx(UGeckoInstruction _inst); - void faddx(UGeckoInstruction _inst); - void fdivx(UGeckoInstruction _inst); - void fmaddx(UGeckoInstruction _inst); - void fmsubx(UGeckoInstruction _inst); - void fmulx(UGeckoInstruction _inst); - void fnmaddx(UGeckoInstruction _inst); - void fnmsubx(UGeckoInstruction _inst); - void frsqrtex(UGeckoInstruction _inst); - void fselx(UGeckoInstruction _inst); - void fsqrtx(UGeckoInstruction _inst); - void fsubx(UGeckoInstruction _inst); + 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 fsqrtsx(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 fsqrtx(UGeckoInstruction _inst); + static void fsubx(UGeckoInstruction _inst); // Integer Instructions - void addi(UGeckoInstruction _inst); - void addic(UGeckoInstruction _inst); - void addic_rc(UGeckoInstruction _inst); - void addis(UGeckoInstruction _inst); - void andi_rc(UGeckoInstruction _inst); - void andis_rc(UGeckoInstruction _inst); - void cmpi(UGeckoInstruction _inst); - void cmpli(UGeckoInstruction _inst); - void mulli(UGeckoInstruction _inst); - void ori(UGeckoInstruction _inst); - void oris(UGeckoInstruction _inst); - void subfic(UGeckoInstruction _inst); - void twi(UGeckoInstruction _inst); - void xori(UGeckoInstruction _inst); - void xoris(UGeckoInstruction _inst); - void rlwimix(UGeckoInstruction _inst); - void rlwinmx(UGeckoInstruction _inst); - void rlwnmx(UGeckoInstruction _inst); - void andx(UGeckoInstruction _inst); - void andcx(UGeckoInstruction _inst); - void cmp(UGeckoInstruction _inst); - void cmpl(UGeckoInstruction _inst); - void cntlzwx(UGeckoInstruction _inst); - void eqvx(UGeckoInstruction _inst); - void extsbx(UGeckoInstruction _inst); - void extshx(UGeckoInstruction _inst); - void nandx(UGeckoInstruction _inst); - void norx(UGeckoInstruction _inst); - void orx(UGeckoInstruction _inst); - void orcx(UGeckoInstruction _inst); - void slwx(UGeckoInstruction _inst); - void srawx(UGeckoInstruction _inst); - void srawix(UGeckoInstruction _inst); - void srwx(UGeckoInstruction _inst); - void tw(UGeckoInstruction _inst); - void xorx(UGeckoInstruction _inst); - void addx(UGeckoInstruction _inst); - void addcx(UGeckoInstruction _inst); - void addex(UGeckoInstruction _inst); - void addmex(UGeckoInstruction _inst); - void addzex(UGeckoInstruction _inst); - void divwx(UGeckoInstruction _inst); - void divwux(UGeckoInstruction _inst); - void mulhwx(UGeckoInstruction _inst); - void mulhwux(UGeckoInstruction _inst); - void mullwx(UGeckoInstruction _inst); - void negx(UGeckoInstruction _inst); - void subfx(UGeckoInstruction _inst); - void subfcx(UGeckoInstruction _inst); - void subfex(UGeckoInstruction _inst); - void subfmex(UGeckoInstruction _inst); - void subfzex(UGeckoInstruction _inst); + 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); // Load/Store Instructions - void lbz(UGeckoInstruction _inst); - void lbzu(UGeckoInstruction _inst); - void lfd(UGeckoInstruction _inst); - void lfdu(UGeckoInstruction _inst); - void lfs(UGeckoInstruction _inst); - void lfsu(UGeckoInstruction _inst); - void lha(UGeckoInstruction _inst); - void lhau(UGeckoInstruction _inst); - void lhz(UGeckoInstruction _inst); - void lhzu(UGeckoInstruction _inst); - void lmw(UGeckoInstruction _inst); - void lwz(UGeckoInstruction _inst); - void lwzu(UGeckoInstruction _inst); - void stb(UGeckoInstruction _inst); - void stbu(UGeckoInstruction _inst); - void stfd(UGeckoInstruction _inst); - void stfdu(UGeckoInstruction _inst); - void stfs(UGeckoInstruction _inst); - void stfsu(UGeckoInstruction _inst); - void sth(UGeckoInstruction _inst); - void sthu(UGeckoInstruction _inst); - void stmw(UGeckoInstruction _inst); - void stw(UGeckoInstruction _inst); - void stwu(UGeckoInstruction _inst); - void dcba(UGeckoInstruction _inst); - void dcbf(UGeckoInstruction _inst); - void dcbi(UGeckoInstruction _inst); - void dcbst(UGeckoInstruction _inst); - void dcbt(UGeckoInstruction _inst); - void dcbtst(UGeckoInstruction _inst); - void dcbz(UGeckoInstruction _inst); - void eciwx(UGeckoInstruction _inst); - void ecowx(UGeckoInstruction _inst); - void eieio(UGeckoInstruction _inst); - void icbi(UGeckoInstruction _inst); - void lbzux(UGeckoInstruction _inst); - void lbzx(UGeckoInstruction _inst); - void lfdux(UGeckoInstruction _inst); - void lfdx(UGeckoInstruction _inst); - void lfsux(UGeckoInstruction _inst); - void lfsx(UGeckoInstruction _inst); - void lhaux(UGeckoInstruction _inst); - void lhax(UGeckoInstruction _inst); - void lhbrx(UGeckoInstruction _inst); - void lhzux(UGeckoInstruction _inst); - void lhzx(UGeckoInstruction _inst); - void lswi(UGeckoInstruction _inst); - void lswx(UGeckoInstruction _inst); - void lwarx(UGeckoInstruction _inst); - void lwbrx(UGeckoInstruction _inst); - void lwzux(UGeckoInstruction _inst); - void lwzx(UGeckoInstruction _inst); - void stbux(UGeckoInstruction _inst); - void stbx(UGeckoInstruction _inst); - void stfdux(UGeckoInstruction _inst); - void stfdx(UGeckoInstruction _inst); - void stfiwx(UGeckoInstruction _inst); - void stfsux(UGeckoInstruction _inst); - void stfsx(UGeckoInstruction _inst); - void sthbrx(UGeckoInstruction _inst); - void sthux(UGeckoInstruction _inst); - void sthx(UGeckoInstruction _inst); - void stswi(UGeckoInstruction _inst); - void stswx(UGeckoInstruction _inst); - void stwbrx(UGeckoInstruction _inst); - void stwcxd(UGeckoInstruction _inst); - void stwux(UGeckoInstruction _inst); - void stwx(UGeckoInstruction _inst); - void sync(UGeckoInstruction _inst); - void tlbia(UGeckoInstruction _inst); - void tlbie(UGeckoInstruction _inst); - void tlbsync(UGeckoInstruction _inst); + 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 sync(UGeckoInstruction _inst); + static void tlbia(UGeckoInstruction _inst); + static void tlbie(UGeckoInstruction _inst); + static void tlbsync(UGeckoInstruction _inst); // Paired Instructions - void psq_l(UGeckoInstruction _inst); - void psq_lu(UGeckoInstruction _inst); - void psq_st(UGeckoInstruction _inst); - void psq_stu(UGeckoInstruction _inst); - void psq_lx(UGeckoInstruction _inst); - void psq_stx(UGeckoInstruction _inst); - void psq_lux(UGeckoInstruction _inst); - void psq_stux(UGeckoInstruction _inst); - void ps_div(UGeckoInstruction _inst); - void ps_sub(UGeckoInstruction _inst); - void ps_add(UGeckoInstruction _inst); - void ps_sel(UGeckoInstruction _inst); - void ps_res(UGeckoInstruction _inst); - void ps_mul(UGeckoInstruction _inst); - void ps_rsqrte(UGeckoInstruction _inst); - void ps_msub(UGeckoInstruction _inst); - void ps_madd(UGeckoInstruction _inst); - void ps_nmsub(UGeckoInstruction _inst); - void ps_nmadd(UGeckoInstruction _inst); - void ps_neg(UGeckoInstruction _inst); - void ps_mr(UGeckoInstruction _inst); - void ps_nabs(UGeckoInstruction _inst); - void ps_abs(UGeckoInstruction _inst); - void ps_sum0(UGeckoInstruction _inst); - void ps_sum1(UGeckoInstruction _inst); - void ps_muls0(UGeckoInstruction _inst); - void ps_muls1(UGeckoInstruction _inst); - void ps_madds0(UGeckoInstruction _inst); - void ps_madds1(UGeckoInstruction _inst); - void ps_cmpu0(UGeckoInstruction _inst); - void ps_cmpo0(UGeckoInstruction _inst); - void ps_cmpu1(UGeckoInstruction _inst); - void ps_cmpo1(UGeckoInstruction _inst); - void ps_merge00(UGeckoInstruction _inst); - void ps_merge01(UGeckoInstruction _inst); - void ps_merge10(UGeckoInstruction _inst); - void ps_merge11(UGeckoInstruction _inst); - void dcbz_l(UGeckoInstruction _inst); + 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); // System Registers Instructions - void mcrfs(UGeckoInstruction _inst); - void mffsx(UGeckoInstruction _inst); - void mtfsb0x(UGeckoInstruction _inst); - void mtfsb1x(UGeckoInstruction _inst); - void mtfsfix(UGeckoInstruction _inst); - void mtfsfx(UGeckoInstruction _inst); - void mcrxr(UGeckoInstruction _inst); - void mfcr(UGeckoInstruction _inst); - void mfmsr(UGeckoInstruction _inst); - void mfsr(UGeckoInstruction _inst); - void mfsrin(UGeckoInstruction _inst); - void mtmsr(UGeckoInstruction _inst); - void mtsr(UGeckoInstruction _inst); - void mtsrin(UGeckoInstruction _inst); - void mfspr(UGeckoInstruction _inst); - void mftb(UGeckoInstruction _inst); - void mtcrf(UGeckoInstruction _inst); - void mtspr(UGeckoInstruction _inst); - void crand(UGeckoInstruction _inst); - void crandc(UGeckoInstruction _inst); - void creqv(UGeckoInstruction _inst); - void crnand(UGeckoInstruction _inst); - void crnor(UGeckoInstruction _inst); - void cror(UGeckoInstruction _inst); - void crorc(UGeckoInstruction _inst); - void crxor(UGeckoInstruction _inst); - void mcrf(UGeckoInstruction _inst); - void rfi(UGeckoInstruction _inst); - void rfid(UGeckoInstruction _inst); -// void sync(UGeckoInstruction _inst); - void isync(UGeckoInstruction _inst); + 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 rfid(UGeckoInstruction _inst); +// static void sync(UGeckoInstruction _inst); + static void isync(UGeckoInstruction _inst); - void RunTable4(UGeckoInstruction _instCode); - void RunTable19(UGeckoInstruction _instCode); - void RunTable31(UGeckoInstruction _instCode); - void RunTable59(UGeckoInstruction _instCode); - void RunTable63(UGeckoInstruction _instCode); + static void RunTable4(UGeckoInstruction _instCode); + static void RunTable19(UGeckoInstruction _instCode); + static void RunTable31(UGeckoInstruction _instCode); + static void RunTable59(UGeckoInstruction _instCode); + static void RunTable63(UGeckoInstruction _instCode); // flag helper - void Helper_UpdateCR0(u32 _uValue); - void Helper_UpdateCR1(double _fValue); - void Helper_UpdateCR1(float _fValue); - void Helper_UpdateCRx(int _x, u32 _uValue); - u32 Helper_Carry(u32 _uValue1, u32 _uValue2); + static void Helper_UpdateCR0(u32 _uValue); + static void Helper_UpdateCR1(double _fValue); + static void Helper_UpdateCR1(float _fValue); + static void Helper_UpdateCRx(int _x, u32 _uValue); + static u32 Helper_Carry(u32 _uValue1, u32 _uValue2); // address helper - u32 Helper_Get_EA (const UGeckoInstruction _inst); - u32 Helper_Get_EA_U (const UGeckoInstruction _inst); - u32 Helper_Get_EA_X (const UGeckoInstruction _inst); - u32 Helper_Get_EA_UX(const UGeckoInstruction _inst); + static u32 Helper_Get_EA (const UGeckoInstruction _inst); + static u32 Helper_Get_EA_U (const UGeckoInstruction _inst); + static u32 Helper_Get_EA_X (const UGeckoInstruction _inst); + static u32 Helper_Get_EA_UX(const UGeckoInstruction _inst); // paired helper - float Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, const unsigned int _uScale); - void Helper_Quantize (const u32 _Addr, const double _fValue, const EQuantizeType _quantizeType, const unsigned _uScale); + static float Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, const unsigned int _uScale); + static void Helper_Quantize (const u32 _Addr, const double _fValue, const EQuantizeType _quantizeType, const unsigned _uScale); // other helper - u32 Helper_Mask(int mb, int me); + static u32 Helper_Mask(int mb, int me); - extern _interpreterInstruction m_opTable[64]; - extern _interpreterInstruction m_opTable4[1024]; - extern _interpreterInstruction m_opTable19[1024]; - extern _interpreterInstruction m_opTable31[1024]; - extern _interpreterInstruction m_opTable59[32]; - extern _interpreterInstruction m_opTable63[1024]; + static _interpreterInstruction m_opTable[64]; + static _interpreterInstruction m_opTable4[1024]; + static _interpreterInstruction m_opTable19[1024]; + static _interpreterInstruction m_opTable31[1024]; + static _interpreterInstruction m_opTable59[32]; + static _interpreterInstruction m_opTable63[1024]; + + // singleton + static Interpreter *getInstance(); + +private: + Interpreter() { } + ~Interpreter() { } + Interpreter(const Interpreter &); + Interpreter & operator=(const Interpreter &); + + // TODO: These should really be in the save state, although it's unlikely to matter much. + // They are for lwarx and its friend stwcxd. + static bool g_bReserve; + static u32 g_reserveAddr; }; #endif diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp index 0141482abc..bc5c8d9aa1 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -20,10 +20,7 @@ #include "../../HLE/HLE.h" #include "../PPCAnalyst.h" -namespace Interpreter -{ - -void bx(UGeckoInstruction _inst) +void Interpreter::bx(UGeckoInstruction _inst) { if (_inst.LK) LR = PC + 4; @@ -43,7 +40,7 @@ void bx(UGeckoInstruction _inst) } // bcx - ugly, straight from PPC manual equations :) -void bcx(UGeckoInstruction _inst) +void Interpreter::bcx(UGeckoInstruction _inst) { if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0) CTR--; @@ -67,7 +64,7 @@ void bcx(UGeckoInstruction _inst) m_EndBlock = true; } -void bcctrx(UGeckoInstruction _inst) +void Interpreter::bcctrx(UGeckoInstruction _inst) { _dbg_assert_msg_(POWERPC, _inst.BO_2 & BO_DONT_DECREMENT_FLAG, "bcctrx with decrement and test CTR option is invalid!"); @@ -82,7 +79,7 @@ void bcctrx(UGeckoInstruction _inst) m_EndBlock = true; } -void bclrx(UGeckoInstruction _inst) +void Interpreter::bclrx(UGeckoInstruction _inst) { if ((_inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0) CTR--; @@ -99,18 +96,18 @@ void bclrx(UGeckoInstruction _inst) m_EndBlock = true; } -void HLEFunction(UGeckoInstruction _inst) +void Interpreter::HLEFunction(UGeckoInstruction _inst) { m_EndBlock = true; HLE::Execute(PC, _inst.hex); } -void CompiledBlock(UGeckoInstruction _inst) +void Interpreter::CompiledBlock(UGeckoInstruction _inst) { _assert_msg_(POWERPC, 0, "CompiledBlock - shouldn't be here!"); } -void rfi(UGeckoInstruction _inst) +void Interpreter::rfi(UGeckoInstruction _inst) { // Restore saved bits from SRR1 to MSR. // Gecko/Broadway can save more bits than explicitly defined in ppc spec @@ -127,7 +124,7 @@ void rfi(UGeckoInstruction _inst) m_EndBlock = true; } -void rfid(UGeckoInstruction _inst) +void Interpreter::rfid(UGeckoInstruction _inst) { _dbg_assert_msg_(POWERPC,0,"Instruction unimplemented (does this instruction even exist?)","rfid"); m_EndBlock = true; @@ -135,11 +132,9 @@ void rfid(UGeckoInstruction _inst) // sc isn't really used for anything important in gc games (just for a write barrier) so we really don't have to emulate it. // We do it anyway, though :P -void sc(UGeckoInstruction _inst) +void Interpreter::sc(UGeckoInstruction _inst) { PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL; PowerPC::CheckExceptions(); m_EndBlock = true; } - -} // namespace diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index 19115e1020..6468b875dc 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -40,20 +40,17 @@ using namespace MathUtil; -namespace Interpreter -{ - void UpdateSSEState(); // Extremely rare - actually, never seen. // Star Wars : Rogue Leader spams that at some point :| -void Helper_UpdateCR1(double _fValue) +void Interpreter::Helper_UpdateCR1(double _fValue) { // Should just update exception flags, not do any compares. PanicAlert("CR1"); } -void fcmpo(UGeckoInstruction _inst) +void Interpreter::fcmpo(UGeckoInstruction _inst) { double fa = rPS0(_inst.FA); double fb = rPS0(_inst.FB); @@ -84,7 +81,7 @@ void fcmpo(UGeckoInstruction _inst) SetCRField(_inst.CRFD, compareResult); } -void fcmpu(UGeckoInstruction _inst) +void Interpreter::fcmpu(UGeckoInstruction _inst) { double fa = rPS0(_inst.FA); double fb = rPS0(_inst.FB); @@ -107,7 +104,7 @@ void fcmpu(UGeckoInstruction _inst) } // Apply current rounding mode -void fctiwx(UGeckoInstruction _inst) +void Interpreter::fctiwx(UGeckoInstruction _inst) { const double b = rPS0(_inst.FB); u32 value; @@ -172,7 +169,7 @@ void fctiwx(UGeckoInstruction _inst) } // Always round toward zero -void fctiwzx(UGeckoInstruction _inst) +void Interpreter::fctiwzx(UGeckoInstruction _inst) { const double b = rPS0(_inst.FB); u32 value; @@ -215,35 +212,35 @@ void fctiwzx(UGeckoInstruction _inst) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fmrx(UGeckoInstruction _inst) +void Interpreter::fmrx(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB); // This is a binary instruction. Does not alter FPSCR if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fabsx(UGeckoInstruction _inst) +void Interpreter::fabsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = fabs(rPS0(_inst.FB)); // This is a binary instruction. Does not alter FPSCR if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fnabsx(UGeckoInstruction _inst) +void Interpreter::fnabsx(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63); // This is a binary instruction. Does not alter FPSCR if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fnegx(UGeckoInstruction _inst) +void Interpreter::fnegx(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63); // This is a binary instruction. Does not alter FPSCR if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fselx(UGeckoInstruction _inst) +void Interpreter::fselx(UGeckoInstruction _inst) { rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB); // This is a binary instruction. Does not alter FPSCR @@ -253,7 +250,7 @@ void 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 frspx(UGeckoInstruction _inst) // round to single +void Interpreter::frspx(UGeckoInstruction _inst) // round to single { double b = rPS0(_inst.FB); double rounded = ForceSingle(b); @@ -265,7 +262,7 @@ void frspx(UGeckoInstruction _inst) // round to single } -void fmulx(UGeckoInstruction _inst) +void Interpreter::fmulx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC))); FPSCR.FI = 0; // are these flags important? @@ -273,7 +270,7 @@ void fmulx(UGeckoInstruction _inst) UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fmulsx(UGeckoInstruction _inst) +void Interpreter::fmulsx(UGeckoInstruction _inst) { double d_value = NI_mul(rPS0(_inst.FA), rPS0(_inst.FC)); rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(d_value); @@ -284,7 +281,7 @@ void fmulsx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fmaddx(UGeckoInstruction _inst) +void Interpreter::fmaddx(UGeckoInstruction _inst) { double result = ForceDouble(NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) )); rPS0(_inst.FD) = result; @@ -292,7 +289,7 @@ void fmaddx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fmaddsx(UGeckoInstruction _inst) +void Interpreter::fmaddsx(UGeckoInstruction _inst) { double d_value = NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ); rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(d_value); @@ -303,20 +300,20 @@ void fmaddsx(UGeckoInstruction _inst) } -void faddx(UGeckoInstruction _inst) +void Interpreter::faddx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void faddsx(UGeckoInstruction _inst) +void Interpreter::faddsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fdivx(UGeckoInstruction _inst) +void Interpreter::fdivx(UGeckoInstruction _inst) { double a = rPS0(_inst.FA); double b = rPS0(_inst.FB); @@ -347,7 +344,7 @@ void fdivx(UGeckoInstruction _inst) // FR,FI,OX,UX??? if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fdivsx(UGeckoInstruction _inst) +void Interpreter::fdivsx(UGeckoInstruction _inst) { double a = rPS0(_inst.FA); double b = rPS0(_inst.FB); @@ -381,7 +378,7 @@ void fdivsx(UGeckoInstruction _inst) } // Single precision only. -void fresx(UGeckoInstruction _inst) +void Interpreter::fresx(UGeckoInstruction _inst) { double b = rPS0(_inst.FB); double one_over = ForceSingle(1.0 / b); @@ -405,7 +402,7 @@ void fresx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void frsqrtex(UGeckoInstruction _inst) +void Interpreter::frsqrtex(UGeckoInstruction _inst) { double b = rPS0(_inst.FB); if (b < 0.0) @@ -447,14 +444,14 @@ void frsqrtex(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fmsubx(UGeckoInstruction _inst) +void Interpreter::fmsubx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) )); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fmsubsx(UGeckoInstruction _inst) +void Interpreter::fmsubsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle( NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) )); @@ -462,13 +459,13 @@ void fmsubsx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fnmaddx(UGeckoInstruction _inst) +void Interpreter::fnmaddx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fnmaddsx(UGeckoInstruction _inst) +void Interpreter::fnmaddsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); @@ -476,7 +473,7 @@ void fnmaddsx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fnmsubx(UGeckoInstruction _inst) +void Interpreter::fnmsubx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); @@ -484,7 +481,7 @@ void fnmsubx(UGeckoInstruction _inst) } // fnmsubsx does not handle QNAN properly - see NI_msub -void fnmsubsx(UGeckoInstruction _inst) +void Interpreter::fnmsubsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); @@ -492,21 +489,21 @@ void fnmsubsx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fsubx(UGeckoInstruction _inst) +void Interpreter::fsubx(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceDouble(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fsubsx(UGeckoInstruction _inst) +void Interpreter::fsubsx(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void fsqrtx(UGeckoInstruction _inst) +void Interpreter::fsqrtx(UGeckoInstruction _inst) { // GEKKO is not supposed to support this instruction. // PanicAlert("fsqrtx"); @@ -518,5 +515,3 @@ void fsqrtx(UGeckoInstruction _inst) UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } - -} // namespace diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp index ae0dc998af..4dd39d6143 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -18,10 +18,7 @@ #include "Interpreter.h" #include "../../Core.h" -namespace Interpreter -{ - -void Helper_UpdateCR0(u32 _uValue) +void Interpreter::Helper_UpdateCR0(u32 _uValue) { u32 new_cr0; int sValue = (int)_uValue; @@ -35,7 +32,7 @@ void Helper_UpdateCR0(u32 _uValue) SetCRField(0, new_cr0); } -void Helper_UpdateCRx(int _x, u32 _uValue) +void Interpreter::Helper_UpdateCRx(int _x, u32 _uValue) { u32 new_crX; int sValue = (int)_uValue; @@ -49,12 +46,12 @@ void Helper_UpdateCRx(int _x, u32 _uValue) SetCRField(_x, new_crX); } -u32 Helper_Carry(u32 _uValue1, u32 _uValue2) +u32 Interpreter::Helper_Carry(u32 _uValue1, u32 _uValue2) { return _uValue2 > (~_uValue1); } -u32 Helper_Mask(int mb, int me) +u32 Interpreter::Helper_Mask(int mb, int me) { //first make 001111111111111 part u32 begin = 0xFFFFFFFF >> mb; @@ -69,7 +66,7 @@ u32 Helper_Mask(int mb, int me) return mask; } -void addi(UGeckoInstruction _inst) +void Interpreter::addi(UGeckoInstruction _inst) { if (_inst.RA) m_GPR[_inst.RD] = m_GPR[_inst.RA] + _inst.SIMM_16; @@ -77,7 +74,7 @@ void addi(UGeckoInstruction _inst) m_GPR[_inst.RD] = _inst.SIMM_16; } -void addic(UGeckoInstruction _inst) +void Interpreter::addic(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 imm = (u32)(s32)_inst.SIMM_16; @@ -86,13 +83,13 @@ void addic(UGeckoInstruction _inst) SetCarry(Helper_Carry(a, imm)); } -void addic_rc(UGeckoInstruction _inst) +void Interpreter::addic_rc(UGeckoInstruction _inst) { addic(_inst); Helper_UpdateCR0(m_GPR[_inst.RD]); } -void addis(UGeckoInstruction _inst) +void Interpreter::addis(UGeckoInstruction _inst) { if (_inst.RA) m_GPR[_inst.RD] = m_GPR[_inst.RA] + (_inst.SIMM_16 << 16); @@ -100,24 +97,24 @@ void addis(UGeckoInstruction _inst) m_GPR[_inst.RD] = (_inst.SIMM_16 << 16); } -void andi_rc(UGeckoInstruction _inst) +void Interpreter::andi_rc(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] & _inst.UIMM; Helper_UpdateCR0(m_GPR[_inst.RA]); } -void andis_rc(UGeckoInstruction _inst) +void Interpreter::andis_rc(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] & ((u32)_inst.UIMM<<16); Helper_UpdateCR0(m_GPR[_inst.RA]); } -void cmpi(UGeckoInstruction _inst) +void Interpreter::cmpi(UGeckoInstruction _inst) { Helper_UpdateCRx(_inst.CRFD, m_GPR[_inst.RA] - _inst.SIMM_16); } -void cmpli(UGeckoInstruction _inst) +void Interpreter::cmpli(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = _inst.UIMM; @@ -129,22 +126,22 @@ void cmpli(UGeckoInstruction _inst) SetCRField(_inst.CRFD, f); } -void mulli(UGeckoInstruction _inst) +void Interpreter::mulli(UGeckoInstruction _inst) { m_GPR[_inst.RD] = (s32)m_GPR[_inst.RA] * _inst.SIMM_16; } -void ori(UGeckoInstruction _inst) +void Interpreter::ori(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] | _inst.UIMM; } -void oris(UGeckoInstruction _inst) +void Interpreter::oris(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] | (_inst.UIMM << 16); } -void subfic(UGeckoInstruction _inst) +void Interpreter::subfic(UGeckoInstruction _inst) { /* u32 rra = ~m_GPR[_inst.RA]; s32 immediate = (s16)_inst.SIMM_16 + 1; @@ -163,7 +160,7 @@ void subfic(UGeckoInstruction _inst) SetCarry((m_GPR[_inst.RA] == 0) || (Helper_Carry(0-m_GPR[_inst.RA], immediate))); } -void twi(UGeckoInstruction _inst) +void Interpreter::twi(UGeckoInstruction _inst) { s32 a = m_GPR[_inst.RA]; s32 b = _inst.SIMM_16; @@ -183,31 +180,31 @@ void twi(UGeckoInstruction _inst) } } -void xori(UGeckoInstruction _inst) +void Interpreter::xori(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ _inst.UIMM; } -void xoris(UGeckoInstruction _inst) +void Interpreter::xoris(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ (_inst.UIMM << 16); } -void rlwimix(UGeckoInstruction _inst) +void Interpreter::rlwimix(UGeckoInstruction _inst) { u32 mask = Helper_Mask(_inst.MB,_inst.ME); m_GPR[_inst.RA] = (m_GPR[_inst.RA] & ~mask) | (_rotl(m_GPR[_inst.RS],_inst.SH) & mask); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void rlwinmx(UGeckoInstruction _inst) +void Interpreter::rlwinmx(UGeckoInstruction _inst) { u32 mask = Helper_Mask(_inst.MB,_inst.ME); m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS],_inst.SH) & mask; if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void rlwnmx(UGeckoInstruction _inst) +void Interpreter::rlwnmx(UGeckoInstruction _inst) { u32 mask = Helper_Mask(_inst.MB,_inst.ME); m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS], m_GPR[_inst.RB] & 0x1F) & mask; @@ -215,21 +212,21 @@ void rlwnmx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void andx(UGeckoInstruction _inst) +void Interpreter::andx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] & m_GPR[_inst.RB]; if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void andcx(UGeckoInstruction _inst) +void Interpreter::andcx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] & ~m_GPR[_inst.RB]; if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void cmp(UGeckoInstruction _inst) +void Interpreter::cmp(UGeckoInstruction _inst) { s32 a = (s32)m_GPR[_inst.RA]; s32 b = (s32)m_GPR[_inst.RB]; @@ -241,7 +238,7 @@ void cmp(UGeckoInstruction _inst) SetCRField(_inst.CRFD, fTemp); } -void cmpl(UGeckoInstruction _inst) +void Interpreter::cmpl(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = m_GPR[_inst.RB]; @@ -254,7 +251,7 @@ void cmpl(UGeckoInstruction _inst) SetCRField(_inst.CRFD, fTemp); } -void cntlzwx(UGeckoInstruction _inst) +void Interpreter::cntlzwx(UGeckoInstruction _inst) { u32 val = m_GPR[_inst.RS]; u32 mask = 0x80000000; @@ -266,56 +263,56 @@ void cntlzwx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void eqvx(UGeckoInstruction _inst) +void Interpreter::eqvx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] ^ m_GPR[_inst.RB]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void extsbx(UGeckoInstruction _inst) +void Interpreter::extsbx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = (u32)(s32)(s8)m_GPR[_inst.RS]; if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void extshx(UGeckoInstruction _inst) +void Interpreter::extshx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = (u32)(s32)(s16)m_GPR[_inst.RS]; if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void nandx(UGeckoInstruction _inst) +void Interpreter::nandx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] & m_GPR[_inst.RB]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void norx(UGeckoInstruction _inst) +void Interpreter::norx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] | m_GPR[_inst.RB]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void orx(UGeckoInstruction _inst) +void Interpreter::orx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] | m_GPR[_inst.RB]; if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void orcx(UGeckoInstruction _inst) +void Interpreter::orcx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] | (~m_GPR[_inst.RB]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void slwx(UGeckoInstruction _inst) +void Interpreter::slwx(UGeckoInstruction _inst) { u32 amount = m_GPR[_inst.RB]; m_GPR[_inst.RA] = (amount & 0x20) ? 0 : m_GPR[_inst.RS] << amount; @@ -323,7 +320,7 @@ void slwx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void srawx(UGeckoInstruction _inst) +void Interpreter::srawx(UGeckoInstruction _inst) { int rb = m_GPR[_inst.RB]; if (rb & 0x20) @@ -360,7 +357,7 @@ void srawx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void srawix(UGeckoInstruction _inst) +void Interpreter::srawix(UGeckoInstruction _inst) { int amount = _inst.SH; @@ -383,7 +380,7 @@ void srawix(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void srwx(UGeckoInstruction _inst) +void Interpreter::srwx(UGeckoInstruction _inst) { u32 amount = m_GPR[_inst.RB]; m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> (amount & 0x1f)); @@ -391,7 +388,7 @@ void srwx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void tw(UGeckoInstruction _inst) +void Interpreter::tw(UGeckoInstruction _inst) { s32 a = m_GPR[_inst.RA]; s32 b = m_GPR[_inst.RB]; @@ -411,14 +408,14 @@ void tw(UGeckoInstruction _inst) } } -void xorx(UGeckoInstruction _inst) +void Interpreter::xorx(UGeckoInstruction _inst) { m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ m_GPR[_inst.RB]; if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); } -void addx(UGeckoInstruction _inst) +void Interpreter::addx(UGeckoInstruction _inst) { m_GPR[_inst.RD] = m_GPR[_inst.RA] + m_GPR[_inst.RB]; @@ -426,7 +423,7 @@ void addx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void addcx(UGeckoInstruction _inst) +void Interpreter::addcx(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = m_GPR[_inst.RB]; @@ -437,7 +434,7 @@ void addcx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void addex(UGeckoInstruction _inst) +void Interpreter::addex(UGeckoInstruction _inst) { int carry = GetCarry(); int a = m_GPR[_inst.RA]; @@ -449,7 +446,7 @@ void addex(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void addmex(UGeckoInstruction _inst) +void Interpreter::addmex(UGeckoInstruction _inst) { int carry = GetCarry(); int a = m_GPR[_inst.RA]; @@ -460,7 +457,7 @@ void addmex(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void addzex(UGeckoInstruction _inst) +void Interpreter::addzex(UGeckoInstruction _inst) { int carry = GetCarry(); int a = m_GPR[_inst.RA]; @@ -471,7 +468,7 @@ void addzex(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void divwx(UGeckoInstruction _inst) +void Interpreter::divwx(UGeckoInstruction _inst) { s32 a = m_GPR[_inst.RA]; s32 b = m_GPR[_inst.RB]; @@ -492,7 +489,7 @@ void divwx(UGeckoInstruction _inst) } -void divwux(UGeckoInstruction _inst) +void Interpreter::divwux(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = m_GPR[_inst.RB]; @@ -510,7 +507,7 @@ void divwux(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void mulhwx(UGeckoInstruction _inst) +void Interpreter::mulhwx(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = m_GPR[_inst.RB]; @@ -519,7 +516,7 @@ void mulhwx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void mulhwux(UGeckoInstruction _inst) +void Interpreter::mulhwux(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = m_GPR[_inst.RB]; @@ -528,7 +525,7 @@ void mulhwux(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void mullwx(UGeckoInstruction _inst) +void Interpreter::mullwx(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = m_GPR[_inst.RB]; @@ -539,7 +536,7 @@ void mullwx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void negx(UGeckoInstruction _inst) +void Interpreter::negx(UGeckoInstruction _inst) { m_GPR[_inst.RD] = (~m_GPR[_inst.RA]) + 1; if (m_GPR[_inst.RD] == 0x80000000) @@ -549,7 +546,7 @@ void negx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void subfx(UGeckoInstruction _inst) +void Interpreter::subfx(UGeckoInstruction _inst) { m_GPR[_inst.RD] = m_GPR[_inst.RB] - m_GPR[_inst.RA]; @@ -557,7 +554,7 @@ void subfx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void subfcx(UGeckoInstruction _inst) +void Interpreter::subfcx(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = m_GPR[_inst.RB]; @@ -568,7 +565,7 @@ void subfcx(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } -void subfex(UGeckoInstruction _inst) +void Interpreter::subfex(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; u32 b = m_GPR[_inst.RB]; @@ -581,7 +578,7 @@ void subfex(UGeckoInstruction _inst) } // sub from minus one -void subfmex(UGeckoInstruction _inst) +void Interpreter::subfmex(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; int carry = GetCarry(); @@ -593,7 +590,7 @@ void subfmex(UGeckoInstruction _inst) } // sub from zero -void subfzex(UGeckoInstruction _inst) +void Interpreter::subfzex(UGeckoInstruction _inst) { u32 a = m_GPR[_inst.RA]; int carry = GetCarry(); @@ -603,5 +600,3 @@ void subfzex(UGeckoInstruction _inst) if (_inst.OE) PanicAlert("OE: subfzex"); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); } - -} // namespace diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp index ea9e3c479d..eb0d012b2f 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -28,42 +28,37 @@ #include "Interpreter_FPUtils.h" -namespace Interpreter -{ +bool Interpreter::g_bReserve; +u32 Interpreter::g_reserveAddr; -// TODO: These should really be in the save state, although it's unlikely to matter much. -// They are for lwarx and its friend stwcxd. -static bool g_bReserve = false; -static u32 g_reserveAddr; - -u32 Helper_Get_EA(const UGeckoInstruction _inst) +u32 Interpreter::Helper_Get_EA(const UGeckoInstruction _inst) { return _inst.RA ? (m_GPR[_inst.RA] + _inst.SIMM_16) : _inst.SIMM_16; } -u32 Helper_Get_EA_U(const UGeckoInstruction _inst) +u32 Interpreter::Helper_Get_EA_U(const UGeckoInstruction _inst) { return (m_GPR[_inst.RA] + _inst.SIMM_16); } -u32 Helper_Get_EA_X(const UGeckoInstruction _inst) +u32 Interpreter::Helper_Get_EA_X(const UGeckoInstruction _inst) { return _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB]; } -u32 Helper_Get_EA_UX(const UGeckoInstruction _inst) +u32 Interpreter::Helper_Get_EA_UX(const UGeckoInstruction _inst) { return (m_GPR[_inst.RA] + m_GPR[_inst.RB]); } -void lbz(UGeckoInstruction _inst) +void Interpreter::lbz(UGeckoInstruction _inst) { u32 temp = (u32)Memory::Read_U8(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) m_GPR[_inst.RD] = temp; } -void lbzu(UGeckoInstruction _inst) +void Interpreter::lbzu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); u32 temp = (u32)Memory::Read_U8(uAddress); @@ -74,14 +69,14 @@ void lbzu(UGeckoInstruction _inst) } } -void lfd(UGeckoInstruction _inst) +void Interpreter::lfd(UGeckoInstruction _inst) { u64 temp = Memory::Read_U64(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) riPS0(_inst.FD) = temp; } -void lfdu(UGeckoInstruction _inst) +void Interpreter::lfdu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); u64 temp = Memory::Read_U64(uAddress); @@ -92,7 +87,7 @@ void lfdu(UGeckoInstruction _inst) } } -void lfdux(UGeckoInstruction _inst) +void Interpreter::lfdux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); u64 temp = Memory::Read_U64(uAddress); @@ -103,14 +98,14 @@ void lfdux(UGeckoInstruction _inst) } } -void lfdx(UGeckoInstruction _inst) +void Interpreter::lfdx(UGeckoInstruction _inst) { u64 temp = Memory::Read_U64(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) riPS0(_inst.FD) = temp; } -void lfs(UGeckoInstruction _inst) +void Interpreter::lfs(UGeckoInstruction _inst) { u32 uTemp = Memory::Read_U32(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -121,7 +116,7 @@ void lfs(UGeckoInstruction _inst) } } -void lfsu(UGeckoInstruction _inst) +void Interpreter::lfsu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); u32 uTemp = Memory::Read_U32(uAddress); @@ -135,7 +130,7 @@ void lfsu(UGeckoInstruction _inst) } -void lfsux(UGeckoInstruction _inst) +void Interpreter::lfsux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); u32 uTemp = Memory::Read_U32(uAddress); @@ -148,7 +143,7 @@ void lfsux(UGeckoInstruction _inst) } } -void lfsx(UGeckoInstruction _inst) +void Interpreter::lfsx(UGeckoInstruction _inst) { u32 uTemp = Memory::Read_U32(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -159,7 +154,7 @@ void lfsx(UGeckoInstruction _inst) } } -void lha(UGeckoInstruction _inst) +void Interpreter::lha(UGeckoInstruction _inst) { u32 temp = (u32)(s32)(s16)Memory::Read_U16(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -168,7 +163,7 @@ void lha(UGeckoInstruction _inst) } } -void lhau(UGeckoInstruction _inst) +void Interpreter::lhau(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); u32 temp = (u32)(s32)(s16)Memory::Read_U16(uAddress); @@ -179,7 +174,7 @@ void lhau(UGeckoInstruction _inst) } } -void lhz(UGeckoInstruction _inst) +void Interpreter::lhz(UGeckoInstruction _inst) { u32 temp = (u32)(u16)Memory::Read_U16(Helper_Get_EA(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -188,7 +183,7 @@ void lhz(UGeckoInstruction _inst) } } -void lhzu(UGeckoInstruction _inst) +void Interpreter::lhzu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); u32 temp = (u32)(u16)Memory::Read_U16(uAddress); @@ -200,7 +195,7 @@ void lhzu(UGeckoInstruction _inst) } // FIXME: lmw should do a total rollback if a DSI occurs -void lmw(UGeckoInstruction _inst) +void Interpreter::lmw(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA(_inst); for (int iReg = _inst.RD; iReg <= 31; iReg++, uAddress += 4) @@ -220,7 +215,7 @@ void lmw(UGeckoInstruction _inst) } // FIXME: stmw should do a total rollback if a DSI occurs -void stmw(UGeckoInstruction _inst) +void Interpreter::stmw(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA(_inst); for (int iReg = _inst.RS; iReg <= 31; iReg++, uAddress+=4) @@ -235,7 +230,7 @@ void stmw(UGeckoInstruction _inst) } } -void lwz(UGeckoInstruction _inst) +void Interpreter::lwz(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA(_inst); u32 temp = Memory::Read_U32(uAddress); @@ -261,7 +256,7 @@ void lwz(UGeckoInstruction _inst) }*/ } -void lwzu(UGeckoInstruction _inst) +void Interpreter::lwzu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); u32 temp = Memory::Read_U32(uAddress); @@ -272,12 +267,12 @@ void lwzu(UGeckoInstruction _inst) } } -void stb(UGeckoInstruction _inst) +void Interpreter::stb(UGeckoInstruction _inst) { Memory::Write_U8((u8)m_GPR[_inst.RS], Helper_Get_EA(_inst)); } -void stbu(UGeckoInstruction _inst) +void Interpreter::stbu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); Memory::Write_U8((u8)m_GPR[_inst.RS], uAddress); @@ -287,12 +282,12 @@ void stbu(UGeckoInstruction _inst) } } -void stfd(UGeckoInstruction _inst) +void Interpreter::stfd(UGeckoInstruction _inst) { Memory::Write_U64(riPS0(_inst.FS), Helper_Get_EA(_inst)); } -void stfdu(UGeckoInstruction _inst) +void Interpreter::stfdu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); Memory::Write_U64(riPS0(_inst.FS), uAddress); @@ -302,7 +297,7 @@ void stfdu(UGeckoInstruction _inst) } } -void stfs(UGeckoInstruction _inst) +void Interpreter::stfs(UGeckoInstruction _inst) { //double value = rPS0(_inst.FS); //float fTemp = (float)value; @@ -310,7 +305,7 @@ void stfs(UGeckoInstruction _inst) Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA(_inst)); } -void stfsu(UGeckoInstruction _inst) +void Interpreter::stfsu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress); @@ -320,12 +315,12 @@ void stfsu(UGeckoInstruction _inst) } } -void sth(UGeckoInstruction _inst) +void Interpreter::sth(UGeckoInstruction _inst) { Memory::Write_U16((u16)m_GPR[_inst.RS], Helper_Get_EA(_inst)); } -void sthu(UGeckoInstruction _inst) +void Interpreter::sthu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); Memory::Write_U16((u16)m_GPR[_inst.RS], uAddress); @@ -335,12 +330,12 @@ void sthu(UGeckoInstruction _inst) } } -void stw(UGeckoInstruction _inst) +void Interpreter::stw(UGeckoInstruction _inst) { Memory::Write_U32(m_GPR[_inst.RS], Helper_Get_EA(_inst)); } -void stwu(UGeckoInstruction _inst) +void Interpreter::stwu(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_U(_inst); Memory::Write_U32(m_GPR[_inst.RS], uAddress); @@ -350,12 +345,12 @@ void stwu(UGeckoInstruction _inst) } } -void dcba(UGeckoInstruction _inst) +void Interpreter::dcba(UGeckoInstruction _inst) { _assert_msg_(POWERPC,0,"dcba - Not implemented - not a Gekko instruction"); } -void dcbf(UGeckoInstruction _inst) +void Interpreter::dcbf(UGeckoInstruction _inst) { //This should tell GFX plugin to throw out any cached data here // !!! SPEEDUP HACK for OSProtectRange !!! @@ -369,29 +364,29 @@ void dcbf(UGeckoInstruction _inst) }*/ } -void dcbi(UGeckoInstruction _inst) +void Interpreter::dcbi(UGeckoInstruction _inst) { // Removes a block from data cache. Since we don't emulate the data cache, we don't need to do anything. // Seen used during initialization. } -void dcbst(UGeckoInstruction _inst) +void Interpreter::dcbst(UGeckoInstruction _inst) { // Cache line flush. Since we don't emulate the data cache, we don't need to do anything. } -void dcbt(UGeckoInstruction _inst) +void Interpreter::dcbt(UGeckoInstruction _inst) { // Prefetch. Since we don't emulate the data cache, we don't need to do anything. } -void dcbtst(UGeckoInstruction _inst) +void Interpreter::dcbtst(UGeckoInstruction _inst) { // This is just some sort of store "prefetching". // Since we don't emulate the data cache, we don't need to do anything. } -void dcbz(UGeckoInstruction _inst) +void Interpreter::dcbz(UGeckoInstruction _inst) { // HACK but works... we think Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32); @@ -399,7 +394,7 @@ void dcbz(UGeckoInstruction _inst) // eciwx/ecowx technically should access the specified device // We just do it instantly from ppc...and hey, it works! :D -void eciwx(UGeckoInstruction _inst) +void Interpreter::eciwx(UGeckoInstruction _inst) { u32 EA, b; if (_inst.RA == 0) @@ -421,7 +416,7 @@ void eciwx(UGeckoInstruction _inst) m_GPR[_inst.RS] = Memory::Read_U32(EA); } -void ecowx(UGeckoInstruction _inst) +void Interpreter::ecowx(UGeckoInstruction _inst) { u32 EA, b; if (_inst.RA == 0) @@ -443,7 +438,7 @@ void ecowx(UGeckoInstruction _inst) Memory::Write_U32(m_GPR[_inst.RS], EA); } -void eieio(UGeckoInstruction _inst) +void Interpreter::eieio(UGeckoInstruction _inst) { // Basically ensures that loads/stores before this instruction // have completed (in order) before executing the next op. @@ -451,13 +446,13 @@ void eieio(UGeckoInstruction _inst) // But (at least in interpreter) we do everything realtime anyways. } -void icbi(UGeckoInstruction _inst) +void Interpreter::icbi(UGeckoInstruction _inst) { u32 address = Helper_Get_EA_X(_inst); PowerPC::ppcState.iCache.Invalidate(address); } -void lbzux(UGeckoInstruction _inst) +void Interpreter::lbzux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); u32 temp = (u32)Memory::Read_U8(uAddress); @@ -468,7 +463,7 @@ void lbzux(UGeckoInstruction _inst) } } -void lbzx(UGeckoInstruction _inst) +void Interpreter::lbzx(UGeckoInstruction _inst) { u32 temp = (u32)Memory::Read_U8(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -477,7 +472,7 @@ void lbzx(UGeckoInstruction _inst) } } -void lhaux(UGeckoInstruction _inst) +void Interpreter::lhaux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); s32 temp = (s32)(s16)Memory::Read_U16(uAddress); @@ -488,7 +483,7 @@ void lhaux(UGeckoInstruction _inst) } } -void lhax(UGeckoInstruction _inst) +void Interpreter::lhax(UGeckoInstruction _inst) { s32 temp = (s32)(s16)Memory::Read_U16(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -497,7 +492,7 @@ void lhax(UGeckoInstruction _inst) } } -void lhbrx(UGeckoInstruction _inst) +void Interpreter::lhbrx(UGeckoInstruction _inst) { u32 temp = (u32)Common::swap16(Memory::Read_U16(Helper_Get_EA_X(_inst))); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -506,7 +501,7 @@ void lhbrx(UGeckoInstruction _inst) } } -void lhzux(UGeckoInstruction _inst) +void Interpreter::lhzux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); u32 temp = (u32)Memory::Read_U16(uAddress); @@ -517,7 +512,7 @@ void lhzux(UGeckoInstruction _inst) } } -void lhzx(UGeckoInstruction _inst) +void Interpreter::lhzx(UGeckoInstruction _inst) { u32 temp = (u32)Memory::Read_U16(Helper_Get_EA_X(_inst)); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -526,7 +521,7 @@ void lhzx(UGeckoInstruction _inst) } } -void lswx(UGeckoInstruction _inst) +void Interpreter::lswx(UGeckoInstruction _inst) { static bool bFirst = true; if (bFirst) @@ -534,7 +529,7 @@ void lswx(UGeckoInstruction _inst) bFirst = false; } -void lwbrx(UGeckoInstruction _inst) +void Interpreter::lwbrx(UGeckoInstruction _inst) { u32 temp = Common::swap32(Memory::Read_U32(Helper_Get_EA_X(_inst))); if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI)) @@ -543,7 +538,7 @@ void lwbrx(UGeckoInstruction _inst) } } -void lwzux(UGeckoInstruction _inst) +void Interpreter::lwzux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); u32 temp = Memory::Read_U32(uAddress); @@ -554,7 +549,7 @@ void lwzux(UGeckoInstruction _inst) } } -void lwzx(UGeckoInstruction _inst) +void Interpreter::lwzx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); u32 temp = Memory::Read_U32(uAddress); @@ -564,7 +559,7 @@ void lwzx(UGeckoInstruction _inst) } } -void stbux(UGeckoInstruction _inst) +void Interpreter::stbux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); Memory::Write_U8((u8)m_GPR[_inst.RS], uAddress); @@ -574,12 +569,12 @@ void stbux(UGeckoInstruction _inst) } } -void stbx(UGeckoInstruction _inst) +void Interpreter::stbx(UGeckoInstruction _inst) { Memory::Write_U8((u8)m_GPR[_inst.RS], Helper_Get_EA_X(_inst)); } -void stfdux(UGeckoInstruction _inst) +void Interpreter::stfdux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); Memory::Write_U64(riPS0(_inst.FS), uAddress); @@ -589,7 +584,7 @@ void stfdux(UGeckoInstruction _inst) } } -void stfdx(UGeckoInstruction _inst) +void Interpreter::stfdx(UGeckoInstruction _inst) { Memory::Write_U64(riPS0(_inst.FS), Helper_Get_EA_X(_inst)); } @@ -598,7 +593,7 @@ void stfdx(UGeckoInstruction _inst) // stfiwx // TODO - examine what this really does // Stores Floating points into Integers indeXed -void stfiwx(UGeckoInstruction _inst) +void Interpreter::stfiwx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); @@ -606,7 +601,7 @@ void stfiwx(UGeckoInstruction _inst) } -void stfsux(UGeckoInstruction _inst) +void Interpreter::stfsux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress); @@ -616,17 +611,17 @@ void stfsux(UGeckoInstruction _inst) } } -void stfsx(UGeckoInstruction _inst) +void Interpreter::stfsx(UGeckoInstruction _inst) { Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA_X(_inst)); } -void sthbrx(UGeckoInstruction _inst) +void Interpreter::sthbrx(UGeckoInstruction _inst) { Memory::Write_U16(Common::swap16((u16)m_GPR[_inst.RS]), Helper_Get_EA_X(_inst)); } -void sthux(UGeckoInstruction _inst) +void Interpreter::sthux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); Memory::Write_U16((u16)m_GPR[_inst.RS], uAddress); @@ -636,7 +631,7 @@ void sthux(UGeckoInstruction _inst) } } -void sthx(UGeckoInstruction _inst) +void Interpreter::sthx(UGeckoInstruction _inst) { Memory::Write_U16((u16)m_GPR[_inst.RS], Helper_Get_EA_X(_inst)); } @@ -644,7 +639,7 @@ void sthx(UGeckoInstruction _inst) // __________________________________________________________________________________________________ // lswi - bizarro string instruction // FIXME: Should rollback if a DSI occurs -void lswi(UGeckoInstruction _inst) +void Interpreter::lswi(UGeckoInstruction _inst) { u32 EA; if (_inst.RA == 0) @@ -690,7 +685,7 @@ void lswi(UGeckoInstruction _inst) // __________________________________________________________________________________________________ // stswi - bizarro string instruction // FIXME: Should rollback if a DSI occurs -void stswi(UGeckoInstruction _inst) +void Interpreter::stswi(UGeckoInstruction _inst) { u32 EA; if (_inst.RA == 0) @@ -727,7 +722,7 @@ void stswi(UGeckoInstruction _inst) } } -void stswx(UGeckoInstruction _inst) +void Interpreter::stswx(UGeckoInstruction _inst) { static bool bFirst = true; if (bFirst) @@ -735,7 +730,7 @@ void stswx(UGeckoInstruction _inst) bFirst = false; } -void stwbrx(UGeckoInstruction _inst) +void Interpreter::stwbrx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); Memory::Write_U32(Common::swap32(m_GPR[_inst.RS]), uAddress); @@ -745,7 +740,7 @@ void 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 lwarx(UGeckoInstruction _inst) +void Interpreter::lwarx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); u32 temp = Memory::Read_U32(uAddress); @@ -757,7 +752,7 @@ void lwarx(UGeckoInstruction _inst) } } -void stwcxd(UGeckoInstruction _inst) +void Interpreter::stwcxd(UGeckoInstruction _inst) { // Stores Word Conditional indeXed u32 uAddress; @@ -777,7 +772,7 @@ void stwcxd(UGeckoInstruction _inst) SetCRField(0, GetXER_SO()); } -void stwux(UGeckoInstruction _inst) +void Interpreter::stwux(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_UX(_inst); Memory::Write_U32(m_GPR[_inst.RS], uAddress); @@ -787,18 +782,18 @@ void stwux(UGeckoInstruction _inst) } } -void stwx(UGeckoInstruction _inst) +void Interpreter::stwx(UGeckoInstruction _inst) { u32 uAddress = Helper_Get_EA_X(_inst); Memory::Write_U32(m_GPR[_inst.RS], uAddress); } -void sync(UGeckoInstruction _inst) +void Interpreter::sync(UGeckoInstruction _inst) { //ignored } -void tlbia(UGeckoInstruction _inst) +void Interpreter::tlbia(UGeckoInstruction _inst) { // Gekko does not support this instructions. PanicAlert("The GC CPU does not support tlbia"); @@ -806,16 +801,14 @@ void tlbia(UGeckoInstruction _inst) //MessageBox(0,"TLBIA","TLBIA",0); } -void tlbie(UGeckoInstruction _inst) +void Interpreter::tlbie(UGeckoInstruction _inst) { // Invalidate TLB entry u32 _Address = m_GPR[_inst.RB]; Memory::InvalidateTLBEntry(_Address); } -void tlbsync(UGeckoInstruction _inst) +void Interpreter::tlbsync(UGeckoInstruction _inst) { //MessageBox(0,"TLBsync","TLBsyncE",0); } - -} // namespace diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp index 3b5ebadb3b..4da0b0b4e3 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_LoadStorePaired.cpp @@ -21,9 +21,6 @@ #include "Interpreter_FPUtils.h" -namespace Interpreter -{ - // dequantize table const float m_dequantizeTable[] = { @@ -73,7 +70,7 @@ inline T CLAMP(T a, T bottom, T top) { return a; } -void Helper_Quantize(const u32 _Addr, const double _fValue, +void Interpreter::Helper_Quantize(const u32 _Addr, const double _fValue, const EQuantizeType _quantizeType, const unsigned int _uScale) { switch (_quantizeType) @@ -117,8 +114,8 @@ void Helper_Quantize(const u32 _Addr, const double _fValue, } } -float Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, - const unsigned int _uScale) +float Interpreter::Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, + const unsigned int _uScale) { // dequantize the value float fResult; @@ -156,7 +153,7 @@ float Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, return fResult; } -void psq_l(UGeckoInstruction _inst) +void Interpreter::psq_l(UGeckoInstruction _inst) { const UGQR gqr(rSPR(SPR_GQR0 + _inst.I)); const EQuantizeType ldType = static_cast(gqr.LD_TYPE); @@ -190,7 +187,7 @@ void psq_l(UGeckoInstruction _inst) } } -void psq_lu(UGeckoInstruction _inst) +void Interpreter::psq_lu(UGeckoInstruction _inst) { const UGQR gqr(rSPR(SPR_GQR0 + _inst.I)); const EQuantizeType ldType = static_cast(gqr.LD_TYPE); @@ -225,7 +222,7 @@ void psq_lu(UGeckoInstruction _inst) m_GPR[_inst.RA] = EA; } -void psq_st(UGeckoInstruction _inst) +void Interpreter::psq_st(UGeckoInstruction _inst) { const UGQR gqr(rSPR(SPR_GQR0 + _inst.I)); const EQuantizeType stType = static_cast(gqr.ST_TYPE); @@ -247,7 +244,7 @@ void psq_st(UGeckoInstruction _inst) } } -void psq_stu(UGeckoInstruction _inst) +void Interpreter::psq_stu(UGeckoInstruction _inst) { const UGQR gqr(rSPR(SPR_GQR0 + _inst.I)); const EQuantizeType stType = static_cast(gqr.ST_TYPE); @@ -274,7 +271,7 @@ void psq_stu(UGeckoInstruction _inst) m_GPR[_inst.RA] = EA; } -void psq_lx(UGeckoInstruction _inst) +void Interpreter::psq_lx(UGeckoInstruction _inst) { const UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix)); const EQuantizeType ldType = static_cast(gqr.LD_TYPE); @@ -313,7 +310,7 @@ void psq_lx(UGeckoInstruction _inst) } } -void psq_stx(UGeckoInstruction _inst) +void Interpreter::psq_stx(UGeckoInstruction _inst) { const UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix)); const EQuantizeType stType = static_cast(gqr.ST_TYPE); @@ -335,7 +332,7 @@ void psq_stx(UGeckoInstruction _inst) } } -void psq_lux(UGeckoInstruction _inst) +void Interpreter::psq_lux(UGeckoInstruction _inst) { const UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix)); const EQuantizeType ldType = static_cast(gqr.LD_TYPE); @@ -370,7 +367,7 @@ void psq_lux(UGeckoInstruction _inst) m_GPR[_inst.RA] = EA; } -void psq_stux(UGeckoInstruction _inst) +void Interpreter::psq_stux(UGeckoInstruction _inst) { const UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix)); const EQuantizeType stType = static_cast(gqr.ST_TYPE); @@ -397,4 +394,3 @@ void psq_stux(UGeckoInstruction _inst) m_GPR[_inst.RA] = EA; } // namespace======= -} diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Paired.cpp index 7222d390ac..923443186c 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -25,39 +25,36 @@ using namespace MathUtil; -namespace Interpreter -{ - // These "binary instructions" do not alter FPSCR. -void ps_sel(UGeckoInstruction _inst) +void Interpreter::ps_sel(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS0(_inst.FA) >= -0.0 ? rPS0(_inst.FC) : rPS0(_inst.FB); rPS1(_inst.FD) = rPS1(_inst.FA) >= -0.0 ? rPS1(_inst.FC) : rPS1(_inst.FB); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_neg(UGeckoInstruction _inst) +void Interpreter::ps_neg(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63); riPS1(_inst.FD) = riPS1(_inst.FB) ^ (1ULL << 63); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_mr(UGeckoInstruction _inst) +void Interpreter::ps_mr(UGeckoInstruction _inst) { rPS0(_inst.FD) = rPS0(_inst.FB); rPS1(_inst.FD) = rPS1(_inst.FB); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_nabs(UGeckoInstruction _inst) +void Interpreter::ps_nabs(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63); riPS1(_inst.FD) = riPS1(_inst.FB) | (1ULL << 63); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_abs(UGeckoInstruction _inst) +void Interpreter::ps_abs(UGeckoInstruction _inst) { riPS0(_inst.FD) = riPS0(_inst.FB) &~ (1ULL << 63); riPS1(_inst.FD) = riPS1(_inst.FB) &~ (1ULL << 63); @@ -65,7 +62,7 @@ void ps_abs(UGeckoInstruction _inst) } // These are just moves, double is OK. -void ps_merge00(UGeckoInstruction _inst) +void Interpreter::ps_merge00(UGeckoInstruction _inst) { double p0 = rPS0(_inst.FA); double p1 = rPS0(_inst.FB); @@ -74,7 +71,7 @@ void ps_merge00(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_merge01(UGeckoInstruction _inst) +void Interpreter::ps_merge01(UGeckoInstruction _inst) { double p0 = rPS0(_inst.FA); double p1 = rPS1(_inst.FB); @@ -83,7 +80,7 @@ void ps_merge01(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_merge10(UGeckoInstruction _inst) +void Interpreter::ps_merge10(UGeckoInstruction _inst) { double p0 = rPS1(_inst.FA); double p1 = rPS0(_inst.FB); @@ -92,7 +89,7 @@ void ps_merge10(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_merge11(UGeckoInstruction _inst) +void Interpreter::ps_merge11(UGeckoInstruction _inst) { double p0 = rPS1(_inst.FA); double p1 = rPS1(_inst.FB); @@ -102,7 +99,7 @@ void ps_merge11(UGeckoInstruction _inst) } // From here on, the real deal. -void ps_div(UGeckoInstruction _inst) +void Interpreter::ps_div(UGeckoInstruction _inst) { u32 ex_mask = 0; @@ -187,7 +184,7 @@ void ps_div(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_res(UGeckoInstruction _inst) +void Interpreter::ps_res(UGeckoInstruction _inst) { // this code is based on the real hardware tests double a = rPS0(_inst.FB); @@ -216,7 +213,7 @@ void ps_res(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_rsqrte(UGeckoInstruction _inst) +void Interpreter::ps_rsqrte(UGeckoInstruction _inst) { // this code is based on the real hardware tests if (rPS0(_inst.FB) == 0.0 || rPS1(_inst.FB) == 0.0) @@ -253,7 +250,7 @@ void ps_rsqrte(UGeckoInstruction _inst) } -void ps_sub(UGeckoInstruction _inst) +void Interpreter::ps_sub(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB))); rPS1(_inst.FD) = ForceSingle(NI_sub(rPS1(_inst.FA), rPS1(_inst.FB))); @@ -261,7 +258,7 @@ void ps_sub(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_add(UGeckoInstruction _inst) +void Interpreter::ps_add(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB))); rPS1(_inst.FD) = ForceSingle(NI_add(rPS1(_inst.FA), rPS1(_inst.FB))); @@ -269,7 +266,7 @@ void ps_add(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_mul(UGeckoInstruction _inst) +void Interpreter::ps_mul(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceSingle(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC))); rPS1(_inst.FD) = ForceSingle(NI_mul(rPS1(_inst.FA), rPS1(_inst.FC))); @@ -278,7 +275,7 @@ void ps_mul(UGeckoInstruction _inst) } -void ps_msub(UGeckoInstruction _inst) +void Interpreter::ps_msub(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceSingle(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); rPS1(_inst.FD) = ForceSingle(NI_msub(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB))); @@ -286,7 +283,7 @@ void ps_msub(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_madd(UGeckoInstruction _inst) +void Interpreter::ps_madd(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceSingle(NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); rPS1(_inst.FD) = ForceSingle(NI_madd(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB))); @@ -294,7 +291,7 @@ void ps_madd(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_nmsub(UGeckoInstruction _inst) +void Interpreter::ps_nmsub(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceSingle( -NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ) ); rPS1(_inst.FD) = ForceSingle( -NI_msub( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) ); @@ -302,7 +299,7 @@ void ps_nmsub(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_nmadd(UGeckoInstruction _inst) +void Interpreter::ps_nmadd(UGeckoInstruction _inst) { rPS0(_inst.FD) = ForceSingle( -NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ) ); rPS1(_inst.FD) = ForceSingle( -NI_madd( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) ); @@ -310,7 +307,7 @@ void ps_nmadd(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_sum0(UGeckoInstruction _inst) +void Interpreter::ps_sum0(UGeckoInstruction _inst) { double p0 = ForceSingle(NI_add(rPS0(_inst.FA), rPS1(_inst.FB))); double p1 = ForceSingle(rPS1(_inst.FC)); @@ -320,7 +317,7 @@ void ps_sum0(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_sum1(UGeckoInstruction _inst) +void Interpreter::ps_sum1(UGeckoInstruction _inst) { double p0 = ForceSingle(rPS0(_inst.FC)); double p1 = ForceSingle(NI_add(rPS0(_inst.FA), rPS1(_inst.FB))); @@ -330,7 +327,7 @@ void ps_sum1(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_muls0(UGeckoInstruction _inst) +void Interpreter::ps_muls0(UGeckoInstruction _inst) { double p0 = ForceSingle(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC))); double p1 = ForceSingle(NI_mul(rPS1(_inst.FA), rPS0(_inst.FC))); @@ -340,7 +337,7 @@ void ps_muls0(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_muls1(UGeckoInstruction _inst) +void Interpreter::ps_muls1(UGeckoInstruction _inst) { double p0 = ForceSingle(NI_mul(rPS0(_inst.FA), rPS1(_inst.FC))); double p1 = ForceSingle(NI_mul(rPS1(_inst.FA), rPS1(_inst.FC))); @@ -350,7 +347,7 @@ void ps_muls1(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_madds0(UGeckoInstruction _inst) +void Interpreter::ps_madds0(UGeckoInstruction _inst) { double p0 = ForceSingle( NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)) ); double p1 = ForceSingle( NI_madd( rPS1(_inst.FA), rPS0(_inst.FC), rPS1(_inst.FB)) ); @@ -360,7 +357,7 @@ void ps_madds0(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_madds1(UGeckoInstruction _inst) +void Interpreter::ps_madds1(UGeckoInstruction _inst) { double p0 = ForceSingle( NI_madd( rPS0(_inst.FA), rPS1(_inst.FC), rPS0(_inst.FB)) ); double p1 = ForceSingle( NI_madd( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB)) ); @@ -370,7 +367,7 @@ void ps_madds1(UGeckoInstruction _inst) if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); } -void ps_cmpu0(UGeckoInstruction _inst) +void Interpreter::ps_cmpu0(UGeckoInstruction _inst) { double fa = rPS0(_inst.FA); double fb = rPS0(_inst.FB); @@ -391,7 +388,7 @@ void ps_cmpu0(UGeckoInstruction _inst) SetCRField(_inst.CRFD, compareResult); } -void ps_cmpo0(UGeckoInstruction _inst) +void Interpreter::ps_cmpo0(UGeckoInstruction _inst) { double fa = rPS0(_inst.FA); double fb = rPS0(_inst.FB); @@ -419,7 +416,7 @@ void ps_cmpo0(UGeckoInstruction _inst) SetCRField(_inst.CRFD, compareResult); } -void ps_cmpu1(UGeckoInstruction _inst) +void Interpreter::ps_cmpu1(UGeckoInstruction _inst) { double fa = rPS1(_inst.FA); double fb = rPS1(_inst.FB); @@ -440,7 +437,7 @@ void ps_cmpu1(UGeckoInstruction _inst) SetCRField(_inst.CRFD, compareResult); } -void ps_cmpo1(UGeckoInstruction _inst) +void Interpreter::ps_cmpo1(UGeckoInstruction _inst) { double fa = rPS1(_inst.FA); double fb = rPS1(_inst.FB); @@ -471,10 +468,8 @@ void ps_cmpo1(UGeckoInstruction _inst) // __________________________________________________________________________________________________ // dcbz_l // TODO(ector) check docs -void dcbz_l(UGeckoInstruction _inst) +void Interpreter::dcbz_l(UGeckoInstruction _inst) { //FAKE: clear memory instead of clearing the cache block Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32); } - -} // namespace diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index 3878723cce..542206f8ef 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -60,9 +60,6 @@ mffsx: 80036650 (huh?) // That is, set rounding mode etc when entering jit code or the interpreter loop // Restore rounding mode when calling anything external -namespace Interpreter -{ - const u32 MASKS = 0x1F80; // mask away the interrupts. const u32 DAZ = 0x40; const u32 FTZ = 0x8000; @@ -121,7 +118,7 @@ void FPSCRtoFPUSettings(UReg_FPSCR fp) _mm_setcsr(csr); } -void mtfsb0x(UGeckoInstruction _inst) +void Interpreter::mtfsb0x(UGeckoInstruction _inst) { u32 b = 0x80000000 >> _inst.CRBD; @@ -134,7 +131,7 @@ void mtfsb0x(UGeckoInstruction _inst) if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc"); } -void mtfsb1x(UGeckoInstruction _inst) +void Interpreter::mtfsb1x(UGeckoInstruction _inst) { // this instruction can affect FX u32 b = 0x80000000 >> _inst.CRBD; @@ -147,7 +144,7 @@ void mtfsb1x(UGeckoInstruction _inst) if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc"); } -void mtfsfix(UGeckoInstruction _inst) +void Interpreter::mtfsfix(UGeckoInstruction _inst) { u32 mask = (0xF0000000 >> (4 * _inst.CRFD)); u32 imm = (_inst.hex << 16) & 0xF0000000; @@ -163,7 +160,7 @@ void mtfsfix(UGeckoInstruction _inst) if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc"); } -void mtfsfx(UGeckoInstruction _inst) +void Interpreter::mtfsfx(UGeckoInstruction _inst) { u32 fm = _inst.FM; u32 m = 0; @@ -183,19 +180,19 @@ void mtfsfx(UGeckoInstruction _inst) if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc"); } -void mcrxr(UGeckoInstruction _inst) +void Interpreter::mcrxr(UGeckoInstruction _inst) { // USES_XER SetCRField(_inst.CRFD, PowerPC::ppcState.spr[SPR_XER] >> 28); PowerPC::ppcState.spr[SPR_XER] &= ~0xF0000000; // clear 0-3 } -void mfcr(UGeckoInstruction _inst) +void Interpreter::mfcr(UGeckoInstruction _inst) { m_GPR[_inst.RD] = GetCR(); } -void mtcrf(UGeckoInstruction _inst) +void Interpreter::mtcrf(UGeckoInstruction _inst) { u32 crm = _inst.CRM; if (crm == 0xFF) @@ -215,24 +212,24 @@ void mtcrf(UGeckoInstruction _inst) } -void mfmsr(UGeckoInstruction _inst) +void Interpreter::mfmsr(UGeckoInstruction _inst) { //Privileged? m_GPR[_inst.RD] = MSR; } -void mfsr(UGeckoInstruction _inst) +void Interpreter::mfsr(UGeckoInstruction _inst) { m_GPR[_inst.RD] = PowerPC::ppcState.sr[_inst.SR]; } -void mfsrin(UGeckoInstruction _inst) +void Interpreter::mfsrin(UGeckoInstruction _inst) { int index = (m_GPR[_inst.RB] >> 28) & 0xF; m_GPR[_inst.RD] = PowerPC::ppcState.sr[index]; } -void mtmsr(UGeckoInstruction _inst) +void Interpreter::mtmsr(UGeckoInstruction _inst) { // Privileged? MSR = m_GPR[_inst.RS]; @@ -246,14 +243,14 @@ void SetSR(int index, u32 value) { PowerPC::ppcState.sr[index] = value; } -void mtsr(UGeckoInstruction _inst) +void Interpreter::mtsr(UGeckoInstruction _inst) { int index = _inst.SR; u32 value = m_GPR[_inst.RS]; SetSR(index, value); } -void mtsrin(UGeckoInstruction _inst) +void Interpreter::mtsrin(UGeckoInstruction _inst) { int index = (m_GPR[_inst.RB] >> 28) & 0xF; u32 value = m_GPR[_inst.RS]; @@ -262,7 +259,7 @@ void mtsrin(UGeckoInstruction _inst) -void mftb(UGeckoInstruction _inst) +void Interpreter::mftb(UGeckoInstruction _inst) { int iIndex = (_inst.TBR >> 5) | ((_inst.TBR & 0x1F) << 5); if (iIndex == SPR_TL) m_GPR[_inst.RD] = TL; @@ -271,7 +268,7 @@ void mftb(UGeckoInstruction _inst) } -void mfspr(UGeckoInstruction _inst) +void Interpreter::mfspr(UGeckoInstruction _inst) { u32 iIndex = ((_inst.SPR & 0x1F) << 5) + ((_inst.SPR >> 5) & 0x1F); @@ -298,7 +295,7 @@ void mfspr(UGeckoInstruction _inst) m_GPR[_inst.RD] = rSPR(iIndex); } -void mtspr(UGeckoInstruction _inst) +void Interpreter::mtspr(UGeckoInstruction _inst) { u32 iIndex = (_inst.SPRU << 5) | (_inst.SPRL & 0x1F); u32 oldValue = rSPR(iIndex); @@ -431,60 +428,60 @@ void mtspr(UGeckoInstruction _inst) } } -void crand(UGeckoInstruction _inst) +void Interpreter::crand(UGeckoInstruction _inst) { SetCRBit(_inst.CRBD, GetCRBit(_inst.CRBA) & GetCRBit(_inst.CRBB)); } -void crandc(UGeckoInstruction _inst) +void Interpreter::crandc(UGeckoInstruction _inst) { SetCRBit(_inst.CRBD, GetCRBit(_inst.CRBA) & (1 ^ GetCRBit(_inst.CRBB))); } -void creqv(UGeckoInstruction _inst) +void Interpreter::creqv(UGeckoInstruction _inst) { SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) ^ GetCRBit(_inst.CRBB))); } -void crnand(UGeckoInstruction _inst) +void Interpreter::crnand(UGeckoInstruction _inst) { SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) & GetCRBit(_inst.CRBB))); } -void crnor(UGeckoInstruction _inst) +void Interpreter::crnor(UGeckoInstruction _inst) { SetCRBit(_inst.CRBD, 1 ^ (GetCRBit(_inst.CRBA) | GetCRBit(_inst.CRBB))); } -void cror(UGeckoInstruction _inst) +void Interpreter::cror(UGeckoInstruction _inst) { SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) | GetCRBit(_inst.CRBB))); } -void crorc(UGeckoInstruction _inst) +void Interpreter::crorc(UGeckoInstruction _inst) { SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) | (1 ^ GetCRBit(_inst.CRBB)))); } -void crxor(UGeckoInstruction _inst) +void Interpreter::crxor(UGeckoInstruction _inst) { SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) ^ GetCRBit(_inst.CRBB))); } -void mcrf(UGeckoInstruction _inst) +void Interpreter::mcrf(UGeckoInstruction _inst) { int cr_f = GetCRField(_inst.CRFS); SetCRField(_inst.CRFD, cr_f); } -void isync(UGeckoInstruction _inst) +void Interpreter::isync(UGeckoInstruction _inst) { //shouldnt do anything } // the following commands read from FPSCR -void mcrfs(UGeckoInstruction _inst) +void Interpreter::mcrfs(UGeckoInstruction _inst) { //if (_inst.CRFS != 3 && _inst.CRFS != 4) // PanicAlert("msrfs at %x, CRFS = %d, CRFD = %d", PC, (int)_inst.CRFS, (int)_inst.CRFD); @@ -520,7 +517,7 @@ void mcrfs(UGeckoInstruction _inst) SetCRField(_inst.CRFD, fpflags); } -void mffsx(UGeckoInstruction _inst) +void Interpreter::mffsx(UGeckoInstruction _inst) { // load from FPSCR // This may or may not be accurate - but better than nothing, I guess @@ -530,5 +527,3 @@ void mffsx(UGeckoInstruction _inst) riPS0(_inst.FD) = (u64)FPSCR.Hex; if (_inst.Rc) PanicAlert("mffsx: inst_.Rc"); } - -} // namespace diff --git a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp index 291232b381..9ea755cdef 100644 --- a/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Interpreter/Interpreter_Tables.cpp @@ -361,8 +361,15 @@ static GekkoOPTemplate table63_2[] = }; namespace InterpreterTables { + +bool initialized = false; + void InitTables() { + // once initialized, tables are read-only + if (initialized) + return; + //clear for (int i = 0; i < 32; i++) { @@ -491,6 +498,8 @@ void InitTables() if (m_numInstructions >= 512) { PanicAlert("m_allInstructions underdimensioned"); } + + initialized = true; } } diff --git a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp index d55702767c..cebff3a80b 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64/Jit64_Tables.cpp @@ -392,8 +392,14 @@ void CompileInstruction(PPCAnalyst::CodeOp & op) } } +bool initialized = false; + void InitTables() { + // once initialized, tables are read-only + if (initialized) + return; + //clear for (int i = 0; i < 32; i++) { @@ -482,6 +488,8 @@ void InitTables() dynaOpTable63[op] = table63_2[j].Inst; } } + + initialized = true; } } // namespace diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp index 76954eb118..29e7573296 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.cpp @@ -376,6 +376,7 @@ static GekkoOPTemplate table63_2[] = namespace JitILTables { + void CompileInstruction(PPCAnalyst::CodeOp & op) { JitIL *jitil = (JitIL *)jit; @@ -393,8 +394,15 @@ void CompileInstruction(PPCAnalyst::CodeOp & op) PanicAlert("Tried to compile illegal (or unknown) instruction %08x, at %08x", op.inst.hex, jit->js.compilerPC); } } + +bool initialized = false; + void InitTables() { + // once initialized, tables are read-only + if (initialized) + return; + //clear for (int i = 0; i < 32; i++) { @@ -483,5 +491,8 @@ void InitTables() dynaOpTable63[op] = table63_2[j].Inst; } } + + initialized = true; } + } diff --git a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.h b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.h index 02d040d70e..a07adb2fb9 100644 --- a/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.h +++ b/Source/Core/Core/Src/PowerPC/Jit64IL/JitIL_Tables.h @@ -25,7 +25,7 @@ namespace JitILTables { void CompileInstruction(PPCAnalyst::CodeOp & op); -void InitTables(); + void InitTables(); } #endif diff --git a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h index 916dd42a8b..b832e96e1f 100644 --- a/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h +++ b/Source/Core/Core/Src/PowerPC/JitCommon/JitBase.h @@ -22,6 +22,7 @@ //#define JIT_LOG_GPR // Enables logging of the PPC general purpose regs //#define JIT_LOG_FPR // Enables logging of the PPC floating point regs +#include "../CPUCoreBase.h" #include "JitCache.h" #include "Jit_Util.h" // for EmuCodeBlock #include "JitBackpatch.h" // for EmuCodeBlock @@ -32,9 +33,7 @@ #define JIT_OPCODE 0 -// TODO: In the future, inherit this from CPUCoreBase and have Interpreter -// inherit from that too? -class JitBase : public EmuCodeBlock +class JitBase : public CPUCoreBase, public EmuCodeBlock { protected: JitBlockCache blocks; @@ -85,18 +84,11 @@ public: JitBlockCache *GetBlockCache() { return &blocks; } - virtual void Init() = 0; - virtual void Shutdown() = 0; - virtual void Jit(u32 em_address) = 0; - virtual void ClearCache() = 0; - virtual void Run() = 0; - virtual void SingleStep() = 0; const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx); virtual const CommonAsmRoutines *GetAsmRoutines() = 0; - virtual const char *GetName() = 0; }; extern JitBase *jit; diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.cpp b/Source/Core/Core/Src/PowerPC/PPCTables.cpp index ac6ad2982c..f1f7b7db1a 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.cpp +++ b/Source/Core/Core/Src/PowerPC/PPCTables.cpp @@ -24,13 +24,11 @@ #include "FileUtil.h" #include "Interpreter/Interpreter.h" #include "Interpreter/Interpreter_Tables.h" -#if !(defined(NOJIT) && NOJIT) #include "Jit64IL/JitIL_Tables.h" #include "Jit64/Jit64_Tables.h" #include "Jit64IL/JitIL.h" #include "Jit64/Jit.h" -#endif struct op_inf { @@ -156,15 +154,33 @@ bool UsesFPU(UGeckoInstruction _inst) } } -void InitTables() +void InitTables(int cpu_core) { // Interpreter ALWAYS needs to be initialized InterpreterTables::InitTables(); - #if !(defined(NOJIT) && NOJIT) - // Should be able to do this a better way than defines in this function - Jit64Tables::InitTables(); - JitILTables::InitTables(); - #endif + switch (cpu_core) + { + case 0: + { + // Interpreter + break; + } + case 1: + { + Jit64Tables::InitTables(); + break; + } + case 2: + { + JitILTables::InitTables(); + break; + } + default: + { + PanicAlert("Unrecognizable cpu_core: %d", cpu_core); + break; + } + } } #define OPLOG diff --git a/Source/Core/Core/Src/PowerPC/PPCTables.h b/Source/Core/Core/Src/PowerPC/PPCTables.h index 752e0fc351..2e4ac0e755 100644 --- a/Source/Core/Core/Src/PowerPC/PPCTables.h +++ b/Source/Core/Core/Src/PowerPC/PPCTables.h @@ -113,7 +113,7 @@ class cJit64; namespace PPCTables { -void InitTables(); +void InitTables(int cpu_core); bool IsValidInstruction(UGeckoInstruction _instCode); bool UsesFPU(UGeckoInstruction _inst); diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.cpp b/Source/Core/Core/Src/PowerPC/PowerPC.cpp index 204d8594aa..064be3f87c 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/Src/PowerPC/PowerPC.cpp @@ -32,9 +32,12 @@ #include "Jit64/Jit.h" #include "PowerPC.h" #include "PPCTables.h" +#include "CPUCoreBase.h" #include "../Host.h" +CPUCoreBase *cpu_core_base; + namespace PowerPC { @@ -42,7 +45,8 @@ namespace PowerPC PowerPCState GC_ALIGNED16(ppcState); volatile CPUState state = CPU_STEPPING; -static CoreMode mode; +Interpreter * const interpreter = Interpreter::getInstance(); +CoreMode mode; BreakPoints breakpoints; MemChecks memchecks; @@ -137,18 +141,46 @@ void Init(int cpu_core) #endif ResetRegisters(); - PPCTables::InitTables(); + PPCTables::InitTables(cpu_core); - // Initialize both execution engines ... - Interpreter::Init(); + // We initialize the interpreter because + // it is used on boot and code window independently. + interpreter->Init(); - if (cpu_core == 1) - jit = new Jit64; + switch (cpu_core) + { + case 0: + { + cpu_core_base = interpreter; + break; + } + case 1: + { + cpu_core_base = new Jit64(); + break; + } + case 2: + { + cpu_core_base = new JitIL(); + break; + } + default: + { + PanicAlert("Unrecognizable cpu_core: %d", cpu_core); + break; + } + } + + if (cpu_core_base != interpreter) + { + jit = dynamic_cast(cpu_core_base); + jit->Init(); + mode = MODE_JIT; + } else - jit = new JitIL; - jit->Init(); - - mode = MODE_JIT; + { + mode = MODE_INTERPRETER; + } state = CPU_STEPPING; ppcState.iCache.Reset(); @@ -156,12 +188,15 @@ void Init(int cpu_core) void Shutdown() { - // Shutdown both execution engines. Doesn't matter which one is active. - jit->Shutdown(); + if (jit) + { + jit->Shutdown(); + delete jit; + jit = NULL; + } + interpreter->Shutdown(); + cpu_core_base = NULL; state = CPU_POWERDOWN; - delete jit; - jit = 0; - Interpreter::Shutdown(); } void SetMode(CoreMode new_mode) @@ -170,43 +205,30 @@ void SetMode(CoreMode new_mode) return; // We don't need to do anything. mode = new_mode; + switch (mode) { case MODE_INTERPRETER: // Switching from JIT to interpreter jit->ClearCache(); // Remove all those nasty JIT patches. + cpu_core_base = interpreter; break; case MODE_JIT: // Switching from interpreter to JIT. // Don't really need to do much. It'll work, the cache will refill itself. + cpu_core_base = jit; break; } } void SingleStep() { - switch (mode) - { - case MODE_INTERPRETER: - Interpreter::SingleStep(); - break; - case MODE_JIT: - jit->SingleStep(); - break; - } + cpu_core_base->SingleStep(); } void RunLoop() { state = CPU_RUNNING; - switch (mode) - { - case MODE_INTERPRETER: - Interpreter::Run(); - break; - case MODE_JIT: - jit->Run(); - break; - } + cpu_core_base->Run(); Host_UpdateDisasmDialog(); } diff --git a/Source/Core/Core/Src/PowerPC/PowerPC.h b/Source/Core/Core/Src/PowerPC/PowerPC.h index b5019ee300..0543903fac 100644 --- a/Source/Core/Core/Src/PowerPC/PowerPC.h +++ b/Source/Core/Core/Src/PowerPC/PowerPC.h @@ -19,6 +19,7 @@ #define _POWERPC_H #include "Common.h" +#include "CPUCoreBase.h" #include "Gekko.h" #include "BreakPoints.h" #include "../Debugger/PPCDebugInterface.h" @@ -26,6 +27,8 @@ class PointerWrap; +extern CPUCoreBase *cpu_core_base; + namespace PowerPC {