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
-4
View File
@@ -800,10 +800,6 @@
RelativePath=".\Src\PowerPC\Gekko.h"
>
</File>
<File
RelativePath=".\Src\PowerPC\ICPUCore.h"
>
</File>
<File
RelativePath=".\Src\PowerPC\PowerPC.cpp"
>
+2 -1
View File
@@ -446,7 +446,8 @@ bool CBoot::Load_BIOS(const std::string& _rBiosFilename)
bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara)
{
const bool bDebugIsoBootup = false;
g_symbolDB.Clear();
VideoInterface::PreInit(_StartupPara.bNTSC);
switch(_StartupPara.m_BootType)
{
+5 -5
View File
@@ -296,17 +296,17 @@ THREAD_RETURN EmuThread(void *pArg)
g_bHwInit = true;
// Load GCM/DOL/ELF whatever ... we boot with the interpreter core
PowerPC::SetCore(PowerPC::CORE_INTERPRETER);
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
CBoot::BootUp(_CoreParameter);
if( g_pUpdateFPSDisplay != NULL )
g_pUpdateFPSDisplay("Loading...");
// setup our core, but can't use dynarec if we are compare server
if (_CoreParameter.bUseDynarec && !_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient)
PowerPC::SetCore(PowerPC::CORE_DYNAREC);
if (_CoreParameter.bUseJIT && !_CoreParameter.bRunCompareServer || _CoreParameter.bRunCompareClient)
PowerPC::SetMode(PowerPC::MODE_JIT);
else
PowerPC::SetCore(PowerPC::CORE_INTERPRETER);
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
// update the window again because all stuff is initialized
Host_UpdateDisasmDialog();
@@ -472,7 +472,7 @@ void Callback_VideoCopiedToXFB()
char temp[256];
sprintf(temp, "FPS: %8.2f - %s - %i MHz (%i real, %i idle skipped) out of %i MHz",
(float)frames / t,
g_CoreStartupParameter.bUseDynarec ? "JIT" : "Interpreter",
g_CoreStartupParameter.bUseJIT ? "JIT" : "Interpreter",
(int)(diff),
(int)(diff-idleDiff),
(int)(idleDiff),
+1 -1
View File
@@ -30,7 +30,7 @@ SCoreStartupParameter::SCoreStartupParameter()
void SCoreStartupParameter::LoadDefaults()
{
bEnableDebugging = false;
bUseDynarec = false;
bUseJIT = false;
bUseDualCore = false;
bRunCompareServer = false;
bLockThreads = true;
+1 -1
View File
@@ -35,7 +35,7 @@ struct SCoreStartupParameter
// flags
bool bEnableDebugging;
bool bUseDynarec;
bool bUseJIT;
bool bUseDualCore;
bool bNTSC;
bool bHLEBios;
+2 -2
View File
@@ -81,7 +81,7 @@ void CCPU::Run()
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);
EnableStepping(true);
@@ -192,7 +192,7 @@ void CCPU::SingleStep()
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);
EnableStepping(true);
+2 -2
View File
@@ -120,7 +120,7 @@ int Sync()
if (!m_bEnabled)
return 0;
if (m_bIsServer) //This should be interpreter
if (m_bIsServer) // This should be interpreter
{
//write cpu state to m_hPipe
HRESULT result;
@@ -135,7 +135,7 @@ int Sync()
}
// LogManager::Redraw();
}
else //This should be dynarec
else // This should be JIT
{
u32 read;
memset(&state,0xcc,stateSize);
+1 -1
View File
@@ -89,7 +89,7 @@ namespace Memory
inline u32 ReadFast32(const u32 _Address)
{
#ifdef _M_IX86
return ReadUnchecked_U32(_Address);
return Common::swap32(*(u32 *)(base + (_Address & MEMVIEW32_MASK))); //ReadUnchecked_U32(_Address);
#elif defined(_M_X64)
return Common::swap32(*(u32 *)(base + _Address));
#endif
-34
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
@@ -27,111 +27,46 @@
#include "PowerPCDisasm.h"
#include "../../IPC_HLE/WII_IPC_HLE.h"
static const unsigned short FPU_PREC_24 = 0 << 8;
static const unsigned short FPU_PREC_53 = 2 << 8;
static const unsigned short FPU_PREC_64 = 3 << 8;
static const unsigned short FPU_PREC_MASK = 3 << 8;
enum {
FPU_PREC_24 = 0 << 8,
FPU_PREC_53 = 2 << 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 {
u32 last_pc;
}
// 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);}
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()
namespace Interpreter
{
// Crash();
#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
}
// cpu register to keep the code readable
u32 *m_GPR = PowerPC::ppcState.gpr;
bool m_EndBlock = false;
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"
void patches()
@@ -152,10 +87,8 @@ void patches()
// WII_IPC_HLE_Interface::Update();
}
void CInterpreter::sStepInner(void)
void SingleStepInner(void)
{
// Log();
/* static int count = 0;
count++;
if ((count % 50) == 0)
@@ -163,8 +96,8 @@ void CInterpreter::sStepInner(void)
static UGeckoInstruction instCode;
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 !!!!!!
//if (PowerPC::ppcState.DebugCount > 0x10f233a) { // 50721ef253a
// printf("> %08x - %08x - %s\n", PC, instCode.hex, DisassembleGekko(instCode.hex, PC));
@@ -199,9 +132,9 @@ void CInterpreter::sStepInner(void)
patches();
}
void CInterpreter::sStep()
void SingleStep()
{
sStepInner();
SingleStepInner();
CoreTiming::slicelength = 1;
CoreTiming::downcount = 0;
@@ -215,7 +148,7 @@ void CInterpreter::sStep()
}
// sFastRun - inspired by GCemu
void CInterpreter::sFastRun()
void Run()
{
while (!PowerPC::state)
{
@@ -226,11 +159,8 @@ void CInterpreter::sFastRun()
int i;
for (i = 0; !m_EndBlock; i++)
{
sStepInner();
SingleStepInner();
}
#if defined(DEBUGFAST) || defined(_DEBUG)
// Core::SyncTrace();
#endif
CoreTiming::downcount -= i;
}
@@ -244,10 +174,12 @@ void CInterpreter::sFastRun()
}
}
void CInterpreter::unknown_instruction(UGeckoInstruction _inst)
void unknown_instruction(UGeckoInstruction _inst)
{
CCPU::Break();
printf("Last PC = %08x : %s\n", last_pc, DisassembleGekko(Memory::ReadUnchecked_U32(last_pc), last_pc));
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);
}
} // namespace
File diff suppressed because it is too large Load Diff
@@ -20,8 +20,10 @@
#include "../../HLE/HLE.h"
#include "../PPCAnalyst.h"
namespace Interpreter
{
void CInterpreter::bx(UGeckoInstruction _inst)
void bx(UGeckoInstruction _inst)
{
if (_inst.LK)
LR = PC + 4;
@@ -41,7 +43,7 @@ void CInterpreter::bx(UGeckoInstruction _inst)
}
// bcx - ugly, straight from PPC manual equations :)
void CInterpreter::bcx(UGeckoInstruction _inst)
void bcx(UGeckoInstruction _inst)
{
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR--;
@@ -65,7 +67,7 @@ void CInterpreter::bcx(UGeckoInstruction _inst)
m_EndBlock = true;
}
void CInterpreter::bcctrx(UGeckoInstruction _inst)
void bcctrx(UGeckoInstruction _inst)
{
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR--;
@@ -81,7 +83,7 @@ void CInterpreter::bcctrx(UGeckoInstruction _inst)
m_EndBlock = true;
}
void CInterpreter::bclrx(UGeckoInstruction _inst)
void bclrx(UGeckoInstruction _inst)
{
if ((_inst.BO & BO_DONT_DECREMENT_FLAG) == 0)
CTR--;
@@ -98,18 +100,18 @@ void CInterpreter::bclrx(UGeckoInstruction _inst)
m_EndBlock = true;
}
void CInterpreter::HLEFunction(UGeckoInstruction _inst)
void HLEFunction(UGeckoInstruction _inst)
{
m_EndBlock = true;
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,1623, 2527, 3031] are placed into the corresponding bits of the MSR.
//MSR[13] is set to 0.
@@ -123,7 +125,7 @@ void CInterpreter::rfi(UGeckoInstruction _inst)
// PowerPC::CheckExceptions();
}
void CInterpreter::rfid(UGeckoInstruction _inst)
void rfid(UGeckoInstruction _inst)
{
_dbg_assert_msg_(GEKKO,0,"Instruction unimplemented (does this instruction even exist?)","rfid");
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.
// We do it anyway, though :P
void CInterpreter::sc(UGeckoInstruction _inst)
void sc(UGeckoInstruction _inst)
{
PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL;
PowerPC::CheckExceptions();
m_EndBlock = true;
}
} // namespace
@@ -57,6 +57,9 @@
// Super Monkey Ball reads FPRF & friends after fmadds, fmuls, frspx
// WHY do the FR & FI flags affect it so much?
namespace Interpreter
{
void UpdateFPSCR(UReg_FPSCR fp);
void UpdateSSEState();
@@ -110,7 +113,7 @@ void UpdateFPRF(double value)
// extremely rare
void CInterpreter::Helper_UpdateCR1(double _fValue)
void Helper_UpdateCR1(double _fValue)
{
FPSCR.FPRF = 0;
if (_fValue == 0.0 || _fValue == -0.0)
@@ -124,12 +127,12 @@ void CInterpreter::Helper_UpdateCR1(double _fValue)
PanicAlert("CR1");
}
bool CInterpreter::IsNAN(double _dValue)
bool IsNAN(double _dValue)
{
return _dValue != _dValue;
}
void CInterpreter::fcmpo(UGeckoInstruction _inst)
void fcmpo(UGeckoInstruction _inst)
{
double fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB);
@@ -151,7 +154,7 @@ void CInterpreter::fcmpo(UGeckoInstruction _inst)
then VXVC ¬ 1 */
}
void CInterpreter::fcmpu(UGeckoInstruction _inst)
void fcmpu(UGeckoInstruction _inst)
{
double fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB);
@@ -171,7 +174,7 @@ void CInterpreter::fcmpu(UGeckoInstruction _inst)
}
// Apply current rounding mode
void CInterpreter::fctiwx(UGeckoInstruction _inst)
void fctiwx(UGeckoInstruction _inst)
{
UpdateSSEState();
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. */
// Always round toward zero
void CInterpreter::fctiwzx(UGeckoInstruction _inst)
void fctiwzx(UGeckoInstruction _inst)
{
//UpdateFPSCR(FPSCR);
const double b = rPS0(_inst.FB);
@@ -241,35 +244,35 @@ void CInterpreter::fctiwzx(UGeckoInstruction _inst)
Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fmrx(UGeckoInstruction _inst)
void fmrx(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fabsx(UGeckoInstruction _inst)
void fabsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = fabs(rPS0(_inst.FB));
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fnabsx(UGeckoInstruction _inst)
void fnabsx(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fnegx(UGeckoInstruction _inst)
void fnegx(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fselx(UGeckoInstruction _inst)
void fselx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB);
// This is a binary instruction. Does not alter FPSCR
@@ -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 is said to be undefined
// 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)
{
@@ -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);
FPSCR.FI = 0;
FPSCR.FR = 1;
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);
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);
FPSCR.FI = 0;
FPSCR.FR = 0;
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);
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);
// FPSCR.FI = 0;
// FPSCR.FR = 1;
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));
// 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);
// FPSCR.FI = 0;
@@ -416,7 +419,7 @@ void CInterpreter::fdivx(UGeckoInstruction _inst)
}
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));
// FPSCR.FI = 0;
@@ -426,7 +429,7 @@ void CInterpreter::fdivsx(UGeckoInstruction _inst)
}
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));
// 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);
// FPSCR.FI = 0;
@@ -446,7 +449,7 @@ void CInterpreter::fmsubx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fmsubsx(UGeckoInstruction _inst)
void fmsubsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) =
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));
// FPSCR.FI = 0;
// FPSCR.FR = 0;
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fnmaddsx(UGeckoInstruction _inst)
void fnmaddsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) =
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));
// FPSCR.FI = 0;
// FPSCR.FR = 0;
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fnmsubsx(UGeckoInstruction _inst)
void fnmsubsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) =
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);
// FPSCR.FI = 0;
// FPSCR.FR = 0;
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));
// 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)));
// FPSCR.FI = 0;
@@ -514,7 +517,7 @@ void CInterpreter::frsqrtex(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
void CInterpreter::fsqrtx(UGeckoInstruction _inst)
void fsqrtx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = sqrt(rPS0(_inst.FB));
// FPSCR.FI = 0;
@@ -522,3 +525,5 @@ void CInterpreter::fsqrtx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR1(rPS0(_inst.FD));
}
} // namespace
@@ -18,6 +18,8 @@
#include "Interpreter.h"
#include "../../Core.h"
namespace Interpreter
{
#ifndef _WIN32
inline u32 _rotl(u32 x, int shift) {
@@ -27,7 +29,7 @@ inline u32 _rotl(u32 x, int shift) {
#endif
void CInterpreter::Helper_UpdateCR0(u32 _uValue)
void Helper_UpdateCR0(u32 _uValue)
{
u32 Flags = 0;
int sValue = (int)_uValue;
@@ -41,7 +43,7 @@ void CInterpreter::Helper_UpdateCR0(u32 _uValue)
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 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);
}
u32 CInterpreter::Helper_Carry(u32 _uValue1, u32 _uValue2)
u32 Helper_Carry(u32 _uValue1, u32 _uValue2)
{
return _uValue2 > (~_uValue1);
}
u32 CInterpreter::Helper_Mask(int mb, int me)
u32 Helper_Mask(int mb, int me)
{
//first make 001111111111111 part
u32 begin = 0xFFFFFFFF >> mb;
@@ -78,7 +80,7 @@ u32 CInterpreter::Helper_Mask(int mb, int me)
return mask;
}
void CInterpreter::addi(UGeckoInstruction _inst)
void addi(UGeckoInstruction _inst)
{
if (_inst.RA)
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;
}
void CInterpreter::addic(UGeckoInstruction _inst)
void addic(UGeckoInstruction _inst)
{
u32 a = m_GPR[_inst.RA];
u32 imm = (u32)(s32)_inst.SIMM_16;
@@ -95,13 +97,13 @@ void CInterpreter::addic(UGeckoInstruction _inst)
SetCarry(Helper_Carry(a, imm));
}
void CInterpreter::addic_rc(UGeckoInstruction _inst)
void addic_rc(UGeckoInstruction _inst)
{
addic(_inst);
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void CInterpreter::addis(UGeckoInstruction _inst)
void addis(UGeckoInstruction _inst)
{
if (_inst.RA)
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);
}
void CInterpreter::andi_rc(UGeckoInstruction _inst)
void andi_rc(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = m_GPR[_inst.RS] & _inst.UIMM;
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);
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);
}
void CInterpreter::cmpli(UGeckoInstruction _inst)
void cmpli(UGeckoInstruction _inst)
{
u32 a = m_GPR[_inst.RA];
u32 b = _inst.UIMM;
@@ -138,22 +140,22 @@ void CInterpreter::cmpli(UGeckoInstruction _inst)
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;
}
void CInterpreter::ori(UGeckoInstruction _inst)
void ori(UGeckoInstruction _inst)
{
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);
}
void CInterpreter::subfic(UGeckoInstruction _inst)
void subfic(UGeckoInstruction _inst)
{
/* u32 rra = ~m_GPR[_inst.RA];
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)));
}
void CInterpreter::twi(UGeckoInstruction _inst)
void twi(UGeckoInstruction _inst)
{
bool bFirst = true;
if (bFirst)
@@ -182,31 +184,31 @@ void CInterpreter::twi(UGeckoInstruction _inst)
bFirst = false;
}
void CInterpreter::xori(UGeckoInstruction _inst)
void xori(UGeckoInstruction _inst)
{
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);
}
void CInterpreter::rlwimix(UGeckoInstruction _inst)
void rlwimix(UGeckoInstruction _inst)
{
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
m_GPR[_inst.RA] = (m_GPR[_inst.RA] & ~mask) | (_rotl(m_GPR[_inst.RS],_inst.SH) & mask);
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void CInterpreter::rlwinmx(UGeckoInstruction _inst)
void rlwinmx(UGeckoInstruction _inst)
{
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS],_inst.SH) & mask;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void CInterpreter::rlwnmx(UGeckoInstruction _inst)
void rlwnmx(UGeckoInstruction _inst)
{
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS], m_GPR[_inst.RB] & 0x1F) & mask;
@@ -214,21 +216,21 @@ void CInterpreter::rlwnmx(UGeckoInstruction _inst)
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];
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];
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 b = (s32)m_GPR[_inst.RB];
@@ -240,7 +242,7 @@ void CInterpreter::cmp(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, fTemp);
}
void CInterpreter::cmpl(UGeckoInstruction _inst)
void cmpl(UGeckoInstruction _inst)
{
u32 a = m_GPR[_inst.RA];
u32 b = m_GPR[_inst.RB];
@@ -252,7 +254,7 @@ void CInterpreter::cmpl(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, fTemp);
}
void CInterpreter::cntlzwx(UGeckoInstruction _inst)
void cntlzwx(UGeckoInstruction _inst)
{
u32 val = m_GPR[_inst.RS];
u32 mask = 0x80000000;
@@ -264,56 +266,56 @@ void CInterpreter::cntlzwx(UGeckoInstruction _inst)
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]);
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];
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];
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]);
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]);
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];
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]);
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void CInterpreter::slwx(UGeckoInstruction _inst)
void slwx(UGeckoInstruction _inst)
{
// TODO(ector): wtf is this code?
/* u32 amount = m_GPR[_inst.RB];
@@ -328,7 +330,7 @@ void CInterpreter::slwx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void CInterpreter::srawx(UGeckoInstruction _inst)
void srawx(UGeckoInstruction _inst)
{
int rb = m_GPR[_inst.RB];
if (rb & 0x20)
@@ -365,7 +367,7 @@ void CInterpreter::srawx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void CInterpreter::srawix(UGeckoInstruction _inst)
void srawix(UGeckoInstruction _inst)
{
int amount = _inst.SH;
@@ -388,7 +390,7 @@ void CInterpreter::srawix(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void CInterpreter::srwx(UGeckoInstruction _inst)
void srwx(UGeckoInstruction _inst)
{
u32 amount = m_GPR[_inst.RB];
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]);
}
void CInterpreter::tw(UGeckoInstruction _inst)
void tw(UGeckoInstruction _inst)
{
static bool bFirst = true;
if (bFirst)
@@ -404,14 +406,14 @@ void CInterpreter::tw(UGeckoInstruction _inst)
bFirst = false;
}
void CInterpreter::xorx(UGeckoInstruction _inst)
void xorx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ m_GPR[_inst.RB];
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void CInterpreter::addx(UGeckoInstruction _inst)
void addx(UGeckoInstruction _inst)
{
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]);
}
void CInterpreter::addcx(UGeckoInstruction _inst)
void addcx(UGeckoInstruction _inst)
{
u32 a = m_GPR[_inst.RA];
u32 b = m_GPR[_inst.RB];
@@ -430,7 +432,7 @@ void CInterpreter::addcx(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void CInterpreter::addex(UGeckoInstruction _inst)
void addex(UGeckoInstruction _inst)
{
int carry = GetCarry();
int a = m_GPR[_inst.RA];
@@ -442,7 +444,7 @@ void CInterpreter::addex(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void CInterpreter::addmex(UGeckoInstruction _inst)
void addmex(UGeckoInstruction _inst)
{
int carry = GetCarry();
int a = m_GPR[_inst.RA];
@@ -453,7 +455,7 @@ void CInterpreter::addmex(UGeckoInstruction _inst)
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void CInterpreter::addzex(UGeckoInstruction _inst)
void addzex(UGeckoInstruction _inst)
{
int carry = GetCarry();
int a = m_GPR[_inst.RA];
@@ -464,7 +466,7 @@ void CInterpreter::addzex(UGeckoInstruction _inst)
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 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 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 b = m_GPR[_inst.RB];
@@ -508,7 +510,7 @@ void CInterpreter::mulhwx(UGeckoInstruction _inst)
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 b = m_GPR[_inst.RB];
@@ -517,7 +519,7 @@ void CInterpreter::mulhwux(UGeckoInstruction _inst)
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 b = m_GPR[_inst.RB];
@@ -528,7 +530,7 @@ void CInterpreter::mullwx(UGeckoInstruction _inst)
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;
if (m_GPR[_inst.RD] == 0x80000000)
@@ -538,7 +540,7 @@ void CInterpreter::negx(UGeckoInstruction _inst)
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];
@@ -546,7 +548,7 @@ void CInterpreter::subfx(UGeckoInstruction _inst)
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 b = m_GPR[_inst.RB];
@@ -557,7 +559,7 @@ void CInterpreter::subfcx(UGeckoInstruction _inst)
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 b = m_GPR[_inst.RB];
@@ -570,7 +572,7 @@ void CInterpreter::subfex(UGeckoInstruction _inst)
}
// sub from minus one
void CInterpreter::subfmex(UGeckoInstruction _inst)
void subfmex(UGeckoInstruction _inst)
{
u32 a = m_GPR[_inst.RA];
int carry = GetCarry();
@@ -582,7 +584,7 @@ void CInterpreter::subfmex(UGeckoInstruction _inst)
}
// sub from zero
void CInterpreter::subfzex(UGeckoInstruction _inst)
void subfzex(UGeckoInstruction _inst)
{
u32 a = m_GPR[_inst.RA];
int carry = GetCarry();
@@ -592,3 +594,5 @@ void CInterpreter::subfzex(UGeckoInstruction _inst)
if (_inst.OE) PanicAlert("OE: subfzex");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
}
} // namespace
File diff suppressed because it is too large Load Diff
@@ -19,6 +19,9 @@
#include "Interpreter.h"
#include "../../HW/Memmap.h"
namespace Interpreter
{
// dequantize table
const float m_dequantizeTable[] =
{
@@ -68,7 +71,7 @@ inline T CLAMP(T a, T bottom, T top) {
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)
{
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)
{
// dequantize the value
@@ -152,7 +155,7 @@ float CInterpreter::Helper_Dequantize(const u32 _Addr, const EQuantizeType _quan
return fResult;
}
void CInterpreter::psq_l(UGeckoInstruction _inst)
void psq_l(UGeckoInstruction _inst)
{
const UGQR gqr(rSPR(SPR_GQR0 + _inst.I));
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 EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
@@ -199,7 +202,7 @@ void CInterpreter::psq_lu(UGeckoInstruction _inst)
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 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 EQuantizeType stType = static_cast<EQuantizeType>(gqr.ST_TYPE);
@@ -244,7 +247,7 @@ void CInterpreter::psq_stu(UGeckoInstruction _inst)
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 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 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 EQuantizeType ldType = static_cast<EQuantizeType>(gqr.LD_TYPE);
@@ -313,7 +316,7 @@ void CInterpreter::psq_lux(UGeckoInstruction _inst)
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 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);
}
m_GPR[_inst.RA] = EA;
} // namespace=======
}
@@ -19,39 +19,42 @@
#include "Interpreter.h"
#include "../../HW/Memmap.h"
namespace Interpreter
{
// 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));
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);
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);
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);
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);
riPS1(_inst.FD) = riPS1(_inst.FB) &~ (1ULL << 63);
}
// These are just moves, double is OK.
void CInterpreter::ps_merge00(UGeckoInstruction _inst)
void ps_merge00(UGeckoInstruction _inst)
{
double p0 = rPS0(_inst.FA);
double p1 = rPS0(_inst.FB);
@@ -59,7 +62,7 @@ void CInterpreter::ps_merge00(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1;
}
void CInterpreter::ps_merge01(UGeckoInstruction _inst)
void ps_merge01(UGeckoInstruction _inst)
{
double p0 = rPS0(_inst.FA);
double p1 = rPS1(_inst.FB);
@@ -67,7 +70,7 @@ void CInterpreter::ps_merge01(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1;
}
void CInterpreter::ps_merge10(UGeckoInstruction _inst)
void ps_merge10(UGeckoInstruction _inst)
{
double p0 = rPS1(_inst.FA);
double p1 = rPS0(_inst.FB);
@@ -75,7 +78,7 @@ void CInterpreter::ps_merge10(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1;
}
void CInterpreter::ps_merge11(UGeckoInstruction _inst)
void ps_merge11(UGeckoInstruction _inst)
{
double p0 = rPS1(_inst.FA);
double p1 = rPS1(_inst.FB);
@@ -86,7 +89,7 @@ void CInterpreter::ps_merge11(UGeckoInstruction _inst)
// 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));
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));
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));
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));
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));
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)));
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));
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));
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)));
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)));
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 p1 = (float)(rPS1(_inst.FC));
@@ -161,7 +164,7 @@ void CInterpreter::ps_sum0(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1;
}
void CInterpreter::ps_sum1(UGeckoInstruction _inst)
void ps_sum1(UGeckoInstruction _inst)
{
double p0 = rPS0(_inst.FC);
double p1 = rPS0(_inst.FA) + rPS1(_inst.FB);
@@ -169,7 +172,7 @@ void CInterpreter::ps_sum1(UGeckoInstruction _inst)
rPS1(_inst.FD) = p1;
}
void CInterpreter::ps_muls0(UGeckoInstruction _inst)
void ps_muls0(UGeckoInstruction _inst)
{
double p0 = rPS0(_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;
}
void CInterpreter::ps_muls1(UGeckoInstruction _inst)
void ps_muls1(UGeckoInstruction _inst)
{
double p0 = rPS0(_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;
}
void CInterpreter::ps_madds0(UGeckoInstruction _inst)
void ps_madds0(UGeckoInstruction _inst)
{
double p0 = (rPS0(_inst.FA) * rPS0(_inst.FC)) + rPS0(_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;
}
void CInterpreter::ps_madds1(UGeckoInstruction _inst)
void ps_madds1(UGeckoInstruction _inst)
{
double p0 = (rPS0(_inst.FA) * rPS1(_inst.FC)) + rPS0(_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;
}
void CInterpreter::ps_cmpu0(UGeckoInstruction _inst)
void ps_cmpu0(UGeckoInstruction _inst)
{
double fa = rPS0(_inst.FA);
double fb = rPS0(_inst.FB);
@@ -212,13 +215,13 @@ void CInterpreter::ps_cmpu0(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, compareResult);
}
void CInterpreter::ps_cmpo0(UGeckoInstruction _inst)
void ps_cmpo0(UGeckoInstruction _inst)
{
// for now HACK
ps_cmpu0(_inst);
}
void CInterpreter::ps_cmpu1(UGeckoInstruction _inst)
void ps_cmpu1(UGeckoInstruction _inst)
{
double fa = rPS1(_inst.FA);
double fb = rPS1(_inst.FB);
@@ -230,7 +233,7 @@ void CInterpreter::ps_cmpu1(UGeckoInstruction _inst)
SetCRField(_inst.CRFD, compareResult);
}
void CInterpreter::ps_cmpo1(UGeckoInstruction _inst)
void ps_cmpo1(UGeckoInstruction _inst)
{
// for now HACK
ps_cmpu1(_inst);
@@ -239,8 +242,7 @@ void CInterpreter::ps_cmpo1(UGeckoInstruction _inst)
// __________________________________________________________________________________________________
// dcbz_l
// TODO(ector) check docs
void
CInterpreter::dcbz_l(UGeckoInstruction _inst)
void dcbz_l(UGeckoInstruction _inst)
{
// 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.
@@ -255,3 +257,5 @@ CInterpreter::dcbz_l(UGeckoInstruction _inst)
Memory::Write_U32(0,i);
*/
}
} // namespace
@@ -49,6 +49,9 @@ mffsx: 80036650 (huh?)
// That is, set rounding mode etc when entering jit code or the interpreter loop
// Restore rounding mode when calling anything external
namespace Interpreter
{
void UpdateSSEState()
{
u32 csr = _mm_getcsr();
@@ -116,7 +119,7 @@ void UpdateFPSCR(UReg_FPSCR fp)
UpdateSSEState();
}
void CInterpreter::mcrfs(UGeckoInstruction _inst)
void mcrfs(UGeckoInstruction _inst)
{
u32 fpflags = ((FPSCR.Hex >> (4*(_inst.CRFS))) & 0xF);
switch (_inst.CRFS) {
@@ -165,7 +168,7 @@ void CInterpreter::mcrfs(UGeckoInstruction _inst)
#define MXCSR_ROUND (16384|8192)
#define MXCSR_FLUSH 32768
void CInterpreter::mffsx(UGeckoInstruction _inst)
void mffsx(UGeckoInstruction _inst)
{
// load from FPSCR
// 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");
}
void CInterpreter::mtfsb0x(UGeckoInstruction _inst)
void mtfsb0x(UGeckoInstruction _inst)
{
FPSCR.Hex &= (~(0x80000000 >> _inst.CRBD));
UpdateFPSCR(FPSCR);
if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc");
}
void CInterpreter::mtfsb1x(UGeckoInstruction _inst)
void mtfsb1x(UGeckoInstruction _inst)
{
FPSCR.Hex |= 0x80000000 >> _inst.CRBD;
UpdateFPSCR(FPSCR);
if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc");
}
void CInterpreter::mtfsfix(UGeckoInstruction _inst)
void mtfsfix(UGeckoInstruction _inst)
{
u32 mask = (0xF0000000 >> (4 * _inst.CRFD));
u32 imm = (_inst.hex << 16) & 0xF0000000;
@@ -198,7 +201,7 @@ void CInterpreter::mtfsfix(UGeckoInstruction _inst)
if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc");
}
void CInterpreter::mtfsfx(UGeckoInstruction _inst)
void mtfsfx(UGeckoInstruction _inst)
{
u32 fm = _inst.FM;
u32 m = 0;
@@ -212,18 +215,18 @@ void CInterpreter::mtfsfx(UGeckoInstruction _inst)
if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc");
}
void CInterpreter::mcrxr(UGeckoInstruction _inst)
void mcrxr(UGeckoInstruction _inst)
{
SetCRField(_inst.CRFD, XER.Hex >> 28);
XER.Hex &= ~0xF0000000; // clear 0-3
}
void CInterpreter::mfcr(UGeckoInstruction _inst)
void mfcr(UGeckoInstruction _inst)
{
m_GPR[_inst.RD] = GetCR();
}
void CInterpreter::mtcrf(UGeckoInstruction _inst)
void mtcrf(UGeckoInstruction _inst)
{
u32 mask = 0;
u32 crm = _inst.CRM;
@@ -240,7 +243,7 @@ void CInterpreter::mtcrf(UGeckoInstruction _inst)
}
void CInterpreter::mfmsr(UGeckoInstruction _inst)
void mfmsr(UGeckoInstruction _inst)
{
//Privileged?
m_GPR[_inst.RD] = MSR;
@@ -248,38 +251,38 @@ void CInterpreter::mfmsr(UGeckoInstruction _inst)
// segment register
// 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];
}
// segment register
void CInterpreter::mfsrin(UGeckoInstruction _inst)
void mfsrin(UGeckoInstruction _inst)
{
int index = m_GPR[_inst.RB] & 0xF;
m_GPR[_inst.RD] = PowerPC::ppcState.sr[index];
}
void CInterpreter::mtmsr(UGeckoInstruction _inst)
void mtmsr(UGeckoInstruction _inst)
{
//Privileged?
MSR = m_GPR[_inst.RS];
}
// segment register
void CInterpreter::mtsr(UGeckoInstruction _inst)
void mtsr(UGeckoInstruction _inst)
{
PowerPC::ppcState.sr[_inst.SR] = m_GPR[_inst.RS];
}
// segment register
void CInterpreter::mtsrin(UGeckoInstruction _inst)
void mtsrin(UGeckoInstruction _inst)
{
int index = m_GPR[_inst.RB] & 0xF;
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);
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);
@@ -315,7 +318,7 @@ void CInterpreter::mfspr(UGeckoInstruction _inst)
m_GPR[_inst.RD] = rSPR(iIndex);
}
void CInterpreter::mtspr(UGeckoInstruction _inst)
void mtspr(UGeckoInstruction _inst)
{
u32 iIndex = (_inst.SPRU << 5) | (_inst.SPRL & 0x1F);
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 a = cr << _inst.CRBA;
@@ -414,7 +417,7 @@ void CInterpreter::crand(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
}
void CInterpreter::crandc(UGeckoInstruction _inst)
void crandc(UGeckoInstruction _inst)
{
u32 cr = GetCR();
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 a = cr << _inst.CRBA;
@@ -433,7 +436,7 @@ void CInterpreter::creqv(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
}
void CInterpreter::crnand(UGeckoInstruction _inst)
void crnand(UGeckoInstruction _inst)
{
u32 cr = GetCR();
u32 a = cr << _inst.CRBA;
@@ -442,7 +445,7 @@ void CInterpreter::crnand(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
}
void CInterpreter::crnor(UGeckoInstruction _inst)
void crnor(UGeckoInstruction _inst)
{
u32 cr = GetCR();
u32 a = cr << _inst.CRBA;
@@ -451,7 +454,7 @@ void CInterpreter::crnor(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
}
void CInterpreter::cror(UGeckoInstruction _inst)
void cror(UGeckoInstruction _inst)
{
u32 cr = GetCR();
u32 a = cr << _inst.CRBA;
@@ -460,7 +463,7 @@ void CInterpreter::cror(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
}
void CInterpreter::crorc(UGeckoInstruction _inst)
void crorc(UGeckoInstruction _inst)
{
u32 cr = GetCR();
u32 a = cr << _inst.CRBA;
@@ -469,7 +472,7 @@ void CInterpreter::crorc(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
}
void CInterpreter::crxor(UGeckoInstruction _inst)
void crxor(UGeckoInstruction _inst)
{
u32 cr = GetCR();
u32 a = cr << _inst.CRBA;
@@ -478,7 +481,7 @@ void CInterpreter::crxor(UGeckoInstruction _inst)
SetCR(d | (cr & ~(0x80000000 >> _inst.CRBD)));
}
void CInterpreter::mcrf(UGeckoInstruction _inst)
void mcrf(UGeckoInstruction _inst)
{
u32 cr = GetCR();
u32 crmask = ~(0xF0000000 >> (4*_inst.CRFD));
@@ -486,7 +489,9 @@ void CInterpreter::mcrf(UGeckoInstruction _inst)
SetCR((cr & crmask) | flags);
}
void CInterpreter::isync(UGeckoInstruction _inst)
void isync(UGeckoInstruction _inst)
{
//shouldnt do anything
}
} // namespace
+10 -13
View File
@@ -80,8 +80,8 @@ extern int blocksExecuted;
//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
//entering "dynarec 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.
//entering "JIT space". However, once we're there, it will be a win.
//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
//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!
// 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) ????
// 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
// 7. Watch Zelda do 20 fps.
// 8. Watch Zelda TP do 30 fps.
// 8. Watch Zelda TP do 30 fps. DONE :D
//Optimizations -
/*
* 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)
* AMD only - use movaps instead of movapd when loading ps from memory?
* HLE functions like floorf, sin, memcpy, etc - they can be much faster
* Optimal sequence to store floats
* TODO: find optimal sequence to store doubles as floats
cvtpd2ps xmm0, xmm0
movss xmm0, f
movss tempspace, xmm0
mov eax, tempspace
bswap eax
mov [edi], eax
I think pshufb does it faster.
BLOCK EXIT DESIGN
TEST whatever
JZ skip
MOV NPC, exit1
@@ -162,9 +162,6 @@ JMP exit1
The problem is, we still need to fit the downcount somewhere...
Low hanging fruit:
stfd -- guaranteed in memory
cmpl
@@ -256,7 +253,7 @@ namespace Jit64
MOV(32, M(&PC), Imm32(js.compilerPC));
MOV(32, M(&NPC), Imm32(js.compilerPC + 4));
}
CInterpreter::_interpreterInstruction instr = GetInterpreterOp(_inst);
Interpreter::_interpreterInstruction instr = GetInterpreterOp(_inst);
ABI_CallFunctionC((void*)instr, _inst.hex);
}
+1 -1
View File
@@ -39,7 +39,7 @@ namespace Jit64
struct JitBlock;
const u8* DoJit(u32 emaddress, JitBlock &b);
bool IsInJitCode(u8 *codePtr);
bool IsInJitCode(const u8 *codePtr);
struct JitState
{

Some files were not shown because too many files have changed in this diff Show More