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;
|
u32 last_pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Interpreter::m_EndBlock;
|
||||||
|
|
||||||
// function tables
|
// 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
|
g_bReserve = false;
|
||||||
u32 *m_GPR = PowerPC::ppcState.gpr;
|
m_EndBlock = false;
|
||||||
bool m_EndBlock = false;
|
}
|
||||||
|
|
||||||
_interpreterInstruction m_opTable[64];
|
void Interpreter::Shutdown()
|
||||||
_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 Shutdown()
|
static void patches()
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void patches()
|
|
||||||
{
|
{
|
||||||
/* if (Memory::Read_U16(0x90000880) == 0x130b)
|
/* if (Memory::Read_U16(0x90000880) == 0x130b)
|
||||||
{
|
{
|
||||||
|
@ -77,7 +74,7 @@ void patches()
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleStepInner(void)
|
void Interpreter::SingleStepInner(void)
|
||||||
{
|
{
|
||||||
static UGeckoInstruction instCode;
|
static UGeckoInstruction instCode;
|
||||||
|
|
||||||
|
@ -135,7 +132,7 @@ void SingleStepInner(void)
|
||||||
patches();
|
patches();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleStep()
|
void Interpreter::SingleStep()
|
||||||
{
|
{
|
||||||
SingleStepInner();
|
SingleStepInner();
|
||||||
|
|
||||||
|
@ -159,7 +156,7 @@ int ShowSteps = 300;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FastRun - inspired by GCemu (to imitate the JIT so that they can be compared).
|
// FastRun - inspired by GCemu (to imitate the JIT so that they can be compared).
|
||||||
void Run()
|
void Interpreter::Run()
|
||||||
{
|
{
|
||||||
while (!PowerPC::GetState())
|
while (!PowerPC::GetState())
|
||||||
{
|
{
|
||||||
|
@ -244,7 +241,7 @@ void Run()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void unknown_instruction(UGeckoInstruction _inst)
|
void Interpreter::unknown_instruction(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
if (_inst.hex != 0)
|
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 "../Gekko.h"
|
||||||
#include "../PowerPC.h"
|
#include "../PowerPC.h"
|
||||||
|
#include "../CPUCoreBase.h"
|
||||||
|
|
||||||
namespace Interpreter
|
class Interpreter : public CPUCoreBase
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
void Init();
|
void Init();
|
||||||
void Shutdown();
|
void Shutdown();
|
||||||
void Reset();
|
void Reset();
|
||||||
void SingleStep();
|
void SingleStep();
|
||||||
void SingleStepInner();
|
void SingleStepInner();
|
||||||
void Run();
|
void Run();
|
||||||
|
void ClearCache();
|
||||||
|
const char *GetName();
|
||||||
|
|
||||||
typedef void (*_interpreterInstruction)(UGeckoInstruction instCode);
|
typedef void (*_interpreterInstruction)(UGeckoInstruction instCode);
|
||||||
|
|
||||||
|
@ -36,288 +40,302 @@ namespace Interpreter
|
||||||
|
|
||||||
void Log();
|
void Log();
|
||||||
|
|
||||||
// pointer to the CPU-Regs to keep the code cleaner
|
// to keep the code cleaner
|
||||||
extern u32* m_GPR;
|
#define m_GPR (PowerPC::ppcState.gpr)
|
||||||
extern bool m_EndBlock;
|
static bool m_EndBlock;
|
||||||
|
|
||||||
void unknown_instruction(UGeckoInstruction _inst);
|
static void unknown_instruction(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Branch Instructions
|
// Branch Instructions
|
||||||
void bx(UGeckoInstruction _inst);
|
static void bx(UGeckoInstruction _inst);
|
||||||
void bcx(UGeckoInstruction _inst);
|
static void bcx(UGeckoInstruction _inst);
|
||||||
void bcctrx(UGeckoInstruction _inst);
|
static void bcctrx(UGeckoInstruction _inst);
|
||||||
void bclrx(UGeckoInstruction _inst);
|
static void bclrx(UGeckoInstruction _inst);
|
||||||
void HLEFunction(UGeckoInstruction _inst);
|
static void HLEFunction(UGeckoInstruction _inst);
|
||||||
void CompiledBlock(UGeckoInstruction _inst);
|
static void CompiledBlock(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Syscall Instruction
|
// Syscall Instruction
|
||||||
void sc(UGeckoInstruction _inst);
|
static void sc(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Floating Point Instructions
|
// Floating Point Instructions
|
||||||
void faddsx(UGeckoInstruction _inst);
|
static void faddsx(UGeckoInstruction _inst);
|
||||||
void fdivsx(UGeckoInstruction _inst);
|
static void fdivsx(UGeckoInstruction _inst);
|
||||||
void fmaddsx(UGeckoInstruction _inst);
|
static void fmaddsx(UGeckoInstruction _inst);
|
||||||
void fmsubsx(UGeckoInstruction _inst);
|
static void fmsubsx(UGeckoInstruction _inst);
|
||||||
void fmulsx(UGeckoInstruction _inst);
|
static void fmulsx(UGeckoInstruction _inst);
|
||||||
void fnmaddsx(UGeckoInstruction _inst);
|
static void fnmaddsx(UGeckoInstruction _inst);
|
||||||
void fnmsubsx(UGeckoInstruction _inst);
|
static void fnmsubsx(UGeckoInstruction _inst);
|
||||||
void fresx(UGeckoInstruction _inst);
|
static void fresx(UGeckoInstruction _inst);
|
||||||
// void fsqrtsx(UGeckoInstruction _inst);
|
// static void fsqrtsx(UGeckoInstruction _inst);
|
||||||
void fsubsx(UGeckoInstruction _inst);
|
static void fsubsx(UGeckoInstruction _inst);
|
||||||
void fabsx(UGeckoInstruction _inst);
|
static void fabsx(UGeckoInstruction _inst);
|
||||||
void fcmpo(UGeckoInstruction _inst);
|
static void fcmpo(UGeckoInstruction _inst);
|
||||||
void fcmpu(UGeckoInstruction _inst);
|
static void fcmpu(UGeckoInstruction _inst);
|
||||||
void fctiwx(UGeckoInstruction _inst);
|
static void fctiwx(UGeckoInstruction _inst);
|
||||||
void fctiwzx(UGeckoInstruction _inst);
|
static void fctiwzx(UGeckoInstruction _inst);
|
||||||
void fmrx(UGeckoInstruction _inst);
|
static void fmrx(UGeckoInstruction _inst);
|
||||||
void fnabsx(UGeckoInstruction _inst);
|
static void fnabsx(UGeckoInstruction _inst);
|
||||||
void fnegx(UGeckoInstruction _inst);
|
static void fnegx(UGeckoInstruction _inst);
|
||||||
void frspx(UGeckoInstruction _inst);
|
static void frspx(UGeckoInstruction _inst);
|
||||||
void faddx(UGeckoInstruction _inst);
|
static void faddx(UGeckoInstruction _inst);
|
||||||
void fdivx(UGeckoInstruction _inst);
|
static void fdivx(UGeckoInstruction _inst);
|
||||||
void fmaddx(UGeckoInstruction _inst);
|
static void fmaddx(UGeckoInstruction _inst);
|
||||||
void fmsubx(UGeckoInstruction _inst);
|
static void fmsubx(UGeckoInstruction _inst);
|
||||||
void fmulx(UGeckoInstruction _inst);
|
static void fmulx(UGeckoInstruction _inst);
|
||||||
void fnmaddx(UGeckoInstruction _inst);
|
static void fnmaddx(UGeckoInstruction _inst);
|
||||||
void fnmsubx(UGeckoInstruction _inst);
|
static void fnmsubx(UGeckoInstruction _inst);
|
||||||
void frsqrtex(UGeckoInstruction _inst);
|
static void frsqrtex(UGeckoInstruction _inst);
|
||||||
void fselx(UGeckoInstruction _inst);
|
static void fselx(UGeckoInstruction _inst);
|
||||||
void fsqrtx(UGeckoInstruction _inst);
|
static void fsqrtx(UGeckoInstruction _inst);
|
||||||
void fsubx(UGeckoInstruction _inst);
|
static void fsubx(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Integer Instructions
|
// Integer Instructions
|
||||||
void addi(UGeckoInstruction _inst);
|
static void addi(UGeckoInstruction _inst);
|
||||||
void addic(UGeckoInstruction _inst);
|
static void addic(UGeckoInstruction _inst);
|
||||||
void addic_rc(UGeckoInstruction _inst);
|
static void addic_rc(UGeckoInstruction _inst);
|
||||||
void addis(UGeckoInstruction _inst);
|
static void addis(UGeckoInstruction _inst);
|
||||||
void andi_rc(UGeckoInstruction _inst);
|
static void andi_rc(UGeckoInstruction _inst);
|
||||||
void andis_rc(UGeckoInstruction _inst);
|
static void andis_rc(UGeckoInstruction _inst);
|
||||||
void cmpi(UGeckoInstruction _inst);
|
static void cmpi(UGeckoInstruction _inst);
|
||||||
void cmpli(UGeckoInstruction _inst);
|
static void cmpli(UGeckoInstruction _inst);
|
||||||
void mulli(UGeckoInstruction _inst);
|
static void mulli(UGeckoInstruction _inst);
|
||||||
void ori(UGeckoInstruction _inst);
|
static void ori(UGeckoInstruction _inst);
|
||||||
void oris(UGeckoInstruction _inst);
|
static void oris(UGeckoInstruction _inst);
|
||||||
void subfic(UGeckoInstruction _inst);
|
static void subfic(UGeckoInstruction _inst);
|
||||||
void twi(UGeckoInstruction _inst);
|
static void twi(UGeckoInstruction _inst);
|
||||||
void xori(UGeckoInstruction _inst);
|
static void xori(UGeckoInstruction _inst);
|
||||||
void xoris(UGeckoInstruction _inst);
|
static void xoris(UGeckoInstruction _inst);
|
||||||
void rlwimix(UGeckoInstruction _inst);
|
static void rlwimix(UGeckoInstruction _inst);
|
||||||
void rlwinmx(UGeckoInstruction _inst);
|
static void rlwinmx(UGeckoInstruction _inst);
|
||||||
void rlwnmx(UGeckoInstruction _inst);
|
static void rlwnmx(UGeckoInstruction _inst);
|
||||||
void andx(UGeckoInstruction _inst);
|
static void andx(UGeckoInstruction _inst);
|
||||||
void andcx(UGeckoInstruction _inst);
|
static void andcx(UGeckoInstruction _inst);
|
||||||
void cmp(UGeckoInstruction _inst);
|
static void cmp(UGeckoInstruction _inst);
|
||||||
void cmpl(UGeckoInstruction _inst);
|
static void cmpl(UGeckoInstruction _inst);
|
||||||
void cntlzwx(UGeckoInstruction _inst);
|
static void cntlzwx(UGeckoInstruction _inst);
|
||||||
void eqvx(UGeckoInstruction _inst);
|
static void eqvx(UGeckoInstruction _inst);
|
||||||
void extsbx(UGeckoInstruction _inst);
|
static void extsbx(UGeckoInstruction _inst);
|
||||||
void extshx(UGeckoInstruction _inst);
|
static void extshx(UGeckoInstruction _inst);
|
||||||
void nandx(UGeckoInstruction _inst);
|
static void nandx(UGeckoInstruction _inst);
|
||||||
void norx(UGeckoInstruction _inst);
|
static void norx(UGeckoInstruction _inst);
|
||||||
void orx(UGeckoInstruction _inst);
|
static void orx(UGeckoInstruction _inst);
|
||||||
void orcx(UGeckoInstruction _inst);
|
static void orcx(UGeckoInstruction _inst);
|
||||||
void slwx(UGeckoInstruction _inst);
|
static void slwx(UGeckoInstruction _inst);
|
||||||
void srawx(UGeckoInstruction _inst);
|
static void srawx(UGeckoInstruction _inst);
|
||||||
void srawix(UGeckoInstruction _inst);
|
static void srawix(UGeckoInstruction _inst);
|
||||||
void srwx(UGeckoInstruction _inst);
|
static void srwx(UGeckoInstruction _inst);
|
||||||
void tw(UGeckoInstruction _inst);
|
static void tw(UGeckoInstruction _inst);
|
||||||
void xorx(UGeckoInstruction _inst);
|
static void xorx(UGeckoInstruction _inst);
|
||||||
void addx(UGeckoInstruction _inst);
|
static void addx(UGeckoInstruction _inst);
|
||||||
void addcx(UGeckoInstruction _inst);
|
static void addcx(UGeckoInstruction _inst);
|
||||||
void addex(UGeckoInstruction _inst);
|
static void addex(UGeckoInstruction _inst);
|
||||||
void addmex(UGeckoInstruction _inst);
|
static void addmex(UGeckoInstruction _inst);
|
||||||
void addzex(UGeckoInstruction _inst);
|
static void addzex(UGeckoInstruction _inst);
|
||||||
void divwx(UGeckoInstruction _inst);
|
static void divwx(UGeckoInstruction _inst);
|
||||||
void divwux(UGeckoInstruction _inst);
|
static void divwux(UGeckoInstruction _inst);
|
||||||
void mulhwx(UGeckoInstruction _inst);
|
static void mulhwx(UGeckoInstruction _inst);
|
||||||
void mulhwux(UGeckoInstruction _inst);
|
static void mulhwux(UGeckoInstruction _inst);
|
||||||
void mullwx(UGeckoInstruction _inst);
|
static void mullwx(UGeckoInstruction _inst);
|
||||||
void negx(UGeckoInstruction _inst);
|
static void negx(UGeckoInstruction _inst);
|
||||||
void subfx(UGeckoInstruction _inst);
|
static void subfx(UGeckoInstruction _inst);
|
||||||
void subfcx(UGeckoInstruction _inst);
|
static void subfcx(UGeckoInstruction _inst);
|
||||||
void subfex(UGeckoInstruction _inst);
|
static void subfex(UGeckoInstruction _inst);
|
||||||
void subfmex(UGeckoInstruction _inst);
|
static void subfmex(UGeckoInstruction _inst);
|
||||||
void subfzex(UGeckoInstruction _inst);
|
static void subfzex(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Load/Store Instructions
|
// Load/Store Instructions
|
||||||
void lbz(UGeckoInstruction _inst);
|
static void lbz(UGeckoInstruction _inst);
|
||||||
void lbzu(UGeckoInstruction _inst);
|
static void lbzu(UGeckoInstruction _inst);
|
||||||
void lfd(UGeckoInstruction _inst);
|
static void lfd(UGeckoInstruction _inst);
|
||||||
void lfdu(UGeckoInstruction _inst);
|
static void lfdu(UGeckoInstruction _inst);
|
||||||
void lfs(UGeckoInstruction _inst);
|
static void lfs(UGeckoInstruction _inst);
|
||||||
void lfsu(UGeckoInstruction _inst);
|
static void lfsu(UGeckoInstruction _inst);
|
||||||
void lha(UGeckoInstruction _inst);
|
static void lha(UGeckoInstruction _inst);
|
||||||
void lhau(UGeckoInstruction _inst);
|
static void lhau(UGeckoInstruction _inst);
|
||||||
void lhz(UGeckoInstruction _inst);
|
static void lhz(UGeckoInstruction _inst);
|
||||||
void lhzu(UGeckoInstruction _inst);
|
static void lhzu(UGeckoInstruction _inst);
|
||||||
void lmw(UGeckoInstruction _inst);
|
static void lmw(UGeckoInstruction _inst);
|
||||||
void lwz(UGeckoInstruction _inst);
|
static void lwz(UGeckoInstruction _inst);
|
||||||
void lwzu(UGeckoInstruction _inst);
|
static void lwzu(UGeckoInstruction _inst);
|
||||||
void stb(UGeckoInstruction _inst);
|
static void stb(UGeckoInstruction _inst);
|
||||||
void stbu(UGeckoInstruction _inst);
|
static void stbu(UGeckoInstruction _inst);
|
||||||
void stfd(UGeckoInstruction _inst);
|
static void stfd(UGeckoInstruction _inst);
|
||||||
void stfdu(UGeckoInstruction _inst);
|
static void stfdu(UGeckoInstruction _inst);
|
||||||
void stfs(UGeckoInstruction _inst);
|
static void stfs(UGeckoInstruction _inst);
|
||||||
void stfsu(UGeckoInstruction _inst);
|
static void stfsu(UGeckoInstruction _inst);
|
||||||
void sth(UGeckoInstruction _inst);
|
static void sth(UGeckoInstruction _inst);
|
||||||
void sthu(UGeckoInstruction _inst);
|
static void sthu(UGeckoInstruction _inst);
|
||||||
void stmw(UGeckoInstruction _inst);
|
static void stmw(UGeckoInstruction _inst);
|
||||||
void stw(UGeckoInstruction _inst);
|
static void stw(UGeckoInstruction _inst);
|
||||||
void stwu(UGeckoInstruction _inst);
|
static void stwu(UGeckoInstruction _inst);
|
||||||
void dcba(UGeckoInstruction _inst);
|
static void dcba(UGeckoInstruction _inst);
|
||||||
void dcbf(UGeckoInstruction _inst);
|
static void dcbf(UGeckoInstruction _inst);
|
||||||
void dcbi(UGeckoInstruction _inst);
|
static void dcbi(UGeckoInstruction _inst);
|
||||||
void dcbst(UGeckoInstruction _inst);
|
static void dcbst(UGeckoInstruction _inst);
|
||||||
void dcbt(UGeckoInstruction _inst);
|
static void dcbt(UGeckoInstruction _inst);
|
||||||
void dcbtst(UGeckoInstruction _inst);
|
static void dcbtst(UGeckoInstruction _inst);
|
||||||
void dcbz(UGeckoInstruction _inst);
|
static void dcbz(UGeckoInstruction _inst);
|
||||||
void eciwx(UGeckoInstruction _inst);
|
static void eciwx(UGeckoInstruction _inst);
|
||||||
void ecowx(UGeckoInstruction _inst);
|
static void ecowx(UGeckoInstruction _inst);
|
||||||
void eieio(UGeckoInstruction _inst);
|
static void eieio(UGeckoInstruction _inst);
|
||||||
void icbi(UGeckoInstruction _inst);
|
static void icbi(UGeckoInstruction _inst);
|
||||||
void lbzux(UGeckoInstruction _inst);
|
static void lbzux(UGeckoInstruction _inst);
|
||||||
void lbzx(UGeckoInstruction _inst);
|
static void lbzx(UGeckoInstruction _inst);
|
||||||
void lfdux(UGeckoInstruction _inst);
|
static void lfdux(UGeckoInstruction _inst);
|
||||||
void lfdx(UGeckoInstruction _inst);
|
static void lfdx(UGeckoInstruction _inst);
|
||||||
void lfsux(UGeckoInstruction _inst);
|
static void lfsux(UGeckoInstruction _inst);
|
||||||
void lfsx(UGeckoInstruction _inst);
|
static void lfsx(UGeckoInstruction _inst);
|
||||||
void lhaux(UGeckoInstruction _inst);
|
static void lhaux(UGeckoInstruction _inst);
|
||||||
void lhax(UGeckoInstruction _inst);
|
static void lhax(UGeckoInstruction _inst);
|
||||||
void lhbrx(UGeckoInstruction _inst);
|
static void lhbrx(UGeckoInstruction _inst);
|
||||||
void lhzux(UGeckoInstruction _inst);
|
static void lhzux(UGeckoInstruction _inst);
|
||||||
void lhzx(UGeckoInstruction _inst);
|
static void lhzx(UGeckoInstruction _inst);
|
||||||
void lswi(UGeckoInstruction _inst);
|
static void lswi(UGeckoInstruction _inst);
|
||||||
void lswx(UGeckoInstruction _inst);
|
static void lswx(UGeckoInstruction _inst);
|
||||||
void lwarx(UGeckoInstruction _inst);
|
static void lwarx(UGeckoInstruction _inst);
|
||||||
void lwbrx(UGeckoInstruction _inst);
|
static void lwbrx(UGeckoInstruction _inst);
|
||||||
void lwzux(UGeckoInstruction _inst);
|
static void lwzux(UGeckoInstruction _inst);
|
||||||
void lwzx(UGeckoInstruction _inst);
|
static void lwzx(UGeckoInstruction _inst);
|
||||||
void stbux(UGeckoInstruction _inst);
|
static void stbux(UGeckoInstruction _inst);
|
||||||
void stbx(UGeckoInstruction _inst);
|
static void stbx(UGeckoInstruction _inst);
|
||||||
void stfdux(UGeckoInstruction _inst);
|
static void stfdux(UGeckoInstruction _inst);
|
||||||
void stfdx(UGeckoInstruction _inst);
|
static void stfdx(UGeckoInstruction _inst);
|
||||||
void stfiwx(UGeckoInstruction _inst);
|
static void stfiwx(UGeckoInstruction _inst);
|
||||||
void stfsux(UGeckoInstruction _inst);
|
static void stfsux(UGeckoInstruction _inst);
|
||||||
void stfsx(UGeckoInstruction _inst);
|
static void stfsx(UGeckoInstruction _inst);
|
||||||
void sthbrx(UGeckoInstruction _inst);
|
static void sthbrx(UGeckoInstruction _inst);
|
||||||
void sthux(UGeckoInstruction _inst);
|
static void sthux(UGeckoInstruction _inst);
|
||||||
void sthx(UGeckoInstruction _inst);
|
static void sthx(UGeckoInstruction _inst);
|
||||||
void stswi(UGeckoInstruction _inst);
|
static void stswi(UGeckoInstruction _inst);
|
||||||
void stswx(UGeckoInstruction _inst);
|
static void stswx(UGeckoInstruction _inst);
|
||||||
void stwbrx(UGeckoInstruction _inst);
|
static void stwbrx(UGeckoInstruction _inst);
|
||||||
void stwcxd(UGeckoInstruction _inst);
|
static void stwcxd(UGeckoInstruction _inst);
|
||||||
void stwux(UGeckoInstruction _inst);
|
static void stwux(UGeckoInstruction _inst);
|
||||||
void stwx(UGeckoInstruction _inst);
|
static void stwx(UGeckoInstruction _inst);
|
||||||
void sync(UGeckoInstruction _inst);
|
static void sync(UGeckoInstruction _inst);
|
||||||
void tlbia(UGeckoInstruction _inst);
|
static void tlbia(UGeckoInstruction _inst);
|
||||||
void tlbie(UGeckoInstruction _inst);
|
static void tlbie(UGeckoInstruction _inst);
|
||||||
void tlbsync(UGeckoInstruction _inst);
|
static void tlbsync(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// Paired Instructions
|
// Paired Instructions
|
||||||
void psq_l(UGeckoInstruction _inst);
|
static void psq_l(UGeckoInstruction _inst);
|
||||||
void psq_lu(UGeckoInstruction _inst);
|
static void psq_lu(UGeckoInstruction _inst);
|
||||||
void psq_st(UGeckoInstruction _inst);
|
static void psq_st(UGeckoInstruction _inst);
|
||||||
void psq_stu(UGeckoInstruction _inst);
|
static void psq_stu(UGeckoInstruction _inst);
|
||||||
void psq_lx(UGeckoInstruction _inst);
|
static void psq_lx(UGeckoInstruction _inst);
|
||||||
void psq_stx(UGeckoInstruction _inst);
|
static void psq_stx(UGeckoInstruction _inst);
|
||||||
void psq_lux(UGeckoInstruction _inst);
|
static void psq_lux(UGeckoInstruction _inst);
|
||||||
void psq_stux(UGeckoInstruction _inst);
|
static void psq_stux(UGeckoInstruction _inst);
|
||||||
void ps_div(UGeckoInstruction _inst);
|
static void ps_div(UGeckoInstruction _inst);
|
||||||
void ps_sub(UGeckoInstruction _inst);
|
static void ps_sub(UGeckoInstruction _inst);
|
||||||
void ps_add(UGeckoInstruction _inst);
|
static void ps_add(UGeckoInstruction _inst);
|
||||||
void ps_sel(UGeckoInstruction _inst);
|
static void ps_sel(UGeckoInstruction _inst);
|
||||||
void ps_res(UGeckoInstruction _inst);
|
static void ps_res(UGeckoInstruction _inst);
|
||||||
void ps_mul(UGeckoInstruction _inst);
|
static void ps_mul(UGeckoInstruction _inst);
|
||||||
void ps_rsqrte(UGeckoInstruction _inst);
|
static void ps_rsqrte(UGeckoInstruction _inst);
|
||||||
void ps_msub(UGeckoInstruction _inst);
|
static void ps_msub(UGeckoInstruction _inst);
|
||||||
void ps_madd(UGeckoInstruction _inst);
|
static void ps_madd(UGeckoInstruction _inst);
|
||||||
void ps_nmsub(UGeckoInstruction _inst);
|
static void ps_nmsub(UGeckoInstruction _inst);
|
||||||
void ps_nmadd(UGeckoInstruction _inst);
|
static void ps_nmadd(UGeckoInstruction _inst);
|
||||||
void ps_neg(UGeckoInstruction _inst);
|
static void ps_neg(UGeckoInstruction _inst);
|
||||||
void ps_mr(UGeckoInstruction _inst);
|
static void ps_mr(UGeckoInstruction _inst);
|
||||||
void ps_nabs(UGeckoInstruction _inst);
|
static void ps_nabs(UGeckoInstruction _inst);
|
||||||
void ps_abs(UGeckoInstruction _inst);
|
static void ps_abs(UGeckoInstruction _inst);
|
||||||
void ps_sum0(UGeckoInstruction _inst);
|
static void ps_sum0(UGeckoInstruction _inst);
|
||||||
void ps_sum1(UGeckoInstruction _inst);
|
static void ps_sum1(UGeckoInstruction _inst);
|
||||||
void ps_muls0(UGeckoInstruction _inst);
|
static void ps_muls0(UGeckoInstruction _inst);
|
||||||
void ps_muls1(UGeckoInstruction _inst);
|
static void ps_muls1(UGeckoInstruction _inst);
|
||||||
void ps_madds0(UGeckoInstruction _inst);
|
static void ps_madds0(UGeckoInstruction _inst);
|
||||||
void ps_madds1(UGeckoInstruction _inst);
|
static void ps_madds1(UGeckoInstruction _inst);
|
||||||
void ps_cmpu0(UGeckoInstruction _inst);
|
static void ps_cmpu0(UGeckoInstruction _inst);
|
||||||
void ps_cmpo0(UGeckoInstruction _inst);
|
static void ps_cmpo0(UGeckoInstruction _inst);
|
||||||
void ps_cmpu1(UGeckoInstruction _inst);
|
static void ps_cmpu1(UGeckoInstruction _inst);
|
||||||
void ps_cmpo1(UGeckoInstruction _inst);
|
static void ps_cmpo1(UGeckoInstruction _inst);
|
||||||
void ps_merge00(UGeckoInstruction _inst);
|
static void ps_merge00(UGeckoInstruction _inst);
|
||||||
void ps_merge01(UGeckoInstruction _inst);
|
static void ps_merge01(UGeckoInstruction _inst);
|
||||||
void ps_merge10(UGeckoInstruction _inst);
|
static void ps_merge10(UGeckoInstruction _inst);
|
||||||
void ps_merge11(UGeckoInstruction _inst);
|
static void ps_merge11(UGeckoInstruction _inst);
|
||||||
void dcbz_l(UGeckoInstruction _inst);
|
static void dcbz_l(UGeckoInstruction _inst);
|
||||||
|
|
||||||
// System Registers Instructions
|
// System Registers Instructions
|
||||||
void mcrfs(UGeckoInstruction _inst);
|
static void mcrfs(UGeckoInstruction _inst);
|
||||||
void mffsx(UGeckoInstruction _inst);
|
static void mffsx(UGeckoInstruction _inst);
|
||||||
void mtfsb0x(UGeckoInstruction _inst);
|
static void mtfsb0x(UGeckoInstruction _inst);
|
||||||
void mtfsb1x(UGeckoInstruction _inst);
|
static void mtfsb1x(UGeckoInstruction _inst);
|
||||||
void mtfsfix(UGeckoInstruction _inst);
|
static void mtfsfix(UGeckoInstruction _inst);
|
||||||
void mtfsfx(UGeckoInstruction _inst);
|
static void mtfsfx(UGeckoInstruction _inst);
|
||||||
void mcrxr(UGeckoInstruction _inst);
|
static void mcrxr(UGeckoInstruction _inst);
|
||||||
void mfcr(UGeckoInstruction _inst);
|
static void mfcr(UGeckoInstruction _inst);
|
||||||
void mfmsr(UGeckoInstruction _inst);
|
static void mfmsr(UGeckoInstruction _inst);
|
||||||
void mfsr(UGeckoInstruction _inst);
|
static void mfsr(UGeckoInstruction _inst);
|
||||||
void mfsrin(UGeckoInstruction _inst);
|
static void mfsrin(UGeckoInstruction _inst);
|
||||||
void mtmsr(UGeckoInstruction _inst);
|
static void mtmsr(UGeckoInstruction _inst);
|
||||||
void mtsr(UGeckoInstruction _inst);
|
static void mtsr(UGeckoInstruction _inst);
|
||||||
void mtsrin(UGeckoInstruction _inst);
|
static void mtsrin(UGeckoInstruction _inst);
|
||||||
void mfspr(UGeckoInstruction _inst);
|
static void mfspr(UGeckoInstruction _inst);
|
||||||
void mftb(UGeckoInstruction _inst);
|
static void mftb(UGeckoInstruction _inst);
|
||||||
void mtcrf(UGeckoInstruction _inst);
|
static void mtcrf(UGeckoInstruction _inst);
|
||||||
void mtspr(UGeckoInstruction _inst);
|
static void mtspr(UGeckoInstruction _inst);
|
||||||
void crand(UGeckoInstruction _inst);
|
static void crand(UGeckoInstruction _inst);
|
||||||
void crandc(UGeckoInstruction _inst);
|
static void crandc(UGeckoInstruction _inst);
|
||||||
void creqv(UGeckoInstruction _inst);
|
static void creqv(UGeckoInstruction _inst);
|
||||||
void crnand(UGeckoInstruction _inst);
|
static void crnand(UGeckoInstruction _inst);
|
||||||
void crnor(UGeckoInstruction _inst);
|
static void crnor(UGeckoInstruction _inst);
|
||||||
void cror(UGeckoInstruction _inst);
|
static void cror(UGeckoInstruction _inst);
|
||||||
void crorc(UGeckoInstruction _inst);
|
static void crorc(UGeckoInstruction _inst);
|
||||||
void crxor(UGeckoInstruction _inst);
|
static void crxor(UGeckoInstruction _inst);
|
||||||
void mcrf(UGeckoInstruction _inst);
|
static void mcrf(UGeckoInstruction _inst);
|
||||||
void rfi(UGeckoInstruction _inst);
|
static void rfi(UGeckoInstruction _inst);
|
||||||
void rfid(UGeckoInstruction _inst);
|
static void rfid(UGeckoInstruction _inst);
|
||||||
// void sync(UGeckoInstruction _inst);
|
// static void sync(UGeckoInstruction _inst);
|
||||||
void isync(UGeckoInstruction _inst);
|
static void isync(UGeckoInstruction _inst);
|
||||||
|
|
||||||
void RunTable4(UGeckoInstruction _instCode);
|
static void RunTable4(UGeckoInstruction _instCode);
|
||||||
void RunTable19(UGeckoInstruction _instCode);
|
static void RunTable19(UGeckoInstruction _instCode);
|
||||||
void RunTable31(UGeckoInstruction _instCode);
|
static void RunTable31(UGeckoInstruction _instCode);
|
||||||
void RunTable59(UGeckoInstruction _instCode);
|
static void RunTable59(UGeckoInstruction _instCode);
|
||||||
void RunTable63(UGeckoInstruction _instCode);
|
static void RunTable63(UGeckoInstruction _instCode);
|
||||||
|
|
||||||
// flag helper
|
// flag helper
|
||||||
void Helper_UpdateCR0(u32 _uValue);
|
static void Helper_UpdateCR0(u32 _uValue);
|
||||||
void Helper_UpdateCR1(double _fValue);
|
static void Helper_UpdateCR1(double _fValue);
|
||||||
void Helper_UpdateCR1(float _fValue);
|
static void Helper_UpdateCR1(float _fValue);
|
||||||
void Helper_UpdateCRx(int _x, u32 _uValue);
|
static void Helper_UpdateCRx(int _x, u32 _uValue);
|
||||||
u32 Helper_Carry(u32 _uValue1, u32 _uValue2);
|
static u32 Helper_Carry(u32 _uValue1, u32 _uValue2);
|
||||||
|
|
||||||
// address helper
|
// address helper
|
||||||
u32 Helper_Get_EA (const UGeckoInstruction _inst);
|
static u32 Helper_Get_EA (const UGeckoInstruction _inst);
|
||||||
u32 Helper_Get_EA_U (const UGeckoInstruction _inst);
|
static u32 Helper_Get_EA_U (const UGeckoInstruction _inst);
|
||||||
u32 Helper_Get_EA_X (const UGeckoInstruction _inst);
|
static u32 Helper_Get_EA_X (const UGeckoInstruction _inst);
|
||||||
u32 Helper_Get_EA_UX(const UGeckoInstruction _inst);
|
static u32 Helper_Get_EA_UX(const UGeckoInstruction _inst);
|
||||||
|
|
||||||
// paired helper
|
// paired helper
|
||||||
float Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, const unsigned int _uScale);
|
static 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 void Helper_Quantize (const u32 _Addr, const double _fValue, const EQuantizeType _quantizeType, const unsigned _uScale);
|
||||||
|
|
||||||
// other helper
|
// other helper
|
||||||
u32 Helper_Mask(int mb, int me);
|
static u32 Helper_Mask(int mb, int me);
|
||||||
|
|
||||||
extern _interpreterInstruction m_opTable[64];
|
static _interpreterInstruction m_opTable[64];
|
||||||
extern _interpreterInstruction m_opTable4[1024];
|
static _interpreterInstruction m_opTable4[1024];
|
||||||
extern _interpreterInstruction m_opTable19[1024];
|
static _interpreterInstruction m_opTable19[1024];
|
||||||
extern _interpreterInstruction m_opTable31[1024];
|
static _interpreterInstruction m_opTable31[1024];
|
||||||
extern _interpreterInstruction m_opTable59[32];
|
static _interpreterInstruction m_opTable59[32];
|
||||||
extern _interpreterInstruction m_opTable63[1024];
|
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
|
#endif
|
||||||
|
|
|
@ -20,10 +20,7 @@
|
||||||
#include "../../HLE/HLE.h"
|
#include "../../HLE/HLE.h"
|
||||||
#include "../PPCAnalyst.h"
|
#include "../PPCAnalyst.h"
|
||||||
|
|
||||||
namespace Interpreter
|
void Interpreter::bx(UGeckoInstruction _inst)
|
||||||
{
|
|
||||||
|
|
||||||
void bx(UGeckoInstruction _inst)
|
|
||||||
{
|
{
|
||||||
if (_inst.LK)
|
if (_inst.LK)
|
||||||
LR = PC + 4;
|
LR = PC + 4;
|
||||||
|
@ -43,7 +40,7 @@ void bx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// bcx - ugly, straight from PPC manual equations :)
|
// bcx - ugly, straight from PPC manual equations :)
|
||||||
void bcx(UGeckoInstruction _inst)
|
void Interpreter::bcx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
CTR--;
|
CTR--;
|
||||||
|
@ -67,7 +64,7 @@ void bcx(UGeckoInstruction _inst)
|
||||||
m_EndBlock = true;
|
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!");
|
_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;
|
m_EndBlock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void bclrx(UGeckoInstruction _inst)
|
void Interpreter::bclrx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
if ((_inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
|
if ((_inst.BO_2 & BO_DONT_DECREMENT_FLAG) == 0)
|
||||||
CTR--;
|
CTR--;
|
||||||
|
@ -99,18 +96,18 @@ void bclrx(UGeckoInstruction _inst)
|
||||||
m_EndBlock = true;
|
m_EndBlock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void HLEFunction(UGeckoInstruction _inst)
|
void Interpreter::HLEFunction(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_EndBlock = true;
|
m_EndBlock = true;
|
||||||
HLE::Execute(PC, _inst.hex);
|
HLE::Execute(PC, _inst.hex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CompiledBlock(UGeckoInstruction _inst)
|
void Interpreter::CompiledBlock(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
_assert_msg_(POWERPC, 0, "CompiledBlock - shouldn't be here!");
|
_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.
|
// Restore saved bits from SRR1 to MSR.
|
||||||
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
|
// Gecko/Broadway can save more bits than explicitly defined in ppc spec
|
||||||
|
@ -127,7 +124,7 @@ void rfi(UGeckoInstruction _inst)
|
||||||
m_EndBlock = true;
|
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");
|
_dbg_assert_msg_(POWERPC,0,"Instruction unimplemented (does this instruction even exist?)","rfid");
|
||||||
m_EndBlock = true;
|
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.
|
// 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
|
// We do it anyway, though :P
|
||||||
void sc(UGeckoInstruction _inst)
|
void Interpreter::sc(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
|
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
|
||||||
PowerPC::CheckExceptions();
|
PowerPC::CheckExceptions();
|
||||||
m_EndBlock = true;
|
m_EndBlock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
|
@ -40,20 +40,17 @@
|
||||||
|
|
||||||
using namespace MathUtil;
|
using namespace MathUtil;
|
||||||
|
|
||||||
namespace Interpreter
|
|
||||||
{
|
|
||||||
|
|
||||||
void UpdateSSEState();
|
void UpdateSSEState();
|
||||||
|
|
||||||
// Extremely rare - actually, never seen.
|
// Extremely rare - actually, never seen.
|
||||||
// Star Wars : Rogue Leader spams that at some point :|
|
// 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.
|
// Should just update exception flags, not do any compares.
|
||||||
PanicAlert("CR1");
|
PanicAlert("CR1");
|
||||||
}
|
}
|
||||||
|
|
||||||
void fcmpo(UGeckoInstruction _inst)
|
void Interpreter::fcmpo(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double fa = rPS0(_inst.FA);
|
double fa = rPS0(_inst.FA);
|
||||||
double fb = rPS0(_inst.FB);
|
double fb = rPS0(_inst.FB);
|
||||||
|
@ -84,7 +81,7 @@ void fcmpo(UGeckoInstruction _inst)
|
||||||
SetCRField(_inst.CRFD, compareResult);
|
SetCRField(_inst.CRFD, compareResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
void fcmpu(UGeckoInstruction _inst)
|
void Interpreter::fcmpu(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double fa = rPS0(_inst.FA);
|
double fa = rPS0(_inst.FA);
|
||||||
double fb = rPS0(_inst.FB);
|
double fb = rPS0(_inst.FB);
|
||||||
|
@ -107,7 +104,7 @@ void fcmpu(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply current rounding mode
|
// Apply current rounding mode
|
||||||
void fctiwx(UGeckoInstruction _inst)
|
void Interpreter::fctiwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
const double b = rPS0(_inst.FB);
|
const double b = rPS0(_inst.FB);
|
||||||
u32 value;
|
u32 value;
|
||||||
|
@ -172,7 +169,7 @@ void fctiwx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Always round toward zero
|
// Always round toward zero
|
||||||
void fctiwzx(UGeckoInstruction _inst)
|
void Interpreter::fctiwzx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
const double b = rPS0(_inst.FB);
|
const double b = rPS0(_inst.FB);
|
||||||
u32 value;
|
u32 value;
|
||||||
|
@ -215,35 +212,35 @@ void fctiwzx(UGeckoInstruction _inst)
|
||||||
Helper_UpdateCR1(rPS0(_inst.FD));
|
Helper_UpdateCR1(rPS0(_inst.FD));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fmrx(UGeckoInstruction _inst)
|
void Interpreter::fmrx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
riPS0(_inst.FD) = riPS0(_inst.FB);
|
riPS0(_inst.FD) = riPS0(_inst.FB);
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
||||||
}
|
}
|
||||||
|
|
||||||
void fabsx(UGeckoInstruction _inst)
|
void Interpreter::fabsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = fabs(rPS0(_inst.FB));
|
rPS0(_inst.FD) = fabs(rPS0(_inst.FB));
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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);
|
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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);
|
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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);
|
rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB);
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
|
@ -253,7 +250,7 @@ void fselx(UGeckoInstruction _inst)
|
||||||
// !!! warning !!!
|
// !!! warning !!!
|
||||||
// PS1 must be set to the value of PS0 or DragonballZ will be f**ked up
|
// PS1 must be set to the value of PS0 or DragonballZ will be f**ked up
|
||||||
// PS1 is said to be undefined
|
// 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 b = rPS0(_inst.FB);
|
||||||
double rounded = ForceSingle(b);
|
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)));
|
rPS0(_inst.FD) = ForceDouble(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC)));
|
||||||
FPSCR.FI = 0; // are these flags important?
|
FPSCR.FI = 0; // are these flags important?
|
||||||
|
@ -273,7 +270,7 @@ void fmulx(UGeckoInstruction _inst)
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1(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));
|
double d_value = NI_mul(rPS0(_inst.FA), rPS0(_inst.FC));
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(d_value);
|
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));
|
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) ));
|
double result = ForceDouble(NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
|
||||||
rPS0(_inst.FD) = result;
|
rPS0(_inst.FD) = result;
|
||||||
|
@ -292,7 +289,7 @@ void fmaddx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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) );
|
double d_value = NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) );
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(d_value);
|
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)));
|
rPS0(_inst.FD) = ForceDouble(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1(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)));
|
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1(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 a = rPS0(_inst.FA);
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
|
@ -347,7 +344,7 @@ void fdivx(UGeckoInstruction _inst)
|
||||||
// FR,FI,OX,UX???
|
// FR,FI,OX,UX???
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
||||||
}
|
}
|
||||||
void fdivsx(UGeckoInstruction _inst)
|
void Interpreter::fdivsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double a = rPS0(_inst.FA);
|
double a = rPS0(_inst.FA);
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
|
@ -381,7 +378,7 @@ void fdivsx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single precision only.
|
// Single precision only.
|
||||||
void fresx(UGeckoInstruction _inst)
|
void Interpreter::fresx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
double one_over = ForceSingle(1.0 / b);
|
double one_over = ForceSingle(1.0 / b);
|
||||||
|
@ -405,7 +402,7 @@ void fresx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
||||||
}
|
}
|
||||||
|
|
||||||
void frsqrtex(UGeckoInstruction _inst)
|
void Interpreter::frsqrtex(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
if (b < 0.0)
|
if (b < 0.0)
|
||||||
|
@ -447,14 +444,14 @@ void frsqrtex(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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) ));
|
rPS0(_inst.FD) = ForceDouble(NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1(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) =
|
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
||||||
ForceSingle( NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
|
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));
|
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)));
|
rPS0(_inst.FD) = ForceDouble(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1(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) =
|
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
||||||
ForceSingle(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
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));
|
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)));
|
rPS0(_inst.FD) = ForceDouble(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
|
@ -484,7 +481,7 @@ void fnmsubx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// fnmsubsx does not handle QNAN properly - see NI_msub
|
// fnmsubsx does not handle QNAN properly - see NI_msub
|
||||||
void fnmsubsx(UGeckoInstruction _inst)
|
void Interpreter::fnmsubsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
||||||
ForceSingle(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
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));
|
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)));
|
rPS0(_inst.FD) = ForceDouble(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1(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)));
|
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1(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.
|
// GEKKO is not supposed to support this instruction.
|
||||||
// PanicAlert("fsqrtx");
|
// PanicAlert("fsqrtx");
|
||||||
|
@ -518,5 +515,3 @@ void fsqrtx(UGeckoInstruction _inst)
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
|
@ -18,10 +18,7 @@
|
||||||
#include "Interpreter.h"
|
#include "Interpreter.h"
|
||||||
#include "../../Core.h"
|
#include "../../Core.h"
|
||||||
|
|
||||||
namespace Interpreter
|
void Interpreter::Helper_UpdateCR0(u32 _uValue)
|
||||||
{
|
|
||||||
|
|
||||||
void Helper_UpdateCR0(u32 _uValue)
|
|
||||||
{
|
{
|
||||||
u32 new_cr0;
|
u32 new_cr0;
|
||||||
int sValue = (int)_uValue;
|
int sValue = (int)_uValue;
|
||||||
|
@ -35,7 +32,7 @@ void Helper_UpdateCR0(u32 _uValue)
|
||||||
SetCRField(0, new_cr0);
|
SetCRField(0, new_cr0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Helper_UpdateCRx(int _x, u32 _uValue)
|
void Interpreter::Helper_UpdateCRx(int _x, u32 _uValue)
|
||||||
{
|
{
|
||||||
u32 new_crX;
|
u32 new_crX;
|
||||||
int sValue = (int)_uValue;
|
int sValue = (int)_uValue;
|
||||||
|
@ -49,12 +46,12 @@ void Helper_UpdateCRx(int _x, u32 _uValue)
|
||||||
SetCRField(_x, new_crX);
|
SetCRField(_x, new_crX);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Helper_Carry(u32 _uValue1, u32 _uValue2)
|
u32 Interpreter::Helper_Carry(u32 _uValue1, u32 _uValue2)
|
||||||
{
|
{
|
||||||
return _uValue2 > (~_uValue1);
|
return _uValue2 > (~_uValue1);
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 Helper_Mask(int mb, int me)
|
u32 Interpreter::Helper_Mask(int mb, int me)
|
||||||
{
|
{
|
||||||
//first make 001111111111111 part
|
//first make 001111111111111 part
|
||||||
u32 begin = 0xFFFFFFFF >> mb;
|
u32 begin = 0xFFFFFFFF >> mb;
|
||||||
|
@ -69,7 +66,7 @@ u32 Helper_Mask(int mb, int me)
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addi(UGeckoInstruction _inst)
|
void Interpreter::addi(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
if (_inst.RA)
|
if (_inst.RA)
|
||||||
m_GPR[_inst.RD] = m_GPR[_inst.RA] + _inst.SIMM_16;
|
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;
|
m_GPR[_inst.RD] = _inst.SIMM_16;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addic(UGeckoInstruction _inst)
|
void Interpreter::addic(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 a = m_GPR[_inst.RA];
|
u32 a = m_GPR[_inst.RA];
|
||||||
u32 imm = (u32)(s32)_inst.SIMM_16;
|
u32 imm = (u32)(s32)_inst.SIMM_16;
|
||||||
|
@ -86,13 +83,13 @@ void addic(UGeckoInstruction _inst)
|
||||||
SetCarry(Helper_Carry(a, imm));
|
SetCarry(Helper_Carry(a, imm));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addic_rc(UGeckoInstruction _inst)
|
void Interpreter::addic_rc(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
addic(_inst);
|
addic(_inst);
|
||||||
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addis(UGeckoInstruction _inst)
|
void Interpreter::addis(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
if (_inst.RA)
|
if (_inst.RA)
|
||||||
m_GPR[_inst.RD] = m_GPR[_inst.RA] + (_inst.SIMM_16 << 16);
|
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);
|
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;
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] & _inst.UIMM;
|
||||||
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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);
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] & ((u32)_inst.UIMM<<16);
|
||||||
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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);
|
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 a = m_GPR[_inst.RA];
|
||||||
u32 b = _inst.UIMM;
|
u32 b = _inst.UIMM;
|
||||||
|
@ -129,22 +126,22 @@ void cmpli(UGeckoInstruction _inst)
|
||||||
SetCRField(_inst.CRFD, f);
|
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;
|
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;
|
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);
|
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];
|
/* u32 rra = ~m_GPR[_inst.RA];
|
||||||
s32 immediate = (s16)_inst.SIMM_16 + 1;
|
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)));
|
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 a = m_GPR[_inst.RA];
|
||||||
s32 b = _inst.SIMM_16;
|
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;
|
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);
|
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);
|
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);
|
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]);
|
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);
|
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
|
||||||
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS],_inst.SH) & mask;
|
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS],_inst.SH) & mask;
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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);
|
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
|
||||||
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS], m_GPR[_inst.RB] & 0x1F) & mask;
|
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]);
|
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];
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] & m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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];
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] & ~m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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 a = (s32)m_GPR[_inst.RA];
|
||||||
s32 b = (s32)m_GPR[_inst.RB];
|
s32 b = (s32)m_GPR[_inst.RB];
|
||||||
|
@ -241,7 +238,7 @@ void cmp(UGeckoInstruction _inst)
|
||||||
SetCRField(_inst.CRFD, fTemp);
|
SetCRField(_inst.CRFD, fTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cmpl(UGeckoInstruction _inst)
|
void Interpreter::cmpl(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 a = m_GPR[_inst.RA];
|
u32 a = m_GPR[_inst.RA];
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
|
@ -254,7 +251,7 @@ void cmpl(UGeckoInstruction _inst)
|
||||||
SetCRField(_inst.CRFD, fTemp);
|
SetCRField(_inst.CRFD, fTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cntlzwx(UGeckoInstruction _inst)
|
void Interpreter::cntlzwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 val = m_GPR[_inst.RS];
|
u32 val = m_GPR[_inst.RS];
|
||||||
u32 mask = 0x80000000;
|
u32 mask = 0x80000000;
|
||||||
|
@ -266,56 +263,56 @@ void cntlzwx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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]);
|
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] ^ m_GPR[_inst.RB]);
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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];
|
m_GPR[_inst.RA] = (u32)(s32)(s8)m_GPR[_inst.RS];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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];
|
m_GPR[_inst.RA] = (u32)(s32)(s16)m_GPR[_inst.RS];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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]);
|
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] & m_GPR[_inst.RB]);
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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]);
|
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] | m_GPR[_inst.RB]);
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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];
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] | m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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]);
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] | (~m_GPR[_inst.RB]);
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void slwx(UGeckoInstruction _inst)
|
void Interpreter::slwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 amount = m_GPR[_inst.RB];
|
u32 amount = m_GPR[_inst.RB];
|
||||||
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : m_GPR[_inst.RS] << amount;
|
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]);
|
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void srawx(UGeckoInstruction _inst)
|
void Interpreter::srawx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int rb = m_GPR[_inst.RB];
|
int rb = m_GPR[_inst.RB];
|
||||||
if (rb & 0x20)
|
if (rb & 0x20)
|
||||||
|
@ -360,7 +357,7 @@ void srawx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void srawix(UGeckoInstruction _inst)
|
void Interpreter::srawix(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int amount = _inst.SH;
|
int amount = _inst.SH;
|
||||||
|
|
||||||
|
@ -383,7 +380,7 @@ void srawix(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void srwx(UGeckoInstruction _inst)
|
void Interpreter::srwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 amount = m_GPR[_inst.RB];
|
u32 amount = m_GPR[_inst.RB];
|
||||||
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> (amount & 0x1f));
|
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]);
|
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 a = m_GPR[_inst.RA];
|
||||||
s32 b = m_GPR[_inst.RB];
|
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];
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
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];
|
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]);
|
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 a = m_GPR[_inst.RA];
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
|
@ -437,7 +434,7 @@ void addcx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addex(UGeckoInstruction _inst)
|
void Interpreter::addex(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int carry = GetCarry();
|
int carry = GetCarry();
|
||||||
int a = m_GPR[_inst.RA];
|
int a = m_GPR[_inst.RA];
|
||||||
|
@ -449,7 +446,7 @@ void addex(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addmex(UGeckoInstruction _inst)
|
void Interpreter::addmex(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int carry = GetCarry();
|
int carry = GetCarry();
|
||||||
int a = m_GPR[_inst.RA];
|
int a = m_GPR[_inst.RA];
|
||||||
|
@ -460,7 +457,7 @@ void addmex(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addzex(UGeckoInstruction _inst)
|
void Interpreter::addzex(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int carry = GetCarry();
|
int carry = GetCarry();
|
||||||
int a = m_GPR[_inst.RA];
|
int a = m_GPR[_inst.RA];
|
||||||
|
@ -471,7 +468,7 @@ void addzex(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
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 a = m_GPR[_inst.RA];
|
||||||
s32 b = m_GPR[_inst.RB];
|
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 a = m_GPR[_inst.RA];
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
|
@ -510,7 +507,7 @@ void divwux(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
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 a = m_GPR[_inst.RA];
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
|
@ -519,7 +516,7 @@ void mulhwx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
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 a = m_GPR[_inst.RA];
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
|
@ -528,7 +525,7 @@ void mulhwux(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
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 a = m_GPR[_inst.RA];
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
|
@ -539,7 +536,7 @@ void mullwx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
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;
|
m_GPR[_inst.RD] = (~m_GPR[_inst.RA]) + 1;
|
||||||
if (m_GPR[_inst.RD] == 0x80000000)
|
if (m_GPR[_inst.RD] == 0x80000000)
|
||||||
|
@ -549,7 +546,7 @@ void negx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
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];
|
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]);
|
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 a = m_GPR[_inst.RA];
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
|
@ -568,7 +565,7 @@ void subfcx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
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 a = m_GPR[_inst.RA];
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
|
@ -581,7 +578,7 @@ void subfex(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sub from minus one
|
// sub from minus one
|
||||||
void subfmex(UGeckoInstruction _inst)
|
void Interpreter::subfmex(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 a = m_GPR[_inst.RA];
|
u32 a = m_GPR[_inst.RA];
|
||||||
int carry = GetCarry();
|
int carry = GetCarry();
|
||||||
|
@ -593,7 +590,7 @@ void subfmex(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sub from zero
|
// sub from zero
|
||||||
void subfzex(UGeckoInstruction _inst)
|
void Interpreter::subfzex(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 a = m_GPR[_inst.RA];
|
u32 a = m_GPR[_inst.RA];
|
||||||
int carry = GetCarry();
|
int carry = GetCarry();
|
||||||
|
@ -603,5 +600,3 @@ void subfzex(UGeckoInstruction _inst)
|
||||||
if (_inst.OE) PanicAlert("OE: subfzex");
|
if (_inst.OE) PanicAlert("OE: subfzex");
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
|
@ -28,42 +28,37 @@
|
||||||
|
|
||||||
#include "Interpreter_FPUtils.h"
|
#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.
|
u32 Interpreter::Helper_Get_EA(const UGeckoInstruction _inst)
|
||||||
// They are for lwarx and its friend stwcxd.
|
|
||||||
static bool g_bReserve = false;
|
|
||||||
static u32 g_reserveAddr;
|
|
||||||
|
|
||||||
u32 Helper_Get_EA(const UGeckoInstruction _inst)
|
|
||||||
{
|
{
|
||||||
return _inst.RA ? (m_GPR[_inst.RA] + _inst.SIMM_16) : _inst.SIMM_16;
|
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);
|
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];
|
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]);
|
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));
|
u32 temp = (u32)Memory::Read_U8(Helper_Get_EA(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||||
m_GPR[_inst.RD] = temp;
|
m_GPR[_inst.RD] = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lbzu(UGeckoInstruction _inst)
|
void Interpreter::lbzu(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 uAddress = Helper_Get_EA_U(_inst);
|
u32 uAddress = Helper_Get_EA_U(_inst);
|
||||||
u32 temp = (u32)Memory::Read_U8(uAddress);
|
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));
|
u64 temp = Memory::Read_U64(Helper_Get_EA(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||||
riPS0(_inst.FD) = temp;
|
riPS0(_inst.FD) = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lfdu(UGeckoInstruction _inst)
|
void Interpreter::lfdu(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 uAddress = Helper_Get_EA_U(_inst);
|
u32 uAddress = Helper_Get_EA_U(_inst);
|
||||||
u64 temp = Memory::Read_U64(uAddress);
|
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);
|
u32 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
u64 temp = Memory::Read_U64(uAddress);
|
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));
|
u64 temp = Memory::Read_U64(Helper_Get_EA_X(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||||
riPS0(_inst.FD) = temp;
|
riPS0(_inst.FD) = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lfs(UGeckoInstruction _inst)
|
void Interpreter::lfs(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 uTemp = Memory::Read_U32(Helper_Get_EA(_inst));
|
u32 uTemp = Memory::Read_U32(Helper_Get_EA(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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 uAddress = Helper_Get_EA_U(_inst);
|
||||||
u32 uTemp = Memory::Read_U32(uAddress);
|
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 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
u32 uTemp = Memory::Read_U32(uAddress);
|
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));
|
u32 uTemp = Memory::Read_U32(Helper_Get_EA_X(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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));
|
u32 temp = (u32)(s32)(s16)Memory::Read_U16(Helper_Get_EA(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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 uAddress = Helper_Get_EA_U(_inst);
|
||||||
u32 temp = (u32)(s32)(s16)Memory::Read_U16(uAddress);
|
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));
|
u32 temp = (u32)(u16)Memory::Read_U16(Helper_Get_EA(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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 uAddress = Helper_Get_EA_U(_inst);
|
||||||
u32 temp = (u32)(u16)Memory::Read_U16(uAddress);
|
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
|
// 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);
|
u32 uAddress = Helper_Get_EA(_inst);
|
||||||
for (int iReg = _inst.RD; iReg <= 31; iReg++, uAddress += 4)
|
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
|
// 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);
|
u32 uAddress = Helper_Get_EA(_inst);
|
||||||
for (int iReg = _inst.RS; iReg <= 31; iReg++, uAddress+=4)
|
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 uAddress = Helper_Get_EA(_inst);
|
||||||
u32 temp = Memory::Read_U32(uAddress);
|
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 uAddress = Helper_Get_EA_U(_inst);
|
||||||
u32 temp = Memory::Read_U32(uAddress);
|
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));
|
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);
|
u32 uAddress = Helper_Get_EA_U(_inst);
|
||||||
Memory::Write_U8((u8)m_GPR[_inst.RS], uAddress);
|
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));
|
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);
|
u32 uAddress = Helper_Get_EA_U(_inst);
|
||||||
Memory::Write_U64(riPS0(_inst.FS), uAddress);
|
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);
|
//double value = rPS0(_inst.FS);
|
||||||
//float fTemp = (float)value;
|
//float fTemp = (float)value;
|
||||||
|
@ -310,7 +305,7 @@ void stfs(UGeckoInstruction _inst)
|
||||||
Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), Helper_Get_EA(_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);
|
u32 uAddress = Helper_Get_EA_U(_inst);
|
||||||
Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress);
|
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));
|
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);
|
u32 uAddress = Helper_Get_EA_U(_inst);
|
||||||
Memory::Write_U16((u16)m_GPR[_inst.RS], uAddress);
|
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));
|
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);
|
u32 uAddress = Helper_Get_EA_U(_inst);
|
||||||
Memory::Write_U32(m_GPR[_inst.RS], uAddress);
|
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");
|
_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
|
//This should tell GFX plugin to throw out any cached data here
|
||||||
// !!! SPEEDUP HACK for OSProtectRange !!!
|
// !!! 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.
|
// 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.
|
// 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.
|
// 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.
|
// 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".
|
// This is just some sort of store "prefetching".
|
||||||
// Since we don't emulate the data cache, we don't need to do anything.
|
// 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
|
// HACK but works... we think
|
||||||
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
|
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
|
// eciwx/ecowx technically should access the specified device
|
||||||
// We just do it instantly from ppc...and hey, it works! :D
|
// We just do it instantly from ppc...and hey, it works! :D
|
||||||
void eciwx(UGeckoInstruction _inst)
|
void Interpreter::eciwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 EA, b;
|
u32 EA, b;
|
||||||
if (_inst.RA == 0)
|
if (_inst.RA == 0)
|
||||||
|
@ -421,7 +416,7 @@ void eciwx(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RS] = Memory::Read_U32(EA);
|
m_GPR[_inst.RS] = Memory::Read_U32(EA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ecowx(UGeckoInstruction _inst)
|
void Interpreter::ecowx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 EA, b;
|
u32 EA, b;
|
||||||
if (_inst.RA == 0)
|
if (_inst.RA == 0)
|
||||||
|
@ -443,7 +438,7 @@ void ecowx(UGeckoInstruction _inst)
|
||||||
Memory::Write_U32(m_GPR[_inst.RS], EA);
|
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
|
// Basically ensures that loads/stores before this instruction
|
||||||
// have completed (in order) before executing the next op.
|
// 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.
|
// 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);
|
u32 address = Helper_Get_EA_X(_inst);
|
||||||
PowerPC::ppcState.iCache.Invalidate(address);
|
PowerPC::ppcState.iCache.Invalidate(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lbzux(UGeckoInstruction _inst)
|
void Interpreter::lbzux(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 uAddress = Helper_Get_EA_UX(_inst);
|
u32 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
u32 temp = (u32)Memory::Read_U8(uAddress);
|
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));
|
u32 temp = (u32)Memory::Read_U8(Helper_Get_EA_X(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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);
|
u32 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
s32 temp = (s32)(s16)Memory::Read_U16(uAddress);
|
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));
|
s32 temp = (s32)(s16)Memory::Read_U16(Helper_Get_EA_X(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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)));
|
u32 temp = (u32)Common::swap16(Memory::Read_U16(Helper_Get_EA_X(_inst)));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
u32 temp = (u32)Memory::Read_U16(uAddress);
|
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));
|
u32 temp = (u32)Memory::Read_U16(Helper_Get_EA_X(_inst));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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;
|
static bool bFirst = true;
|
||||||
if (bFirst)
|
if (bFirst)
|
||||||
|
@ -534,7 +529,7 @@ void lswx(UGeckoInstruction _inst)
|
||||||
bFirst = false;
|
bFirst = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lwbrx(UGeckoInstruction _inst)
|
void Interpreter::lwbrx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 temp = Common::swap32(Memory::Read_U32(Helper_Get_EA_X(_inst)));
|
u32 temp = Common::swap32(Memory::Read_U32(Helper_Get_EA_X(_inst)));
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
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 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
u32 temp = Memory::Read_U32(uAddress);
|
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 uAddress = Helper_Get_EA_X(_inst);
|
||||||
u32 temp = Memory::Read_U32(uAddress);
|
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);
|
u32 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
Memory::Write_U8((u8)m_GPR[_inst.RS], uAddress);
|
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));
|
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);
|
u32 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
Memory::Write_U64(riPS0(_inst.FS), uAddress);
|
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));
|
Memory::Write_U64(riPS0(_inst.FS), Helper_Get_EA_X(_inst));
|
||||||
}
|
}
|
||||||
|
@ -598,7 +593,7 @@ void stfdx(UGeckoInstruction _inst)
|
||||||
// stfiwx
|
// stfiwx
|
||||||
// TODO - examine what this really does
|
// TODO - examine what this really does
|
||||||
// Stores Floating points into Integers indeXed
|
// Stores Floating points into Integers indeXed
|
||||||
void stfiwx(UGeckoInstruction _inst)
|
void Interpreter::stfiwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 uAddress = Helper_Get_EA_X(_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);
|
u32 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
Memory::Write_U32(ConvertToSingle(riPS0(_inst.FS)), uAddress);
|
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));
|
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));
|
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);
|
u32 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
Memory::Write_U16((u16)m_GPR[_inst.RS], uAddress);
|
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));
|
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
|
// lswi - bizarro string instruction
|
||||||
// FIXME: Should rollback if a DSI occurs
|
// FIXME: Should rollback if a DSI occurs
|
||||||
void lswi(UGeckoInstruction _inst)
|
void Interpreter::lswi(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 EA;
|
u32 EA;
|
||||||
if (_inst.RA == 0)
|
if (_inst.RA == 0)
|
||||||
|
@ -690,7 +685,7 @@ void lswi(UGeckoInstruction _inst)
|
||||||
// __________________________________________________________________________________________________
|
// __________________________________________________________________________________________________
|
||||||
// stswi - bizarro string instruction
|
// stswi - bizarro string instruction
|
||||||
// FIXME: Should rollback if a DSI occurs
|
// FIXME: Should rollback if a DSI occurs
|
||||||
void stswi(UGeckoInstruction _inst)
|
void Interpreter::stswi(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 EA;
|
u32 EA;
|
||||||
if (_inst.RA == 0)
|
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;
|
static bool bFirst = true;
|
||||||
if (bFirst)
|
if (bFirst)
|
||||||
|
@ -735,7 +730,7 @@ void stswx(UGeckoInstruction _inst)
|
||||||
bFirst = false;
|
bFirst = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stwbrx(UGeckoInstruction _inst)
|
void Interpreter::stwbrx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 uAddress = Helper_Get_EA_X(_inst);
|
u32 uAddress = Helper_Get_EA_X(_inst);
|
||||||
Memory::Write_U32(Common::swap32(m_GPR[_inst.RS]), uAddress);
|
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
|
// The following two instructions are for SMP communications. On a single
|
||||||
// CPU, they cannot fail unless an interrupt happens in between.
|
// 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 uAddress = Helper_Get_EA_X(_inst);
|
||||||
u32 temp = Memory::Read_U32(uAddress);
|
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
|
// Stores Word Conditional indeXed
|
||||||
u32 uAddress;
|
u32 uAddress;
|
||||||
|
@ -777,7 +772,7 @@ void stwcxd(UGeckoInstruction _inst)
|
||||||
SetCRField(0, GetXER_SO());
|
SetCRField(0, GetXER_SO());
|
||||||
}
|
}
|
||||||
|
|
||||||
void stwux(UGeckoInstruction _inst)
|
void Interpreter::stwux(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 uAddress = Helper_Get_EA_UX(_inst);
|
u32 uAddress = Helper_Get_EA_UX(_inst);
|
||||||
Memory::Write_U32(m_GPR[_inst.RS], uAddress);
|
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);
|
u32 uAddress = Helper_Get_EA_X(_inst);
|
||||||
Memory::Write_U32(m_GPR[_inst.RS], uAddress);
|
Memory::Write_U32(m_GPR[_inst.RS], uAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
void sync(UGeckoInstruction _inst)
|
void Interpreter::sync(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
//ignored
|
//ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
void tlbia(UGeckoInstruction _inst)
|
void Interpreter::tlbia(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// Gekko does not support this instructions.
|
// Gekko does not support this instructions.
|
||||||
PanicAlert("The GC CPU does not support tlbia");
|
PanicAlert("The GC CPU does not support tlbia");
|
||||||
|
@ -806,16 +801,14 @@ void tlbia(UGeckoInstruction _inst)
|
||||||
//MessageBox(0,"TLBIA","TLBIA",0);
|
//MessageBox(0,"TLBIA","TLBIA",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tlbie(UGeckoInstruction _inst)
|
void Interpreter::tlbie(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// Invalidate TLB entry
|
// Invalidate TLB entry
|
||||||
u32 _Address = m_GPR[_inst.RB];
|
u32 _Address = m_GPR[_inst.RB];
|
||||||
Memory::InvalidateTLBEntry(_Address);
|
Memory::InvalidateTLBEntry(_Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
void tlbsync(UGeckoInstruction _inst)
|
void Interpreter::tlbsync(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
//MessageBox(0,"TLBsync","TLBsyncE",0);
|
//MessageBox(0,"TLBsync","TLBsyncE",0);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
|
@ -21,9 +21,6 @@
|
||||||
|
|
||||||
#include "Interpreter_FPUtils.h"
|
#include "Interpreter_FPUtils.h"
|
||||||
|
|
||||||
namespace Interpreter
|
|
||||||
{
|
|
||||||
|
|
||||||
// dequantize table
|
// dequantize table
|
||||||
const float m_dequantizeTable[] =
|
const float m_dequantizeTable[] =
|
||||||
{
|
{
|
||||||
|
@ -73,7 +70,7 @@ inline T CLAMP(T a, T bottom, T top) {
|
||||||
return a;
|
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)
|
const EQuantizeType _quantizeType, const unsigned int _uScale)
|
||||||
{
|
{
|
||||||
switch (_quantizeType)
|
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)
|
const unsigned int _uScale)
|
||||||
{
|
{
|
||||||
// dequantize the value
|
// dequantize the value
|
||||||
|
@ -156,7 +153,7 @@ float Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType,
|
||||||
return fResult;
|
return fResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
void psq_l(UGeckoInstruction _inst)
|
void Interpreter::psq_l(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
const UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
|
const UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
|
||||||
const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
|
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 UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
|
||||||
const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
|
const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
|
||||||
|
@ -225,7 +222,7 @@ void psq_lu(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RA] = EA;
|
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 UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
|
||||||
const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
|
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 UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
|
||||||
const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
|
const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
|
||||||
|
@ -274,7 +271,7 @@ void psq_stu(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RA] = EA;
|
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 UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix));
|
||||||
const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
|
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 UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix));
|
||||||
const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
|
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 UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix));
|
||||||
const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
|
const EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
|
||||||
|
@ -370,7 +367,7 @@ void psq_lux(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RA] = EA;
|
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 UGQR gqr(rSPR(SPR_GQR0 + _inst.Ix));
|
||||||
const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
|
const EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
|
||||||
|
@ -397,4 +394,3 @@ void psq_stux(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RA] = EA;
|
m_GPR[_inst.RA] = EA;
|
||||||
|
|
||||||
} // namespace=======
|
} // namespace=======
|
||||||
}
|
|
||||||
|
|
|
@ -25,39 +25,36 @@
|
||||||
|
|
||||||
using namespace MathUtil;
|
using namespace MathUtil;
|
||||||
|
|
||||||
namespace Interpreter
|
|
||||||
{
|
|
||||||
|
|
||||||
// These "binary instructions" do not alter FPSCR.
|
// 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);
|
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);
|
rPS1(_inst.FD) = rPS1(_inst.FA) >= -0.0 ? rPS1(_inst.FC) : rPS1(_inst.FB);
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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);
|
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
|
||||||
riPS1(_inst.FD) = riPS1(_inst.FB) ^ (1ULL << 63);
|
riPS1(_inst.FD) = riPS1(_inst.FB) ^ (1ULL << 63);
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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);
|
rPS0(_inst.FD) = rPS0(_inst.FB);
|
||||||
rPS1(_inst.FD) = rPS1(_inst.FB);
|
rPS1(_inst.FD) = rPS1(_inst.FB);
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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);
|
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
|
||||||
riPS1(_inst.FD) = riPS1(_inst.FB) | (1ULL << 63);
|
riPS1(_inst.FD) = riPS1(_inst.FB) | (1ULL << 63);
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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);
|
riPS0(_inst.FD) = riPS0(_inst.FB) &~ (1ULL << 63);
|
||||||
riPS1(_inst.FD) = riPS1(_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.
|
// These are just moves, double is OK.
|
||||||
void ps_merge00(UGeckoInstruction _inst)
|
void Interpreter::ps_merge00(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double p0 = rPS0(_inst.FA);
|
double p0 = rPS0(_inst.FA);
|
||||||
double p1 = rPS0(_inst.FB);
|
double p1 = rPS0(_inst.FB);
|
||||||
|
@ -74,7 +71,7 @@ void ps_merge00(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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 p0 = rPS0(_inst.FA);
|
||||||
double p1 = rPS1(_inst.FB);
|
double p1 = rPS1(_inst.FB);
|
||||||
|
@ -83,7 +80,7 @@ void ps_merge01(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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 p0 = rPS1(_inst.FA);
|
||||||
double p1 = rPS0(_inst.FB);
|
double p1 = rPS0(_inst.FB);
|
||||||
|
@ -92,7 +89,7 @@ void ps_merge10(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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 p0 = rPS1(_inst.FA);
|
||||||
double p1 = rPS1(_inst.FB);
|
double p1 = rPS1(_inst.FB);
|
||||||
|
@ -102,7 +99,7 @@ void ps_merge11(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
// From here on, the real deal.
|
// From here on, the real deal.
|
||||||
void ps_div(UGeckoInstruction _inst)
|
void Interpreter::ps_div(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 ex_mask = 0;
|
u32 ex_mask = 0;
|
||||||
|
|
||||||
|
@ -187,7 +184,7 @@ void ps_div(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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
|
// this code is based on the real hardware tests
|
||||||
double a = rPS0(_inst.FB);
|
double a = rPS0(_inst.FB);
|
||||||
|
@ -216,7 +213,7 @@ void ps_res(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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
|
// this code is based on the real hardware tests
|
||||||
if (rPS0(_inst.FB) == 0.0 || rPS1(_inst.FB) == 0.0)
|
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)));
|
rPS0(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
rPS1(_inst.FD) = ForceSingle(NI_sub(rPS1(_inst.FA), rPS1(_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));
|
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)));
|
rPS0(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
rPS1(_inst.FD) = ForceSingle(NI_add(rPS1(_inst.FA), rPS1(_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));
|
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)));
|
rPS0(_inst.FD) = ForceSingle(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC)));
|
||||||
rPS1(_inst.FD) = ForceSingle(NI_mul(rPS1(_inst.FA), rPS1(_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)));
|
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)));
|
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));
|
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)));
|
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)));
|
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));
|
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) ) );
|
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) ) );
|
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));
|
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) ) );
|
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) ) );
|
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));
|
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 p0 = ForceSingle(NI_add(rPS0(_inst.FA), rPS1(_inst.FB)));
|
||||||
double p1 = ForceSingle(rPS1(_inst.FC));
|
double p1 = ForceSingle(rPS1(_inst.FC));
|
||||||
|
@ -320,7 +317,7 @@ void ps_sum0(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
|
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 p0 = ForceSingle(rPS0(_inst.FC));
|
||||||
double p1 = ForceSingle(NI_add(rPS0(_inst.FA), rPS1(_inst.FB)));
|
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));
|
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 p0 = ForceSingle(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC)));
|
||||||
double p1 = ForceSingle(NI_mul(rPS1(_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));
|
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 p0 = ForceSingle(NI_mul(rPS0(_inst.FA), rPS1(_inst.FC)));
|
||||||
double p1 = ForceSingle(NI_mul(rPS1(_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));
|
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 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)) );
|
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));
|
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 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)) );
|
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));
|
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 fa = rPS0(_inst.FA);
|
||||||
double fb = rPS0(_inst.FB);
|
double fb = rPS0(_inst.FB);
|
||||||
|
@ -391,7 +388,7 @@ void ps_cmpu0(UGeckoInstruction _inst)
|
||||||
SetCRField(_inst.CRFD, compareResult);
|
SetCRField(_inst.CRFD, compareResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ps_cmpo0(UGeckoInstruction _inst)
|
void Interpreter::ps_cmpo0(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double fa = rPS0(_inst.FA);
|
double fa = rPS0(_inst.FA);
|
||||||
double fb = rPS0(_inst.FB);
|
double fb = rPS0(_inst.FB);
|
||||||
|
@ -419,7 +416,7 @@ void ps_cmpo0(UGeckoInstruction _inst)
|
||||||
SetCRField(_inst.CRFD, compareResult);
|
SetCRField(_inst.CRFD, compareResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ps_cmpu1(UGeckoInstruction _inst)
|
void Interpreter::ps_cmpu1(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double fa = rPS1(_inst.FA);
|
double fa = rPS1(_inst.FA);
|
||||||
double fb = rPS1(_inst.FB);
|
double fb = rPS1(_inst.FB);
|
||||||
|
@ -440,7 +437,7 @@ void ps_cmpu1(UGeckoInstruction _inst)
|
||||||
SetCRField(_inst.CRFD, compareResult);
|
SetCRField(_inst.CRFD, compareResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ps_cmpo1(UGeckoInstruction _inst)
|
void Interpreter::ps_cmpo1(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double fa = rPS1(_inst.FA);
|
double fa = rPS1(_inst.FA);
|
||||||
double fb = rPS1(_inst.FB);
|
double fb = rPS1(_inst.FB);
|
||||||
|
@ -471,10 +468,8 @@ void ps_cmpo1(UGeckoInstruction _inst)
|
||||||
// __________________________________________________________________________________________________
|
// __________________________________________________________________________________________________
|
||||||
// dcbz_l
|
// dcbz_l
|
||||||
// TODO(ector) check docs
|
// TODO(ector) check docs
|
||||||
void dcbz_l(UGeckoInstruction _inst)
|
void Interpreter::dcbz_l(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
//FAKE: clear memory instead of clearing the cache block
|
//FAKE: clear memory instead of clearing the cache block
|
||||||
Memory::Memset(Helper_Get_EA_X(_inst) & (~31), 0, 32);
|
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
|
// That is, set rounding mode etc when entering jit code or the interpreter loop
|
||||||
// Restore rounding mode when calling anything external
|
// Restore rounding mode when calling anything external
|
||||||
|
|
||||||
namespace Interpreter
|
|
||||||
{
|
|
||||||
|
|
||||||
const u32 MASKS = 0x1F80; // mask away the interrupts.
|
const u32 MASKS = 0x1F80; // mask away the interrupts.
|
||||||
const u32 DAZ = 0x40;
|
const u32 DAZ = 0x40;
|
||||||
const u32 FTZ = 0x8000;
|
const u32 FTZ = 0x8000;
|
||||||
|
@ -121,7 +118,7 @@ void FPSCRtoFPUSettings(UReg_FPSCR fp)
|
||||||
_mm_setcsr(csr);
|
_mm_setcsr(csr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtfsb0x(UGeckoInstruction _inst)
|
void Interpreter::mtfsb0x(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 b = 0x80000000 >> _inst.CRBD;
|
u32 b = 0x80000000 >> _inst.CRBD;
|
||||||
|
|
||||||
|
@ -134,7 +131,7 @@ void mtfsb0x(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc");
|
if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtfsb1x(UGeckoInstruction _inst)
|
void Interpreter::mtfsb1x(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// this instruction can affect FX
|
// this instruction can affect FX
|
||||||
u32 b = 0x80000000 >> _inst.CRBD;
|
u32 b = 0x80000000 >> _inst.CRBD;
|
||||||
|
@ -147,7 +144,7 @@ void mtfsb1x(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc");
|
if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtfsfix(UGeckoInstruction _inst)
|
void Interpreter::mtfsfix(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 mask = (0xF0000000 >> (4 * _inst.CRFD));
|
u32 mask = (0xF0000000 >> (4 * _inst.CRFD));
|
||||||
u32 imm = (_inst.hex << 16) & 0xF0000000;
|
u32 imm = (_inst.hex << 16) & 0xF0000000;
|
||||||
|
@ -163,7 +160,7 @@ void mtfsfix(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc");
|
if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtfsfx(UGeckoInstruction _inst)
|
void Interpreter::mtfsfx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 fm = _inst.FM;
|
u32 fm = _inst.FM;
|
||||||
u32 m = 0;
|
u32 m = 0;
|
||||||
|
@ -183,19 +180,19 @@ void mtfsfx(UGeckoInstruction _inst)
|
||||||
if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc");
|
if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void mcrxr(UGeckoInstruction _inst)
|
void Interpreter::mcrxr(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// USES_XER
|
// USES_XER
|
||||||
SetCRField(_inst.CRFD, PowerPC::ppcState.spr[SPR_XER] >> 28);
|
SetCRField(_inst.CRFD, PowerPC::ppcState.spr[SPR_XER] >> 28);
|
||||||
PowerPC::ppcState.spr[SPR_XER] &= ~0xF0000000; // clear 0-3
|
PowerPC::ppcState.spr[SPR_XER] &= ~0xF0000000; // clear 0-3
|
||||||
}
|
}
|
||||||
|
|
||||||
void mfcr(UGeckoInstruction _inst)
|
void Interpreter::mfcr(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RD] = GetCR();
|
m_GPR[_inst.RD] = GetCR();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtcrf(UGeckoInstruction _inst)
|
void Interpreter::mtcrf(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 crm = _inst.CRM;
|
u32 crm = _inst.CRM;
|
||||||
if (crm == 0xFF)
|
if (crm == 0xFF)
|
||||||
|
@ -215,24 +212,24 @@ void mtcrf(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mfmsr(UGeckoInstruction _inst)
|
void Interpreter::mfmsr(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
//Privileged?
|
//Privileged?
|
||||||
m_GPR[_inst.RD] = MSR;
|
m_GPR[_inst.RD] = MSR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mfsr(UGeckoInstruction _inst)
|
void Interpreter::mfsr(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RD] = PowerPC::ppcState.sr[_inst.SR];
|
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;
|
int index = (m_GPR[_inst.RB] >> 28) & 0xF;
|
||||||
m_GPR[_inst.RD] = PowerPC::ppcState.sr[index];
|
m_GPR[_inst.RD] = PowerPC::ppcState.sr[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtmsr(UGeckoInstruction _inst)
|
void Interpreter::mtmsr(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// Privileged?
|
// Privileged?
|
||||||
MSR = m_GPR[_inst.RS];
|
MSR = m_GPR[_inst.RS];
|
||||||
|
@ -246,14 +243,14 @@ void SetSR(int index, u32 value) {
|
||||||
PowerPC::ppcState.sr[index] = value;
|
PowerPC::ppcState.sr[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtsr(UGeckoInstruction _inst)
|
void Interpreter::mtsr(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int index = _inst.SR;
|
int index = _inst.SR;
|
||||||
u32 value = m_GPR[_inst.RS];
|
u32 value = m_GPR[_inst.RS];
|
||||||
SetSR(index, value);
|
SetSR(index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtsrin(UGeckoInstruction _inst)
|
void Interpreter::mtsrin(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int index = (m_GPR[_inst.RB] >> 28) & 0xF;
|
int index = (m_GPR[_inst.RB] >> 28) & 0xF;
|
||||||
u32 value = m_GPR[_inst.RS];
|
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);
|
int iIndex = (_inst.TBR >> 5) | ((_inst.TBR & 0x1F) << 5);
|
||||||
if (iIndex == SPR_TL) m_GPR[_inst.RD] = TL;
|
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);
|
u32 iIndex = ((_inst.SPR & 0x1F) << 5) + ((_inst.SPR >> 5) & 0x1F);
|
||||||
|
|
||||||
|
@ -298,7 +295,7 @@ void mfspr(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = rSPR(iIndex);
|
m_GPR[_inst.RD] = rSPR(iIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtspr(UGeckoInstruction _inst)
|
void Interpreter::mtspr(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 iIndex = (_inst.SPRU << 5) | (_inst.SPRL & 0x1F);
|
u32 iIndex = (_inst.SPRU << 5) | (_inst.SPRL & 0x1F);
|
||||||
u32 oldValue = rSPR(iIndex);
|
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));
|
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)));
|
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)));
|
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)));
|
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)));
|
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)));
|
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))));
|
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)));
|
SetCRBit(_inst.CRBD, (GetCRBit(_inst.CRBA) ^ GetCRBit(_inst.CRBB)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void mcrf(UGeckoInstruction _inst)
|
void Interpreter::mcrf(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int cr_f = GetCRField(_inst.CRFS);
|
int cr_f = GetCRField(_inst.CRFS);
|
||||||
SetCRField(_inst.CRFD, cr_f);
|
SetCRField(_inst.CRFD, cr_f);
|
||||||
}
|
}
|
||||||
|
|
||||||
void isync(UGeckoInstruction _inst)
|
void Interpreter::isync(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
//shouldnt do anything
|
//shouldnt do anything
|
||||||
}
|
}
|
||||||
|
|
||||||
// the following commands read from FPSCR
|
// the following commands read from FPSCR
|
||||||
|
|
||||||
void mcrfs(UGeckoInstruction _inst)
|
void Interpreter::mcrfs(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
//if (_inst.CRFS != 3 && _inst.CRFS != 4)
|
//if (_inst.CRFS != 3 && _inst.CRFS != 4)
|
||||||
// PanicAlert("msrfs at %x, CRFS = %d, CRFD = %d", PC, (int)_inst.CRFS, (int)_inst.CRFD);
|
// 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);
|
SetCRField(_inst.CRFD, fpflags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mffsx(UGeckoInstruction _inst)
|
void Interpreter::mffsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// load from FPSCR
|
// load from FPSCR
|
||||||
// This may or may not be accurate - but better than nothing, I guess
|
// 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;
|
riPS0(_inst.FD) = (u64)FPSCR.Hex;
|
||||||
if (_inst.Rc) PanicAlert("mffsx: inst_.Rc");
|
if (_inst.Rc) PanicAlert("mffsx: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
|
@ -361,8 +361,15 @@ static GekkoOPTemplate table63_2[] =
|
||||||
};
|
};
|
||||||
namespace InterpreterTables
|
namespace InterpreterTables
|
||||||
{
|
{
|
||||||
|
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
void InitTables()
|
void InitTables()
|
||||||
{
|
{
|
||||||
|
// once initialized, tables are read-only
|
||||||
|
if (initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
//clear
|
//clear
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
|
@ -491,6 +498,8 @@ void InitTables()
|
||||||
if (m_numInstructions >= 512) {
|
if (m_numInstructions >= 512) {
|
||||||
PanicAlert("m_allInstructions underdimensioned");
|
PanicAlert("m_allInstructions underdimensioned");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -392,8 +392,14 @@ void CompileInstruction(PPCAnalyst::CodeOp & op)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
void InitTables()
|
void InitTables()
|
||||||
{
|
{
|
||||||
|
// once initialized, tables are read-only
|
||||||
|
if (initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
//clear
|
//clear
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
|
@ -482,6 +488,8 @@ void InitTables()
|
||||||
dynaOpTable63[op] = table63_2[j].Inst;
|
dynaOpTable63[op] = table63_2[j].Inst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
|
@ -376,6 +376,7 @@ static GekkoOPTemplate table63_2[] =
|
||||||
|
|
||||||
namespace JitILTables
|
namespace JitILTables
|
||||||
{
|
{
|
||||||
|
|
||||||
void CompileInstruction(PPCAnalyst::CodeOp & op)
|
void CompileInstruction(PPCAnalyst::CodeOp & op)
|
||||||
{
|
{
|
||||||
JitIL *jitil = (JitIL *)jit;
|
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);
|
PanicAlert("Tried to compile illegal (or unknown) instruction %08x, at %08x", op.inst.hex, jit->js.compilerPC);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool initialized = false;
|
||||||
|
|
||||||
void InitTables()
|
void InitTables()
|
||||||
{
|
{
|
||||||
|
// once initialized, tables are read-only
|
||||||
|
if (initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
//clear
|
//clear
|
||||||
for (int i = 0; i < 32; i++)
|
for (int i = 0; i < 32; i++)
|
||||||
{
|
{
|
||||||
|
@ -483,5 +491,8 @@ void InitTables()
|
||||||
dynaOpTable63[op] = table63_2[j].Inst;
|
dynaOpTable63[op] = table63_2[j].Inst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
//#define JIT_LOG_GPR // Enables logging of the PPC general purpose regs
|
//#define JIT_LOG_GPR // Enables logging of the PPC general purpose regs
|
||||||
//#define JIT_LOG_FPR // Enables logging of the PPC floating point regs
|
//#define JIT_LOG_FPR // Enables logging of the PPC floating point regs
|
||||||
|
|
||||||
|
#include "../CPUCoreBase.h"
|
||||||
#include "JitCache.h"
|
#include "JitCache.h"
|
||||||
#include "Jit_Util.h" // for EmuCodeBlock
|
#include "Jit_Util.h" // for EmuCodeBlock
|
||||||
#include "JitBackpatch.h" // for EmuCodeBlock
|
#include "JitBackpatch.h" // for EmuCodeBlock
|
||||||
|
@ -32,9 +33,7 @@
|
||||||
|
|
||||||
#define JIT_OPCODE 0
|
#define JIT_OPCODE 0
|
||||||
|
|
||||||
// TODO: In the future, inherit this from CPUCoreBase and have Interpreter
|
class JitBase : public CPUCoreBase, public EmuCodeBlock
|
||||||
// inherit from that too?
|
|
||||||
class JitBase : public EmuCodeBlock
|
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
JitBlockCache blocks;
|
JitBlockCache blocks;
|
||||||
|
@ -85,18 +84,11 @@ public:
|
||||||
|
|
||||||
JitBlockCache *GetBlockCache() { return &blocks; }
|
JitBlockCache *GetBlockCache() { return &blocks; }
|
||||||
|
|
||||||
virtual void Init() = 0;
|
|
||||||
virtual void Shutdown() = 0;
|
|
||||||
|
|
||||||
virtual void Jit(u32 em_address) = 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);
|
const u8 *BackPatch(u8 *codePtr, int accessType, u32 em_address, void *ctx);
|
||||||
|
|
||||||
virtual const CommonAsmRoutines *GetAsmRoutines() = 0;
|
virtual const CommonAsmRoutines *GetAsmRoutines() = 0;
|
||||||
virtual const char *GetName() = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern JitBase *jit;
|
extern JitBase *jit;
|
||||||
|
|
|
@ -24,13 +24,11 @@
|
||||||
#include "FileUtil.h"
|
#include "FileUtil.h"
|
||||||
#include "Interpreter/Interpreter.h"
|
#include "Interpreter/Interpreter.h"
|
||||||
#include "Interpreter/Interpreter_Tables.h"
|
#include "Interpreter/Interpreter_Tables.h"
|
||||||
#if !(defined(NOJIT) && NOJIT)
|
|
||||||
#include "Jit64IL/JitIL_Tables.h"
|
#include "Jit64IL/JitIL_Tables.h"
|
||||||
#include "Jit64/Jit64_Tables.h"
|
#include "Jit64/Jit64_Tables.h"
|
||||||
|
|
||||||
#include "Jit64IL/JitIL.h"
|
#include "Jit64IL/JitIL.h"
|
||||||
#include "Jit64/Jit.h"
|
#include "Jit64/Jit.h"
|
||||||
#endif
|
|
||||||
|
|
||||||
struct op_inf
|
struct op_inf
|
||||||
{
|
{
|
||||||
|
@ -156,15 +154,33 @@ bool UsesFPU(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InitTables()
|
void InitTables(int cpu_core)
|
||||||
{
|
{
|
||||||
// Interpreter ALWAYS needs to be initialized
|
// Interpreter ALWAYS needs to be initialized
|
||||||
InterpreterTables::InitTables();
|
InterpreterTables::InitTables();
|
||||||
#if !(defined(NOJIT) && NOJIT)
|
switch (cpu_core)
|
||||||
// Should be able to do this a better way than defines in this function
|
{
|
||||||
|
case 0:
|
||||||
|
{
|
||||||
|
// Interpreter
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
Jit64Tables::InitTables();
|
Jit64Tables::InitTables();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
JitILTables::InitTables();
|
JitILTables::InitTables();
|
||||||
#endif
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
PanicAlert("Unrecognizable cpu_core: %d", cpu_core);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OPLOG
|
#define OPLOG
|
||||||
|
|
|
@ -113,7 +113,7 @@ class cJit64;
|
||||||
namespace PPCTables
|
namespace PPCTables
|
||||||
{
|
{
|
||||||
|
|
||||||
void InitTables();
|
void InitTables(int cpu_core);
|
||||||
bool IsValidInstruction(UGeckoInstruction _instCode);
|
bool IsValidInstruction(UGeckoInstruction _instCode);
|
||||||
bool UsesFPU(UGeckoInstruction _inst);
|
bool UsesFPU(UGeckoInstruction _inst);
|
||||||
|
|
||||||
|
|
|
@ -32,9 +32,12 @@
|
||||||
#include "Jit64/Jit.h"
|
#include "Jit64/Jit.h"
|
||||||
#include "PowerPC.h"
|
#include "PowerPC.h"
|
||||||
#include "PPCTables.h"
|
#include "PPCTables.h"
|
||||||
|
#include "CPUCoreBase.h"
|
||||||
|
|
||||||
#include "../Host.h"
|
#include "../Host.h"
|
||||||
|
|
||||||
|
CPUCoreBase *cpu_core_base;
|
||||||
|
|
||||||
namespace PowerPC
|
namespace PowerPC
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -42,7 +45,8 @@ namespace PowerPC
|
||||||
PowerPCState GC_ALIGNED16(ppcState);
|
PowerPCState GC_ALIGNED16(ppcState);
|
||||||
volatile CPUState state = CPU_STEPPING;
|
volatile CPUState state = CPU_STEPPING;
|
||||||
|
|
||||||
static CoreMode mode;
|
Interpreter * const interpreter = Interpreter::getInstance();
|
||||||
|
CoreMode mode;
|
||||||
|
|
||||||
BreakPoints breakpoints;
|
BreakPoints breakpoints;
|
||||||
MemChecks memchecks;
|
MemChecks memchecks;
|
||||||
|
@ -137,18 +141,46 @@ void Init(int cpu_core)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ResetRegisters();
|
ResetRegisters();
|
||||||
PPCTables::InitTables();
|
PPCTables::InitTables(cpu_core);
|
||||||
|
|
||||||
// Initialize both execution engines ...
|
// We initialize the interpreter because
|
||||||
Interpreter::Init();
|
// it is used on boot and code window independently.
|
||||||
|
interpreter->Init();
|
||||||
|
|
||||||
if (cpu_core == 1)
|
switch (cpu_core)
|
||||||
jit = new Jit64;
|
{
|
||||||
else
|
case 0:
|
||||||
jit = new JitIL;
|
{
|
||||||
|
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();
|
jit->Init();
|
||||||
|
|
||||||
mode = MODE_JIT;
|
mode = MODE_JIT;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mode = MODE_INTERPRETER;
|
||||||
|
}
|
||||||
state = CPU_STEPPING;
|
state = CPU_STEPPING;
|
||||||
|
|
||||||
ppcState.iCache.Reset();
|
ppcState.iCache.Reset();
|
||||||
|
@ -156,12 +188,15 @@ void Init(int cpu_core)
|
||||||
|
|
||||||
void Shutdown()
|
void Shutdown()
|
||||||
{
|
{
|
||||||
// Shutdown both execution engines. Doesn't matter which one is active.
|
if (jit)
|
||||||
|
{
|
||||||
jit->Shutdown();
|
jit->Shutdown();
|
||||||
state = CPU_POWERDOWN;
|
|
||||||
delete jit;
|
delete jit;
|
||||||
jit = 0;
|
jit = NULL;
|
||||||
Interpreter::Shutdown();
|
}
|
||||||
|
interpreter->Shutdown();
|
||||||
|
cpu_core_base = NULL;
|
||||||
|
state = CPU_POWERDOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetMode(CoreMode new_mode)
|
void SetMode(CoreMode new_mode)
|
||||||
|
@ -170,43 +205,30 @@ void SetMode(CoreMode new_mode)
|
||||||
return; // We don't need to do anything.
|
return; // We don't need to do anything.
|
||||||
|
|
||||||
mode = new_mode;
|
mode = new_mode;
|
||||||
|
|
||||||
switch (mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case MODE_INTERPRETER: // Switching from JIT to interpreter
|
case MODE_INTERPRETER: // Switching from JIT to interpreter
|
||||||
jit->ClearCache(); // Remove all those nasty JIT patches.
|
jit->ClearCache(); // Remove all those nasty JIT patches.
|
||||||
|
cpu_core_base = interpreter;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MODE_JIT: // Switching from interpreter to JIT.
|
case MODE_JIT: // Switching from interpreter to JIT.
|
||||||
// Don't really need to do much. It'll work, the cache will refill itself.
|
// Don't really need to do much. It'll work, the cache will refill itself.
|
||||||
|
cpu_core_base = jit;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SingleStep()
|
void SingleStep()
|
||||||
{
|
{
|
||||||
switch (mode)
|
cpu_core_base->SingleStep();
|
||||||
{
|
|
||||||
case MODE_INTERPRETER:
|
|
||||||
Interpreter::SingleStep();
|
|
||||||
break;
|
|
||||||
case MODE_JIT:
|
|
||||||
jit->SingleStep();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RunLoop()
|
void RunLoop()
|
||||||
{
|
{
|
||||||
state = CPU_RUNNING;
|
state = CPU_RUNNING;
|
||||||
switch (mode)
|
cpu_core_base->Run();
|
||||||
{
|
|
||||||
case MODE_INTERPRETER:
|
|
||||||
Interpreter::Run();
|
|
||||||
break;
|
|
||||||
case MODE_JIT:
|
|
||||||
jit->Run();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Host_UpdateDisasmDialog();
|
Host_UpdateDisasmDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
#define _POWERPC_H
|
#define _POWERPC_H
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "CPUCoreBase.h"
|
||||||
#include "Gekko.h"
|
#include "Gekko.h"
|
||||||
#include "BreakPoints.h"
|
#include "BreakPoints.h"
|
||||||
#include "../Debugger/PPCDebugInterface.h"
|
#include "../Debugger/PPCDebugInterface.h"
|
||||||
|
@ -26,6 +27,8 @@
|
||||||
|
|
||||||
class PointerWrap;
|
class PointerWrap;
|
||||||
|
|
||||||
|
extern CPUCoreBase *cpu_core_base;
|
||||||
|
|
||||||
namespace PowerPC
|
namespace PowerPC
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue