My first commit!
Done some refactoring around the PowerPC stuff. Main changes: * Declared CPUCoreBase class * Wrapped the interpreter into a class and made both it and JitBase inherit from CPUCoreBase * Avoided reinitializing interpreter's and Jit's tables A great deal of this work was done by nodchip, so kudos to him :-) To finish, please forgive me for my not-so-great english. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6132 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
46e8ea8094
commit
d082f50c34
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,7 +114,7 @@ void Helper_Quantize(const u32 _Addr, const double _fValue,
|
|||
}
|
||||
}
|
||||
|
||||
float Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType,
|
||||
float Interpreter::Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType,
|
||||
const unsigned int _uScale)
|
||||
{
|
||||
// dequantize the value
|
||||
|
@ -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<EQuantizeType>(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<EQuantizeType>(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<EQuantizeType>(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<EQuantizeType>(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<EQuantizeType>(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<EQuantizeType>(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<EQuantizeType>(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<EQuantizeType>(gqr.ST_TYPE);
|
||||
|
@ -397,4 +394,3 @@ void psq_stux(UGeckoInstruction _inst)
|
|||
m_GPR[_inst.RA] = EA;
|
||||
|
||||
} // namespace=======
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
namespace JitILTables
|
||||
{
|
||||
void CompileInstruction(PPCAnalyst::CodeOp & op);
|
||||
void InitTables();
|
||||
void InitTables();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
switch (cpu_core)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
// Interpreter
|
||||
break;
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
Jit64Tables::InitTables();
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
JitILTables::InitTables();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
PanicAlert("Unrecognizable cpu_core: %d", cpu_core);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define OPLOG
|
||||
|
|
|
@ -113,7 +113,7 @@ class cJit64;
|
|||
namespace PPCTables
|
||||
{
|
||||
|
||||
void InitTables();
|
||||
void InitTables(int cpu_core);
|
||||
bool IsValidInstruction(UGeckoInstruction _instCode);
|
||||
bool UsesFPU(UGeckoInstruction _inst);
|
||||
|
||||
|
|
|
@ -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;
|
||||
else
|
||||
jit = new JitIL;
|
||||
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<JitBase*>(cpu_core_base);
|
||||
jit->Init();
|
||||
|
||||
mode = MODE_JIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
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.
|
||||
if (jit)
|
||||
{
|
||||
jit->Shutdown();
|
||||
state = CPU_POWERDOWN;
|
||||
delete jit;
|
||||
jit = 0;
|
||||
Interpreter::Shutdown();
|
||||
jit = NULL;
|
||||
}
|
||||
interpreter->Shutdown();
|
||||
cpu_core_base = NULL;
|
||||
state = CPU_POWERDOWN;
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
||||
|
|
Loading…
Reference in New Issue