Switch between JIT and Interpreter at runtime using the debug window (pause first!)

Plus assorted cleanup & fixes.

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@312 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
hrydgard 2008-08-25 20:34:11 +00:00
parent 35fdbdc360
commit fd188ec09e
32 changed files with 1039 additions and 1150 deletions

View File

@ -800,10 +800,6 @@
RelativePath=".\Src\PowerPC\Gekko.h" RelativePath=".\Src\PowerPC\Gekko.h"
> >
</File> </File>
<File
RelativePath=".\Src\PowerPC\ICPUCore.h"
>
</File>
<File <File
RelativePath=".\Src\PowerPC\PowerPC.cpp" RelativePath=".\Src\PowerPC\PowerPC.cpp"
> >

View File

@ -446,7 +446,8 @@ bool CBoot::Load_BIOS(const std::string& _rBiosFilename)
bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara) bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara)
{ {
const bool bDebugIsoBootup = false; const bool bDebugIsoBootup = false;
g_symbolDB.Clear();
VideoInterface::PreInit(_StartupPara.bNTSC); VideoInterface::PreInit(_StartupPara.bNTSC);
switch(_StartupPara.m_BootType) switch(_StartupPara.m_BootType)
{ {

View File

@ -296,17 +296,17 @@ THREAD_RETURN EmuThread(void *pArg)
g_bHwInit = true; g_bHwInit = true;
// Load GCM/DOL/ELF whatever ... we boot with the interpreter core // Load GCM/DOL/ELF whatever ... we boot with the interpreter core
PowerPC::SetCore(PowerPC::CORE_INTERPRETER); PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
CBoot::BootUp(_CoreParameter); CBoot::BootUp(_CoreParameter);
if( g_pUpdateFPSDisplay != NULL ) if( g_pUpdateFPSDisplay != NULL )
g_pUpdateFPSDisplay("Loading..."); g_pUpdateFPSDisplay("Loading...");
// setup our core, but can't use dynarec if we are compare server // setup our core, but can't use dynarec if we are compare server
if (_CoreParameter.bUseDynarec && !_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient) if (_CoreParameter.bUseJIT && !_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient)
PowerPC::SetCore(PowerPC::CORE_DYNAREC); PowerPC::SetMode(PowerPC::MODE_JIT);
else else
PowerPC::SetCore(PowerPC::CORE_INTERPRETER); PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
// update the window again because all stuff is initialized // update the window again because all stuff is initialized
Host_UpdateDisasmDialog(); Host_UpdateDisasmDialog();
@ -472,7 +472,7 @@ void Callback_VideoCopiedToXFB()
char temp[256]; char temp[256];
sprintf(temp, "FPS: %8.2f - %s - %i MHz (%i real, %i idle skipped) out of %i MHz", sprintf(temp, "FPS: %8.2f - %s - %i MHz (%i real, %i idle skipped) out of %i MHz",
(float)frames / t, (float)frames / t,
g_CoreStartupParameter.bUseDynarec ? "JIT" : "Interpreter", g_CoreStartupParameter.bUseJIT ? "JIT" : "Interpreter",
(int)(diff), (int)(diff),
(int)(diff-idleDiff), (int)(diff-idleDiff),
(int)(idleDiff), (int)(idleDiff),

View File

@ -30,7 +30,7 @@ SCoreStartupParameter::SCoreStartupParameter()
void SCoreStartupParameter::LoadDefaults() void SCoreStartupParameter::LoadDefaults()
{ {
bEnableDebugging = false; bEnableDebugging = false;
bUseDynarec = false; bUseJIT = false;
bUseDualCore = false; bUseDualCore = false;
bRunCompareServer = false; bRunCompareServer = false;
bLockThreads = true; bLockThreads = true;

View File

@ -35,7 +35,7 @@ struct SCoreStartupParameter
// flags // flags
bool bEnableDebugging; bool bEnableDebugging;
bool bUseDynarec; bool bUseJIT;
bool bUseDualCore; bool bUseDualCore;
bool bNTSC; bool bNTSC;
bool bHLEBios; bool bHLEBios;

View File

@ -81,7 +81,7 @@ void CCPU::Run()
break; break;
} }
/* if (!Core::g_CoreStartupParameter.bUseDynarec && CBreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount) /* if (!Core::g_CoreStartupParameter.bUseJIT && CBreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount)
{ {
LOG(GEKKO, "Hit DebugCount breakpoint - %i", PowerPC::ppcState.DebugCount); LOG(GEKKO, "Hit DebugCount breakpoint - %i", PowerPC::ppcState.DebugCount);
EnableStepping(true); EnableStepping(true);
@ -192,7 +192,7 @@ void CCPU::SingleStep()
break; break;
} }
if (!Core::g_CoreStartupParameter.bUseDynarec && CBreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount) if (!Core::g_CoreStartupParameter.bUseJIT && CBreakPoints::GetBreakCount() == PowerPC::ppcState.DebugCount)
{ {
LOG(GEKKO, "Hit DebugCount breakpoint - %i", PowerPC::ppcState.DebugCount); LOG(GEKKO, "Hit DebugCount breakpoint - %i", PowerPC::ppcState.DebugCount);
EnableStepping(true); EnableStepping(true);

View File

@ -120,7 +120,7 @@ int Sync()
if (!m_bEnabled) if (!m_bEnabled)
return 0; return 0;
if (m_bIsServer) //This should be interpreter if (m_bIsServer) // This should be interpreter
{ {
//write cpu state to m_hPipe //write cpu state to m_hPipe
HRESULT result; HRESULT result;
@ -135,7 +135,7 @@ int Sync()
} }
// LogManager::Redraw(); // LogManager::Redraw();
} }
else //This should be dynarec else // This should be JIT
{ {
u32 read; u32 read;
memset(&state,0xcc,stateSize); memset(&state,0xcc,stateSize);

View File

@ -89,7 +89,7 @@ namespace Memory
inline u32 ReadFast32(const u32 _Address) inline u32 ReadFast32(const u32 _Address)
{ {
#ifdef _M_IX86 #ifdef _M_IX86
return ReadUnchecked_U32(_Address); return Common::swap32(*(u32 *)(base + (_Address & MEMVIEW32_MASK))); //ReadUnchecked_U32(_Address);
#elif defined(_M_X64) #elif defined(_M_X64)
return Common::swap32(*(u32 *)(base + _Address)); return Common::swap32(*(u32 *)(base + _Address));
#endif #endif

View File

@ -1,34 +0,0 @@
// Copyright (C) 2003-2008 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/
// Interface to connect a core like interpreter or dynarec
//
#ifndef _ICPUCORE_H
#define _ICPUCORE_H
class ICPUCore
{
public:
virtual ~ICPUCore() {}
virtual void Init() = 0;
virtual void Shutdown() = 0;
virtual void Reset() = 0;
virtual void SingleStep() = 0;
virtual void Run() = 0;
};
#endif

View File

@ -27,111 +27,46 @@
#include "PowerPCDisasm.h" #include "PowerPCDisasm.h"
#include "../../IPC_HLE/WII_IPC_HLE.h" #include "../../IPC_HLE/WII_IPC_HLE.h"
static const unsigned short FPU_PREC_24 = 0 << 8; enum {
static const unsigned short FPU_PREC_53 = 2 << 8; FPU_PREC_24 = 0 << 8,
static const unsigned short FPU_PREC_64 = 3 << 8; FPU_PREC_53 = 2 << 8,
static const unsigned short FPU_PREC_MASK = 3 << 8; FPU_PREC_64 = 3 << 8,
FPU_PREC_MASK = 3 << 8,
};
// cpu register to keep the code readable
u32* CInterpreter::m_GPR = PowerPC::ppcState.gpr;
bool CInterpreter::m_EndBlock = false;
namespace { namespace {
u32 last_pc; u32 last_pc;
} }
// function tables // function tables
CInterpreter::_interpreterInstruction CInterpreter::m_opTable[64];
CInterpreter::_interpreterInstruction CInterpreter::m_opTable4[1024];
CInterpreter::_interpreterInstruction CInterpreter::m_opTable19[1024];
CInterpreter::_interpreterInstruction CInterpreter::m_opTable31[1024];
CInterpreter::_interpreterInstruction CInterpreter::m_opTable59[32];
CInterpreter::_interpreterInstruction CInterpreter::m_opTable63[1024];
void CInterpreter::RunTable4(UGeckoInstruction _inst) {m_opTable4 [_inst.SUBOP10](_inst);} namespace Interpreter
void CInterpreter::RunTable19(UGeckoInstruction _inst) {m_opTable19[_inst.SUBOP10](_inst);}
void CInterpreter::RunTable31(UGeckoInstruction _inst) {m_opTable31[_inst.SUBOP10](_inst);}
void CInterpreter::RunTable59(UGeckoInstruction _inst) {m_opTable59[_inst.SUBOP5 ](_inst);}
void CInterpreter::RunTable63(UGeckoInstruction _inst) {m_opTable63[_inst.SUBOP10](_inst);}
void CInterpreter::sInit()
{ {
// Crash(); // cpu register to keep the code readable
#ifdef _M_IX86 u32 *m_GPR = PowerPC::ppcState.gpr;
// sets the floating-point lib to 53-bit bool m_EndBlock = false;
// PowerPC has a 53bit floating pipeline only
// eg: sscanf is very sensitive
#ifdef _WIN32
_control87(_PC_53, MCW_PC);
#else
unsigned short mode;
asm ("fstcw %0" : : "m" (mode));
mode = (mode & ~FPU_PREC_MASK) | FPU_PREC_53;
asm ("fldcw %0" : : "m" (mode));
#endif
#else
//x64 doesn't need this - fpu is done with SSE
//but still - set any useful sse options here
#endif
}
void CInterpreter::sShutdown() _interpreterInstruction m_opTable[64];
_interpreterInstruction m_opTable4[1024];
_interpreterInstruction m_opTable19[1024];
_interpreterInstruction m_opTable31[1024];
_interpreterInstruction m_opTable59[32];
_interpreterInstruction m_opTable63[1024];
void RunTable4(UGeckoInstruction _inst) {m_opTable4 [_inst.SUBOP10](_inst);}
void RunTable19(UGeckoInstruction _inst) {m_opTable19[_inst.SUBOP10](_inst);}
void RunTable31(UGeckoInstruction _inst) {m_opTable31[_inst.SUBOP10](_inst);}
void RunTable59(UGeckoInstruction _inst) {m_opTable59[_inst.SUBOP5 ](_inst);}
void RunTable63(UGeckoInstruction _inst) {m_opTable63[_inst.SUBOP10](_inst);}
void Init()
{ {
} }
void CInterpreter::sReset() void Shutdown()
{ {
} }
void CInterpreter::Log()
{
static u32 startPC = 0x80003154;
const char *kLogFile = "D:\\dolphin.txt";
static bool bStart = false;
if ((PC == startPC) && (bStart == false))
{
FILE* pOut = fopen(kLogFile, "wt");
if (pOut)
fclose(pOut);
bStart = true;
// just for sync
/* m_FPR[8].u64 = 0x0000000080000000;
m_FPR[10].u64 = 0x00000000a0000000;
m_FPR[4].u64 = 0x0000000000000000;
m_FPR[5].u64 = 0x0000000000000000;
m_FPR[6].u64 = 0x0000000000000000;
m_FPR[12].u64 = 0x0000000040000000; */
}
if (bStart)
{
static int steps = 0;
steps ++;
// if (steps > 150000)
{
FILE* pOut = fopen(kLogFile, "at");
if (pOut != NULL)
{
fprintf(pOut, "0x%08x: PC: 0x%08x (carry: %i)\n", steps, PC, GetCarry() ? 1:0);
for (int i=0; i<32;i++)
{
//fprintf(pOut, "GPR[%02i] 0x%08x\n", i, m_GPR[i]);
}
for (int i=0; i<32;i++)
{
// fprintf(pOut, "FPR[%02i] 0x%016x (%.4f)\n", i, m_FPR[i].u64, m_FPR[i].d);
// fprintf(pOut, "FPR[%02i] 0x%016x\n", i, m_FPR[i].u64);
// fprintf(pOut, "PS[%02i] %.4f %.4f\n", i, m_PS0[i], m_PS0[i]);
}
fclose(pOut);
}
//if (steps >= 10000)
//exit(1);
}
}
}
//#include "../../Plugins/Plugin_DSP.h" //#include "../../Plugins/Plugin_DSP.h"
void patches() void patches()
@ -152,10 +87,8 @@ void patches()
// WII_IPC_HLE_Interface::Update(); // WII_IPC_HLE_Interface::Update();
} }
void CInterpreter::sStepInner(void) void SingleStepInner(void)
{ {
// Log();
/* static int count = 0; /* static int count = 0;
count++; count++;
if ((count % 50) == 0) if ((count % 50) == 0)
@ -163,8 +96,8 @@ void CInterpreter::sStepInner(void)
static UGeckoInstruction instCode; static UGeckoInstruction instCode;
NPC = PC + sizeof(UGeckoInstruction); NPC = PC + sizeof(UGeckoInstruction);
instCode.hex = Memory::ReadFast32(PC); // Memory::ReadUnchecked_U32(PC);
instCode.hex = Memory::ReadUnchecked_U32(PC);
//Memory::Read_Instruction(PC); // use the memory functions to read from the memory !!!!!! //Memory::Read_Instruction(PC); // use the memory functions to read from the memory !!!!!!
//if (PowerPC::ppcState.DebugCount > 0x10f233a) { // 50721ef253a //if (PowerPC::ppcState.DebugCount > 0x10f233a) { // 50721ef253a
// printf("> %08x - %08x - %s\n", PC, instCode.hex, DisassembleGekko(instCode.hex, PC)); // printf("> %08x - %08x - %s\n", PC, instCode.hex, DisassembleGekko(instCode.hex, PC));
@ -199,9 +132,9 @@ void CInterpreter::sStepInner(void)
patches(); patches();
} }
void CInterpreter::sStep() void SingleStep()
{ {
sStepInner(); SingleStepInner();
CoreTiming::slicelength = 1; CoreTiming::slicelength = 1;
CoreTiming::downcount = 0; CoreTiming::downcount = 0;
@ -215,7 +148,7 @@ void CInterpreter::sStep()
} }
// sFastRun - inspired by GCemu // sFastRun - inspired by GCemu
void CInterpreter::sFastRun() void Run()
{ {
while (!PowerPC::state) while (!PowerPC::state)
{ {
@ -226,11 +159,8 @@ void CInterpreter::sFastRun()
int i; int i;
for (i = 0; !m_EndBlock; i++) for (i = 0; !m_EndBlock; i++)
{ {
sStepInner(); SingleStepInner();
} }
#if defined(DEBUGFAST) || defined(_DEBUG)
// Core::SyncTrace();
#endif
CoreTiming::downcount -= i; CoreTiming::downcount -= i;
} }
@ -244,10 +174,12 @@ void CInterpreter::sFastRun()
} }
} }
void CInterpreter::unknown_instruction(UGeckoInstruction _inst) void unknown_instruction(UGeckoInstruction _inst)
{ {
CCPU::Break(); CCPU::Break();
printf("Last PC = %08x : %s\n", last_pc, DisassembleGekko(Memory::ReadUnchecked_U32(last_pc), last_pc)); printf("Last PC = %08x : %s\n", last_pc, DisassembleGekko(Memory::ReadUnchecked_U32(last_pc), last_pc));
Debugger::PrintCallstack(); Debugger::PrintCallstack();
_dbg_assert_msg_(GEKKO, 0, "\nIntCPU: Unknown instr %08x at PC = %08x last_PC = %08x LR = %08x\n", _inst.hex, PC, last_pc, LR); _dbg_assert_msg_(GEKKO, 0, "\nIntCPU: Unknown instr %08x at PC = %08x last_PC = %08x LR = %08x\n", _inst.hex, PC, last_pc, LR);
} }
} // namespace

View File

@ -21,326 +21,304 @@
#include "../Gekko.h" #include "../Gekko.h"
#include "../PowerPC.h" #include "../PowerPC.h"
class CInterpreter : public ICPUCore namespace Interpreter
{ {
public: void Init();
// ICPUCore Interface void Shutdown();
void Init() { sInit(); } void Reset();
void Shutdown() { sShutdown(); } void SingleStep();
void Reset() { sReset(); } void SingleStepInner();
void SingleStep() { sStep(); } void Run();
void Run() { sFastRun(); }
static void sInit();
static void sShutdown();
static void sReset();
static void sStep();
static void sStepInner();
static void sFastRun();
typedef void (*_interpreterInstruction)(UGeckoInstruction instCode); typedef void (*_interpreterInstruction)(UGeckoInstruction instCode);
static _interpreterInstruction GetInstruction(UGeckoInstruction instCode); _interpreterInstruction GetInstruction(UGeckoInstruction instCode);
private: void Log();
static void Log();
// pointer to the CPU-Regs to keep the code cleaner // pointer to the CPU-Regs to keep the code cleaner
static u32* m_GPR; extern u32* m_GPR;
static bool m_EndBlock; extern bool m_EndBlock;
public: void unknown_instruction(UGeckoInstruction _inst);
static void unknown_instruction(UGeckoInstruction _inst);
// Branch Instructions // Branch Instructions
static void bx(UGeckoInstruction _inst); void bx(UGeckoInstruction _inst);
static void bcx(UGeckoInstruction _inst); void bcx(UGeckoInstruction _inst);
static void bcctrx(UGeckoInstruction _inst); void bcctrx(UGeckoInstruction _inst);
static void bclrx(UGeckoInstruction _inst); void bclrx(UGeckoInstruction _inst);
static void HLEFunction(UGeckoInstruction _inst); void HLEFunction(UGeckoInstruction _inst);
static void CompiledBlock(UGeckoInstruction _inst); void CompiledBlock(UGeckoInstruction _inst);
// Syscall Instruction // Syscall Instruction
static void sc(UGeckoInstruction _inst); void sc(UGeckoInstruction _inst);
// Floating Point Instructions // Floating Point Instructions
static void faddsx(UGeckoInstruction _inst); void faddsx(UGeckoInstruction _inst);
static void fdivsx(UGeckoInstruction _inst); void fdivsx(UGeckoInstruction _inst);
static void fmaddsx(UGeckoInstruction _inst); void fmaddsx(UGeckoInstruction _inst);
static void fmsubsx(UGeckoInstruction _inst); void fmsubsx(UGeckoInstruction _inst);
static void fmulsx(UGeckoInstruction _inst); void fmulsx(UGeckoInstruction _inst);
static void fnmaddsx(UGeckoInstruction _inst); void fnmaddsx(UGeckoInstruction _inst);
static void fnmsubsx(UGeckoInstruction _inst); void fnmsubsx(UGeckoInstruction _inst);
static void fresx(UGeckoInstruction _inst); void fresx(UGeckoInstruction _inst);
// static void fsqrtsx(UGeckoInstruction _inst); // void fsqrtsx(UGeckoInstruction _inst);
static void fsubsx(UGeckoInstruction _inst); void fsubsx(UGeckoInstruction _inst);
static void fabsx(UGeckoInstruction _inst); void fabsx(UGeckoInstruction _inst);
static void fcmpo(UGeckoInstruction _inst); void fcmpo(UGeckoInstruction _inst);
static void fcmpu(UGeckoInstruction _inst); void fcmpu(UGeckoInstruction _inst);
static void fctiwx(UGeckoInstruction _inst); void fctiwx(UGeckoInstruction _inst);
static void fctiwzx(UGeckoInstruction _inst); void fctiwzx(UGeckoInstruction _inst);
static void fmrx(UGeckoInstruction _inst); void fmrx(UGeckoInstruction _inst);
static void fnabsx(UGeckoInstruction _inst); void fnabsx(UGeckoInstruction _inst);
static void fnegx(UGeckoInstruction _inst); void fnegx(UGeckoInstruction _inst);
static void frspx(UGeckoInstruction _inst); void frspx(UGeckoInstruction _inst);
static void faddx(UGeckoInstruction _inst); void faddx(UGeckoInstruction _inst);
static void fdivx(UGeckoInstruction _inst); void fdivx(UGeckoInstruction _inst);
static void fmaddx(UGeckoInstruction _inst); void fmaddx(UGeckoInstruction _inst);
static void fmsubx(UGeckoInstruction _inst); void fmsubx(UGeckoInstruction _inst);
static void fmulx(UGeckoInstruction _inst); void fmulx(UGeckoInstruction _inst);
static void fnmaddx(UGeckoInstruction _inst); void fnmaddx(UGeckoInstruction _inst);
static void fnmsubx(UGeckoInstruction _inst); void fnmsubx(UGeckoInstruction _inst);
static void frsqrtex(UGeckoInstruction _inst); void frsqrtex(UGeckoInstruction _inst);
static void fselx(UGeckoInstruction _inst); void fselx(UGeckoInstruction _inst);
static void fsqrtx(UGeckoInstruction _inst); void fsqrtx(UGeckoInstruction _inst);
static void fsubx(UGeckoInstruction _inst); void fsubx(UGeckoInstruction _inst);
// Integer Instructions // Integer Instructions
static void addi(UGeckoInstruction _inst); void addi(UGeckoInstruction _inst);
static void addic(UGeckoInstruction _inst); void addic(UGeckoInstruction _inst);
static void addic_rc(UGeckoInstruction _inst); void addic_rc(UGeckoInstruction _inst);
static void addis(UGeckoInstruction _inst); void addis(UGeckoInstruction _inst);
static void andi_rc(UGeckoInstruction _inst); void andi_rc(UGeckoInstruction _inst);
static void andis_rc(UGeckoInstruction _inst); void andis_rc(UGeckoInstruction _inst);
static void cmpi(UGeckoInstruction _inst); void cmpi(UGeckoInstruction _inst);
static void cmpli(UGeckoInstruction _inst); void cmpli(UGeckoInstruction _inst);
static void mulli(UGeckoInstruction _inst); void mulli(UGeckoInstruction _inst);
static void ori(UGeckoInstruction _inst); void ori(UGeckoInstruction _inst);
static void oris(UGeckoInstruction _inst); void oris(UGeckoInstruction _inst);
static void subfic(UGeckoInstruction _inst); void subfic(UGeckoInstruction _inst);
static void twi(UGeckoInstruction _inst); void twi(UGeckoInstruction _inst);
static void xori(UGeckoInstruction _inst); void xori(UGeckoInstruction _inst);
static void xoris(UGeckoInstruction _inst); void xoris(UGeckoInstruction _inst);
static void rlwimix(UGeckoInstruction _inst); void rlwimix(UGeckoInstruction _inst);
static void rlwinmx(UGeckoInstruction _inst); void rlwinmx(UGeckoInstruction _inst);
static void rlwnmx(UGeckoInstruction _inst); void rlwnmx(UGeckoInstruction _inst);
static void andx(UGeckoInstruction _inst); void andx(UGeckoInstruction _inst);
static void andcx(UGeckoInstruction _inst); void andcx(UGeckoInstruction _inst);
static void cmp(UGeckoInstruction _inst); void cmp(UGeckoInstruction _inst);
static void cmpl(UGeckoInstruction _inst); void cmpl(UGeckoInstruction _inst);
static void cntlzwx(UGeckoInstruction _inst); void cntlzwx(UGeckoInstruction _inst);
static void eqvx(UGeckoInstruction _inst); void eqvx(UGeckoInstruction _inst);
static void extsbx(UGeckoInstruction _inst); void extsbx(UGeckoInstruction _inst);
static void extshx(UGeckoInstruction _inst); void extshx(UGeckoInstruction _inst);
static void nandx(UGeckoInstruction _inst); void nandx(UGeckoInstruction _inst);
static void norx(UGeckoInstruction _inst); void norx(UGeckoInstruction _inst);
static void orx(UGeckoInstruction _inst); void orx(UGeckoInstruction _inst);
static void orcx(UGeckoInstruction _inst); void orcx(UGeckoInstruction _inst);
static void slwx(UGeckoInstruction _inst); void slwx(UGeckoInstruction _inst);
static void srawx(UGeckoInstruction _inst); void srawx(UGeckoInstruction _inst);
static void srawix(UGeckoInstruction _inst); void srawix(UGeckoInstruction _inst);
static void srwx(UGeckoInstruction _inst); void srwx(UGeckoInstruction _inst);
static void tw(UGeckoInstruction _inst); void tw(UGeckoInstruction _inst);
static void xorx(UGeckoInstruction _inst); void xorx(UGeckoInstruction _inst);
static void addx(UGeckoInstruction _inst); void addx(UGeckoInstruction _inst);
static void addcx(UGeckoInstruction _inst); void addcx(UGeckoInstruction _inst);
static void addex(UGeckoInstruction _inst); void addex(UGeckoInstruction _inst);
static void addmex(UGeckoInstruction _inst); void addmex(UGeckoInstruction _inst);
static void addzex(UGeckoInstruction _inst); void addzex(UGeckoInstruction _inst);
static void divwx(UGeckoInstruction _inst); void divwx(UGeckoInstruction _inst);
static void divwux(UGeckoInstruction _inst); void divwux(UGeckoInstruction _inst);
static void mulhwx(UGeckoInstruction _inst); void mulhwx(UGeckoInstruction _inst);
static void mulhwux(UGeckoInstruction _inst); void mulhwux(UGeckoInstruction _inst);
static void mullwx(UGeckoInstruction _inst); void mullwx(UGeckoInstruction _inst);
static void negx(UGeckoInstruction _inst); void negx(UGeckoInstruction _inst);
static void subfx(UGeckoInstruction _inst); void subfx(UGeckoInstruction _inst);
static void subfcx(UGeckoInstruction _inst); void subfcx(UGeckoInstruction _inst);
static void subfex(UGeckoInstruction _inst); void subfex(UGeckoInstruction _inst);
static void subfmex(UGeckoInstruction _inst); void subfmex(UGeckoInstruction _inst);
static void subfzex(UGeckoInstruction _inst); void subfzex(UGeckoInstruction _inst);
// Load/Store Instructions // Load/Store Instructions
static void lbz(UGeckoInstruction _inst); void lbz(UGeckoInstruction _inst);
static void lbzu(UGeckoInstruction _inst); void lbzu(UGeckoInstruction _inst);
static void lfd(UGeckoInstruction _inst); void lfd(UGeckoInstruction _inst);
static void lfdu(UGeckoInstruction _inst); void lfdu(UGeckoInstruction _inst);
static void lfs(UGeckoInstruction _inst); void lfs(UGeckoInstruction _inst);
static void lfsu(UGeckoInstruction _inst); void lfsu(UGeckoInstruction _inst);
static void lha(UGeckoInstruction _inst); void lha(UGeckoInstruction _inst);
static void lhau(UGeckoInstruction _inst); void lhau(UGeckoInstruction _inst);
static void lhz(UGeckoInstruction _inst); void lhz(UGeckoInstruction _inst);
static void lhzu(UGeckoInstruction _inst); void lhzu(UGeckoInstruction _inst);
static void lmw(UGeckoInstruction _inst); void lmw(UGeckoInstruction _inst);
static void lwz(UGeckoInstruction _inst); void lwz(UGeckoInstruction _inst);
static void lwzu(UGeckoInstruction _inst); void lwzu(UGeckoInstruction _inst);
static void stb(UGeckoInstruction _inst); void stb(UGeckoInstruction _inst);
static void stbu(UGeckoInstruction _inst); void stbu(UGeckoInstruction _inst);
static void stfd(UGeckoInstruction _inst); void stfd(UGeckoInstruction _inst);
static void stfdu(UGeckoInstruction _inst); void stfdu(UGeckoInstruction _inst);
static void stfs(UGeckoInstruction _inst); void stfs(UGeckoInstruction _inst);
static void stfsu(UGeckoInstruction _inst); void stfsu(UGeckoInstruction _inst);
static void sth(UGeckoInstruction _inst); void sth(UGeckoInstruction _inst);
static void sthu(UGeckoInstruction _inst); void sthu(UGeckoInstruction _inst);
static void stmw(UGeckoInstruction _inst); void stmw(UGeckoInstruction _inst);
static void stw(UGeckoInstruction _inst); void stw(UGeckoInstruction _inst);
static void stwu(UGeckoInstruction _inst); void stwu(UGeckoInstruction _inst);
static void dcba(UGeckoInstruction _inst); void dcba(UGeckoInstruction _inst);
static void dcbf(UGeckoInstruction _inst); void dcbf(UGeckoInstruction _inst);
static void dcbi(UGeckoInstruction _inst); void dcbi(UGeckoInstruction _inst);
static void dcbst(UGeckoInstruction _inst); void dcbst(UGeckoInstruction _inst);
static void dcbt(UGeckoInstruction _inst); void dcbt(UGeckoInstruction _inst);
static void dcbtst(UGeckoInstruction _inst); void dcbtst(UGeckoInstruction _inst);
static void dcbz(UGeckoInstruction _inst); void dcbz(UGeckoInstruction _inst);
static void eciwx(UGeckoInstruction _inst); void eciwx(UGeckoInstruction _inst);
static void ecowx(UGeckoInstruction _inst); void ecowx(UGeckoInstruction _inst);
static void eieio(UGeckoInstruction _inst); void eieio(UGeckoInstruction _inst);
static void icbi(UGeckoInstruction _inst); void icbi(UGeckoInstruction _inst);
static void lbzux(UGeckoInstruction _inst); void lbzux(UGeckoInstruction _inst);
static void lbzx(UGeckoInstruction _inst); void lbzx(UGeckoInstruction _inst);
static void lfdux(UGeckoInstruction _inst); void lfdux(UGeckoInstruction _inst);
static void lfdx(UGeckoInstruction _inst); void lfdx(UGeckoInstruction _inst);
static void lfsux(UGeckoInstruction _inst); void lfsux(UGeckoInstruction _inst);
static void lfsx(UGeckoInstruction _inst); void lfsx(UGeckoInstruction _inst);
static void lhaux(UGeckoInstruction _inst); void lhaux(UGeckoInstruction _inst);
static void lhax(UGeckoInstruction _inst); void lhax(UGeckoInstruction _inst);
static void lhbrx(UGeckoInstruction _inst); void lhbrx(UGeckoInstruction _inst);
static void lhzux(UGeckoInstruction _inst); void lhzux(UGeckoInstruction _inst);
static void lhzx(UGeckoInstruction _inst); void lhzx(UGeckoInstruction _inst);
static void lswi(UGeckoInstruction _inst); void lswi(UGeckoInstruction _inst);
static void lswx(UGeckoInstruction _inst); void lswx(UGeckoInstruction _inst);
static void lwarx(UGeckoInstruction _inst); void lwarx(UGeckoInstruction _inst);
static void lwbrx(UGeckoInstruction _inst); void lwbrx(UGeckoInstruction _inst);
static void lwzux(UGeckoInstruction _inst); void lwzux(UGeckoInstruction _inst);
static void lwzx(UGeckoInstruction _inst); void lwzx(UGeckoInstruction _inst);
static void stbux(UGeckoInstruction _inst); void stbux(UGeckoInstruction _inst);
static void stbx(UGeckoInstruction _inst); void stbx(UGeckoInstruction _inst);
static void stfdux(UGeckoInstruction _inst); void stfdux(UGeckoInstruction _inst);
static void stfdx(UGeckoInstruction _inst); void stfdx(UGeckoInstruction _inst);
static void stfiwx(UGeckoInstruction _inst); void stfiwx(UGeckoInstruction _inst);
static void stfsux(UGeckoInstruction _inst); void stfsux(UGeckoInstruction _inst);
static void stfsx(UGeckoInstruction _inst); void stfsx(UGeckoInstruction _inst);
static void sthbrx(UGeckoInstruction _inst); void sthbrx(UGeckoInstruction _inst);
static void sthux(UGeckoInstruction _inst); void sthux(UGeckoInstruction _inst);
static void sthx(UGeckoInstruction _inst); void sthx(UGeckoInstruction _inst);
static void stswi(UGeckoInstruction _inst); void stswi(UGeckoInstruction _inst);
static void stswx(UGeckoInstruction _inst); void stswx(UGeckoInstruction _inst);
static void stwbrx(UGeckoInstruction _inst); void stwbrx(UGeckoInstruction _inst);
static void stwcxd(UGeckoInstruction _inst); void stwcxd(UGeckoInstruction _inst);
static void stwux(UGeckoInstruction _inst); void stwux(UGeckoInstruction _inst);
static void stwx(UGeckoInstruction _inst); void stwx(UGeckoInstruction _inst);
static void sync(UGeckoInstruction _inst); void sync(UGeckoInstruction _inst);
static void tlbia(UGeckoInstruction _inst); void tlbia(UGeckoInstruction _inst);
static void tlbie(UGeckoInstruction _inst); void tlbie(UGeckoInstruction _inst);
static void tlbsync(UGeckoInstruction _inst); void tlbsync(UGeckoInstruction _inst);
// Paired Instructions // Paired Instructions
static void psq_l(UGeckoInstruction _inst); void psq_l(UGeckoInstruction _inst);
static void psq_lu(UGeckoInstruction _inst); void psq_lu(UGeckoInstruction _inst);
static void psq_st(UGeckoInstruction _inst); void psq_st(UGeckoInstruction _inst);
static void psq_stu(UGeckoInstruction _inst); void psq_stu(UGeckoInstruction _inst);
static void psq_lx(UGeckoInstruction _inst); void psq_lx(UGeckoInstruction _inst);
static void psq_stx(UGeckoInstruction _inst); void psq_stx(UGeckoInstruction _inst);
static void psq_lux(UGeckoInstruction _inst); void psq_lux(UGeckoInstruction _inst);
static void psq_stux(UGeckoInstruction _inst); void psq_stux(UGeckoInstruction _inst);
static void ps_div(UGeckoInstruction _inst); void ps_div(UGeckoInstruction _inst);
static void ps_sub(UGeckoInstruction _inst); void ps_sub(UGeckoInstruction _inst);
static void ps_add(UGeckoInstruction _inst); void ps_add(UGeckoInstruction _inst);
static void ps_sel(UGeckoInstruction _inst); void ps_sel(UGeckoInstruction _inst);
static void ps_res(UGeckoInstruction _inst); void ps_res(UGeckoInstruction _inst);
static void ps_mul(UGeckoInstruction _inst); void ps_mul(UGeckoInstruction _inst);
static void ps_rsqrte(UGeckoInstruction _inst); void ps_rsqrte(UGeckoInstruction _inst);
static void ps_msub(UGeckoInstruction _inst); void ps_msub(UGeckoInstruction _inst);
static void ps_madd(UGeckoInstruction _inst); void ps_madd(UGeckoInstruction _inst);
static void ps_nmsub(UGeckoInstruction _inst); void ps_nmsub(UGeckoInstruction _inst);
static void ps_nmadd(UGeckoInstruction _inst); void ps_nmadd(UGeckoInstruction _inst);
static void ps_neg(UGeckoInstruction _inst); void ps_neg(UGeckoInstruction _inst);
static void ps_mr(UGeckoInstruction _inst); void ps_mr(UGeckoInstruction _inst);
static void ps_nabs(UGeckoInstruction _inst); void ps_nabs(UGeckoInstruction _inst);
static void ps_abs(UGeckoInstruction _inst); void ps_abs(UGeckoInstruction _inst);
static void ps_sum0(UGeckoInstruction _inst); void ps_sum0(UGeckoInstruction _inst);
static void ps_sum1(UGeckoInstruction _inst); void ps_sum1(UGeckoInstruction _inst);
static void ps_muls0(UGeckoInstruction _inst); void ps_muls0(UGeckoInstruction _inst);
static void ps_muls1(UGeckoInstruction _inst); void ps_muls1(UGeckoInstruction _inst);
static void ps_madds0(UGeckoInstruction _inst); void ps_madds0(UGeckoInstruction _inst);
static void ps_madds1(UGeckoInstruction _inst); void ps_madds1(UGeckoInstruction _inst);
static void ps_cmpu0(UGeckoInstruction _inst); void ps_cmpu0(UGeckoInstruction _inst);
static void ps_cmpo0(UGeckoInstruction _inst); void ps_cmpo0(UGeckoInstruction _inst);
static void ps_cmpu1(UGeckoInstruction _inst); void ps_cmpu1(UGeckoInstruction _inst);
static void ps_cmpo1(UGeckoInstruction _inst); void ps_cmpo1(UGeckoInstruction _inst);
static void ps_merge00(UGeckoInstruction _inst); void ps_merge00(UGeckoInstruction _inst);
static void ps_merge01(UGeckoInstruction _inst); void ps_merge01(UGeckoInstruction _inst);
static void ps_merge10(UGeckoInstruction _inst); void ps_merge10(UGeckoInstruction _inst);
static void ps_merge11(UGeckoInstruction _inst); void ps_merge11(UGeckoInstruction _inst);
static void dcbz_l(UGeckoInstruction _inst); void dcbz_l(UGeckoInstruction _inst);
// System Registers Instructions // System Registers Instructions
static void mcrfs(UGeckoInstruction _inst); void mcrfs(UGeckoInstruction _inst);
static void mffsx(UGeckoInstruction _inst); void mffsx(UGeckoInstruction _inst);
static void mtfsb0x(UGeckoInstruction _inst); void mtfsb0x(UGeckoInstruction _inst);
static void mtfsb1x(UGeckoInstruction _inst); void mtfsb1x(UGeckoInstruction _inst);
static void mtfsfix(UGeckoInstruction _inst); void mtfsfix(UGeckoInstruction _inst);
static void mtfsfx(UGeckoInstruction _inst); void mtfsfx(UGeckoInstruction _inst);
static void mcrxr(UGeckoInstruction _inst); void mcrxr(UGeckoInstruction _inst);
static void mfcr(UGeckoInstruction _inst); void mfcr(UGeckoInstruction _inst);
static void mfmsr(UGeckoInstruction _inst); void mfmsr(UGeckoInstruction _inst);
static void mfsr(UGeckoInstruction _inst); void mfsr(UGeckoInstruction _inst);
static void mfsrin(UGeckoInstruction _inst); void mfsrin(UGeckoInstruction _inst);
static void mtmsr(UGeckoInstruction _inst); void mtmsr(UGeckoInstruction _inst);
static void mtsr(UGeckoInstruction _inst); void mtsr(UGeckoInstruction _inst);
static void mtsrin(UGeckoInstruction _inst); void mtsrin(UGeckoInstruction _inst);
static void mfspr(UGeckoInstruction _inst); void mfspr(UGeckoInstruction _inst);
static void mftb(UGeckoInstruction _inst); void mftb(UGeckoInstruction _inst);
static void mtcrf(UGeckoInstruction _inst); void mtcrf(UGeckoInstruction _inst);
static void mtspr(UGeckoInstruction _inst); void mtspr(UGeckoInstruction _inst);
static void crand(UGeckoInstruction _inst); void crand(UGeckoInstruction _inst);
static void crandc(UGeckoInstruction _inst); void crandc(UGeckoInstruction _inst);
static void creqv(UGeckoInstruction _inst); void creqv(UGeckoInstruction _inst);
static void crnand(UGeckoInstruction _inst); void crnand(UGeckoInstruction _inst);
static void crnor(UGeckoInstruction _inst); void crnor(UGeckoInstruction _inst);
static void cror(UGeckoInstruction _inst); void cror(UGeckoInstruction _inst);
static void crorc(UGeckoInstruction _inst); void crorc(UGeckoInstruction _inst);
static void crxor(UGeckoInstruction _inst); void crxor(UGeckoInstruction _inst);
static void mcrf(UGeckoInstruction _inst); void mcrf(UGeckoInstruction _inst);
static void rfi(UGeckoInstruction _inst); void rfi(UGeckoInstruction _inst);
static void rfid(UGeckoInstruction _inst); void rfid(UGeckoInstruction _inst);
// static void sync(UGeckoInstruction _inst); // void sync(UGeckoInstruction _inst);
static void isync(UGeckoInstruction _inst); void isync(UGeckoInstruction _inst);
static void RunTable4(UGeckoInstruction _instCode); void RunTable4(UGeckoInstruction _instCode);
static void RunTable19(UGeckoInstruction _instCode); void RunTable19(UGeckoInstruction _instCode);
static void RunTable31(UGeckoInstruction _instCode); void RunTable31(UGeckoInstruction _instCode);
static void RunTable59(UGeckoInstruction _instCode); void RunTable59(UGeckoInstruction _instCode);
static void RunTable63(UGeckoInstruction _instCode); void RunTable63(UGeckoInstruction _instCode);
private:
// flag helper // flag helper
static inline void Helper_UpdateCR0(u32 _uValue); inline void Helper_UpdateCR0(u32 _uValue);
static inline void Helper_UpdateCR1(double _fValue); inline void Helper_UpdateCR1(double _fValue);
static inline void Helper_UpdateCR1(float _fValue); inline void Helper_UpdateCR1(float _fValue);
static inline void Helper_UpdateCRx(int _x, u32 _uValue); inline void Helper_UpdateCRx(int _x, u32 _uValue);
static inline u32 Helper_Carry(u32 _uValue1, u32 _uValue2); inline u32 Helper_Carry(u32 _uValue1, u32 _uValue2);
// address helper // address helper
static inline u32 Helper_Get_EA (const UGeckoInstruction _inst); inline u32 Helper_Get_EA (const UGeckoInstruction _inst);
static inline u32 Helper_Get_EA_U (const UGeckoInstruction _inst); inline u32 Helper_Get_EA_U (const UGeckoInstruction _inst);
static inline u32 Helper_Get_EA_X (const UGeckoInstruction _inst); inline u32 Helper_Get_EA_X (const UGeckoInstruction _inst);
static inline u32 Helper_Get_EA_UX(const UGeckoInstruction _inst); inline u32 Helper_Get_EA_UX(const UGeckoInstruction _inst);
// paired helper // paired helper
static float inline Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, const unsigned int _uScale); float inline Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, const unsigned int _uScale);
static void inline Helper_Quantize (const u32 _Addr, const float _fValue, const EQuantizeType _quantizeType, const unsigned _uScale); void inline Helper_Quantize (const u32 _Addr, const float _fValue, const EQuantizeType _quantizeType, const unsigned _uScale);
// other helper // other helper
static u32 Helper_Mask(int mb, int me); u32 Helper_Mask(int mb, int me);
static inline bool IsNAN(double _dValue); inline bool IsNAN(double _dValue);
// extern _interpreterInstruction m_opTable[64];
// --- Variables --- extern _interpreterInstruction m_opTable4[1024];
// extern _interpreterInstruction m_opTable19[1024];
extern _interpreterInstruction m_opTable31[1024];
// Helper tables extern _interpreterInstruction m_opTable59[32];
//static const float m_quantizeTable[]; extern _interpreterInstruction m_opTable63[1024];
//static const float m_dequantizeTable[];
// Instruction Tables
public: //made these public until i figure out a better way
static _interpreterInstruction m_opTable[64];
static _interpreterInstruction m_opTable4[1024];
static _interpreterInstruction m_opTable19[1024];
static _interpreterInstruction m_opTable31[1024];
static _interpreterInstruction m_opTable59[32];
static _interpreterInstruction m_opTable63[1024];
}; };
#endif #endif

View File

@ -20,8 +20,10 @@
#include "../../HLE/HLE.h" #include "../../HLE/HLE.h"
#include "../PPCAnalyst.h" #include "../PPCAnalyst.h"
namespace Interpreter
{
void CInterpreter::bx(UGeckoInstruction _inst) void bx(UGeckoInstruction _inst)
{ {
if (_inst.LK) if (_inst.LK)
LR = PC + 4; LR = PC + 4;
@ -41,7 +43,7 @@ void CInterpreter::bx(UGeckoInstruction _inst)
} }
// bcx - ugly, straight from PPC manual equations :) // bcx - ugly, straight from PPC manual equations :)
void CInterpreter::bcx(UGeckoInstruction _inst) void bcx(UGeckoInstruction _inst)
{ {
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0) if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR--; CTR--;
@ -65,7 +67,7 @@ void CInterpreter::bcx(UGeckoInstruction _inst)
m_EndBlock = true; m_EndBlock = true;
} }
void CInterpreter::bcctrx(UGeckoInstruction _inst) void bcctrx(UGeckoInstruction _inst)
{ {
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0) if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR--; CTR--;
@ -81,7 +83,7 @@ void CInterpreter::bcctrx(UGeckoInstruction _inst)
m_EndBlock = true; m_EndBlock = true;
} }
void CInterpreter::bclrx(UGeckoInstruction _inst) void bclrx(UGeckoInstruction _inst)
{ {
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0) if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR--; CTR--;
@ -98,18 +100,18 @@ void CInterpreter::bclrx(UGeckoInstruction _inst)
m_EndBlock = true; m_EndBlock = true;
} }
void CInterpreter::HLEFunction(UGeckoInstruction _inst) void HLEFunction(UGeckoInstruction _inst)
{ {
m_EndBlock = true; m_EndBlock = true;
HLE::Execute(PC, _inst.hex); HLE::Execute(PC, _inst.hex);
} }
void CInterpreter::CompiledBlock(UGeckoInstruction _inst) void CompiledBlock(UGeckoInstruction _inst)
{ {
_assert_msg_(GEKKO, 0, "CInterpreter::CompiledBlock - shouldn't be here!"); _assert_msg_(GEKKO, 0, "CompiledBlock - shouldn't be here!");
} }
void CInterpreter::rfi(UGeckoInstruction _inst) void rfi(UGeckoInstruction _inst)
{ {
//Bits SRR1[0,5-9,16<31>23, 25<32>27, 30<33>31] are placed into the corresponding bits of the MSR. //Bits SRR1[0,5-9,16<31>23, 25<32>27, 30<33>31] are placed into the corresponding bits of the MSR.
//MSR[13] is set to 0. //MSR[13] is set to 0.
@ -123,7 +125,7 @@ void CInterpreter::rfi(UGeckoInstruction _inst)
// PowerPC::CheckExceptions(); // PowerPC::CheckExceptions();
} }
void CInterpreter::rfid(UGeckoInstruction _inst) void rfid(UGeckoInstruction _inst)
{ {
_dbg_assert_msg_(GEKKO,0,"Instruction unimplemented (does this instruction even exist?)","rfid"); _dbg_assert_msg_(GEKKO,0,"Instruction unimplemented (does this instruction even exist?)","rfid");
m_EndBlock = true; m_EndBlock = true;
@ -131,10 +133,11 @@ void CInterpreter::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 CInterpreter::sc(UGeckoInstruction _inst) void sc(UGeckoInstruction _inst)
{ {
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL; PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
PowerPC::CheckExceptions(); PowerPC::CheckExceptions();
m_EndBlock = true; m_EndBlock = true;
} }
} // namespace

View File

@ -57,6 +57,9 @@
// Super Monkey Ball reads FPRF & friends after fmadds, fmuls, frspx // Super Monkey Ball reads FPRF & friends after fmadds, fmuls, frspx
// WHY do the FR & FI flags affect it so much? // WHY do the FR & FI flags affect it so much?
namespace Interpreter
{
void UpdateFPSCR(UReg_FPSCR fp); void UpdateFPSCR(UReg_FPSCR fp);
void UpdateSSEState(); void UpdateSSEState();
@ -110,7 +113,7 @@ void UpdateFPRF(double value)
// extremely rare // extremely rare
void CInterpreter::Helper_UpdateCR1(double _fValue) void Helper_UpdateCR1(double _fValue)
{ {
FPSCR.FPRF = 0; FPSCR.FPRF = 0;
if (_fValue == 0.0 || _fValue == -0.0) if (_fValue == 0.0 || _fValue == -0.0)
@ -124,12 +127,12 @@ void CInterpreter::Helper_UpdateCR1(double _fValue)
PanicAlert("CR1"); PanicAlert("CR1");
} }
bool CInterpreter::IsNAN(double _dValue) bool IsNAN(double _dValue)
{ {
return _dValue != _dValue; return _dValue != _dValue;
} }
void CInterpreter::fcmpo(UGeckoInstruction _inst) void fcmpo(UGeckoInstruction _inst)
{ {
double fa = rPS0(_inst.FA); double fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB); double fb = rPS0(_inst.FB);
@ -151,7 +154,7 @@ void CInterpreter::fcmpo(UGeckoInstruction _inst)
then VXVC ¬ 1 */ then VXVC ¬ 1 */
} }
void CInterpreter::fcmpu(UGeckoInstruction _inst) void fcmpu(UGeckoInstruction _inst)
{ {
double fa = rPS0(_inst.FA); double fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB); double fb = rPS0(_inst.FB);
@ -171,7 +174,7 @@ void CInterpreter::fcmpu(UGeckoInstruction _inst)
} }
// Apply current rounding mode // Apply current rounding mode
void CInterpreter::fctiwx(UGeckoInstruction _inst) void fctiwx(UGeckoInstruction _inst)
{ {
UpdateSSEState(); UpdateSSEState();
const double b = rPS0(_inst.FB); const double b = rPS0(_inst.FB);
@ -210,7 +213,7 @@ representable int result in 0x80000000 (a very negative number) rather than the
largest representable int on PowerPC. */ largest representable int on PowerPC. */
// Always round toward zero // Always round toward zero
void CInterpreter::fctiwzx(UGeckoInstruction _inst) void fctiwzx(UGeckoInstruction _inst)
{ {
//UpdateFPSCR(FPSCR); //UpdateFPSCR(FPSCR);
const double b = rPS0(_inst.FB); const double b = rPS0(_inst.FB);
@ -241,35 +244,35 @@ void CInterpreter::fctiwzx(UGeckoInstruction _inst)
Helper_UpdateCR1(rPS0(_inst.FD)); Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fmrx(UGeckoInstruction _inst) void 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 CInterpreter::fabsx(UGeckoInstruction _inst) void 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 CInterpreter::fnabsx(UGeckoInstruction _inst) void 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 CInterpreter::fnegx(UGeckoInstruction _inst) void 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 CInterpreter::fselx(UGeckoInstruction _inst) void 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
@ -281,7 +284,7 @@ void CInterpreter::fselx(UGeckoInstruction _inst)
// 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
// Super Monkey Ball is using this to do wacky tricks so we need 100% correct emulation. // Super Monkey Ball is using this to do wacky tricks so we need 100% correct emulation.
void CInterpreter::frspx(UGeckoInstruction _inst) // round to single void frspx(UGeckoInstruction _inst) // round to single
{ {
if (true || FPSCR.RN != 0) if (true || FPSCR.RN != 0)
{ {
@ -352,14 +355,14 @@ void CInterpreter::frspx(UGeckoInstruction _inst) // round to single
} }
void CInterpreter::fmulx(UGeckoInstruction _inst) void fmulx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS0(_inst.FA) * rPS0(_inst.FC); rPS0(_inst.FD) = rPS0(_inst.FA) * rPS0(_inst.FC);
FPSCR.FI = 0; FPSCR.FI = 0;
FPSCR.FR = 1; FPSCR.FR = 1;
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fmulsx(UGeckoInstruction _inst) void fmulsx(UGeckoInstruction _inst)
{ {
double d_value = rPS0(_inst.FA) * rPS0(_inst.FC); double d_value = rPS0(_inst.FA) * rPS0(_inst.FC);
rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(d_value); rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(d_value);
@ -370,14 +373,14 @@ void CInterpreter::fmulsx(UGeckoInstruction _inst)
} }
void CInterpreter::fmaddx(UGeckoInstruction _inst) void fmaddx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = (rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB); rPS0(_inst.FD) = (rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB);
FPSCR.FI = 0; FPSCR.FI = 0;
FPSCR.FR = 0; FPSCR.FR = 0;
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fmaddsx(UGeckoInstruction _inst) void fmaddsx(UGeckoInstruction _inst)
{ {
double d_value = (rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB); double d_value = (rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB);
rPS0(_inst.FD) = rPS1(_inst.FD) = rPS0(_inst.FD) = rPS1(_inst.FD) =
@ -389,14 +392,14 @@ void CInterpreter::fmaddsx(UGeckoInstruction _inst)
} }
void CInterpreter::faddx(UGeckoInstruction _inst) void faddx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS0(_inst.FA) + rPS0(_inst.FB); rPS0(_inst.FD) = rPS0(_inst.FA) + rPS0(_inst.FB);
// FPSCR.FI = 0; // FPSCR.FI = 0;
// FPSCR.FR = 1; // FPSCR.FR = 1;
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::faddsx(UGeckoInstruction _inst) void faddsx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(rPS0(_inst.FA) + rPS0(_inst.FB)); rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(rPS0(_inst.FA) + rPS0(_inst.FB));
// FPSCR.FI = 0; // FPSCR.FI = 0;
@ -406,7 +409,7 @@ void CInterpreter::faddsx(UGeckoInstruction _inst)
} }
void CInterpreter::fdivx(UGeckoInstruction _inst) void fdivx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS0(_inst.FA) / rPS0(_inst.FB); rPS0(_inst.FD) = rPS0(_inst.FA) / rPS0(_inst.FB);
// FPSCR.FI = 0; // FPSCR.FI = 0;
@ -416,7 +419,7 @@ void CInterpreter::fdivx(UGeckoInstruction _inst)
} }
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fdivsx(UGeckoInstruction _inst) void fdivsx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(rPS0(_inst.FA) / rPS0(_inst.FB)); rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(rPS0(_inst.FA) / rPS0(_inst.FB));
// FPSCR.FI = 0; // FPSCR.FI = 0;
@ -426,7 +429,7 @@ void CInterpreter::fdivsx(UGeckoInstruction _inst)
} }
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fresx(UGeckoInstruction _inst) void fresx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(1.0f / rPS0(_inst.FB)); rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(1.0f / rPS0(_inst.FB));
// FPSCR.FI = 0; // FPSCR.FI = 0;
@ -438,7 +441,7 @@ void CInterpreter::fresx(UGeckoInstruction _inst)
} }
void CInterpreter::fmsubx(UGeckoInstruction _inst) void fmsubx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = (rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB); rPS0(_inst.FD) = (rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB);
// FPSCR.FI = 0; // FPSCR.FI = 0;
@ -446,7 +449,7 @@ void CInterpreter::fmsubx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fmsubsx(UGeckoInstruction _inst) void fmsubsx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = rPS0(_inst.FD) = rPS1(_inst.FD) =
static_cast<float>((rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB)); static_cast<float>((rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB));
@ -456,14 +459,14 @@ void CInterpreter::fmsubsx(UGeckoInstruction _inst)
} }
void CInterpreter::fnmaddx(UGeckoInstruction _inst) void fnmaddx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = -((rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB)); rPS0(_inst.FD) = -((rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB));
// FPSCR.FI = 0; // FPSCR.FI = 0;
// FPSCR.FR = 0; // FPSCR.FR = 0;
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fnmaddsx(UGeckoInstruction _inst) void fnmaddsx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = rPS0(_inst.FD) = rPS1(_inst.FD) =
static_cast<float>(-((rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB))); static_cast<float>(-((rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB)));
@ -473,14 +476,14 @@ void CInterpreter::fnmaddsx(UGeckoInstruction _inst)
} }
void CInterpreter::fnmsubx(UGeckoInstruction _inst) void fnmsubx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = -((rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB)); rPS0(_inst.FD) = -((rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB));
// FPSCR.FI = 0; // FPSCR.FI = 0;
// FPSCR.FR = 0; // FPSCR.FR = 0;
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fnmsubsx(UGeckoInstruction _inst) void fnmsubsx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = rPS0(_inst.FD) = rPS1(_inst.FD) =
static_cast<float>(-((rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB))); static_cast<float>(-((rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB)));
@ -490,14 +493,14 @@ void CInterpreter::fnmsubsx(UGeckoInstruction _inst)
} }
void CInterpreter::fsubx(UGeckoInstruction _inst) void fsubx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS0(_inst.FA) - rPS0(_inst.FB); rPS0(_inst.FD) = rPS0(_inst.FA) - rPS0(_inst.FB);
// FPSCR.FI = 0; // FPSCR.FI = 0;
// FPSCR.FR = 0; // FPSCR.FR = 0;
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fsubsx(UGeckoInstruction _inst) void fsubsx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(rPS0(_inst.FA) - rPS0(_inst.FB)); rPS0(_inst.FD) = rPS1(_inst.FD) = static_cast<float>(rPS0(_inst.FA) - rPS0(_inst.FB));
// FPSCR.FI = 0; // FPSCR.FI = 0;
@ -506,7 +509,7 @@ void CInterpreter::fsubsx(UGeckoInstruction _inst)
} }
void CInterpreter::frsqrtex(UGeckoInstruction _inst) void frsqrtex(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = 1.0f / (sqrt(rPS0(_inst.FB))); rPS0(_inst.FD) = 1.0f / (sqrt(rPS0(_inst.FB)));
// FPSCR.FI = 0; // FPSCR.FI = 0;
@ -514,7 +517,7 @@ void CInterpreter::frsqrtex(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
void CInterpreter::fsqrtx(UGeckoInstruction _inst) void fsqrtx(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = sqrt(rPS0(_inst.FB)); rPS0(_inst.FD) = sqrt(rPS0(_inst.FB));
// FPSCR.FI = 0; // FPSCR.FI = 0;
@ -522,3 +525,5 @@ void CInterpreter::fsqrtx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD)); if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
} }
} // namespace

View File

@ -18,6 +18,8 @@
#include "Interpreter.h" #include "Interpreter.h"
#include "../../Core.h" #include "../../Core.h"
namespace Interpreter
{
#ifndef _WIN32 #ifndef _WIN32
inline u32 _rotl(u32 x, int shift) { inline u32 _rotl(u32 x, int shift) {
@ -27,7 +29,7 @@ inline u32 _rotl(u32 x, int shift) {
#endif #endif
void CInterpreter::Helper_UpdateCR0(u32 _uValue) void Helper_UpdateCR0(u32 _uValue)
{ {
u32 Flags = 0; u32 Flags = 0;
int sValue = (int)_uValue; int sValue = (int)_uValue;
@ -41,7 +43,7 @@ void CInterpreter::Helper_UpdateCR0(u32 _uValue)
PowerPC::ppcState.cr = (PowerPC::ppcState.cr & 0xFFFFFFF) | Flags; PowerPC::ppcState.cr = (PowerPC::ppcState.cr & 0xFFFFFFF) | Flags;
} }
void CInterpreter::Helper_UpdateCRx(int _x, u32 _uValue) void Helper_UpdateCRx(int _x, u32 _uValue)
{ {
int shiftamount = _x*4; int shiftamount = _x*4;
int crmask = 0xFFFFFFFF ^ (0xF0000000 >> shiftamount); int crmask = 0xFFFFFFFF ^ (0xF0000000 >> shiftamount);
@ -58,12 +60,12 @@ void CInterpreter::Helper_UpdateCRx(int _x, u32 _uValue)
PowerPC::ppcState.cr = (PowerPC::ppcState.cr & crmask) | (Flags >> shiftamount); PowerPC::ppcState.cr = (PowerPC::ppcState.cr & crmask) | (Flags >> shiftamount);
} }
u32 CInterpreter::Helper_Carry(u32 _uValue1, u32 _uValue2) u32 Helper_Carry(u32 _uValue1, u32 _uValue2)
{ {
return _uValue2 > (~_uValue1); return _uValue2 > (~_uValue1);
} }
u32 CInterpreter::Helper_Mask(int mb, int me) u32 Helper_Mask(int mb, int me)
{ {
//first make 001111111111111 part //first make 001111111111111 part
u32 begin = 0xFFFFFFFF >> mb; u32 begin = 0xFFFFFFFF >> mb;
@ -78,7 +80,7 @@ u32 CInterpreter::Helper_Mask(int mb, int me)
return mask; return mask;
} }
void CInterpreter::addi(UGeckoInstruction _inst) void 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;
@ -86,7 +88,7 @@ void CInterpreter::addi(UGeckoInstruction _inst)
m_GPR[_inst.RD] = _inst.SIMM_16; m_GPR[_inst.RD] = _inst.SIMM_16;
} }
void CInterpreter::addic(UGeckoInstruction _inst) void 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;
@ -95,13 +97,13 @@ void CInterpreter::addic(UGeckoInstruction _inst)
SetCarry(Helper_Carry(a, imm)); SetCarry(Helper_Carry(a, imm));
} }
void CInterpreter::addic_rc(UGeckoInstruction _inst) void addic_rc(UGeckoInstruction _inst)
{ {
addic(_inst); addic(_inst);
Helper_UpdateCR0(m_GPR[_inst.RD]); Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::addis(UGeckoInstruction _inst) void 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);
@ -109,24 +111,24 @@ void CInterpreter::addis(UGeckoInstruction _inst)
m_GPR[_inst.RD] = (_inst.SIMM_16 << 16); m_GPR[_inst.RD] = (_inst.SIMM_16 << 16);
} }
void CInterpreter::andi_rc(UGeckoInstruction _inst) void 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 CInterpreter::andis_rc(UGeckoInstruction _inst) void 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 CInterpreter::cmpi(UGeckoInstruction _inst) void 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 CInterpreter::cmpli(UGeckoInstruction _inst) void cmpli(UGeckoInstruction _inst)
{ {
u32 a = m_GPR[_inst.RA]; u32 a = m_GPR[_inst.RA];
u32 b = _inst.UIMM; u32 b = _inst.UIMM;
@ -138,22 +140,22 @@ void CInterpreter::cmpli(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, f); SetCRField(_inst.CRFD, f);
} }
void CInterpreter::mulli(UGeckoInstruction _inst) void 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 CInterpreter::ori(UGeckoInstruction _inst) void ori(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RA] = m_GPR[_inst.RS] | _inst.UIMM; m_GPR[_inst.RA] = m_GPR[_inst.RS] | _inst.UIMM;
} }
void CInterpreter::oris(UGeckoInstruction _inst) void 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 CInterpreter::subfic(UGeckoInstruction _inst) void 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;
@ -173,7 +175,7 @@ void CInterpreter::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 CInterpreter::twi(UGeckoInstruction _inst) void twi(UGeckoInstruction _inst)
{ {
bool bFirst = true; bool bFirst = true;
if (bFirst) if (bFirst)
@ -182,31 +184,31 @@ void CInterpreter::twi(UGeckoInstruction _inst)
bFirst = false; bFirst = false;
} }
void CInterpreter::xori(UGeckoInstruction _inst) void xori(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ _inst.UIMM; m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ _inst.UIMM;
} }
void CInterpreter::xoris(UGeckoInstruction _inst) void 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 CInterpreter::rlwimix(UGeckoInstruction _inst) void 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 CInterpreter::rlwinmx(UGeckoInstruction _inst) void 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 CInterpreter::rlwnmx(UGeckoInstruction _inst) void 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;
@ -214,21 +216,21 @@ void CInterpreter::rlwnmx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
} }
void CInterpreter::andx(UGeckoInstruction _inst) void 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 CInterpreter::andcx(UGeckoInstruction _inst) void 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 CInterpreter::cmp(UGeckoInstruction _inst) void 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];
@ -240,7 +242,7 @@ void CInterpreter::cmp(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, fTemp); SetCRField(_inst.CRFD, fTemp);
} }
void CInterpreter::cmpl(UGeckoInstruction _inst) void 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];
@ -252,7 +254,7 @@ void CInterpreter::cmpl(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, fTemp); SetCRField(_inst.CRFD, fTemp);
} }
void CInterpreter::cntlzwx(UGeckoInstruction _inst) void cntlzwx(UGeckoInstruction _inst)
{ {
u32 val = m_GPR[_inst.RS]; u32 val = m_GPR[_inst.RS];
u32 mask = 0x80000000; u32 mask = 0x80000000;
@ -264,56 +266,56 @@ void CInterpreter::cntlzwx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
} }
void CInterpreter::eqvx(UGeckoInstruction _inst) void 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 CInterpreter::extsbx(UGeckoInstruction _inst) void 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 CInterpreter::extshx(UGeckoInstruction _inst) void 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 CInterpreter::nandx(UGeckoInstruction _inst) void 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 CInterpreter::norx(UGeckoInstruction _inst) void 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 CInterpreter::orx(UGeckoInstruction _inst) void 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 CInterpreter::orcx(UGeckoInstruction _inst) void 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 CInterpreter::slwx(UGeckoInstruction _inst) void slwx(UGeckoInstruction _inst)
{ {
// TODO(ector): wtf is this code? // TODO(ector): wtf is this code?
/* u32 amount = m_GPR[_inst.RB]; /* u32 amount = m_GPR[_inst.RB];
@ -328,7 +330,7 @@ void CInterpreter::slwx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
} }
void CInterpreter::srawx(UGeckoInstruction _inst) void srawx(UGeckoInstruction _inst)
{ {
int rb = m_GPR[_inst.RB]; int rb = m_GPR[_inst.RB];
if (rb & 0x20) if (rb & 0x20)
@ -365,7 +367,7 @@ void CInterpreter::srawx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
} }
void CInterpreter::srawix(UGeckoInstruction _inst) void srawix(UGeckoInstruction _inst)
{ {
int amount = _inst.SH; int amount = _inst.SH;
@ -388,7 +390,7 @@ void CInterpreter::srawix(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
} }
void CInterpreter::srwx(UGeckoInstruction _inst) void 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); m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> amount);
@ -396,7 +398,7 @@ void CInterpreter::srwx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
} }
void CInterpreter::tw(UGeckoInstruction _inst) void tw(UGeckoInstruction _inst)
{ {
static bool bFirst = true; static bool bFirst = true;
if (bFirst) if (bFirst)
@ -404,14 +406,14 @@ void CInterpreter::tw(UGeckoInstruction _inst)
bFirst = false; bFirst = false;
} }
void CInterpreter::xorx(UGeckoInstruction _inst) void 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 CInterpreter::addx(UGeckoInstruction _inst) void 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];
@ -419,7 +421,7 @@ void CInterpreter::addx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::addcx(UGeckoInstruction _inst) void 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];
@ -430,7 +432,7 @@ void CInterpreter::addcx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::addex(UGeckoInstruction _inst) void addex(UGeckoInstruction _inst)
{ {
int carry = GetCarry(); int carry = GetCarry();
int a = m_GPR[_inst.RA]; int a = m_GPR[_inst.RA];
@ -442,7 +444,7 @@ void CInterpreter::addex(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::addmex(UGeckoInstruction _inst) void addmex(UGeckoInstruction _inst)
{ {
int carry = GetCarry(); int carry = GetCarry();
int a = m_GPR[_inst.RA]; int a = m_GPR[_inst.RA];
@ -453,7 +455,7 @@ void CInterpreter::addmex(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::addzex(UGeckoInstruction _inst) void addzex(UGeckoInstruction _inst)
{ {
int carry = GetCarry(); int carry = GetCarry();
int a = m_GPR[_inst.RA]; int a = m_GPR[_inst.RA];
@ -464,7 +466,7 @@ void CInterpreter::addzex(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::divwx(UGeckoInstruction _inst) void 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];
@ -481,7 +483,7 @@ void CInterpreter::divwx(UGeckoInstruction _inst)
} }
void CInterpreter::divwux(UGeckoInstruction _inst) void 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];
@ -499,7 +501,7 @@ void CInterpreter::divwux(UGeckoInstruction _inst)
} }
} }
void CInterpreter::mulhwx(UGeckoInstruction _inst) void 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];
@ -508,7 +510,7 @@ void CInterpreter::mulhwx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::mulhwux(UGeckoInstruction _inst) void 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];
@ -517,7 +519,7 @@ void CInterpreter::mulhwux(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::mullwx(UGeckoInstruction _inst) void 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];
@ -528,7 +530,7 @@ void CInterpreter::mullwx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::negx(UGeckoInstruction _inst) void 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)
@ -538,7 +540,7 @@ void CInterpreter::negx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::subfx(UGeckoInstruction _inst) void 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];
@ -546,7 +548,7 @@ void CInterpreter::subfx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::subfcx(UGeckoInstruction _inst) void 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];
@ -557,7 +559,7 @@ void CInterpreter::subfcx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]); if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
} }
void CInterpreter::subfex(UGeckoInstruction _inst) void 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];
@ -570,7 +572,7 @@ void CInterpreter::subfex(UGeckoInstruction _inst)
} }
// sub from minus one // sub from minus one
void CInterpreter::subfmex(UGeckoInstruction _inst) void subfmex(UGeckoInstruction _inst)
{ {
u32 a = m_GPR[_inst.RA]; u32 a = m_GPR[_inst.RA];
int carry = GetCarry(); int carry = GetCarry();
@ -582,7 +584,7 @@ void CInterpreter::subfmex(UGeckoInstruction _inst)
} }
// sub from zero // sub from zero
void CInterpreter::subfzex(UGeckoInstruction _inst) void subfzex(UGeckoInstruction _inst)
{ {
u32 a = m_GPR[_inst.RA]; u32 a = m_GPR[_inst.RA];
int carry = GetCarry(); int carry = GetCarry();
@ -592,3 +594,5 @@ void CInterpreter::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

View File

@ -25,70 +25,73 @@
#include "../Jit64/Jit.h" #include "../Jit64/Jit.h"
#include "../Jit64/JitCache.h" #include "../Jit64/JitCache.h"
u32 CInterpreter::Helper_Get_EA(const UGeckoInstruction _inst) namespace Interpreter
{
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 CInterpreter::Helper_Get_EA_U(const UGeckoInstruction _inst) u32 Helper_Get_EA_U(const UGeckoInstruction _inst)
{ {
return (m_GPR[_inst.RA] + _inst.SIMM_16); return (m_GPR[_inst.RA] + _inst.SIMM_16);
} }
u32 CInterpreter::Helper_Get_EA_X(const UGeckoInstruction _inst) u32 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 CInterpreter::Helper_Get_EA_UX(const UGeckoInstruction _inst) u32 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 CInterpreter::lbz(UGeckoInstruction _inst) void lbz(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = (u32)Memory::Read_U8(Helper_Get_EA(_inst)); m_GPR[_inst.RD] = (u32)Memory::Read_U8(Helper_Get_EA(_inst));
} }
void CInterpreter::lbzu(UGeckoInstruction _inst) void lbzu(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(_inst);
m_GPR[_inst.RD] = (u32)Memory::Read_U8(uAddress); m_GPR[_inst.RD] = (u32)Memory::Read_U8(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lfd(UGeckoInstruction _inst) void lfd(UGeckoInstruction _inst)
{ {
riPS0(_inst.FD) = Memory::Read_U64(Helper_Get_EA(_inst)); riPS0(_inst.FD) = Memory::Read_U64(Helper_Get_EA(_inst));
} }
void CInterpreter::lfdu(UGeckoInstruction _inst) void lfdu(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(_inst);
riPS0(_inst.FD) = Memory::Read_U64(uAddress); riPS0(_inst.FD) = Memory::Read_U64(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lfdux(UGeckoInstruction _inst) void lfdux(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(_inst);
riPS0(_inst.FD) = Memory::Read_U64(uAddress); riPS0(_inst.FD) = Memory::Read_U64(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lfdx(UGeckoInstruction _inst) void lfdx(UGeckoInstruction _inst)
{ {
riPS0(_inst.FD) = Memory::Read_U64(Helper_Get_EA_X(_inst)); riPS0(_inst.FD) = Memory::Read_U64(Helper_Get_EA_X(_inst));
} }
void CInterpreter::lfs(UGeckoInstruction _inst) void lfs(UGeckoInstruction _inst)
{ {
u32 uTemp = Memory::Read_U32(Helper_Get_EA(_inst)); u32 uTemp = Memory::Read_U32(Helper_Get_EA(_inst));
rPS0(_inst.FD) = *(float*)&uTemp; rPS0(_inst.FD) = *(float*)&uTemp;
rPS1(_inst.FD) = rPS0(_inst.FD); rPS1(_inst.FD) = rPS0(_inst.FD);
} }
void CInterpreter::lfsu(UGeckoInstruction _inst) void 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);
@ -97,7 +100,7 @@ void CInterpreter::lfsu(UGeckoInstruction _inst)
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lfsux(UGeckoInstruction _inst) void 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);
@ -106,38 +109,38 @@ void CInterpreter::lfsux(UGeckoInstruction _inst)
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lfsx(UGeckoInstruction _inst) void lfsx(UGeckoInstruction _inst)
{ {
u32 uTemp = Memory::Read_U32(Helper_Get_EA_X(_inst)); u32 uTemp = Memory::Read_U32(Helper_Get_EA_X(_inst));
rPS0(_inst.FD) = *(float*)&uTemp; rPS0(_inst.FD) = *(float*)&uTemp;
rPS1(_inst.FD) = rPS0(_inst.FD); rPS1(_inst.FD) = rPS0(_inst.FD);
} }
void CInterpreter::lha(UGeckoInstruction _inst) void lha(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = (u32)(s32)(s16)Memory::Read_U16(Helper_Get_EA(_inst)); m_GPR[_inst.RD] = (u32)(s32)(s16)Memory::Read_U16(Helper_Get_EA(_inst));
} }
void CInterpreter::lhau(UGeckoInstruction _inst) void lhau(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(_inst);
m_GPR[_inst.RD] = (u32)(s32)(s16)Memory::Read_U16(uAddress); m_GPR[_inst.RD] = (u32)(s32)(s16)Memory::Read_U16(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lhz(UGeckoInstruction _inst) void lhz(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = (u32)(u16)Memory::Read_U16(Helper_Get_EA(_inst)); m_GPR[_inst.RD] = (u32)(u16)Memory::Read_U16(Helper_Get_EA(_inst));
} }
void CInterpreter::lhzu(UGeckoInstruction _inst) void lhzu(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(_inst);
m_GPR[_inst.RD] = (u32)(u16)Memory::Read_U16(uAddress); m_GPR[_inst.RD] = (u32)(u16)Memory::Read_U16(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lmw(UGeckoInstruction _inst) void 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)
@ -153,7 +156,7 @@ void CInterpreter::lmw(UGeckoInstruction _inst)
} }
} }
void CInterpreter::stmw(UGeckoInstruction _inst) void 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)
@ -164,7 +167,7 @@ void CInterpreter::stmw(UGeckoInstruction _inst)
} }
} }
void CInterpreter::lwz(UGeckoInstruction _inst) void lwz(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA(_inst); u32 uAddress = Helper_Get_EA(_inst);
m_GPR[_inst.RD] = Memory::Read_U32(uAddress); m_GPR[_inst.RD] = Memory::Read_U32(uAddress);
@ -186,55 +189,44 @@ void CInterpreter::lwz(UGeckoInstruction _inst)
}*/ }*/
} }
void CInterpreter::lwzu(UGeckoInstruction _inst) void lwzu(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(_inst);
m_GPR[_inst.RD] = Memory::Read_U32(uAddress); m_GPR[_inst.RD] = Memory::Read_U32(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::stb(UGeckoInstruction _inst) void 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 CInterpreter::stbu(UGeckoInstruction _inst) void 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);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::stfd(UGeckoInstruction _inst) void stfd(UGeckoInstruction _inst)
{ {
Memory::Write_U64(riPS0(_inst.FS), Helper_Get_EA(_inst)); Memory::Write_U64(riPS0(_inst.FS), Helper_Get_EA(_inst));
} }
void CInterpreter::stfdu(UGeckoInstruction _inst) void 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);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
// __________________________________________________________________________________________________ void stfs(UGeckoInstruction _inst)
// stfs
//
// no paired ??
//
void
CInterpreter::stfs(UGeckoInstruction _inst)
{ {
float fTemp = (float)rPS0(_inst.FS); float fTemp = (float)rPS0(_inst.FS);
Memory::Write_U32(*(u32*)&fTemp, Helper_Get_EA(_inst)); Memory::Write_U32(*(u32*)&fTemp, Helper_Get_EA(_inst));
} }
// __________________________________________________________________________________________________ void stfsu(UGeckoInstruction _inst)
// stfsu
//
// no paired ??
//
void CInterpreter::stfsu(UGeckoInstruction _inst)
{ {
float fTemp = (float)rPS0(_inst.FS); float fTemp = (float)rPS0(_inst.FS);
u32 uAddress = Helper_Get_EA_U(_inst); u32 uAddress = Helper_Get_EA_U(_inst);
@ -242,36 +234,36 @@ void CInterpreter::stfsu(UGeckoInstruction _inst)
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::sth(UGeckoInstruction _inst) void 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 CInterpreter::sthu(UGeckoInstruction _inst) void 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);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::stw(UGeckoInstruction _inst) void 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 CInterpreter::stwu(UGeckoInstruction _inst) void 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);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::dcba(UGeckoInstruction _inst) void dcba(UGeckoInstruction _inst)
{ {
_assert_msg_(GEKKO,0,"dcba - Not implemented - not a Gekko instruction"); _assert_msg_(GEKKO,0,"dcba - Not implemented - not a Gekko instruction");
} }
void CInterpreter::dcbf(UGeckoInstruction _inst) void 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 !!!
@ -285,25 +277,25 @@ void CInterpreter::dcbf(UGeckoInstruction _inst)
}*/ }*/
} }
void CInterpreter::dcbi(UGeckoInstruction _inst) void dcbi(UGeckoInstruction _inst)
{ {
//Used during initialization //Used during initialization
//_assert_msg_(GEKKO,0,"dcbi - Not implemented"); //_assert_msg_(GEKKO,0,"dcbi - Not implemented");
} }
void CInterpreter::dcbst(UGeckoInstruction _inst) void dcbst(UGeckoInstruction _inst)
{ {
//_assert_msg_(GEKKO,0,"dcbst - Not implemented"); //_assert_msg_(GEKKO,0,"dcbst - Not implemented");
} }
void CInterpreter::dcbt(UGeckoInstruction _inst) void dcbt(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
//Used by Ikaruga //Used by Ikaruga
//_assert_msg_(GEKKO,0,"dcbt - Not implemented"); //_assert_msg_(GEKKO,0,"dcbt - Not implemented");
} }
void CInterpreter::dcbtst(UGeckoInstruction _inst) void dcbtst(UGeckoInstruction _inst)
{ {
_assert_msg_(GEKKO,0,"dcbtst - Not implemented"); _assert_msg_(GEKKO,0,"dcbtst - Not implemented");
} }
@ -311,82 +303,83 @@ void CInterpreter::dcbtst(UGeckoInstruction _inst)
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// dcbz // dcbz
// TODO(ector) check docs // TODO(ector) check docs
void CInterpreter::dcbz(UGeckoInstruction _inst) void 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);
} }
void CInterpreter::eciwx(UGeckoInstruction _inst) void eciwx(UGeckoInstruction _inst)
{ {
_assert_msg_(GEKKO,0,"eciwx - Not implemented"); _assert_msg_(GEKKO,0,"eciwx - Not implemented");
} }
void CInterpreter::ecowx(UGeckoInstruction _inst) void ecowx(UGeckoInstruction _inst)
{ {
_assert_msg_(GEKKO,0,"ecowx - Not implemented"); _assert_msg_(GEKKO,0,"ecowx - Not implemented");
} }
void CInterpreter::eieio(UGeckoInstruction _inst) void eieio(UGeckoInstruction _inst)
{ {
_assert_msg_(GEKKO,0,"eieio - Not implemented"); _assert_msg_(GEKKO,0,"eieio - Not implemented");
} }
void CInterpreter::icbi(UGeckoInstruction _inst) void icbi(UGeckoInstruction _inst)
{ {
u32 address = CInterpreter::Helper_Get_EA_X(_inst); u32 address = Helper_Get_EA_X(_inst);
//block size seems to be 0x20 // block size seems to be 0x20
address &= ~0x1f; address &= ~0x1f;
//Inform the dynarec to kill off this area of code NOW // this comment is slightly outdated but still relevant:
//VERY IMPORTANT when we start linking blocks // Inform the JIT to kill off this area of code NOW
//There are a TON of these so hopefully we can make this mechanism // VERY IMPORTANT when we start linking blocks
//fast in the dynarec // There are a TON of these so hopefully we can make this mechanism
// fast in the JIT
Jit64::InvalidateCodeRange(address, 0x20); Jit64::InvalidateCodeRange(address, 0x20);
} }
void CInterpreter::lbzux(UGeckoInstruction _inst) void lbzux(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(_inst);
m_GPR[_inst.RD] = (u32)Memory::Read_U8(uAddress); m_GPR[_inst.RD] = (u32)Memory::Read_U8(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lbzx(UGeckoInstruction _inst) void lbzx(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = (u32)Memory::Read_U8(Helper_Get_EA_X(_inst)); m_GPR[_inst.RD] = (u32)Memory::Read_U8(Helper_Get_EA_X(_inst));
} }
void CInterpreter::lhaux(UGeckoInstruction _inst) void lhaux(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(_inst);
m_GPR[_inst.RD] = (s32)(s16)Memory::Read_U16(uAddress); m_GPR[_inst.RD] = (s32)(s16)Memory::Read_U16(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lhax(UGeckoInstruction _inst) void lhax(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = (s32)(s16)Memory::Read_U16(Helper_Get_EA_X(_inst)); m_GPR[_inst.RD] = (s32)(s16)Memory::Read_U16(Helper_Get_EA_X(_inst));
} }
void CInterpreter::lhbrx(UGeckoInstruction _inst) void lhbrx(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = (u32)Common::swap16(Memory::Read_U16(Helper_Get_EA_X(_inst))); m_GPR[_inst.RD] = (u32)Common::swap16(Memory::Read_U16(Helper_Get_EA_X(_inst)));
} }
void CInterpreter::lhzux(UGeckoInstruction _inst) void lhzux(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(_inst);
m_GPR[_inst.RD] = (u32)Memory::Read_U16(uAddress); m_GPR[_inst.RD] = (u32)Memory::Read_U16(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lhzx(UGeckoInstruction _inst) void lhzx(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = (u32)Memory::Read_U16(Helper_Get_EA_X(_inst)); m_GPR[_inst.RD] = (u32)Memory::Read_U16(Helper_Get_EA_X(_inst));
} }
void CInterpreter::lswx(UGeckoInstruction _inst) void lswx(UGeckoInstruction _inst)
{ {
static bool bFirst = true; static bool bFirst = true;
if (bFirst) if (bFirst)
@ -394,44 +387,44 @@ void CInterpreter::lswx(UGeckoInstruction _inst)
bFirst = false; bFirst = false;
} }
void CInterpreter::lwbrx(UGeckoInstruction _inst) void lwbrx(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = Common::swap32(Memory::Read_U32(Helper_Get_EA_X(_inst))); m_GPR[_inst.RD] = Common::swap32(Memory::Read_U32(Helper_Get_EA_X(_inst)));
} }
void CInterpreter::lwzux(UGeckoInstruction _inst) void lwzux(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(_inst);
m_GPR[_inst.RD] = Memory::Read_U32(uAddress); m_GPR[_inst.RD] = Memory::Read_U32(uAddress);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::lwzx(UGeckoInstruction _inst) void lwzx(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_X(_inst); u32 uAddress = Helper_Get_EA_X(_inst);
m_GPR[_inst.RD] = Memory::Read_U32(uAddress); m_GPR[_inst.RD] = Memory::Read_U32(uAddress);
} }
void CInterpreter::stbux(UGeckoInstruction _inst) void 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);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::stbx(UGeckoInstruction _inst) void 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 CInterpreter::stfdux(UGeckoInstruction _inst) void 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);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::stfdx(UGeckoInstruction _inst) void 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));
} }
@ -439,7 +432,7 @@ void CInterpreter::stfdx(UGeckoInstruction _inst)
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// stfiwx // stfiwx
// TODO - examine what this really does // TODO - examine what this really does
void CInterpreter::stfiwx(UGeckoInstruction _inst) void stfiwx(UGeckoInstruction _inst)
{ {
u32 uAddress = Helper_Get_EA_X(_inst); u32 uAddress = Helper_Get_EA_X(_inst);
@ -451,7 +444,7 @@ void CInterpreter::stfiwx(UGeckoInstruction _inst)
// //
// no paired ?? // no paired ??
// //
void CInterpreter::stfsux(UGeckoInstruction _inst) void stfsux(UGeckoInstruction _inst)
{ {
float fTemp = (float)rPS0(_inst.FS); float fTemp = (float)rPS0(_inst.FS);
u32 uAddress = Helper_Get_EA_UX(_inst); u32 uAddress = Helper_Get_EA_UX(_inst);
@ -464,25 +457,25 @@ void CInterpreter::stfsux(UGeckoInstruction _inst)
// //
// no paired ?? // no paired ??
// //
void CInterpreter::stfsx(UGeckoInstruction _inst) void stfsx(UGeckoInstruction _inst)
{ {
float fTemp = (float)rPS0(_inst.FS); float fTemp = (float)rPS0(_inst.FS);
Memory::Write_U32(*(u32 *)&fTemp, Helper_Get_EA_X(_inst)); Memory::Write_U32(*(u32 *)&fTemp, Helper_Get_EA_X(_inst));
} }
void CInterpreter::sthbrx(UGeckoInstruction _inst) void 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 CInterpreter::sthux(UGeckoInstruction _inst) void 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);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::sthx(UGeckoInstruction _inst) void 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));
} }
@ -490,7 +483,7 @@ void CInterpreter::sthx(UGeckoInstruction _inst)
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// lswi - bizarro string instruction // lswi - bizarro string instruction
// //
void CInterpreter::lswi(UGeckoInstruction _inst) void lswi(UGeckoInstruction _inst)
{ {
u32 EA; u32 EA;
if (_inst.RA == 0) if (_inst.RA == 0)
@ -536,7 +529,7 @@ void CInterpreter::lswi(UGeckoInstruction _inst)
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// stswi - bizarro string instruction // stswi - bizarro string instruction
// //
void CInterpreter::stswi(UGeckoInstruction _inst) void stswi(UGeckoInstruction _inst)
{ {
u32 EA; u32 EA;
if (_inst.RA == 0) if (_inst.RA == 0)
@ -571,7 +564,7 @@ void CInterpreter::stswi(UGeckoInstruction _inst)
} }
} }
void CInterpreter::stswx(UGeckoInstruction _inst) void stswx(UGeckoInstruction _inst)
{ {
static bool bFirst = true; static bool bFirst = true;
if (bFirst) if (bFirst)
@ -579,7 +572,7 @@ void CInterpreter::stswx(UGeckoInstruction _inst)
bFirst = false; bFirst = false;
} }
void CInterpreter::stwbrx(UGeckoInstruction _inst) void 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);
@ -589,7 +582,7 @@ void CInterpreter::stwbrx(UGeckoInstruction _inst)
// The following two instructions are for inter-cpu communications. On a single CPU, they cannot // The following two instructions are for inter-cpu communications. On a single CPU, they cannot
// fail unless an interrupt happens in between, which usually won't happen with the JIT, so we just pretend // fail unless an interrupt happens in between, which usually won't happen with the JIT, so we just pretend
// they are regular loads and stores for now. If this proves to be a problem, we could add a reservation flag. // they are regular loads and stores for now. If this proves to be a problem, we could add a reservation flag.
void CInterpreter::lwarx(UGeckoInstruction _inst) void lwarx(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = Memory::Read_U32(Helper_Get_EA_X(_inst)); m_GPR[_inst.RD] = Memory::Read_U32(Helper_Get_EA_X(_inst));
//static bool bFirst = true; //static bool bFirst = true;
@ -598,7 +591,7 @@ void CInterpreter::lwarx(UGeckoInstruction _inst)
//bFirst = false; //bFirst = false;
} }
void CInterpreter::stwcxd(UGeckoInstruction _inst) void stwcxd(UGeckoInstruction _inst)
{ {
// This instruction, to // This instruction, to
static bool bFirst = true; static bool bFirst = true;
@ -609,25 +602,25 @@ void CInterpreter::stwcxd(UGeckoInstruction _inst)
Memory::Write_U32(m_GPR[_inst.RS], uAddress); Memory::Write_U32(m_GPR[_inst.RS], uAddress);
} }
void CInterpreter::stwux(UGeckoInstruction _inst) void 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);
m_GPR[_inst.RA] = uAddress; m_GPR[_inst.RA] = uAddress;
} }
void CInterpreter::stwx(UGeckoInstruction _inst) void 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 CInterpreter::sync(UGeckoInstruction _inst) void sync(UGeckoInstruction _inst)
{ {
//ignored //ignored
} }
void CInterpreter::tlbia(UGeckoInstruction _inst) void 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");
@ -635,7 +628,7 @@ void CInterpreter::tlbia(UGeckoInstruction _inst)
//MessageBox(0,"TLBIA","TLBIA",0); //MessageBox(0,"TLBIA","TLBIA",0);
} }
void CInterpreter::tlbie(UGeckoInstruction _inst) void tlbie(UGeckoInstruction _inst)
{ {
// invalid entry // invalid entry
int entry = _inst.RB; int entry = _inst.RB;
@ -643,7 +636,9 @@ void CInterpreter::tlbie(UGeckoInstruction _inst)
//MessageBox(0,"TLBIE","TLBIE",0); //MessageBox(0,"TLBIE","TLBIE",0);
} }
void CInterpreter::tlbsync(UGeckoInstruction _inst) void tlbsync(UGeckoInstruction _inst)
{ {
//MessageBox(0,"TLBsync","TLBsyncE",0); //MessageBox(0,"TLBsync","TLBsyncE",0);
} }
} // namespace

View File

@ -19,6 +19,9 @@
#include "Interpreter.h" #include "Interpreter.h"
#include "../../HW/Memmap.h" #include "../../HW/Memmap.h"
namespace Interpreter
{
// dequantize table // dequantize table
const float m_dequantizeTable[] = const float m_dequantizeTable[] =
{ {
@ -68,7 +71,7 @@ inline T CLAMP(T a, T bottom, T top) {
return a; return a;
} }
void CInterpreter::Helper_Quantize(const u32 _Addr, const float _fValue, void Helper_Quantize(const u32 _Addr, const float _fValue,
const EQuantizeType _quantizeType, const unsigned int _uScale) const EQuantizeType _quantizeType, const unsigned int _uScale)
{ {
switch(_quantizeType) switch(_quantizeType)
@ -112,7 +115,7 @@ void CInterpreter::Helper_Quantize(const u32 _Addr, const float _fValue,
} }
} }
float CInterpreter::Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType, float Helper_Dequantize(const u32 _Addr, const EQuantizeType _quantizeType,
const unsigned int _uScale) const unsigned int _uScale)
{ {
// dequantize the value // dequantize the value
@ -152,7 +155,7 @@ float CInterpreter::Helper_Dequantize(const u32 _Addr, const EQuantizeType _quan
return fResult; return fResult;
} }
void CInterpreter::psq_l(UGeckoInstruction _inst) void 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);
@ -175,7 +178,7 @@ void CInterpreter::psq_l(UGeckoInstruction _inst)
} }
} }
void CInterpreter::psq_lu(UGeckoInstruction _inst) void 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);
@ -199,7 +202,7 @@ void CInterpreter::psq_lu(UGeckoInstruction _inst)
m_GPR[_inst.RA] = EA; m_GPR[_inst.RA] = EA;
} }
void CInterpreter::psq_st(UGeckoInstruction _inst) void 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);
@ -221,7 +224,7 @@ void CInterpreter::psq_st(UGeckoInstruction _inst)
} }
} }
void CInterpreter::psq_stu(UGeckoInstruction _inst) void 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);
@ -244,7 +247,7 @@ void CInterpreter::psq_stu(UGeckoInstruction _inst)
m_GPR[_inst.RA] = EA; m_GPR[_inst.RA] = EA;
} }
void CInterpreter::psq_lx(UGeckoInstruction _inst) void 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);
@ -267,7 +270,7 @@ void CInterpreter::psq_lx(UGeckoInstruction _inst)
} }
} }
void CInterpreter::psq_stx(UGeckoInstruction _inst) void 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);
@ -289,7 +292,7 @@ void CInterpreter::psq_stx(UGeckoInstruction _inst)
} }
} }
void CInterpreter::psq_lux(UGeckoInstruction _inst) void 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);
@ -313,7 +316,7 @@ void CInterpreter::psq_lux(UGeckoInstruction _inst)
m_GPR[_inst.RA] = EA; m_GPR[_inst.RA] = EA;
} }
void CInterpreter::psq_stux(UGeckoInstruction _inst) void 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);
@ -334,4 +337,6 @@ void CInterpreter::psq_stux(UGeckoInstruction _inst)
Helper_Quantize(EA, (float)rPS0(_inst.RS), stType, stScale); Helper_Quantize(EA, (float)rPS0(_inst.RS), stType, stScale);
} }
m_GPR[_inst.RA] = EA; m_GPR[_inst.RA] = EA;
} // namespace=======
} }

View File

@ -19,39 +19,42 @@
#include "Interpreter.h" #include "Interpreter.h"
#include "../../HW/Memmap.h" #include "../../HW/Memmap.h"
namespace Interpreter
{
// These "binary instructions" do not alter FPSCR. // These "binary instructions" do not alter FPSCR.
void CInterpreter::ps_sel(UGeckoInstruction _inst) void ps_sel(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>((rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB)); rPS0(_inst.FD) = static_cast<float>((rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB));
rPS1(_inst.FD) = static_cast<float>((rPS1(_inst.FA) >= -0.0) ? rPS1(_inst.FC) : rPS1(_inst.FB)); rPS1(_inst.FD) = static_cast<float>((rPS1(_inst.FA) >= -0.0) ? rPS1(_inst.FC) : rPS1(_inst.FB));
} }
void CInterpreter::ps_neg(UGeckoInstruction _inst) void 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);
} }
void CInterpreter::ps_mr(UGeckoInstruction _inst) void 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);
} }
void CInterpreter::ps_nabs(UGeckoInstruction _inst) void 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);
} }
void CInterpreter::ps_abs(UGeckoInstruction _inst) void 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);
} }
// These are just moves, double is OK. // These are just moves, double is OK.
void CInterpreter::ps_merge00(UGeckoInstruction _inst) void ps_merge00(UGeckoInstruction _inst)
{ {
double p0 = rPS0(_inst.FA); double p0 = rPS0(_inst.FA);
double p1 = rPS0(_inst.FB); double p1 = rPS0(_inst.FB);
@ -59,7 +62,7 @@ void CInterpreter::ps_merge00(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_merge01(UGeckoInstruction _inst) void ps_merge01(UGeckoInstruction _inst)
{ {
double p0 = rPS0(_inst.FA); double p0 = rPS0(_inst.FA);
double p1 = rPS1(_inst.FB); double p1 = rPS1(_inst.FB);
@ -67,7 +70,7 @@ void CInterpreter::ps_merge01(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_merge10(UGeckoInstruction _inst) void ps_merge10(UGeckoInstruction _inst)
{ {
double p0 = rPS1(_inst.FA); double p0 = rPS1(_inst.FA);
double p1 = rPS0(_inst.FB); double p1 = rPS0(_inst.FB);
@ -75,7 +78,7 @@ void CInterpreter::ps_merge10(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_merge11(UGeckoInstruction _inst) void ps_merge11(UGeckoInstruction _inst)
{ {
double p0 = rPS1(_inst.FA); double p0 = rPS1(_inst.FA);
double p1 = rPS1(_inst.FB); double p1 = rPS1(_inst.FB);
@ -86,7 +89,7 @@ void CInterpreter::ps_merge11(UGeckoInstruction _inst)
// From here on, the real deal. // From here on, the real deal.
void CInterpreter::ps_div(UGeckoInstruction _inst) void ps_div(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>(rPS0(_inst.FA) / rPS0(_inst.FB)); rPS0(_inst.FD) = static_cast<float>(rPS0(_inst.FA) / rPS0(_inst.FB));
rPS1(_inst.FD) = static_cast<float>(rPS1(_inst.FA) / rPS1(_inst.FB)); rPS1(_inst.FD) = static_cast<float>(rPS1(_inst.FA) / rPS1(_inst.FB));
@ -96,31 +99,31 @@ void CInterpreter::ps_div(UGeckoInstruction _inst)
} }
} }
void CInterpreter::ps_sub(UGeckoInstruction _inst) void ps_sub(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>(rPS0(_inst.FA) - rPS0(_inst.FB)); rPS0(_inst.FD) = static_cast<float>(rPS0(_inst.FA) - rPS0(_inst.FB));
rPS1(_inst.FD) = static_cast<float>(rPS1(_inst.FA) - rPS1(_inst.FB)); rPS1(_inst.FD) = static_cast<float>(rPS1(_inst.FA) - rPS1(_inst.FB));
} }
void CInterpreter::ps_add(UGeckoInstruction _inst) void ps_add(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>(rPS0(_inst.FA) + rPS0(_inst.FB)); rPS0(_inst.FD) = static_cast<float>(rPS0(_inst.FA) + rPS0(_inst.FB));
rPS1(_inst.FD) = static_cast<float>(rPS1(_inst.FA) + rPS1(_inst.FB)); rPS1(_inst.FD) = static_cast<float>(rPS1(_inst.FA) + rPS1(_inst.FB));
} }
void CInterpreter::ps_res(UGeckoInstruction _inst) void ps_res(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = 1.0f / static_cast<float>(rPS0(_inst.FB)); rPS0(_inst.FD) = 1.0f / static_cast<float>(rPS0(_inst.FB));
rPS1(_inst.FD) = 1.0f / static_cast<float>(rPS1(_inst.FB)); rPS1(_inst.FD) = 1.0f / static_cast<float>(rPS1(_inst.FB));
} }
void CInterpreter::ps_mul(UGeckoInstruction _inst) void ps_mul(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>(rPS0(_inst.FA) * rPS0(_inst.FC)); rPS0(_inst.FD) = static_cast<float>(rPS0(_inst.FA) * rPS0(_inst.FC));
rPS1(_inst.FD) = static_cast<float>(rPS1(_inst.FA) * rPS1(_inst.FC)); rPS1(_inst.FD) = static_cast<float>(rPS1(_inst.FA) * rPS1(_inst.FC));
} }
void CInterpreter::ps_rsqrte(UGeckoInstruction _inst) void ps_rsqrte(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<double>(1.0f / sqrtf((float)rPS0(_inst.FB))); rPS0(_inst.FD) = static_cast<double>(1.0f / sqrtf((float)rPS0(_inst.FB)));
rPS1(_inst.FD) = static_cast<double>(1.0f / sqrtf((float)rPS1(_inst.FB))); rPS1(_inst.FD) = static_cast<double>(1.0f / sqrtf((float)rPS1(_inst.FB)));
@ -129,31 +132,31 @@ void CInterpreter::ps_rsqrte(UGeckoInstruction _inst)
} }
} }
void CInterpreter::ps_msub(UGeckoInstruction _inst) void ps_msub(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>((rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB)); rPS0(_inst.FD) = static_cast<float>((rPS0(_inst.FA) * rPS0(_inst.FC)) - rPS0(_inst.FB));
rPS1(_inst.FD) = static_cast<float>((rPS1(_inst.FA) * rPS1(_inst.FC)) - rPS1(_inst.FB)); rPS1(_inst.FD) = static_cast<float>((rPS1(_inst.FA) * rPS1(_inst.FC)) - rPS1(_inst.FB));
} }
void CInterpreter::ps_madd(UGeckoInstruction _inst) void ps_madd(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>((rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB)); rPS0(_inst.FD) = static_cast<float>((rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB));
rPS1(_inst.FD) = static_cast<float>((rPS1(_inst.FA) * rPS1(_inst.FC)) + rPS1(_inst.FB)); rPS1(_inst.FD) = static_cast<float>((rPS1(_inst.FA) * rPS1(_inst.FC)) + rPS1(_inst.FB));
} }
void CInterpreter::ps_nmsub(UGeckoInstruction _inst) void ps_nmsub(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>(-(rPS0(_inst.FA) * rPS0(_inst.FC) - rPS0(_inst.FB))); rPS0(_inst.FD) = static_cast<float>(-(rPS0(_inst.FA) * rPS0(_inst.FC) - rPS0(_inst.FB)));
rPS1(_inst.FD) = static_cast<float>(-(rPS1(_inst.FA) * rPS1(_inst.FC) - rPS1(_inst.FB))); rPS1(_inst.FD) = static_cast<float>(-(rPS1(_inst.FA) * rPS1(_inst.FC) - rPS1(_inst.FB)));
} }
void CInterpreter::ps_nmadd(UGeckoInstruction _inst) void ps_nmadd(UGeckoInstruction _inst)
{ {
rPS0(_inst.FD) = static_cast<float>(-(rPS0(_inst.FA) * rPS0(_inst.FC) + rPS0(_inst.FB))); rPS0(_inst.FD) = static_cast<float>(-(rPS0(_inst.FA) * rPS0(_inst.FC) + rPS0(_inst.FB)));
rPS1(_inst.FD) = static_cast<float>(-(rPS1(_inst.FA) * rPS1(_inst.FC) + rPS1(_inst.FB))); rPS1(_inst.FD) = static_cast<float>(-(rPS1(_inst.FA) * rPS1(_inst.FC) + rPS1(_inst.FB)));
} }
void CInterpreter::ps_sum0(UGeckoInstruction _inst) void ps_sum0(UGeckoInstruction _inst)
{ {
double p0 = (float)(rPS0(_inst.FA) + rPS1(_inst.FB)); double p0 = (float)(rPS0(_inst.FA) + rPS1(_inst.FB));
double p1 = (float)(rPS1(_inst.FC)); double p1 = (float)(rPS1(_inst.FC));
@ -161,7 +164,7 @@ void CInterpreter::ps_sum0(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_sum1(UGeckoInstruction _inst) void ps_sum1(UGeckoInstruction _inst)
{ {
double p0 = rPS0(_inst.FC); double p0 = rPS0(_inst.FC);
double p1 = rPS0(_inst.FA) + rPS1(_inst.FB); double p1 = rPS0(_inst.FA) + rPS1(_inst.FB);
@ -169,7 +172,7 @@ void CInterpreter::ps_sum1(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_muls0(UGeckoInstruction _inst) void ps_muls0(UGeckoInstruction _inst)
{ {
double p0 = rPS0(_inst.FA) * rPS0(_inst.FC); double p0 = rPS0(_inst.FA) * rPS0(_inst.FC);
double p1 = rPS1(_inst.FA) * rPS0(_inst.FC); double p1 = rPS1(_inst.FA) * rPS0(_inst.FC);
@ -177,7 +180,7 @@ void CInterpreter::ps_muls0(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_muls1(UGeckoInstruction _inst) void ps_muls1(UGeckoInstruction _inst)
{ {
double p0 = rPS0(_inst.FA) * rPS1(_inst.FC); double p0 = rPS0(_inst.FA) * rPS1(_inst.FC);
double p1 = rPS1(_inst.FA) * rPS1(_inst.FC); double p1 = rPS1(_inst.FA) * rPS1(_inst.FC);
@ -185,7 +188,7 @@ void CInterpreter::ps_muls1(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_madds0(UGeckoInstruction _inst) void ps_madds0(UGeckoInstruction _inst)
{ {
double p0 = (rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB); double p0 = (rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_inst.FB);
double p1 = (rPS1(_inst.FA) * rPS0(_inst.FC)) + rPS1(_inst.FB); double p1 = (rPS1(_inst.FA) * rPS0(_inst.FC)) + rPS1(_inst.FB);
@ -193,7 +196,7 @@ void CInterpreter::ps_madds0(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_madds1(UGeckoInstruction _inst) void ps_madds1(UGeckoInstruction _inst)
{ {
double p0 = (rPS0(_inst.FA) * rPS1(_inst.FC)) + rPS0(_inst.FB); double p0 = (rPS0(_inst.FA) * rPS1(_inst.FC)) + rPS0(_inst.FB);
double p1 = (rPS1(_inst.FA) * rPS1(_inst.FC)) + rPS1(_inst.FB); double p1 = (rPS1(_inst.FA) * rPS1(_inst.FC)) + rPS1(_inst.FB);
@ -201,7 +204,7 @@ void CInterpreter::ps_madds1(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1; rPS1(_inst.FD) = p1;
} }
void CInterpreter::ps_cmpu0(UGeckoInstruction _inst) void ps_cmpu0(UGeckoInstruction _inst)
{ {
double fa = rPS0(_inst.FA); double fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB); double fb = rPS0(_inst.FB);
@ -212,13 +215,13 @@ void CInterpreter::ps_cmpu0(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, compareResult); SetCRField(_inst.CRFD, compareResult);
} }
void CInterpreter::ps_cmpo0(UGeckoInstruction _inst) void ps_cmpo0(UGeckoInstruction _inst)
{ {
// for now HACK // for now HACK
ps_cmpu0(_inst); ps_cmpu0(_inst);
} }
void CInterpreter::ps_cmpu1(UGeckoInstruction _inst) void ps_cmpu1(UGeckoInstruction _inst)
{ {
double fa = rPS1(_inst.FA); double fa = rPS1(_inst.FA);
double fb = rPS1(_inst.FB); double fb = rPS1(_inst.FB);
@ -230,7 +233,7 @@ void CInterpreter::ps_cmpu1(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, compareResult); SetCRField(_inst.CRFD, compareResult);
} }
void CInterpreter::ps_cmpo1(UGeckoInstruction _inst) void ps_cmpo1(UGeckoInstruction _inst)
{ {
// for now HACK // for now HACK
ps_cmpu1(_inst); ps_cmpu1(_inst);
@ -239,8 +242,7 @@ void CInterpreter::ps_cmpo1(UGeckoInstruction _inst)
// __________________________________________________________________________________________________ // __________________________________________________________________________________________________
// dcbz_l // dcbz_l
// TODO(ector) check docs // TODO(ector) check docs
void void dcbz_l(UGeckoInstruction _inst)
CInterpreter::dcbz_l(UGeckoInstruction _inst)
{ {
// This is supposed to allocate a cache line in the locked cache. Not entirely sure how // This is supposed to allocate a cache line in the locked cache. Not entirely sure how
// this is visible to the rest of the world. For now, we ignore it. // this is visible to the rest of the world. For now, we ignore it.
@ -255,3 +257,5 @@ CInterpreter::dcbz_l(UGeckoInstruction _inst)
Memory::Write_U32(0,i); Memory::Write_U32(0,i);
*/ */
} }
} // namespace

View File

@ -49,6 +49,9 @@ 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
{
void UpdateSSEState() void UpdateSSEState()
{ {
u32 csr = _mm_getcsr(); u32 csr = _mm_getcsr();
@ -116,7 +119,7 @@ void UpdateFPSCR(UReg_FPSCR fp)
UpdateSSEState(); UpdateSSEState();
} }
void CInterpreter::mcrfs(UGeckoInstruction _inst) void mcrfs(UGeckoInstruction _inst)
{ {
u32 fpflags = ((FPSCR.Hex >> (4*(_inst.CRFS))) & 0xF); u32 fpflags = ((FPSCR.Hex >> (4*(_inst.CRFS))) & 0xF);
switch (_inst.CRFS) { switch (_inst.CRFS) {
@ -165,7 +168,7 @@ void CInterpreter::mcrfs(UGeckoInstruction _inst)
#define MXCSR_ROUND (16384|8192) #define MXCSR_ROUND (16384|8192)
#define MXCSR_FLUSH 32768 #define MXCSR_FLUSH 32768
void CInterpreter::mffsx(UGeckoInstruction _inst) void 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
@ -175,21 +178,21 @@ void CInterpreter::mffsx(UGeckoInstruction _inst)
if (_inst.Rc) PanicAlert("mffsx: inst_.Rc"); if (_inst.Rc) PanicAlert("mffsx: inst_.Rc");
} }
void CInterpreter::mtfsb0x(UGeckoInstruction _inst) void mtfsb0x(UGeckoInstruction _inst)
{ {
FPSCR.Hex &= (~(0x80000000 >> _inst.CRBD)); FPSCR.Hex &= (~(0x80000000 >> _inst.CRBD));
UpdateFPSCR(FPSCR); UpdateFPSCR(FPSCR);
if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc"); if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc");
} }
void CInterpreter::mtfsb1x(UGeckoInstruction _inst) void mtfsb1x(UGeckoInstruction _inst)
{ {
FPSCR.Hex |= 0x80000000 >> _inst.CRBD; FPSCR.Hex |= 0x80000000 >> _inst.CRBD;
UpdateFPSCR(FPSCR); UpdateFPSCR(FPSCR);
if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc"); if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc");
} }
void CInterpreter::mtfsfix(UGeckoInstruction _inst) void 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;
@ -198,7 +201,7 @@ void CInterpreter::mtfsfix(UGeckoInstruction _inst)
if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc"); if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc");
} }
void CInterpreter::mtfsfx(UGeckoInstruction _inst) void mtfsfx(UGeckoInstruction _inst)
{ {
u32 fm = _inst.FM; u32 fm = _inst.FM;
u32 m = 0; u32 m = 0;
@ -212,18 +215,18 @@ void CInterpreter::mtfsfx(UGeckoInstruction _inst)
if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc"); if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc");
} }
void CInterpreter::mcrxr(UGeckoInstruction _inst) void mcrxr(UGeckoInstruction _inst)
{ {
SetCRField(_inst.CRFD, XER.Hex >> 28); SetCRField(_inst.CRFD, XER.Hex >> 28);
XER.Hex &= ~0xF0000000; // clear 0-3 XER.Hex &= ~0xF0000000; // clear 0-3
} }
void CInterpreter::mfcr(UGeckoInstruction _inst) void mfcr(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = GetCR(); m_GPR[_inst.RD] = GetCR();
} }
void CInterpreter::mtcrf(UGeckoInstruction _inst) void mtcrf(UGeckoInstruction _inst)
{ {
u32 mask = 0; u32 mask = 0;
u32 crm = _inst.CRM; u32 crm = _inst.CRM;
@ -240,7 +243,7 @@ void CInterpreter::mtcrf(UGeckoInstruction _inst)
} }
void CInterpreter::mfmsr(UGeckoInstruction _inst) void mfmsr(UGeckoInstruction _inst)
{ {
//Privileged? //Privileged?
m_GPR[_inst.RD] = MSR; m_GPR[_inst.RD] = MSR;
@ -248,38 +251,38 @@ void CInterpreter::mfmsr(UGeckoInstruction _inst)
// segment register // segment register
// We can probably ignore all this junk // We can probably ignore all this junk
void CInterpreter::mfsr(UGeckoInstruction _inst) void mfsr(UGeckoInstruction _inst)
{ {
m_GPR[_inst.RD] = PowerPC::ppcState.sr[_inst.SR]; m_GPR[_inst.RD] = PowerPC::ppcState.sr[_inst.SR];
} }
// segment register // segment register
void CInterpreter::mfsrin(UGeckoInstruction _inst) void mfsrin(UGeckoInstruction _inst)
{ {
int index = m_GPR[_inst.RB] & 0xF; int index = m_GPR[_inst.RB] & 0xF;
m_GPR[_inst.RD] = PowerPC::ppcState.sr[index]; m_GPR[_inst.RD] = PowerPC::ppcState.sr[index];
} }
void CInterpreter::mtmsr(UGeckoInstruction _inst) void mtmsr(UGeckoInstruction _inst)
{ {
//Privileged? //Privileged?
MSR = m_GPR[_inst.RS]; MSR = m_GPR[_inst.RS];
} }
// segment register // segment register
void CInterpreter::mtsr(UGeckoInstruction _inst) void mtsr(UGeckoInstruction _inst)
{ {
PowerPC::ppcState.sr[_inst.SR] = m_GPR[_inst.RS]; PowerPC::ppcState.sr[_inst.SR] = m_GPR[_inst.RS];
} }
// segment register // segment register
void CInterpreter::mtsrin(UGeckoInstruction _inst) void mtsrin(UGeckoInstruction _inst)
{ {
int index = m_GPR[_inst.RB] & 0xF; int index = m_GPR[_inst.RB] & 0xF;
PowerPC::ppcState.sr[index] = m_GPR[_inst.RS]; PowerPC::ppcState.sr[index] = m_GPR[_inst.RS];
} }
void CInterpreter::mftb(UGeckoInstruction _inst) void mftb(UGeckoInstruction _inst)
{ {
int iIndex = (_inst.TBR >> 5) | ((_inst.TBR & 0x1F) << 5); int iIndex = (_inst.TBR >> 5) | ((_inst.TBR & 0x1F) << 5);
if (iIndex == 268) m_GPR[_inst.RD] = TL; if (iIndex == 268) m_GPR[_inst.RD] = TL;
@ -288,7 +291,7 @@ void CInterpreter::mftb(UGeckoInstruction _inst)
} }
void CInterpreter::mfspr(UGeckoInstruction _inst) void mfspr(UGeckoInstruction _inst)
{ {
u32 iIndex = ((_inst.SPR & 0x1F) << 5) + ((_inst.SPR >> 5) & 0x1F); u32 iIndex = ((_inst.SPR & 0x1F) << 5) + ((_inst.SPR >> 5) & 0x1F);
@ -315,7 +318,7 @@ void CInterpreter::mfspr(UGeckoInstruction _inst)
m_GPR[_inst.RD] = rSPR(iIndex); m_GPR[_inst.RD] = rSPR(iIndex);
} }
void CInterpreter::mtspr(UGeckoInstruction _inst) void 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);
@ -405,7 +408,7 @@ void CInterpreter::mtspr(UGeckoInstruction _inst)
} }
} }
void CInterpreter::crand(UGeckoInstruction _inst) void crand(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 a = cr << _inst.CRBA; u32 a = cr << _inst.CRBA;
@ -414,7 +417,7 @@ void CInterpreter::crand(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD))); SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
} }
void CInterpreter::crandc(UGeckoInstruction _inst) void crandc(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 a = cr << _inst.CRBA; u32 a = cr << _inst.CRBA;
@ -424,7 +427,7 @@ void CInterpreter::crandc(UGeckoInstruction _inst)
} }
void CInterpreter::creqv(UGeckoInstruction _inst) void creqv(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 a = cr << _inst.CRBA; u32 a = cr << _inst.CRBA;
@ -433,7 +436,7 @@ void CInterpreter::creqv(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD))); SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
} }
void CInterpreter::crnand(UGeckoInstruction _inst) void crnand(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 a = cr << _inst.CRBA; u32 a = cr << _inst.CRBA;
@ -442,7 +445,7 @@ void CInterpreter::crnand(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD))); SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
} }
void CInterpreter::crnor(UGeckoInstruction _inst) void crnor(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 a = cr << _inst.CRBA; u32 a = cr << _inst.CRBA;
@ -451,7 +454,7 @@ void CInterpreter::crnor(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD))); SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
} }
void CInterpreter::cror(UGeckoInstruction _inst) void cror(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 a = cr << _inst.CRBA; u32 a = cr << _inst.CRBA;
@ -460,7 +463,7 @@ void CInterpreter::cror(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD))); SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
} }
void CInterpreter::crorc(UGeckoInstruction _inst) void crorc(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 a = cr << _inst.CRBA; u32 a = cr << _inst.CRBA;
@ -469,7 +472,7 @@ void CInterpreter::crorc(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD))); SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
} }
void CInterpreter::crxor(UGeckoInstruction _inst) void crxor(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 a = cr << _inst.CRBA; u32 a = cr << _inst.CRBA;
@ -478,7 +481,7 @@ void CInterpreter::crxor(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD))); SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
} }
void CInterpreter::mcrf(UGeckoInstruction _inst) void mcrf(UGeckoInstruction _inst)
{ {
u32 cr = GetCR(); u32 cr = GetCR();
u32 crmask = ~(0xF0000000 >> (4*_inst.CRFD)); u32 crmask = ~(0xF0000000 >> (4*_inst.CRFD));
@ -486,7 +489,9 @@ void CInterpreter::mcrf(UGeckoInstruction _inst)
SetCR((cr & crmask) | flags); SetCR((cr & crmask) | flags);
} }
void CInterpreter::isync(UGeckoInstruction _inst) void isync(UGeckoInstruction _inst)
{ {
//shouldnt do anything //shouldnt do anything
} }
} // namespace

View File

@ -80,8 +80,8 @@ extern int blocksExecuted;
//be allocated, it should just be a temporary to do non-destructive trinary ops. //be allocated, it should just be a temporary to do non-destructive trinary ops.
//However, for the above to work and be a win, we need to store away the non volatiles before //However, for the above to work and be a win, we need to store away the non volatiles before
//entering "dynarec space". However, once we're there, it will be a win. //entering "JIT space". However, once we're there, it will be a win.
//Also, dynarec space will need to be surrounded with stack adjusting, since functions will be called. //Also, JIT space will need to be surrounded with stack adjusting, since functions will be called.
//Many instructions have shorter forms for EAX. However, I believe their performance boost //Many instructions have shorter forms for EAX. However, I believe their performance boost
//will be as small to be negligble, so I haven't dirtied up the code with that. AMD recommends it in their //will be as small to be negligble, so I haven't dirtied up the code with that. AMD recommends it in their
@ -118,36 +118,36 @@ extern int blocksExecuted;
// Plan: 1. Byteswap Dolphin DONE! // Plan: 1. Byteswap Dolphin DONE!
// 2. Fix timing WORKING // 2. Fix timing WORKING
// 3. Lay groundwork for x64 dynarec WORKING // 3. Lay groundwork for x64 JIT WORKING
// 4. Get OneTri up to 60fps, and check compatibility from time to time (yea right) ???? // 4. Get OneTri up to 60fps, and check compatibility from time to time (yea right) ????
// 5. Add block linking to dynarec << NOT SO IMPORTANT // 5. Add block linking to JIT << NOT SO IMPORTANT
// 6. Optimize GFX plugin to hell << IMPORTANT // 6. Optimize GFX plugin to hell << IMPORTANT
// 7. Watch Zelda do 20 fps. // 7. Watch Zelda do 20 fps.
// 8. Watch Zelda TP do 30 fps. // 8. Watch Zelda TP do 30 fps. DONE :D
//Optimizations - //Optimizations -
/* /*
* Assume SP is in main RAM (in Wii mode too?) * Assume SP is in main RAM (in Wii mode too?)
* Assume all floating point loads and double precision stores are to/from main ram (single precision can be used in write gather) * Assume all floating point loads and double precision loads+stores are to/from main ram
(single precision can be used in write gather)
(this is valid on Wii too when using the VM emulator) (this is valid on Wii too when using the VM emulator)
* AMD only - use movaps instead of movapd when loading ps from memory? * AMD only - use movaps instead of movapd when loading ps from memory?
* HLE functions like floorf, sin, memcpy, etc - they can be much faster * HLE functions like floorf, sin, memcpy, etc - they can be much faster
* Optimal sequence to store floats * Optimal sequence to store floats
* TODO: find optimal sequence to store doubles as floats * TODO: find optimal sequence to store doubles as floats
cvtpd2ps xmm0, xmm0
movss xmm0, f movss xmm0, f
movss tempspace, xmm0 movss tempspace, xmm0
mov eax, tempspace mov eax, tempspace
bswap eax bswap eax
mov [edi], eax mov [edi], eax
I think pshufb does it faster.
BLOCK EXIT DESIGN BLOCK EXIT DESIGN
TEST whatever TEST whatever
JZ skip JZ skip
MOV NPC, exit1 MOV NPC, exit1
@ -162,9 +162,6 @@ JMP exit1
The problem is, we still need to fit the downcount somewhere... The problem is, we still need to fit the downcount somewhere...
Low hanging fruit: Low hanging fruit:
stfd -- guaranteed in memory stfd -- guaranteed in memory
cmpl cmpl
@ -256,7 +253,7 @@ namespace Jit64
MOV(32, M(&PC), Imm32(js.compilerPC)); MOV(32, M(&PC), Imm32(js.compilerPC));
MOV(32, M(&NPC), Imm32(js.compilerPC + 4)); MOV(32, M(&NPC), Imm32(js.compilerPC + 4));
} }
CInterpreter::_interpreterInstruction instr = GetInterpreterOp(_inst); Interpreter::_interpreterInstruction instr = GetInterpreterOp(_inst);
ABI_CallFunctionC((void*)instr, _inst.hex); ABI_CallFunctionC((void*)instr, _inst.hex);
} }

View File

@ -39,7 +39,7 @@ namespace Jit64
struct JitBlock; struct JitBlock;
const u8* DoJit(u32 emaddress, JitBlock &b); const u8* DoJit(u32 emaddress, JitBlock &b);
bool IsInJitCode(u8 *codePtr); bool IsInJitCode(const u8 *codePtr);
struct JitState struct JitState
{ {

View File

@ -62,13 +62,12 @@ namespace Jit64
static JitBlock *blocks; static JitBlock *blocks;
static int numBlocks; static int numBlocks;
//stats
static int numFlushes; void DestroyBlock(int blocknum, bool invalidate);
void PrintStats() void PrintStats()
{ {
LOG(DYNA_REC, "JIT Statistics ======================="); LOG(DYNA_REC, "JIT Statistics =======================");
LOG(DYNA_REC, "Number of full cache flushes: %i", numFlushes);
LOG(DYNA_REC, "Number of blocks currently: %i", numBlocks); LOG(DYNA_REC, "Number of blocks currently: %i", numBlocks);
LOG(DYNA_REC, "Code cache size: %i b", GetCodePtr() - codeCache); LOG(DYNA_REC, "Code cache size: %i b", GetCodePtr() - codeCache);
LOG(DYNA_REC, "======================================"); LOG(DYNA_REC, "======================================");
@ -80,7 +79,6 @@ namespace Jit64
genFunctions = (u8*)AllocateExecutableMemory(GEN_SIZE); genFunctions = (u8*)AllocateExecutableMemory(GEN_SIZE);
trampolineCache = (u8*)AllocateExecutableMemory(TRAMPOLINE_SIZE); trampolineCache = (u8*)AllocateExecutableMemory(TRAMPOLINE_SIZE);
trampolineCodePtr = trampolineCache; trampolineCodePtr = trampolineCache;
numFlushes = 0;
blocks = new JitBlock[MAX_NUM_BLOCKS]; blocks = new JitBlock[MAX_NUM_BLOCKS];
blockCodePointers = new u8*[MAX_NUM_BLOCKS]; blockCodePointers = new u8*[MAX_NUM_BLOCKS];
@ -88,10 +86,44 @@ namespace Jit64
SetCodePtr(genFunctions); SetCodePtr(genFunctions);
Asm::Generate(); Asm::Generate();
// Protect the generated functions // Protect the generated functions
WriteProtectMemory(genFunctions, 4096, true); WriteProtectMemory(genFunctions, GEN_SIZE, true);
SetCodePtr(codeCache); SetCodePtr(codeCache);
} }
void ShutdownCache()
{
UnWriteProtectMemory(genFunctions, GEN_SIZE, true);
FreeMemoryPages(codeCache, CODE_SIZE);
FreeMemoryPages(genFunctions, GEN_SIZE);
FreeMemoryPages(trampolineCache, TRAMPOLINE_SIZE);
delete [] blocks;
delete [] blockCodePointers;
blocks = 0;
blockCodePointers = 0;
numBlocks = 0;
}
void ClearCache()
{
Core::DisplayMessage("Cleared code cache.", 3000);
// Is destroying the blocks really necessary?
for (int i = 0; i < numBlocks; i++) {
DestroyBlock(i, false);
}
links_to.clear();
trampolineCodePtr = trampolineCache;
numBlocks = 0;
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS);
memset(codeCache, 0xCC, CODE_SIZE);
SetCodePtr(codeCache);
}
void ResetCache()
{
ShutdownCache();
InitCache();
}
JitBlock *CurBlock() JitBlock *CurBlock()
{ {
return &blocks[numBlocks]; return &blocks[numBlocks];
@ -123,10 +155,10 @@ namespace Jit64
{ {
if (GetCodePtr() >= codeCache + CODE_SIZE - 0x10000 || numBlocks >= MAX_NUM_BLOCKS - 1) if (GetCodePtr() >= codeCache + CODE_SIZE - 0x10000 || numBlocks >= MAX_NUM_BLOCKS - 1)
{ {
// PanicAlert("Cleared cache"); LOG(DYNA_REC, "JIT cache full - clearing.")
LOG(DYNA_REC, "JIT code cache full - clearing cache and restoring memory")
ClearCache(); ClearCache();
} }
JitBlock &b = blocks[numBlocks]; JitBlock &b = blocks[numBlocks];
b.invalid = false; b.invalid = false;
b.originalAddress = emAddress; b.originalAddress = emAddress;
@ -169,12 +201,10 @@ namespace Jit64
return blockCodePointers; return blockCodePointers;
} }
bool IsInJitCode(const u8 *codePtr) {
bool IsInJitCode(u8 *codePtr) {
return codePtr >= codeCache && codePtr <= GetCodePtr(); return codePtr >= codeCache && codePtr <= GetCodePtr();
} }
void EnterFastRun() void EnterFastRun()
{ {
CompiledCode pExecAddr = (CompiledCode)Asm::enterCode; CompiledCode pExecAddr = (CompiledCode)Asm::enterCode;
@ -182,25 +212,6 @@ namespace Jit64
//Will return when PowerPC::state changes //Will return when PowerPC::state changes
} }
void ShutdownCache()
{
UnWriteProtectMemory(genFunctions, 4096, true);
FreeMemoryPages(codeCache, CODE_SIZE);
FreeMemoryPages(genFunctions, GEN_SIZE);
FreeMemoryPages(trampolineCache, TRAMPOLINE_SIZE);
delete [] blocks;
delete [] blockCodePointers;
blocks = 0;
blockCodePointers = 0;
numBlocks = 0;
}
void ResetCache()
{
ShutdownCache();
InitCache();
}
int GetBlockNumberFromAddress(u32 addr) int GetBlockNumberFromAddress(u32 addr)
{ {
if (!blocks) if (!blocks)
@ -226,6 +237,7 @@ namespace Jit64
return -1; return -1;
} }
} }
u32 GetOriginalCode(u32 address) u32 GetOriginalCode(u32 address)
{ {
int num = GetBlockNumberFromAddress(address); int num = GetBlockNumberFromAddress(address);
@ -357,21 +369,4 @@ namespace Jit64
} }
} }
void ClearCache() } // namespace
{
Core::DisplayMessage("Cleared code cache.", 3000);
// Is destroying the blocks really necessary?
for (int i = 0; i < numBlocks; i++) {
DestroyBlock(i, false);
}
links_to.clear();
trampolineCodePtr = trampolineCache;
numBlocks = 0;
numFlushes++;
memset(blockCodePointers, 0, sizeof(u8*)*MAX_NUM_BLOCKS);
memset(codeCache, 0xCC, CODE_SIZE);
SetCodePtr(codeCache);
}
}

View File

@ -30,38 +30,30 @@
namespace Jit64 namespace Jit64
{ {
void Jit64Core::Init() namespace Core
{ {
::Jit64::Init();
InitCache();
Asm::compareEnabled = Core::g_CoreStartupParameter.bRunCompareClient;
}
void Jit64Core::Shutdown() void Init()
{ {
ShutdownCache(); ::Jit64::Init();
} InitCache();
Asm::compareEnabled = ::Core::g_CoreStartupParameter.bRunCompareClient;
void Jit64Core::Reset()
{
ResetCache();
}
void Jit64Core::SingleStep()
{
Run();
/*
CompiledCode pExecAddr = (CompiledCode)GetCompiledCode(PC);
if (pExecAddr == NULL)
{
pExecAddr = (CompiledCode)Jit(PC);
}
pExecAddr();
*/
}
void Jit64Core::Run()
{
EnterFastRun();
}
} }
void Shutdown()
{
ShutdownCache();
}
void SingleStep()
{
Run();
}
void Run()
{
EnterFastRun();
}
} // namespace
} // namespace

View File

@ -17,13 +17,10 @@
#ifndef _JITCORE_H #ifndef _JITCORE_H
#define _JITCORE_H #define _JITCORE_H
#include "../ICPUCore.h"
namespace Jit64 namespace Jit64
{ {
class Jit64Core : public ICPUCore namespace Core
{ {
public:
void Init(); void Init();
void Shutdown(); void Shutdown();
void Reset(); void Reset();

View File

@ -95,7 +95,7 @@ GekkoOPInfo *GetOpInfo(UGeckoInstruction _inst)
} }
} }
CInterpreter::_interpreterInstruction GetInterpreterOp(UGeckoInstruction _inst) Interpreter::_interpreterInstruction GetInterpreterOp(UGeckoInstruction _inst)
{ {
const GekkoOPInfo *info = m_infoTable[_inst.OPCD]; const GekkoOPInfo *info = m_infoTable[_inst.OPCD];
if ((info->type & 0xFFFFFF) == OPTYPE_SUBTABLE) if ((info->type & 0xFFFFFF) == OPTYPE_SUBTABLE)
@ -103,11 +103,11 @@ CInterpreter::_interpreterInstruction GetInterpreterOp(UGeckoInstruction _inst)
int table = info->type>>24; int table = info->type>>24;
switch(table) switch(table)
{ {
case 4: return CInterpreter::m_opTable4[_inst.SUBOP10]; case 4: return Interpreter::m_opTable4[_inst.SUBOP10];
case 19: return CInterpreter::m_opTable19[_inst.SUBOP10]; case 19: return Interpreter::m_opTable19[_inst.SUBOP10];
case 31: return CInterpreter::m_opTable31[_inst.SUBOP10]; case 31: return Interpreter::m_opTable31[_inst.SUBOP10];
case 59: return CInterpreter::m_opTable59[_inst.SUBOP5]; case 59: return Interpreter::m_opTable59[_inst.SUBOP5];
case 63: return CInterpreter::m_opTable63[_inst.SUBOP10]; case 63: return Interpreter::m_opTable63[_inst.SUBOP10];
default: default:
_assert_msg_(GEKKO,0,"GetInterpreterOp - invalid subtable op %08x @ %08x", _inst, PC); _assert_msg_(GEKKO,0,"GetInterpreterOp - invalid subtable op %08x @ %08x", _inst, PC);
return 0; return 0;
@ -120,338 +120,338 @@ CInterpreter::_interpreterInstruction GetInterpreterOp(UGeckoInstruction _inst)
_assert_msg_(GEKKO,0,"GetInterpreterOp - invalid op %08x @ %08x", _inst, PC); _assert_msg_(GEKKO,0,"GetInterpreterOp - invalid op %08x @ %08x", _inst, PC);
return 0; return 0;
} }
return CInterpreter::m_opTable[_inst.OPCD]; return Interpreter::m_opTable[_inst.OPCD];
} }
} }
GekkoOPTemplate primarytable[] = GekkoOPTemplate primarytable[] =
{ {
{4, CInterpreter::RunTable4, DynaRunTable4, {"RunTable4", OPTYPE_SUBTABLE | (4<<24), 0}}, {4, Interpreter::RunTable4, DynaRunTable4, {"RunTable4", OPTYPE_SUBTABLE | (4<<24), 0}},
{19, CInterpreter::RunTable19, DynaRunTable19, {"RunTable19", OPTYPE_SUBTABLE | (19<<24), 0}}, {19, Interpreter::RunTable19, DynaRunTable19, {"RunTable19", OPTYPE_SUBTABLE | (19<<24), 0}},
{31, CInterpreter::RunTable31, DynaRunTable31, {"RunTable31", OPTYPE_SUBTABLE | (31<<24), 0}}, {31, Interpreter::RunTable31, DynaRunTable31, {"RunTable31", OPTYPE_SUBTABLE | (31<<24), 0}},
{59, CInterpreter::RunTable59, DynaRunTable59, {"RunTable59", OPTYPE_SUBTABLE | (59<<24), 0}}, {59, Interpreter::RunTable59, DynaRunTable59, {"RunTable59", OPTYPE_SUBTABLE | (59<<24), 0}},
{63, CInterpreter::RunTable63, DynaRunTable63, {"RunTable63", OPTYPE_SUBTABLE | (63<<24), 0}}, {63, Interpreter::RunTable63, DynaRunTable63, {"RunTable63", OPTYPE_SUBTABLE | (63<<24), 0}},
{16, CInterpreter::bcx, Jit64::bcx, {"bcx", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {16, Interpreter::bcx, Jit64::bcx, {"bcx", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{18, CInterpreter::bx, Jit64::bx, {"bx", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {18, Interpreter::bx, Jit64::bx, {"bx", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{1, CInterpreter::HLEFunction, Jit64::HLEFunction, {"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {1, Interpreter::HLEFunction, Jit64::HLEFunction, {"HLEFunction", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{2, CInterpreter::CompiledBlock, Jit64::Default, {"DynaBlock", OPTYPE_SYSTEM, 0}}, {2, Interpreter::CompiledBlock, Jit64::Default, {"DynaBlock", OPTYPE_SYSTEM, 0}},
{3, CInterpreter::twi, Jit64::Default, {"twi", OPTYPE_SYSTEM, 0}}, {3, Interpreter::twi, Jit64::Default, {"twi", OPTYPE_SYSTEM, 0}},
{17, CInterpreter::sc, Jit64::sc, {"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}}, {17, Interpreter::sc, Jit64::sc, {"sc", OPTYPE_SYSTEM, FL_ENDBLOCK, 1}},
{7, CInterpreter::mulli, Jit64::mulli, {"mulli", OPTYPE_INTEGER, FL_RC_BIT, 2}}, {7, Interpreter::mulli, Jit64::mulli, {"mulli", OPTYPE_INTEGER, FL_RC_BIT, 2}},
{8, CInterpreter::subfic, Jit64::subfic, {"subfic", OPTYPE_INTEGER, FL_SET_CA}}, {8, Interpreter::subfic, Jit64::subfic, {"subfic", OPTYPE_INTEGER, FL_SET_CA}},
{10, CInterpreter::cmpli, Jit64::cmpli, {"cmpli", OPTYPE_INTEGER, FL_SET_CRn}}, {10, Interpreter::cmpli, Jit64::cmpli, {"cmpli", OPTYPE_INTEGER, FL_SET_CRn}},
{11, CInterpreter::cmpi, Jit64::cmpi, {"cmpi", OPTYPE_INTEGER, FL_SET_CRn}}, {11, Interpreter::cmpi, Jit64::cmpi, {"cmpi", OPTYPE_INTEGER, FL_SET_CRn}},
{12, CInterpreter::addic, Jit64::reg_imm, {"addic", OPTYPE_INTEGER, FL_SET_CA}}, {12, Interpreter::addic, Jit64::reg_imm, {"addic", OPTYPE_INTEGER, FL_SET_CA}},
{13, CInterpreter::addic_rc, Jit64::reg_imm, {"addic_rc", OPTYPE_INTEGER, FL_SET_CR0}}, {13, Interpreter::addic_rc, Jit64::reg_imm, {"addic_rc", OPTYPE_INTEGER, FL_SET_CR0}},
{14, CInterpreter::addi, Jit64::reg_imm, {"addi", OPTYPE_INTEGER, 0}}, {14, Interpreter::addi, Jit64::reg_imm, {"addi", OPTYPE_INTEGER, 0}},
{15, CInterpreter::addis, Jit64::reg_imm, {"addis", OPTYPE_INTEGER, 0}}, {15, Interpreter::addis, Jit64::reg_imm, {"addis", OPTYPE_INTEGER, 0}},
{20, CInterpreter::rlwimix, Jit64::rlwimix, {"rlwimix", OPTYPE_INTEGER, FL_RC_BIT}}, {20, Interpreter::rlwimix, Jit64::rlwimix, {"rlwimix", OPTYPE_INTEGER, FL_RC_BIT}},
{21, CInterpreter::rlwinmx, Jit64::rlwinmx, {"rlwinmx", OPTYPE_INTEGER, FL_RC_BIT}}, {21, Interpreter::rlwinmx, Jit64::rlwinmx, {"rlwinmx", OPTYPE_INTEGER, FL_RC_BIT}},
{23, CInterpreter::rlwnmx, Jit64::rlwnmx, {"rlwnmx", OPTYPE_INTEGER, FL_RC_BIT}}, {23, Interpreter::rlwnmx, Jit64::rlwnmx, {"rlwnmx", OPTYPE_INTEGER, FL_RC_BIT}},
{24, CInterpreter::ori, Jit64::reg_imm, {"ori", OPTYPE_INTEGER, 0}}, {24, Interpreter::ori, Jit64::reg_imm, {"ori", OPTYPE_INTEGER, 0}},
{25, CInterpreter::oris, Jit64::reg_imm, {"oris", OPTYPE_INTEGER, 0}}, {25, Interpreter::oris, Jit64::reg_imm, {"oris", OPTYPE_INTEGER, 0}},
{26, CInterpreter::xori, Jit64::reg_imm, {"xori", OPTYPE_INTEGER, 0}}, {26, Interpreter::xori, Jit64::reg_imm, {"xori", OPTYPE_INTEGER, 0}},
{27, CInterpreter::xoris, Jit64::reg_imm, {"xoris", OPTYPE_INTEGER, 0}}, {27, Interpreter::xoris, Jit64::reg_imm, {"xoris", OPTYPE_INTEGER, 0}},
{28, CInterpreter::andi_rc, Jit64::reg_imm, {"andi_rc", OPTYPE_INTEGER, FL_SET_CR0}}, {28, Interpreter::andi_rc, Jit64::reg_imm, {"andi_rc", OPTYPE_INTEGER, FL_SET_CR0}},
{29, CInterpreter::andis_rc, Jit64::reg_imm, {"andis_rc", OPTYPE_INTEGER, FL_SET_CR0}}, {29, Interpreter::andis_rc, Jit64::reg_imm, {"andis_rc", OPTYPE_INTEGER, FL_SET_CR0}},
{32, CInterpreter::lwz, Jit64::lXz, {"lwz", OPTYPE_LOAD, 0}}, {32, Interpreter::lwz, Jit64::lXz, {"lwz", OPTYPE_LOAD, 0}},
{33, CInterpreter::lwzu, Jit64::Default, {"lwzu", OPTYPE_LOAD, 0}}, {33, Interpreter::lwzu, Jit64::Default, {"lwzu", OPTYPE_LOAD, 0}},
{34, CInterpreter::lbz, Jit64::lXz, {"lbz", OPTYPE_LOAD, 0}}, {34, Interpreter::lbz, Jit64::lXz, {"lbz", OPTYPE_LOAD, 0}},
{35, CInterpreter::lbzu, Jit64::Default, {"lbzu", OPTYPE_LOAD, 0}}, {35, Interpreter::lbzu, Jit64::Default, {"lbzu", OPTYPE_LOAD, 0}},
{40, CInterpreter::lhz, Jit64::lXz, {"lhz", OPTYPE_LOAD, 0}}, {40, Interpreter::lhz, Jit64::lXz, {"lhz", OPTYPE_LOAD, 0}},
{41, CInterpreter::lhzu, Jit64::Default, {"lhzu", OPTYPE_LOAD, 0}}, {41, Interpreter::lhzu, Jit64::Default, {"lhzu", OPTYPE_LOAD, 0}},
{42, CInterpreter::lha, Jit64::lha, {"lha", OPTYPE_LOAD, 0}}, {42, Interpreter::lha, Jit64::lha, {"lha", OPTYPE_LOAD, 0}},
{43, CInterpreter::lhau, Jit64::Default, {"lhau", OPTYPE_LOAD, 0}}, {43, Interpreter::lhau, Jit64::Default, {"lhau", OPTYPE_LOAD, 0}},
{48, CInterpreter::lfs, Jit64::lfs, {"lfs", OPTYPE_LOADFP, 0}}, {48, Interpreter::lfs, Jit64::lfs, {"lfs", OPTYPE_LOADFP, 0}},
{49, CInterpreter::lfsu, Jit64::Default, {"lfsu", OPTYPE_LOADFP, 0}}, {49, Interpreter::lfsu, Jit64::Default, {"lfsu", OPTYPE_LOADFP, 0}},
{50, CInterpreter::lfd, Jit64::lfd, {"lfd", OPTYPE_LOADFP, 0}}, {50, Interpreter::lfd, Jit64::lfd, {"lfd", OPTYPE_LOADFP, 0}},
{51, CInterpreter::lfdu, Jit64::Default, {"lfdu", OPTYPE_LOADFP, 0}}, {51, Interpreter::lfdu, Jit64::Default, {"lfdu", OPTYPE_LOADFP, 0}},
{44, CInterpreter::sth, Jit64::stX, {"sth", OPTYPE_STORE, 0}}, {44, Interpreter::sth, Jit64::stX, {"sth", OPTYPE_STORE, 0}},
{45, CInterpreter::sthu, Jit64::stX, {"sthu", OPTYPE_STORE, 0}}, {45, Interpreter::sthu, Jit64::stX, {"sthu", OPTYPE_STORE, 0}},
{36, CInterpreter::stw, Jit64::stX, {"stw", OPTYPE_STORE, 0}}, {36, Interpreter::stw, Jit64::stX, {"stw", OPTYPE_STORE, 0}},
{37, CInterpreter::stwu, Jit64::stX, {"stwu", OPTYPE_STORE, 0}}, {37, Interpreter::stwu, Jit64::stX, {"stwu", OPTYPE_STORE, 0}},
{38, CInterpreter::stb, Jit64::stX, {"stb", OPTYPE_STORE, 0}}, {38, Interpreter::stb, Jit64::stX, {"stb", OPTYPE_STORE, 0}},
{39, CInterpreter::stbu, Jit64::stX, {"stbu", OPTYPE_STORE, 0}}, {39, Interpreter::stbu, Jit64::stX, {"stbu", OPTYPE_STORE, 0}},
{52, CInterpreter::stfs, Jit64::stfs, {"stfs", OPTYPE_STOREFP, 0}}, {52, Interpreter::stfs, Jit64::stfs, {"stfs", OPTYPE_STOREFP, 0}},
{53, CInterpreter::stfsu, Jit64::stfs, {"stfsu", OPTYPE_STOREFP, 0}}, {53, Interpreter::stfsu, Jit64::stfs, {"stfsu", OPTYPE_STOREFP, 0}},
{54, CInterpreter::stfd, Jit64::stfd, {"stfd", OPTYPE_STOREFP, 0}}, {54, Interpreter::stfd, Jit64::stfd, {"stfd", OPTYPE_STOREFP, 0}},
{55, CInterpreter::stfdu, Jit64::Default, {"stfdu", OPTYPE_STOREFP, 0}}, {55, Interpreter::stfdu, Jit64::Default, {"stfdu", OPTYPE_STOREFP, 0}},
{46, CInterpreter::lmw, Jit64::lmw, {"lmw", OPTYPE_SYSTEM, 0, 10}}, {46, Interpreter::lmw, Jit64::lmw, {"lmw", OPTYPE_SYSTEM, 0, 10}},
{47, CInterpreter::stmw, Jit64::stmw, {"stmw", OPTYPE_SYSTEM, 0, 10}}, {47, Interpreter::stmw, Jit64::stmw, {"stmw", OPTYPE_SYSTEM, 0, 10}},
{56, CInterpreter::psq_l, Jit64::psq_l, {"psq_l", OPTYPE_PS, 0}}, {56, Interpreter::psq_l, Jit64::psq_l, {"psq_l", OPTYPE_PS, 0}},
{57, CInterpreter::psq_lu, Jit64::psq_l, {"psq_lu", OPTYPE_PS, 0}}, {57, Interpreter::psq_lu, Jit64::psq_l, {"psq_lu", OPTYPE_PS, 0}},
{60, CInterpreter::psq_st, Jit64::psq_st, {"psq_st", OPTYPE_PS, 0}}, {60, Interpreter::psq_st, Jit64::psq_st, {"psq_st", OPTYPE_PS, 0}},
{61, CInterpreter::psq_stu, Jit64::psq_st, {"psq_stu", OPTYPE_PS, 0}}, {61, Interpreter::psq_stu, Jit64::psq_st, {"psq_stu", OPTYPE_PS, 0}},
//missing: 0, 5, 6, 9, 22, 30, 62, 58 //missing: 0, 5, 6, 9, 22, 30, 62, 58
{0, CInterpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, {0, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}},
{5, CInterpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, {5, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}},
{6, CInterpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, {6, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}},
{9, CInterpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, {9, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}},
{22, CInterpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, {22, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}},
{30, CInterpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, {30, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}},
{62, CInterpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, {62, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}},
{58, CInterpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}}, {58, Interpreter::unknown_instruction, Jit64::Default, {"unknown_instruction", OPTYPE_UNKNOWN, 0}},
}; };
GekkoOPTemplate table4[] = GekkoOPTemplate table4[] =
{ {
{0, CInterpreter::ps_cmpu0, Jit64::Default, {"ps_cmpu0", OPTYPE_PS, FL_SET_CRn}}, {0, Interpreter::ps_cmpu0, Jit64::Default, {"ps_cmpu0", OPTYPE_PS, FL_SET_CRn}},
{32, CInterpreter::ps_cmpo0, Jit64::Default, {"ps_cmpo0", OPTYPE_PS, FL_SET_CRn}}, {32, Interpreter::ps_cmpo0, Jit64::Default, {"ps_cmpo0", OPTYPE_PS, FL_SET_CRn}},
{40, CInterpreter::ps_neg, Jit64::ps_sign, {"ps_neg", OPTYPE_PS, FL_RC_BIT}}, {40, Interpreter::ps_neg, Jit64::ps_sign, {"ps_neg", OPTYPE_PS, FL_RC_BIT}},
{136, CInterpreter::ps_nabs, Jit64::ps_sign, {"ps_nabs", OPTYPE_PS, FL_RC_BIT}}, {136, Interpreter::ps_nabs, Jit64::ps_sign, {"ps_nabs", OPTYPE_PS, FL_RC_BIT}},
{264, CInterpreter::ps_abs, Jit64::ps_sign, {"ps_abs", OPTYPE_PS, FL_RC_BIT}}, {264, Interpreter::ps_abs, Jit64::ps_sign, {"ps_abs", OPTYPE_PS, FL_RC_BIT}},
{64, CInterpreter::ps_cmpu1, Jit64::Default, {"ps_cmpu1", OPTYPE_PS, FL_RC_BIT}}, {64, Interpreter::ps_cmpu1, Jit64::Default, {"ps_cmpu1", OPTYPE_PS, FL_RC_BIT}},
{72, CInterpreter::ps_mr, Jit64::ps_mr, {"ps_mr", OPTYPE_PS, FL_RC_BIT}}, {72, Interpreter::ps_mr, Jit64::ps_mr, {"ps_mr", OPTYPE_PS, FL_RC_BIT}},
{96, CInterpreter::ps_cmpo1, Jit64::Default, {"ps_cmpo1", OPTYPE_PS, FL_RC_BIT}}, {96, Interpreter::ps_cmpo1, Jit64::Default, {"ps_cmpo1", OPTYPE_PS, FL_RC_BIT}},
{528, CInterpreter::ps_merge00, Jit64::ps_mergeXX, {"ps_merge00", OPTYPE_PS, FL_RC_BIT}}, {528, Interpreter::ps_merge00, Jit64::ps_mergeXX, {"ps_merge00", OPTYPE_PS, FL_RC_BIT}},
{560, CInterpreter::ps_merge01, Jit64::ps_mergeXX, {"ps_merge01", OPTYPE_PS, FL_RC_BIT}}, {560, Interpreter::ps_merge01, Jit64::ps_mergeXX, {"ps_merge01", OPTYPE_PS, FL_RC_BIT}},
{592, CInterpreter::ps_merge10, Jit64::ps_mergeXX, {"ps_merge10", OPTYPE_PS, FL_RC_BIT}}, {592, Interpreter::ps_merge10, Jit64::ps_mergeXX, {"ps_merge10", OPTYPE_PS, FL_RC_BIT}},
{624, CInterpreter::ps_merge11, Jit64::ps_mergeXX, {"ps_merge11", OPTYPE_PS, FL_RC_BIT}}, {624, Interpreter::ps_merge11, Jit64::ps_mergeXX, {"ps_merge11", OPTYPE_PS, FL_RC_BIT}},
{1014, CInterpreter::dcbz_l, Jit64::Default, {"dcbz_l", OPTYPE_SYSTEM, 0}}, {1014, Interpreter::dcbz_l, Jit64::Default, {"dcbz_l", OPTYPE_SYSTEM, 0}},
}; };
GekkoOPTemplate table4_2[] = GekkoOPTemplate table4_2[] =
{ {
{10, CInterpreter::ps_sum0, Jit64::Default, {"ps_sum0", OPTYPE_PS, 0}}, {10, Interpreter::ps_sum0, Jit64::Default, {"ps_sum0", OPTYPE_PS, 0}},
{11, CInterpreter::ps_sum1, Jit64::Default, {"ps_sum1", OPTYPE_PS, 0}}, {11, Interpreter::ps_sum1, Jit64::Default, {"ps_sum1", OPTYPE_PS, 0}},
{12, CInterpreter::ps_muls0, Jit64::Default, {"ps_muls0", OPTYPE_PS, 0}}, {12, Interpreter::ps_muls0, Jit64::Default, {"ps_muls0", OPTYPE_PS, 0}},
{13, CInterpreter::ps_muls1, Jit64::Default, {"ps_muls1", OPTYPE_PS, 0}}, {13, Interpreter::ps_muls1, Jit64::Default, {"ps_muls1", OPTYPE_PS, 0}},
{14, CInterpreter::ps_madds0, Jit64::Default, {"ps_madds0", OPTYPE_PS, 0}}, {14, Interpreter::ps_madds0, Jit64::Default, {"ps_madds0", OPTYPE_PS, 0}},
{15, CInterpreter::ps_madds1, Jit64::Default, {"ps_madds1", OPTYPE_PS, 0}}, {15, Interpreter::ps_madds1, Jit64::Default, {"ps_madds1", OPTYPE_PS, 0}},
{18, CInterpreter::ps_div, Jit64::ps_arith, {"ps_div", OPTYPE_PS, 0, 16}}, {18, Interpreter::ps_div, Jit64::ps_arith, {"ps_div", OPTYPE_PS, 0, 16}},
{20, CInterpreter::ps_sub, Jit64::ps_arith, {"ps_sub", OPTYPE_PS, 0}}, {20, Interpreter::ps_sub, Jit64::ps_arith, {"ps_sub", OPTYPE_PS, 0}},
{21, CInterpreter::ps_add, Jit64::ps_arith, {"ps_add", OPTYPE_PS, 0}}, {21, Interpreter::ps_add, Jit64::ps_arith, {"ps_add", OPTYPE_PS, 0}},
{23, CInterpreter::ps_sel, Jit64::ps_sel, {"ps_sel", OPTYPE_PS, 0}}, {23, Interpreter::ps_sel, Jit64::ps_sel, {"ps_sel", OPTYPE_PS, 0}},
{24, CInterpreter::ps_res, Jit64::Default, {"ps_res", OPTYPE_PS, 0}}, {24, Interpreter::ps_res, Jit64::Default, {"ps_res", OPTYPE_PS, 0}},
{25, CInterpreter::ps_mul, Jit64::ps_arith, {"ps_mul", OPTYPE_PS, 0}}, {25, Interpreter::ps_mul, Jit64::ps_arith, {"ps_mul", OPTYPE_PS, 0}},
{26, CInterpreter::ps_rsqrte, Jit64::ps_rsqrte, {"ps_rsqrte", OPTYPE_PS, 0}}, {26, Interpreter::ps_rsqrte, Jit64::ps_rsqrte, {"ps_rsqrte", OPTYPE_PS, 0}},
{28, CInterpreter::ps_msub, Jit64::ps_maddXX, {"ps_msub", OPTYPE_PS, 0}}, {28, Interpreter::ps_msub, Jit64::ps_maddXX, {"ps_msub", OPTYPE_PS, 0}},
{29, CInterpreter::ps_madd, Jit64::ps_maddXX, {"ps_madd", OPTYPE_PS, 0}}, {29, Interpreter::ps_madd, Jit64::ps_maddXX, {"ps_madd", OPTYPE_PS, 0}},
{30, CInterpreter::ps_nmsub, Jit64::ps_maddXX, {"ps_nmsub", OPTYPE_PS, 0}}, {30, Interpreter::ps_nmsub, Jit64::ps_maddXX, {"ps_nmsub", OPTYPE_PS, 0}},
{31, CInterpreter::ps_nmadd, Jit64::ps_maddXX, {"ps_nmadd", OPTYPE_PS, 0}}, {31, Interpreter::ps_nmadd, Jit64::ps_maddXX, {"ps_nmadd", OPTYPE_PS, 0}},
}; };
GekkoOPTemplate table4_3[] = GekkoOPTemplate table4_3[] =
{ {
{6, CInterpreter::psq_lx, Jit64::Default, {"psq_lx", OPTYPE_PS, 0}}, {6, Interpreter::psq_lx, Jit64::Default, {"psq_lx", OPTYPE_PS, 0}},
{7, CInterpreter::psq_stx, Jit64::Default, {"psq_stx", OPTYPE_PS, 0}}, {7, Interpreter::psq_stx, Jit64::Default, {"psq_stx", OPTYPE_PS, 0}},
{38, CInterpreter::psq_lux, Jit64::Default, {"psq_lux", OPTYPE_PS, 0}}, {38, Interpreter::psq_lux, Jit64::Default, {"psq_lux", OPTYPE_PS, 0}},
{39, CInterpreter::psq_stux, Jit64::Default, {"psq_stux", OPTYPE_PS, 0}}, {39, Interpreter::psq_stux, Jit64::Default, {"psq_stux", OPTYPE_PS, 0}},
}; };
GekkoOPTemplate table19[] = GekkoOPTemplate table19[] =
{ {
{528, CInterpreter::bcctrx, Jit64::bcctrx, {"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, {528, Interpreter::bcctrx, Jit64::bcctrx, {"bcctrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
{16, CInterpreter::bclrx, Jit64::bclrx, {"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}}, {16, Interpreter::bclrx, Jit64::bclrx, {"bclrx", OPTYPE_BRANCH, FL_ENDBLOCK}},
{257, CInterpreter::crand, Jit64::Default, {"crand", OPTYPE_CR, 0}}, {257, Interpreter::crand, Jit64::Default, {"crand", OPTYPE_CR, 0}},
{129, CInterpreter::crandc, Jit64::Default, {"crandc", OPTYPE_CR, 0}}, {129, Interpreter::crandc, Jit64::Default, {"crandc", OPTYPE_CR, 0}},
{289, CInterpreter::creqv, Jit64::Default, {"creqv", OPTYPE_CR, 0}}, {289, Interpreter::creqv, Jit64::Default, {"creqv", OPTYPE_CR, 0}},
{225, CInterpreter::crnand, Jit64::Default, {"crnand", OPTYPE_CR, 0}}, {225, Interpreter::crnand, Jit64::Default, {"crnand", OPTYPE_CR, 0}},
{33, CInterpreter::crnor, Jit64::Default, {"crnor", OPTYPE_CR, 0}}, {33, Interpreter::crnor, Jit64::Default, {"crnor", OPTYPE_CR, 0}},
{449, CInterpreter::cror, Jit64::Default, {"cror", OPTYPE_CR, 0}}, {449, Interpreter::cror, Jit64::Default, {"cror", OPTYPE_CR, 0}},
{417, CInterpreter::crorc, Jit64::Default, {"crorc", OPTYPE_CR, 0}}, {417, Interpreter::crorc, Jit64::Default, {"crorc", OPTYPE_CR, 0}},
{193, CInterpreter::crxor, Jit64::Default, {"crxor", OPTYPE_CR, 0}}, {193, Interpreter::crxor, Jit64::Default, {"crxor", OPTYPE_CR, 0}},
{150, CInterpreter::isync, Jit64::DoNothing, {"isync", OPTYPE_ICACHE, 0 }}, {150, Interpreter::isync, Jit64::DoNothing, {"isync", OPTYPE_ICACHE, 0 }},
{0, CInterpreter::mcrf, Jit64::Default, {"mcrf", OPTYPE_SYSTEM, 0}}, {0, Interpreter::mcrf, Jit64::Default, {"mcrf", OPTYPE_SYSTEM, 0}},
{50, CInterpreter::rfi, Jit64::rfi, {"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}}, {50, Interpreter::rfi, Jit64::rfi, {"rfi", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS, 1}},
{18, CInterpreter::rfid, Jit64::Default, {"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}} {18, Interpreter::rfid, Jit64::Default, {"rfid", OPTYPE_SYSTEM, FL_ENDBLOCK | FL_CHECKEXCEPTIONS}}
}; };
GekkoOPTemplate table31[] = GekkoOPTemplate table31[] =
{ {
{28, CInterpreter::andx, Jit64::andx, {"andx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}}, {28, Interpreter::andx, Jit64::andx, {"andx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}},
{60, CInterpreter::andcx, Jit64::Default, {"andcx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}}, {60, Interpreter::andcx, Jit64::Default, {"andcx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}},
{444, CInterpreter::orx, Jit64::orx, {"orx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}}, {444, Interpreter::orx, Jit64::orx, {"orx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}},
{124, CInterpreter::norx, Jit64::Default, {"norx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}}, {124, Interpreter::norx, Jit64::Default, {"norx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}},
{316, CInterpreter::xorx, Jit64::Default, {"xorx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}}, {316, Interpreter::xorx, Jit64::Default, {"xorx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}},
{412, CInterpreter::orcx, Jit64::Default, {"orcx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}}, {412, Interpreter::orcx, Jit64::Default, {"orcx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}},
{476, CInterpreter::nandx, Jit64::Default, {"nandx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}}, {476, Interpreter::nandx, Jit64::Default, {"nandx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}},
{284, CInterpreter::eqvx, Jit64::Default, {"eqvx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}}, {284, Interpreter::eqvx, Jit64::Default, {"eqvx", OPTYPE_INTEGER, FL_IN_AB | FL_OUT_S | FL_RC_BIT}},
{0, CInterpreter::cmp, Jit64::cmp, {"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, {0, Interpreter::cmp, Jit64::cmp, {"cmp", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
{32, CInterpreter::cmpl, Jit64::cmpl, {"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}}, {32, Interpreter::cmpl, Jit64::cmpl, {"cmpl", OPTYPE_INTEGER, FL_IN_AB | FL_SET_CRn}},
{26, CInterpreter::cntlzwx, Jit64::cntlzwx, {"cntlzwx",OPTYPE_INTEGER, FL_IN_A | FL_OUT_S | FL_RC_BIT}}, {26, Interpreter::cntlzwx, Jit64::cntlzwx, {"cntlzwx",OPTYPE_INTEGER, FL_IN_A | FL_OUT_S | FL_RC_BIT}},
{922, CInterpreter::extshx, Jit64::extshx, {"extshx", OPTYPE_INTEGER, FL_IN_A | FL_OUT_S | FL_RC_BIT}}, {922, Interpreter::extshx, Jit64::extshx, {"extshx", OPTYPE_INTEGER, FL_IN_A | FL_OUT_S | FL_RC_BIT}},
{954, CInterpreter::extsbx, Jit64::extsbx, {"extsbx", OPTYPE_INTEGER, FL_IN_A | FL_OUT_S | FL_RC_BIT}}, {954, Interpreter::extsbx, Jit64::extsbx, {"extsbx", OPTYPE_INTEGER, FL_IN_A | FL_OUT_S | FL_RC_BIT}},
{536, CInterpreter::srwx, Jit64::srwx, {"srwx", OPTYPE_INTEGER, FL_RC_BIT}}, {536, Interpreter::srwx, Jit64::srwx, {"srwx", OPTYPE_INTEGER, FL_RC_BIT}},
{792, CInterpreter::srawx, Jit64::Default, {"srawx", OPTYPE_INTEGER, FL_RC_BIT}}, {792, Interpreter::srawx, Jit64::Default, {"srawx", OPTYPE_INTEGER, FL_RC_BIT}},
{824, CInterpreter::srawix, Jit64::srawix, {"srawix", OPTYPE_INTEGER, FL_RC_BIT}}, {824, Interpreter::srawix, Jit64::srawix, {"srawix", OPTYPE_INTEGER, FL_RC_BIT}},
{24, CInterpreter::slwx, Jit64::slwx, {"slwx", OPTYPE_INTEGER, FL_RC_BIT}}, {24, Interpreter::slwx, Jit64::slwx, {"slwx", OPTYPE_INTEGER, FL_RC_BIT}},
{54, CInterpreter::dcbst, Jit64::Default, {"dcbst", OPTYPE_DCACHE, 0, 4}}, {54, Interpreter::dcbst, Jit64::Default, {"dcbst", OPTYPE_DCACHE, 0, 4}},
{86, CInterpreter::dcbf, Jit64::Default, {"dcbf", OPTYPE_DCACHE, 0, 4}}, {86, Interpreter::dcbf, Jit64::Default, {"dcbf", OPTYPE_DCACHE, 0, 4}},
{246, CInterpreter::dcbtst, Jit64::Default, {"dcbtst", OPTYPE_DCACHE, 0, 1}}, {246, Interpreter::dcbtst, Jit64::Default, {"dcbtst", OPTYPE_DCACHE, 0, 1}},
{278, CInterpreter::dcbt, Jit64::Default, {"dcbt", OPTYPE_DCACHE, 0, 1}}, {278, Interpreter::dcbt, Jit64::Default, {"dcbt", OPTYPE_DCACHE, 0, 1}},
{470, CInterpreter::dcbi, Jit64::Default, {"dcbi", OPTYPE_DCACHE, 0, 4}}, {470, Interpreter::dcbi, Jit64::Default, {"dcbi", OPTYPE_DCACHE, 0, 4}},
{758, CInterpreter::dcba, Jit64::Default, {"dcba", OPTYPE_DCACHE, 0, 4}}, {758, Interpreter::dcba, Jit64::Default, {"dcba", OPTYPE_DCACHE, 0, 4}},
{1014, CInterpreter::dcbz, Jit64::dcbz, {"dcbz", OPTYPE_DCACHE, 0, 4}}, {1014, Interpreter::dcbz, Jit64::dcbz, {"dcbz", OPTYPE_DCACHE, 0, 4}},
//load word //load word
{23, CInterpreter::lwzx, Jit64::Default, {"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {23, Interpreter::lwzx, Jit64::Default, {"lwzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
{55, CInterpreter::lwzux, Jit64::Default, {"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_IN_A | FL_IN_B}}, {55, Interpreter::lwzux, Jit64::Default, {"lwzux", OPTYPE_LOAD, FL_OUT_D | FL_IN_A | FL_IN_B}},
//load halfword //load halfword
{279, CInterpreter::lhzx, Jit64::Default, {"lhzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {279, Interpreter::lhzx, Jit64::Default, {"lhzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
{311, CInterpreter::lhzux, Jit64::Default, {"lhzux", OPTYPE_LOAD, FL_OUT_D | FL_IN_A | FL_IN_B}}, {311, Interpreter::lhzux, Jit64::Default, {"lhzux", OPTYPE_LOAD, FL_OUT_D | FL_IN_A | FL_IN_B}},
//load halfword signextend //load halfword signextend
{343, CInterpreter::lhax, Jit64::Default, {"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {343, Interpreter::lhax, Jit64::Default, {"lhax", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
{375, CInterpreter::lhaux, Jit64::Default, {"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_IN_A | FL_IN_B}}, {375, Interpreter::lhaux, Jit64::Default, {"lhaux", OPTYPE_LOAD, FL_OUT_D | FL_IN_A | FL_IN_B}},
//load byte //load byte
{87, CInterpreter::lbzx, Jit64::lbzx, {"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {87, Interpreter::lbzx, Jit64::lbzx, {"lbzx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
{119, CInterpreter::lbzux, Jit64::Default, {"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_IN_A | FL_IN_B}}, {119, Interpreter::lbzux, Jit64::Default, {"lbzux", OPTYPE_LOAD, FL_OUT_D | FL_IN_A | FL_IN_B}},
//load byte reverse //load byte reverse
{534, CInterpreter::lwbrx, Jit64::Default, {"lwbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {534, Interpreter::lwbrx, Jit64::Default, {"lwbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
{790, CInterpreter::lhbrx, Jit64::Default, {"lhbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}}, {790, Interpreter::lhbrx, Jit64::Default, {"lhbrx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0 | FL_IN_B}},
{20, CInterpreter::lwarx, Jit64::Default, {"lwarx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0B}}, {20, Interpreter::lwarx, Jit64::Default, {"lwarx", OPTYPE_LOAD, FL_OUT_D | FL_IN_A0B}},
//load string (interpret these) //load string (interpret these)
{533, CInterpreter::lswx, Jit64::Default, {"lswx", OPTYPE_LOAD, FL_IN_A | FL_OUT_D}}, {533, Interpreter::lswx, Jit64::Default, {"lswx", OPTYPE_LOAD, FL_IN_A | FL_OUT_D}},
{597, CInterpreter::lswi, Jit64::Default, {"lswi", OPTYPE_LOAD, FL_IN_AB | FL_OUT_D}}, {597, Interpreter::lswi, Jit64::Default, {"lswi", OPTYPE_LOAD, FL_IN_AB | FL_OUT_D}},
{535, CInterpreter::lfsx, Jit64::lfsx, {"lfsx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, {535, Interpreter::lfsx, Jit64::lfsx, {"lfsx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}},
{567, CInterpreter::lfsux, Jit64::Default, {"lfsux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, {567, Interpreter::lfsux, Jit64::Default, {"lfsux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}},
{599, CInterpreter::lfdx, Jit64::Default, {"lfdx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}}, {599, Interpreter::lfdx, Jit64::Default, {"lfdx", OPTYPE_LOADFP, FL_IN_A0 | FL_IN_B}},
{631, CInterpreter::lfdux, Jit64::Default, {"lfdux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}}, {631, Interpreter::lfdux, Jit64::Default, {"lfdux", OPTYPE_LOADFP, FL_IN_A | FL_IN_B}},
//store word //store word
{151, CInterpreter::stwx, Jit64::Default, {"stwx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, {151, Interpreter::stwx, Jit64::Default, {"stwx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}},
{183, CInterpreter::stwux, Jit64::Default, {"stwux", OPTYPE_STORE, FL_IN_A | FL_IN_B}}, {183, Interpreter::stwux, Jit64::Default, {"stwux", OPTYPE_STORE, FL_IN_A | FL_IN_B}},
//store halfword //store halfword
{407, CInterpreter::sthx, Jit64::Default, {"sthx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, {407, Interpreter::sthx, Jit64::Default, {"sthx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}},
{439, CInterpreter::sthux, Jit64::Default, {"sthux", OPTYPE_STORE, FL_IN_A | FL_IN_B}}, {439, Interpreter::sthux, Jit64::Default, {"sthux", OPTYPE_STORE, FL_IN_A | FL_IN_B}},
//store byte //store byte
{215, CInterpreter::stbx, Jit64::Default, {"stbx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, {215, Interpreter::stbx, Jit64::Default, {"stbx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}},
{247, CInterpreter::stbux, Jit64::Default, {"stbux", OPTYPE_STORE, FL_IN_A | FL_IN_B}}, {247, Interpreter::stbux, Jit64::Default, {"stbux", OPTYPE_STORE, FL_IN_A | FL_IN_B}},
//store bytereverse //store bytereverse
{662, CInterpreter::stwbrx, Jit64::Default, {"stwbrx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}}, {662, Interpreter::stwbrx, Jit64::Default, {"stwbrx", OPTYPE_STORE, FL_IN_A0 | FL_IN_B}},
{918, CInterpreter::sthbrx, Jit64::Default, {"sthbrx", OPTYPE_STORE, FL_IN_A | FL_IN_B}}, {918, Interpreter::sthbrx, Jit64::Default, {"sthbrx", OPTYPE_STORE, FL_IN_A | FL_IN_B}},
{661, CInterpreter::stswx, Jit64::Default, {"stswx", OPTYPE_STORE, 0}}, {661, Interpreter::stswx, Jit64::Default, {"stswx", OPTYPE_STORE, 0}},
{725, CInterpreter::stswi, Jit64::Default, {"stswi", OPTYPE_STORE, 0}}, {725, Interpreter::stswi, Jit64::Default, {"stswi", OPTYPE_STORE, 0}},
{663, CInterpreter::stfsx, Jit64::Default, {"stfsx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, {663, Interpreter::stfsx, Jit64::Default, {"stfsx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
{695, CInterpreter::stfsux, Jit64::Default, {"stfsux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, {695, Interpreter::stfsux, Jit64::Default, {"stfsux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
{727, CInterpreter::stfdx, Jit64::Default, {"stfdx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, {727, Interpreter::stfdx, Jit64::Default, {"stfdx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
{759, CInterpreter::stfdux, Jit64::Default, {"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}}, {759, Interpreter::stfdux, Jit64::Default, {"stfdux", OPTYPE_STOREFP, FL_IN_A | FL_IN_B}},
{983, CInterpreter::stfiwx, Jit64::Default, {"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}}, {983, Interpreter::stfiwx, Jit64::Default, {"stfiwx", OPTYPE_STOREFP, FL_IN_A0 | FL_IN_B}},
{19, CInterpreter::mfcr, Jit64::Default, {"mfcr", OPTYPE_SYSTEM, 0}}, {19, Interpreter::mfcr, Jit64::Default, {"mfcr", OPTYPE_SYSTEM, 0}},
{83, CInterpreter::mfmsr, Jit64::mfmsr, {"mfmsr", OPTYPE_SYSTEM, 0}}, {83, Interpreter::mfmsr, Jit64::mfmsr, {"mfmsr", OPTYPE_SYSTEM, 0}},
{144, CInterpreter::mtcrf, Jit64::Default, {"mtcrf", OPTYPE_SYSTEM, 0}}, {144, Interpreter::mtcrf, Jit64::Default, {"mtcrf", OPTYPE_SYSTEM, 0}},
{146, CInterpreter::mtmsr, Jit64::mtmsr, {"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}}, {146, Interpreter::mtmsr, Jit64::mtmsr, {"mtmsr", OPTYPE_SYSTEM, FL_ENDBLOCK}},
{210, CInterpreter::mtsr, Jit64::Default, {"mtsr", OPTYPE_SYSTEM, 0}}, {210, Interpreter::mtsr, Jit64::Default, {"mtsr", OPTYPE_SYSTEM, 0}},
{242, CInterpreter::mtsrin, Jit64::Default, {"mtsrin", OPTYPE_SYSTEM, 0}}, {242, Interpreter::mtsrin, Jit64::Default, {"mtsrin", OPTYPE_SYSTEM, 0}},
{339, CInterpreter::mfspr, Jit64::mfspr, {"mfspr", OPTYPE_SYSTEM, 0}}, {339, Interpreter::mfspr, Jit64::mfspr, {"mfspr", OPTYPE_SYSTEM, 0}},
{467, CInterpreter::mtspr, Jit64::mtspr, {"mtspr", OPTYPE_SYSTEM, 0, 2}}, {467, Interpreter::mtspr, Jit64::mtspr, {"mtspr", OPTYPE_SYSTEM, 0, 2}},
{371, CInterpreter::mftb, Jit64::mftb, {"mftb", OPTYPE_SYSTEM, FL_TIMER}}, {371, Interpreter::mftb, Jit64::mftb, {"mftb", OPTYPE_SYSTEM, FL_TIMER}},
{512, CInterpreter::mcrxr, Jit64::Default, {"mcrxr", OPTYPE_SYSTEM, 0}}, {512, Interpreter::mcrxr, Jit64::Default, {"mcrxr", OPTYPE_SYSTEM, 0}},
{595, CInterpreter::mfsr, Jit64::Default, {"mfsr", OPTYPE_SYSTEM, 0, 2}}, {595, Interpreter::mfsr, Jit64::Default, {"mfsr", OPTYPE_SYSTEM, 0, 2}},
{659, CInterpreter::mfsrin, Jit64::Default, {"mfsrin", OPTYPE_SYSTEM, 0, 2}}, {659, Interpreter::mfsrin, Jit64::Default, {"mfsrin", OPTYPE_SYSTEM, 0, 2}},
{4, CInterpreter::tw, Jit64::Default, {"tw", OPTYPE_SYSTEM, 0, 1}}, {4, Interpreter::tw, Jit64::Default, {"tw", OPTYPE_SYSTEM, 0, 1}},
{598, CInterpreter::sync, Jit64::Default, {"sync", OPTYPE_SYSTEM, 0, 2}}, {598, Interpreter::sync, Jit64::Default, {"sync", OPTYPE_SYSTEM, 0, 2}},
{982, CInterpreter::icbi, Jit64::Default, {"icbi", OPTYPE_SYSTEM, 0, 3}}, {982, Interpreter::icbi, Jit64::Default, {"icbi", OPTYPE_SYSTEM, 0, 3}},
//Unused instructions on GC //Unused instructions on GC
{310, CInterpreter::eciwx, Jit64::Default, {"eciwx", OPTYPE_INTEGER, FL_RC_BIT}}, {310, Interpreter::eciwx, Jit64::Default, {"eciwx", OPTYPE_INTEGER, FL_RC_BIT}},
{438, CInterpreter::ecowx, Jit64::Default, {"ecowx", OPTYPE_INTEGER, FL_RC_BIT}}, {438, Interpreter::ecowx, Jit64::Default, {"ecowx", OPTYPE_INTEGER, FL_RC_BIT}},
{854, CInterpreter::eieio, Jit64::Default, {"eieio", OPTYPE_INTEGER, FL_RC_BIT}}, {854, Interpreter::eieio, Jit64::Default, {"eieio", OPTYPE_INTEGER, FL_RC_BIT}},
{306, CInterpreter::tlbie, Jit64::Default, {"tlbie", OPTYPE_SYSTEM, 0}}, {306, Interpreter::tlbie, Jit64::Default, {"tlbie", OPTYPE_SYSTEM, 0}},
{370, CInterpreter::tlbia, Jit64::Default, {"tlbia", OPTYPE_SYSTEM, 0}}, {370, Interpreter::tlbia, Jit64::Default, {"tlbia", OPTYPE_SYSTEM, 0}},
{566, CInterpreter::tlbsync, Jit64::Default, {"tlbsync", OPTYPE_SYSTEM, 0}}, {566, Interpreter::tlbsync, Jit64::Default, {"tlbsync", OPTYPE_SYSTEM, 0}},
{150, CInterpreter::stwcxd, Jit64::Default, {"stwcxd", OPTYPE_STORE, 0}}, {150, Interpreter::stwcxd, Jit64::Default, {"stwcxd", OPTYPE_STORE, 0}},
}; };
GekkoOPTemplate table31_2[] = GekkoOPTemplate table31_2[] =
{ {
{266, CInterpreter::addx, Jit64::addx, {"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT}}, {266, Interpreter::addx, Jit64::addx, {"addx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT}},
{10, CInterpreter::addcx, Jit64::Default, {"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_SET_CA | FL_RC_BIT}}, {10, Interpreter::addcx, Jit64::Default, {"addcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_SET_CA | FL_RC_BIT}},
{138, CInterpreter::addex, Jit64::addex, {"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {138, Interpreter::addex, Jit64::addex, {"addex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{234, CInterpreter::addmex, Jit64::Default, {"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {234, Interpreter::addmex, Jit64::Default, {"addmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{202, CInterpreter::addzex, Jit64::Default, {"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {202, Interpreter::addzex, Jit64::Default, {"addzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{491, CInterpreter::divwx, Jit64::Default, {"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 39}}, {491, Interpreter::divwx, Jit64::Default, {"divwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 39}},
{459, CInterpreter::divwux, Jit64::divwux, {"divwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 39}}, {459, Interpreter::divwux, Jit64::divwux, {"divwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 39}},
{75, CInterpreter::mulhwx, Jit64::Default, {"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 4}}, {75, Interpreter::mulhwx, Jit64::Default, {"mulhwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 4}},
{11, CInterpreter::mulhwux, Jit64::mulhwux, {"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 4}}, {11, Interpreter::mulhwux, Jit64::mulhwux, {"mulhwux", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 4}},
{235, CInterpreter::mullwx, Jit64::mullwx, {"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 4}}, {235, Interpreter::mullwx, Jit64::mullwx, {"mullwx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT, 4}},
{104, CInterpreter::negx, Jit64::negx, {"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT}}, {104, Interpreter::negx, Jit64::negx, {"negx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT}},
{40, CInterpreter::subfx, Jit64::subfx, {"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT}}, {40, Interpreter::subfx, Jit64::subfx, {"subfx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_RC_BIT}},
{8, CInterpreter::subfcx, Jit64::subfcx, {"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_SET_CA | FL_RC_BIT}}, {8, Interpreter::subfcx, Jit64::subfcx, {"subfcx", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_SET_CA | FL_RC_BIT}},
{136, CInterpreter::subfex, Jit64::Default, {"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {136, Interpreter::subfex, Jit64::Default, {"subfex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{232, CInterpreter::subfmex, Jit64::Default, {"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {232, Interpreter::subfmex, Jit64::Default, {"subfmex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
{200, CInterpreter::subfzex, Jit64::Default, {"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}}, {200, Interpreter::subfzex, Jit64::Default, {"subfzex", OPTYPE_INTEGER, FL_OUT_D | FL_IN_A | FL_IN_B | FL_READ_CA | FL_SET_CA | FL_RC_BIT}},
}; };
GekkoOPTemplate table59[] = GekkoOPTemplate table59[] =
{ {
{18, CInterpreter::fdivsx, Jit64::fp_arith_s, {"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}}, {18, Interpreter::fdivsx, Jit64::fp_arith_s, {"fdivsx", OPTYPE_FPU, FL_RC_BIT_F, 16}},
{20, CInterpreter::fsubsx, Jit64::fp_arith_s, {"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, {20, Interpreter::fsubsx, Jit64::fp_arith_s, {"fsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
{21, CInterpreter::faddsx, Jit64::fp_arith_s, {"faddsx", OPTYPE_FPU, FL_RC_BIT_F}}, {21, Interpreter::faddsx, Jit64::fp_arith_s, {"faddsx", OPTYPE_FPU, FL_RC_BIT_F}},
// {22, CInterpreter::fsqrtsx, Jit64::Default, {"fsqrtsx", OPTYPE_FPU, FL_RC_BIT_F}}, // Not implemented on gekko // {22, Interpreter::fsqrtsx, Jit64::Default, {"fsqrtsx", OPTYPE_FPU, FL_RC_BIT_F}}, // Not implemented on gekko
{24, CInterpreter::fresx, Jit64::Default, {"fresx", OPTYPE_FPU, FL_RC_BIT_F}}, {24, Interpreter::fresx, Jit64::Default, {"fresx", OPTYPE_FPU, FL_RC_BIT_F}},
{25, CInterpreter::fmulsx, Jit64::fp_arith_s, {"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}}, {25, Interpreter::fmulsx, Jit64::fp_arith_s, {"fmulsx", OPTYPE_FPU, FL_RC_BIT_F}},
{28, CInterpreter::fmsubsx, Jit64::fmaddXX, {"fmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, {28, Interpreter::fmsubsx, Jit64::fmaddXX, {"fmsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
{29, CInterpreter::fmaddsx, Jit64::fmaddXX, {"fmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, {29, Interpreter::fmaddsx, Jit64::fmaddXX, {"fmaddsx", OPTYPE_FPU, FL_RC_BIT_F}},
{30, CInterpreter::fnmsubsx, Jit64::fmaddXX, {"fnmsubsx", OPTYPE_FPU, FL_RC_BIT_F}}, {30, Interpreter::fnmsubsx, Jit64::fmaddXX, {"fnmsubsx", OPTYPE_FPU, FL_RC_BIT_F}},
{31, CInterpreter::fnmaddsx, Jit64::fmaddXX, {"fnmaddsx", OPTYPE_FPU, FL_RC_BIT_F}}, {31, Interpreter::fnmaddsx, Jit64::fmaddXX, {"fnmaddsx", OPTYPE_FPU, FL_RC_BIT_F}},
}; };
GekkoOPTemplate table63[] = GekkoOPTemplate table63[] =
{ {
{264, CInterpreter::fabsx, Jit64::Default, {"fabsx", OPTYPE_FPU, FL_RC_BIT_F}}, {264, Interpreter::fabsx, Jit64::Default, {"fabsx", OPTYPE_FPU, FL_RC_BIT_F}},
{32, CInterpreter::fcmpo, Jit64::fcmpx, {"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}}, {32, Interpreter::fcmpo, Jit64::fcmpx, {"fcmpo", OPTYPE_FPU, FL_RC_BIT_F}},
{0, CInterpreter::fcmpu, Jit64::fcmpx, {"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}}, {0, Interpreter::fcmpu, Jit64::fcmpx, {"fcmpu", OPTYPE_FPU, FL_RC_BIT_F}},
{14, CInterpreter::fctiwx, Jit64::Default, {"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}}, {14, Interpreter::fctiwx, Jit64::Default, {"fctiwx", OPTYPE_FPU, FL_RC_BIT_F}},
{15, CInterpreter::fctiwzx, Jit64::Default, {"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}}, {15, Interpreter::fctiwzx, Jit64::Default, {"fctiwzx", OPTYPE_FPU, FL_RC_BIT_F}},
{72, CInterpreter::fmrx, Jit64::fmrx, {"fmrx", OPTYPE_FPU, FL_RC_BIT_F}}, {72, Interpreter::fmrx, Jit64::fmrx, {"fmrx", OPTYPE_FPU, FL_RC_BIT_F}},
{136, CInterpreter::fnabsx, Jit64::Default, {"fnabsx", OPTYPE_FPU, FL_RC_BIT_F}}, {136, Interpreter::fnabsx, Jit64::Default, {"fnabsx", OPTYPE_FPU, FL_RC_BIT_F}},
{40, CInterpreter::fnegx, Jit64::Default, {"fnegx", OPTYPE_FPU, FL_RC_BIT_F}}, {40, Interpreter::fnegx, Jit64::Default, {"fnegx", OPTYPE_FPU, FL_RC_BIT_F}},
{12, CInterpreter::frspx, Jit64::Default, {"frspx", OPTYPE_FPU, FL_RC_BIT_F}}, {12, Interpreter::frspx, Jit64::Default, {"frspx", OPTYPE_FPU, FL_RC_BIT_F}},
{64, CInterpreter::mcrfs, Jit64::Default, {"mcrfs", OPTYPE_SYSTEMFP, 0}}, {64, Interpreter::mcrfs, Jit64::Default, {"mcrfs", OPTYPE_SYSTEMFP, 0}},
{583, CInterpreter::mffsx, Jit64::Default, {"mffsx", OPTYPE_SYSTEMFP, 0}}, {583, Interpreter::mffsx, Jit64::Default, {"mffsx", OPTYPE_SYSTEMFP, 0}},
{70, CInterpreter::mtfsb0x, Jit64::Default, {"mtfsb0x", OPTYPE_SYSTEMFP, 0, 2}}, {70, Interpreter::mtfsb0x, Jit64::Default, {"mtfsb0x", OPTYPE_SYSTEMFP, 0, 2}},
{38, CInterpreter::mtfsb1x, Jit64::Default, {"mtfsb1x", OPTYPE_SYSTEMFP, 0, 2}}, {38, Interpreter::mtfsb1x, Jit64::Default, {"mtfsb1x", OPTYPE_SYSTEMFP, 0, 2}},
{134, CInterpreter::mtfsfix, Jit64::Default, {"mtfsfix", OPTYPE_SYSTEMFP, 0, 2}}, {134, Interpreter::mtfsfix, Jit64::Default, {"mtfsfix", OPTYPE_SYSTEMFP, 0, 2}},
{711, CInterpreter::mtfsfx, Jit64::Default, {"mtfsfx", OPTYPE_SYSTEMFP, 0, 2}}, {711, Interpreter::mtfsfx, Jit64::Default, {"mtfsfx", OPTYPE_SYSTEMFP, 0, 2}},
}; };
GekkoOPTemplate table63_2[] = GekkoOPTemplate table63_2[] =
{ {
{18, CInterpreter::fdivx, Jit64::Default, {"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}}, {18, Interpreter::fdivx, Jit64::Default, {"fdivx", OPTYPE_FPU, FL_RC_BIT_F, 30}},
{20, CInterpreter::fsubx, Jit64::Default, {"fsubx", OPTYPE_FPU, FL_RC_BIT_F}}, {20, Interpreter::fsubx, Jit64::Default, {"fsubx", OPTYPE_FPU, FL_RC_BIT_F}},
{21, CInterpreter::faddx, Jit64::Default, {"faddx", OPTYPE_FPU, FL_RC_BIT_F}}, {21, Interpreter::faddx, Jit64::Default, {"faddx", OPTYPE_FPU, FL_RC_BIT_F}},
{22, CInterpreter::fsqrtx, Jit64::Default, {"fsqrtx", OPTYPE_FPU, FL_RC_BIT_F}}, {22, Interpreter::fsqrtx, Jit64::Default, {"fsqrtx", OPTYPE_FPU, FL_RC_BIT_F}},
{23, CInterpreter::fselx, Jit64::Default, {"fselx", OPTYPE_FPU, FL_RC_BIT_F}}, {23, Interpreter::fselx, Jit64::Default, {"fselx", OPTYPE_FPU, FL_RC_BIT_F}},
{25, CInterpreter::fmulx, Jit64::Default, {"fmulx", OPTYPE_FPU, FL_RC_BIT_F}}, {25, Interpreter::fmulx, Jit64::Default, {"fmulx", OPTYPE_FPU, FL_RC_BIT_F}},
{26, CInterpreter::frsqrtex,Jit64::Default, {"frsqrtex", OPTYPE_FPU, FL_RC_BIT_F}}, {26, Interpreter::frsqrtex,Jit64::Default, {"frsqrtex", OPTYPE_FPU, FL_RC_BIT_F}},
{28, CInterpreter::fmsubx, Jit64::Default, {"fmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, {28, Interpreter::fmsubx, Jit64::Default, {"fmsubx", OPTYPE_FPU, FL_RC_BIT_F}},
{29, CInterpreter::fmaddx, Jit64::Default, {"fmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, {29, Interpreter::fmaddx, Jit64::Default, {"fmaddx", OPTYPE_FPU, FL_RC_BIT_F}},
{30, CInterpreter::fnmsubx, Jit64::Default, {"fnmsubx", OPTYPE_FPU, FL_RC_BIT_F}}, {30, Interpreter::fnmsubx, Jit64::Default, {"fnmsubx", OPTYPE_FPU, FL_RC_BIT_F}},
{31, CInterpreter::fnmaddx, Jit64::Default, {"fnmaddx", OPTYPE_FPU, FL_RC_BIT_F}}, {31, Interpreter::fnmaddx, Jit64::Default, {"fnmaddx", OPTYPE_FPU, FL_RC_BIT_F}},
}; };
bool PPCTables::UsesFPU(UGeckoInstruction _inst) bool PPCTables::UsesFPU(UGeckoInstruction _inst)
@ -502,17 +502,17 @@ void PPCTables::InitTables()
//clear //clear
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
{ {
CInterpreter::m_opTable59[i] = CInterpreter::unknown_instruction; Interpreter::m_opTable59[i] = Interpreter::unknown_instruction;
dynaOpTable59[i] = Jit64::unknown_instruction; dynaOpTable59[i] = Jit64::unknown_instruction;
m_infoTable59[i] = 0; m_infoTable59[i] = 0;
} }
for (int i = 0; i < 1024; i++) for (int i = 0; i < 1024; i++)
{ {
CInterpreter::m_opTable4 [i] = CInterpreter::unknown_instruction; Interpreter::m_opTable4 [i] = Interpreter::unknown_instruction;
CInterpreter::m_opTable19[i] = CInterpreter::unknown_instruction; Interpreter::m_opTable19[i] = Interpreter::unknown_instruction;
CInterpreter::m_opTable31[i] = CInterpreter::unknown_instruction; Interpreter::m_opTable31[i] = Interpreter::unknown_instruction;
CInterpreter::m_opTable63[i] = CInterpreter::unknown_instruction; Interpreter::m_opTable63[i] = Interpreter::unknown_instruction;
dynaOpTable4 [i] = Jit64::unknown_instruction; dynaOpTable4 [i] = Jit64::unknown_instruction;
dynaOpTable19[i] = Jit64::unknown_instruction; dynaOpTable19[i] = Jit64::unknown_instruction;
dynaOpTable31[i] = Jit64::unknown_instruction; dynaOpTable31[i] = Jit64::unknown_instruction;
@ -525,7 +525,7 @@ void PPCTables::InitTables()
for (int i = 0; i < (int)(sizeof(primarytable) / sizeof(GekkoOPTemplate)); i++) for (int i = 0; i < (int)(sizeof(primarytable) / sizeof(GekkoOPTemplate)); i++)
{ {
CInterpreter::m_opTable[primarytable[i].opcode] = primarytable[i].interpret; Interpreter::m_opTable[primarytable[i].opcode] = primarytable[i].interpret;
dynaOpTable[primarytable[i].opcode] = primarytable[i].recompile; dynaOpTable[primarytable[i].opcode] = primarytable[i].recompile;
m_infoTable[primarytable[i].opcode] = &primarytable[i].opinfo; m_infoTable[primarytable[i].opcode] = &primarytable[i].opinfo;
} }
@ -536,7 +536,7 @@ void PPCTables::InitTables()
for (int j = 0; j < (int)(sizeof(table4_2) / sizeof(GekkoOPTemplate)); j++) for (int j = 0; j < (int)(sizeof(table4_2) / sizeof(GekkoOPTemplate)); j++)
{ {
int op = fill+table4_2[j].opcode; int op = fill+table4_2[j].opcode;
CInterpreter::m_opTable4[op] = table4_2[j].interpret; Interpreter::m_opTable4[op] = table4_2[j].interpret;
dynaOpTable4[op] = table4_2[j].recompile; dynaOpTable4[op] = table4_2[j].recompile;
m_infoTable4[op] = &table4_2[j].opinfo; m_infoTable4[op] = &table4_2[j].opinfo;
} }
@ -548,7 +548,7 @@ void PPCTables::InitTables()
for (int j = 0; j < (int)(sizeof(table4_3) / sizeof(GekkoOPTemplate)); j++) for (int j = 0; j < (int)(sizeof(table4_3) / sizeof(GekkoOPTemplate)); j++)
{ {
int op = fill+table4_3[j].opcode; int op = fill+table4_3[j].opcode;
CInterpreter::m_opTable4[op] = table4_3[j].interpret; Interpreter::m_opTable4[op] = table4_3[j].interpret;
dynaOpTable4[op] = table4_3[j].recompile; dynaOpTable4[op] = table4_3[j].recompile;
m_infoTable4[op] = &table4_3[j].opinfo; m_infoTable4[op] = &table4_3[j].opinfo;
} }
@ -557,7 +557,7 @@ void PPCTables::InitTables()
for (int i = 0; i < (int)(sizeof(table4) / sizeof(GekkoOPTemplate)); i++) for (int i = 0; i < (int)(sizeof(table4) / sizeof(GekkoOPTemplate)); i++)
{ {
int op = table4[i].opcode; int op = table4[i].opcode;
CInterpreter::m_opTable4[op] = table4[i].interpret; Interpreter::m_opTable4[op] = table4[i].interpret;
dynaOpTable4[op] = table4[i].recompile; dynaOpTable4[op] = table4[i].recompile;
m_infoTable4[op] = &table4[i].opinfo; m_infoTable4[op] = &table4[i].opinfo;
} }
@ -565,7 +565,7 @@ void PPCTables::InitTables()
for (int i = 0; i < (int)(sizeof(table31) / sizeof(GekkoOPTemplate)); i++) for (int i = 0; i < (int)(sizeof(table31) / sizeof(GekkoOPTemplate)); i++)
{ {
int op = table31[i].opcode; int op = table31[i].opcode;
CInterpreter::m_opTable31[op] = table31[i].interpret; Interpreter::m_opTable31[op] = table31[i].interpret;
dynaOpTable31[op] = table31[i].recompile; dynaOpTable31[op] = table31[i].recompile;
m_infoTable31[op] = &table31[i].opinfo; m_infoTable31[op] = &table31[i].opinfo;
} }
@ -576,7 +576,7 @@ void PPCTables::InitTables()
for (int j = 0; j < (int)(sizeof(table31_2) / sizeof(GekkoOPTemplate)); j++) for (int j = 0; j < (int)(sizeof(table31_2) / sizeof(GekkoOPTemplate)); j++)
{ {
int op = fill + table31_2[j].opcode; int op = fill + table31_2[j].opcode;
CInterpreter::m_opTable31[op] = table31_2[j].interpret; Interpreter::m_opTable31[op] = table31_2[j].interpret;
dynaOpTable31[op] = table31_2[j].recompile; dynaOpTable31[op] = table31_2[j].recompile;
m_infoTable31[op] = &table31_2[j].opinfo; m_infoTable31[op] = &table31_2[j].opinfo;
} }
@ -585,7 +585,7 @@ void PPCTables::InitTables()
for (int i = 0; i < (int)(sizeof(table19) / sizeof(GekkoOPTemplate)); i++) for (int i = 0; i < (int)(sizeof(table19) / sizeof(GekkoOPTemplate)); i++)
{ {
int op = table19[i].opcode; int op = table19[i].opcode;
CInterpreter::m_opTable19[op] = table19[i].interpret; Interpreter::m_opTable19[op] = table19[i].interpret;
dynaOpTable19[op] = table19[i].recompile; dynaOpTable19[op] = table19[i].recompile;
m_infoTable19[op] = &table19[i].opinfo; m_infoTable19[op] = &table19[i].opinfo;
} }
@ -593,7 +593,7 @@ void PPCTables::InitTables()
for (int i = 0; i < (int)(sizeof(table59) / sizeof(GekkoOPTemplate)); i++) for (int i = 0; i < (int)(sizeof(table59) / sizeof(GekkoOPTemplate)); i++)
{ {
int op = table59[i].opcode; int op = table59[i].opcode;
CInterpreter::m_opTable59[op] = table59[i].interpret; Interpreter::m_opTable59[op] = table59[i].interpret;
dynaOpTable59[op] = table59[i].recompile; dynaOpTable59[op] = table59[i].recompile;
m_infoTable59[op] = &table59[i].opinfo; m_infoTable59[op] = &table59[i].opinfo;
} }
@ -601,7 +601,7 @@ void PPCTables::InitTables()
for (int i = 0; i < (int)(sizeof(table63) / sizeof(GekkoOPTemplate)); i++) for (int i = 0; i < (int)(sizeof(table63) / sizeof(GekkoOPTemplate)); i++)
{ {
int op = table63[i].opcode; int op = table63[i].opcode;
CInterpreter::m_opTable63[op] = table63[i].interpret; Interpreter::m_opTable63[op] = table63[i].interpret;
dynaOpTable63[op] = table63[i].recompile; dynaOpTable63[op] = table63[i].recompile;
m_infoTable63[op] = &table63[i].opinfo; m_infoTable63[op] = &table63[i].opinfo;
} }
@ -612,7 +612,7 @@ void PPCTables::InitTables()
for (int j = 0; j < (int)(sizeof(table63_2) / sizeof(GekkoOPTemplate)); j++) for (int j = 0; j < (int)(sizeof(table63_2) / sizeof(GekkoOPTemplate)); j++)
{ {
int op = fill + table63_2[j].opcode; int op = fill + table63_2[j].opcode;
CInterpreter::m_opTable63[op] = table63_2[j].interpret; Interpreter::m_opTable63[op] = table63_2[j].interpret;
dynaOpTable63[op] = table63_2[j].recompile; dynaOpTable63[op] = table63_2[j].recompile;
m_infoTable63[op] = &table63_2[j].opinfo; m_infoTable63[op] = &table63_2[j].opinfo;
} }

View File

@ -78,10 +78,8 @@ struct GekkoOPInfo
u32 lastUse; u32 lastUse;
}; };
GekkoOPInfo *GetOpInfo(UGeckoInstruction _inst); GekkoOPInfo *GetOpInfo(UGeckoInstruction _inst);
CInterpreter::_interpreterInstruction GetInterpreterOp(UGeckoInstruction _inst); Interpreter::_interpreterInstruction GetInterpreterOp(UGeckoInstruction _inst);
class PPCTables class PPCTables
{ {

View File

@ -15,6 +15,10 @@
// Official SVN repository and contact information can be found at // Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/ // http://code.google.com/p/dolphin-emu/
#ifdef _WIN32
#include <float.h>
#endif
#include "Common.h" #include "Common.h"
#include "ChunkFile.h" #include "ChunkFile.h"
@ -25,6 +29,7 @@
#include "Interpreter/Interpreter.h" #include "Interpreter/Interpreter.h"
#include "Jit64/JitCore.h" #include "Jit64/JitCore.h"
#include "Jit64/JitCache.h"
#include "PowerPC.h" #include "PowerPC.h"
#include "PPCTables.h" #include "PPCTables.h"
@ -36,7 +41,7 @@ namespace PowerPC
PowerPCState GC_ALIGNED16(ppcState); PowerPCState GC_ALIGNED16(ppcState);
volatile CPUState state = CPU_STEPPING; volatile CPUState state = CPU_STEPPING;
ICPUCore* m_pCore = NULL; static CoreMode mode;
void DoState(ChunkFile &f) void DoState(ChunkFile &f)
{ {
@ -48,10 +53,6 @@ namespace PowerPC
void ResetRegisters() void ResetRegisters()
{ {
if (((u64)&ppcState & 0xf) != 0) {
PanicAlert("The compiler misaligned ppcState in memory. Likely to cause crashes.");
}
for (int i = 0; i < 32; i++) for (int i = 0; i < 32; i++)
{ {
ppcState.gpr[i] = 0; ppcState.gpr[i] = 0;
@ -70,73 +71,90 @@ namespace PowerPC
TL = 0; TL = 0;
TU = 0; TU = 0;
ppcState.DoPreRetrace = true;
ppcState.msr = 0; ppcState.msr = 0;
rDEC = 0xFFFFFFFF; rDEC = 0xFFFFFFFF;
} }
void Init() void Init()
{ {
#ifdef _M_IX86
// sets the floating-point lib to 53-bit
// PowerPC has a 53bit floating pipeline only
// eg: sscanf is very sensitive
#ifdef _WIN32
_control87(_PC_53, MCW_PC);
#else
unsigned short mode;
asm ("fstcw %0" : : "m" (mode));
mode = (mode & ~FPU_PREC_MASK) | FPU_PREC_53;
asm ("fldcw %0" : : "m" (mode));
#endif
#else
//x64 doesn't need this - fpu is done with SSE
//but still - set any useful sse options here
#endif
ResetRegisters(); ResetRegisters();
PPCTables::InitTables(); PPCTables::InitTables();
// Initialize both execution engines ...
Interpreter::Init();
Jit64::Core::Init();
// ... but start as interpreter by default.
mode = MODE_INTERPRETER;
state = CPU_STEPPING; state = CPU_STEPPING;
SetCore(CORE_INTERPRETER);
} }
void Shutdown() void Shutdown()
{ {
if (m_pCore != NULL) // Shutdown both execution engines. Doesn't matter which one is active.
{ Jit64::Core::Shutdown();
m_pCore->Shutdown(); Interpreter::Shutdown();
delete m_pCore;
m_pCore = NULL;
}
} }
void Reset() void SetMode(CoreMode new_mode)
{ {
ResetRegisters(); if (new_mode == mode)
if (m_pCore!= NULL) return; // We don't need to do anything.
m_pCore->Reset();
}
void SetCore(ECoreType _coreType) mode = new_mode;
{ switch (mode)
// shutdown the old core
if (m_pCore != NULL)
{ {
m_pCore->Shutdown(); case MODE_INTERPRETER: // Switching from JIT to interpreter
delete m_pCore; Jit64::ClearCache(); // Remove all those nasty JIT patches.
m_pCore = NULL;
}
// create the new one
switch(_coreType)
{
case CORE_INTERPRETER:
m_pCore = new CInterpreter();
m_pCore->Init();
break; break;
case CORE_DYNAREC: case MODE_JIT: // Switching from interpreter to JIT.
m_pCore = new Jit64::Jit64Core(); // Don't really need to do much. It'll work, the cache will refill itself.
m_pCore->Init();
break;
default:
break; break;
} }
} }
void SingleStep() void SingleStep()
{ {
m_pCore->SingleStep(); switch (mode)
{
case MODE_INTERPRETER:
Interpreter::SingleStep();
break;
case MODE_JIT:
Jit64::Core::SingleStep();
break;
}
} }
void RunLoop() void RunLoop()
{ {
state = CPU_RUNNING; state = CPU_RUNNING;
m_pCore->Run(); switch (mode)
{
case MODE_INTERPRETER:
Interpreter::Run();
break;
case MODE_JIT:
Jit64::Core::Run();
break;
}
Host_UpdateDisasmDialog(); Host_UpdateDisasmDialog();
} }
@ -240,7 +258,7 @@ namespace PowerPC
LOG(GEKKO, "EXCEPTION_EXTERNAL_INT"); LOG(GEKKO, "EXCEPTION_EXTERNAL_INT");
SRR1 |= 0x02; //set it to recoverable SRR1 |= 0x02; //set it to recoverable
_dbg_assert_msg_(GEKKO,(SRR1 & 0x02) != 0,"GEKKO","EXTERNAL_INT unrecoverable???"); // unrecoverable exception !?! _dbg_assert_msg_(GEKKO, (SRR1 & 0x02) != 0, "GEKKO", "EXTERNAL_INT unrecoverable???"); // unrecoverable exception !?!
} }
else if (ppcState.Exceptions & EXCEPTION_DECREMENTER) else if (ppcState.Exceptions & EXCEPTION_DECREMENTER)
{ {

View File

@ -27,46 +27,43 @@
#include "Common.h" #include "Common.h"
#include "Gekko.h" #include "Gekko.h"
#include "ICPUCore.h"
class ChunkFile; class ChunkFile;
namespace PowerPC namespace PowerPC
{ {
enum ECoreType enum CoreMode
{ {
CORE_INTERPRETER, MODE_INTERPRETER,
CORE_DYNAREC, MODE_JIT,
}; };
struct GC_ALIGNED64(PowerPCState) struct GC_ALIGNED64(PowerPCState)
{ {
u32 mojs[128]; u32 mojs[128]; // Try to isolate the regs from other variables in the cache.
// sets of registers u32 gpr[32]; // General purpose registers. r1 = stack pointer.
u32 gpr[32];
// the paired singles are strange : PS0 is stored in the full 64 bits of each FPR // The paired singles are strange : PS0 is stored in the full 64 bits of each FPR
// but ps calculations are probably only 32-bit // but ps calculations are only done in 32-bit precision, and PS1 is only 32 bits.
// Since we want to use SIMD, SSE2 is the only viable alternative - 2x double.
u64 ps[32][2]; u64 ps[32][2];
// program counter u32 pc; // program counter
u32 pc;
u32 npc; u32 npc;
// flags u32 cr; // flags
u32 cr; u32 msr; // machine specific register
u32 msr; u32 fpscr; // floating point flags/status bits
u32 fpscr;
//exception management // Exception management.
u32 Exceptions; u32 Exceptions;
u32 sr[16]; u32 sr[16]; // Segment registers. Unused.
// interrupts hack
u32 DoPreRetrace;
u32 DebugCount; u32 DebugCount;
// additional special purpose registers // special purpose registers - controlls quantizers, DMA, and lots of other misc extensions.
// also for power management, but we don't care about that.
u32 spr[1024]; u32 spr[1024];
}; };
@ -79,29 +76,21 @@ namespace PowerPC
}; };
extern PowerPCState ppcState; extern PowerPCState ppcState;
extern volatile CPUState state; // Execution engines should poll this to know when to exit.
extern volatile CPUState state; //cpu cores should poll this
void ResetRegisters();
void Reset();
void Init(); void Init();
void Shutdown(); void Shutdown();
void DoState(ChunkFile &f); void DoState(ChunkFile &f);
void SetCore(ECoreType _coreType); void SetMode(CoreMode _coreType);
ICPUCore& GetCore(); void SingleStep();
void SingleStep();
void CheckExceptions(); void CheckExceptions();
void RunLoop(); void RunLoop();
void Start(); void Start();
void Pause(); void Pause();
void Stop(); void Stop();
u32 ConvertMillisecondToTicks(u32 _Milliseconds);
void OnIdle(u32 _uThreadAddr); void OnIdle(u32 _uThreadAddr);
} }

View File

@ -341,9 +341,8 @@ void CCodeView::OnPaint(wxPaintEvent& event)
dc.DrawRectangle(0, 0, 16, rc.height); dc.DrawRectangle(0, 0, 16, rc.height);
dc.DrawRectangle(0, 0, rc.width, 5); dc.DrawRectangle(0, 0, rc.width, 5);
// TODO - clean up this freaking mess!!!!! // TODO - clean up this freaking mess!!!!!
int i;
for (i = -numRows; i <= numRows; i++) for (int i = -numRows; i <= numRows; i++)
{ {
unsigned int address = curAddress + i * align; unsigned int address = curAddress + i * align;
@ -469,7 +468,7 @@ void CCodeView::OnPaint(wxPaintEvent& event)
dc.SetPen(currentPen); dc.SetPen(currentPen);
for (i = 0; i < numBranches; i++) for (int i = 0; i < numBranches; i++)
{ {
int x = 300 + (branches[i].srcAddr % 9) * 8; int x = 300 + (branches[i].srcAddr % 9) * 8;
_MoveTo(x-2, branches[i].src); _MoveTo(x-2, branches[i].src);

View File

@ -75,6 +75,8 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxFrame)
EVT_MENU(IDM_BREAKPOINTWINDOW, CCodeWindow::OnToggleBreakPointWindow) EVT_MENU(IDM_BREAKPOINTWINDOW, CCodeWindow::OnToggleBreakPointWindow)
EVT_MENU(IDM_MEMORYWINDOW, CCodeWindow::OnToggleMemoryWindow) EVT_MENU(IDM_MEMORYWINDOW, CCodeWindow::OnToggleMemoryWindow)
EVT_MENU(IDM_INTERPRETER, CCodeWindow::OnInterpreter)
EVT_MENU(IDM_CLEARSYMBOLS, CCodeWindow::OnSymbolsMenu) EVT_MENU(IDM_CLEARSYMBOLS, CCodeWindow::OnSymbolsMenu)
EVT_MENU(IDM_LOADMAPFILE, CCodeWindow::OnSymbolsMenu) EVT_MENU(IDM_LOADMAPFILE, CCodeWindow::OnSymbolsMenu)
EVT_MENU(IDM_SCANFUNCTIONS, CCodeWindow::OnSymbolsMenu) EVT_MENU(IDM_SCANFUNCTIONS, CCodeWindow::OnSymbolsMenu)
@ -103,7 +105,6 @@ inline wxBitmap _wxGetBitmapFromMemory(const unsigned char* data, int length)
return(wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1)); return(wxBitmap(wxImage(is, wxBITMAP_TYPE_ANY, -1), -1));
} }
CCodeWindow::CCodeWindow(const SCoreStartupParameter& _LocalCoreStartupParameter, wxWindow* parent, wxWindowID id, CCodeWindow::CCodeWindow(const SCoreStartupParameter& _LocalCoreStartupParameter, wxWindow* parent, wxWindowID id,
const wxString& title, const wxPoint& pos, const wxSize& size, long style) const wxString& title, const wxPoint& pos, const wxSize& size, long style)
: wxFrame(parent, id, title, pos, size, style) : wxFrame(parent, id, title, pos, size, style)
@ -225,12 +226,12 @@ void CCodeWindow::CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParam
{ {
wxMenu* pCoreMenu = new wxMenu; wxMenu* pCoreMenu = new wxMenu;
wxMenuItem* interpreter = pCoreMenu->Append(IDM_INTERPRETER, _T("&Interpreter"), wxEmptyString, wxITEM_CHECK); wxMenuItem* interpreter = pCoreMenu->Append(IDM_INTERPRETER, _T("&Interpreter"), wxEmptyString, wxITEM_CHECK);
interpreter->Check(!_LocalCoreStartupParameter.bUseDynarec); interpreter->Check(!_LocalCoreStartupParameter.bUseJIT);
// wxMenuItem* dualcore = pDebugMenu->Append(IDM_DUALCORE, _T("&DualCore"), wxEmptyString, wxITEM_CHECK); // wxMenuItem* dualcore = pDebugMenu->Append(IDM_DUALCORE, _T("&DualCore"), wxEmptyString, wxITEM_CHECK);
// dualcore->Check(_LocalCoreStartupParameter.bUseDualCore); // dualcore->Check(_LocalCoreStartupParameter.bUseDualCore);
pMenuBar->Append(pCoreMenu, _T("&Core Startup")); pMenuBar->Append(pCoreMenu, _T("&CPU Mode"));
} }
{ {
@ -289,6 +290,14 @@ bool CCodeWindow::UseDualCore()
return(GetMenuBar()->IsChecked(IDM_DUALCORE)); return(GetMenuBar()->IsChecked(IDM_DUALCORE));
} }
void CCodeWindow::OnInterpreter(wxCommandEvent& event)
{
if (Core::GetState() != Core::CORE_RUN) {
PowerPC::SetMode(UseInterpreter() ? PowerPC::MODE_INTERPRETER : PowerPC::MODE_JIT);
} else {
wxMessageBox(_T("Please pause the emulator before changing mode."));
}
}
void CCodeWindow::OnJitMenu(wxCommandEvent& event) void CCodeWindow::OnJitMenu(wxCommandEvent& event)
{ {

View File

@ -144,6 +144,7 @@ class CCodeWindow
void OnHostMessage(wxCommandEvent& event); void OnHostMessage(wxCommandEvent& event);
void OnSymbolsMenu(wxCommandEvent& event); void OnSymbolsMenu(wxCommandEvent& event);
void OnJitMenu(wxCommandEvent& event); void OnJitMenu(wxCommandEvent& event);
void OnInterpreter(wxCommandEvent& event);
void CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter); void CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter);

View File

@ -50,12 +50,12 @@ bool BootCore(const std::string& _rFilename)
if (g_pCodeWindow) if (g_pCodeWindow)
{ {
// StartUp.bUseDualCore = code_frame->UseDualCore(); // StartUp.bUseDualCore = code_frame->UseDualCore();
StartUp.bUseDynarec = !g_pCodeWindow->UseInterpreter(); StartUp.bUseJIT = !g_pCodeWindow->UseInterpreter();
} }
else else
{ {
// StartUp.bUseDualCore = false; // StartUp.bUseDualCore = false;
StartUp.bUseDynarec = true; StartUp.bUseJIT = true;
} }
StartUp.m_BootType = SCoreStartupParameter::BOOT_ISO; StartUp.m_BootType = SCoreStartupParameter::BOOT_ISO;
StartUp.m_strFilename = _rFilename; StartUp.m_strFilename = _rFilename;

View File

@ -64,7 +64,7 @@ void SConfig::SaveSettings()
ini.Set("Core", "PadPlugin", m_LocalCoreStartupParameter.m_strPadPlugin); ini.Set("Core", "PadPlugin", m_LocalCoreStartupParameter.m_strPadPlugin);
ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios); ini.Set("Core", "HLEBios", m_LocalCoreStartupParameter.bHLEBios);
ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseDynarec); ini.Set("Core", "UseDynarec", m_LocalCoreStartupParameter.bUseJIT);
ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore); ini.Set("Core", "UseDualCore", m_LocalCoreStartupParameter.bUseDualCore);
ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads); ini.Set("Core", "LockThreads", m_LocalCoreStartupParameter.bLockThreads);
ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM); ini.Set("Core", "DefaultGCM", m_LocalCoreStartupParameter.m_strDefaultGCM);
@ -114,7 +114,7 @@ void SConfig::LoadSettings()
ini.Get("Core", "PadPlugin", &m_LocalCoreStartupParameter.m_strPadPlugin, m_DefaultPADPlugin.c_str()); ini.Get("Core", "PadPlugin", &m_LocalCoreStartupParameter.m_strPadPlugin, m_DefaultPADPlugin.c_str());
ini.Get("Core", "HLEBios", &m_LocalCoreStartupParameter.bHLEBios, true); ini.Get("Core", "HLEBios", &m_LocalCoreStartupParameter.bHLEBios, true);
ini.Get("Core", "UseDynarec", &m_LocalCoreStartupParameter.bUseDynarec, true); ini.Get("Core", "UseDynarec", &m_LocalCoreStartupParameter.bUseJIT, true);
ini.Get("Core", "UseDualCore", &m_LocalCoreStartupParameter.bUseDualCore, false); ini.Get("Core", "UseDualCore", &m_LocalCoreStartupParameter.bUseDualCore, false);
ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, true); ini.Get("Core", "LockThreads", &m_LocalCoreStartupParameter.bLockThreads, true);
ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true); ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true);