Merge pull request #715 from lioncash/interp

Core: Clean up coding style in the Interpreter
This commit is contained in:
Lioncash 2014-08-02 08:39:11 -04:00
commit a723fd39df
10 changed files with 476 additions and 180 deletions

View File

@ -18,7 +18,8 @@
#include "Core/PowerPC/GDBStub.h"
#endif
namespace {
namespace
{
u32 last_pc;
}
@ -32,11 +33,11 @@ Interpreter::_interpreterInstruction Interpreter::m_opTable31[1024];
Interpreter::_interpreterInstruction Interpreter::m_opTable59[32];
Interpreter::_interpreterInstruction Interpreter::m_opTable63[1024];
void Interpreter::RunTable4(UGeckoInstruction _inst) {m_opTable4 [_inst.SUBOP10](_inst);}
void Interpreter::RunTable19(UGeckoInstruction _inst) {m_opTable19[_inst.SUBOP10](_inst);}
void Interpreter::RunTable31(UGeckoInstruction _inst) {m_opTable31[_inst.SUBOP10](_inst);}
void Interpreter::RunTable59(UGeckoInstruction _inst) {m_opTable59[_inst.SUBOP5 ](_inst);}
void Interpreter::RunTable63(UGeckoInstruction _inst) {m_opTable63[_inst.SUBOP10](_inst);}
void Interpreter::RunTable4(UGeckoInstruction _inst) { m_opTable4 [_inst.SUBOP10](_inst); }
void Interpreter::RunTable19(UGeckoInstruction _inst) { m_opTable19[_inst.SUBOP10](_inst); }
void Interpreter::RunTable31(UGeckoInstruction _inst) { m_opTable31[_inst.SUBOP10](_inst); }
void Interpreter::RunTable59(UGeckoInstruction _inst) { m_opTable59[_inst.SUBOP5 ](_inst); }
void Interpreter::RunTable63(UGeckoInstruction _inst) { m_opTable63[_inst.SUBOP10](_inst); }
void Interpreter::Init()
{
@ -116,8 +117,8 @@ int Interpreter::SingleStepInner(void)
if (function == 0)
{
#ifdef USE_GDBSTUB
if (gdb_active() && gdb_bp_x(PC)) {
if (gdb_active() && gdb_bp_x(PC))
{
Host_UpdateDisasmDialog();
gdb_signal(SIGTRAP);
@ -260,8 +261,10 @@ void Interpreter::Run()
{
// Write space
if (j > 0)
{
if (PCVec.at(j) != PCVec.at(j-1) + 4)
NOTICE_LOG(POWERPC, "");
}
NOTICE_LOG(POWERPC, "PC: 0x%08x", PCVec.at(j));
}

View File

@ -9,6 +9,7 @@ void Interpreter::bx(UGeckoInstruction _inst)
{
if (_inst.LK)
LR = PC + 4;
if (_inst.AA)
NPC = SignExt26(_inst.LI << 2);
else
@ -41,11 +42,13 @@ void Interpreter::bcx(UGeckoInstruction _inst)
{
if (_inst.LK)
LR = PC + 4;
if (_inst.AA)
NPC = SignExt16(_inst.BD << 2);
else
NPC = PC + SignExt16(_inst.BD << 2);
}
m_EndBlock = true;
}
@ -61,6 +64,7 @@ void Interpreter::bcctrx(UGeckoInstruction _inst)
if (_inst.LK_3)
LR = PC + 4;
}
m_EndBlock = true;
}
@ -78,6 +82,7 @@ void Interpreter::bclrx(UGeckoInstruction _inst)
if (_inst.LK_3)
LR = PC + 4;
}
m_EndBlock = true;
}

View File

@ -43,7 +43,8 @@ const u64 PPC_NAN_U64 = 0x7ff8000000000000ull;
const double PPC_NAN = *(double* const)&PPC_NAN_U64;
// the 4 less-significand bits in FPSCR[FPRF]
enum FPCC {
enum FPCC
{
FL = 8, // <
FG = 4, // >
FE = 2, // =
@ -264,6 +265,7 @@ inline u64 ConvertToDouble(u32 _x)
frac <<= 1;
exp -= 1;
} while ((frac & 0x00800000) == 0);
return ((x & 0x80000000) << 32) | (exp << 52) | ((frac & 0x007fffff) << 29);
}
else // QNaN, SNaN or Zero
@ -303,6 +305,7 @@ inline double ApproximateReciprocal(double val)
double valf;
s64 vali;
};
valf = val;
s64 mantissa = vali & ((1LL << 52) - 1);
s64 sign = vali & (1ULL << 63);
@ -312,6 +315,7 @@ inline double ApproximateReciprocal(double val)
if (mantissa == 0 && exponent == 0)
return sign ? -std::numeric_limits<double>::infinity() :
std::numeric_limits<double>::infinity();
// Special case NaN-ish numbers
if (exponent == (0x7FFLL << 52))
{
@ -319,10 +323,12 @@ inline double ApproximateReciprocal(double val)
return sign ? -0.0 : 0.0;
return 0.0 + valf;
}
// Special case small inputs
if (exponent < (895LL << 52))
return sign ? -std::numeric_limits<float>::max() :
std::numeric_limits<float>::max();
// Special case large inputs
if (exponent >= (1149LL << 52))
return sign ? -0.0f : 0.0f;
@ -379,10 +385,13 @@ inline double ApproximateReciprocalSquareRoot(double val)
{
if (sign)
return std::numeric_limits<double>::quiet_NaN();
return 0.0;
}
return 0.0 + valf;
}
// Negative numbers return NaN
if (sign)
return std::numeric_limits<double>::quiet_NaN();

View File

@ -87,6 +87,7 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction _inst, double f
SetFPException(FPSCR_VXSNAN);
}
}
FPSCR.FPRF = compareResult;
SetCRField(_inst.CRFD, compareResult);
}
@ -106,6 +107,7 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
{
const double b = rPS0(_inst.FB);
u32 value;
if (b > (double)0x7fffffff)
{
value = 0x7fffffff;
@ -129,7 +131,11 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
{
double t = b + 0.5;
i = (s32)t;
if (t - i < 0 || (t - i == 0 && b > 0)) i--;
if (t - i < 0 || (t - i == 0 && b > 0))
{
i--;
}
break;
}
case 1: // zero
@ -137,11 +143,17 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
break;
case 2: // +inf
i = (s32)b;
if (b - i > 0) i++;
if (b - i > 0)
{
i++;
}
break;
case 3: // -inf
i = (s32)b;
if (b - i < 0) i--;
if (b - i < 0)
{
i--;
}
break;
}
value = (u32)i;
@ -157,6 +169,7 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
FPSCR.FR = fabs(di) > fabs(b);
}
}
// based on HW tests
// FPRF is not affected
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
@ -171,6 +184,7 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst)
{
const double b = rPS0(_inst.FB);
u32 value;
if (b > (double)0x7fffffff)
{
value = 0x7fffffff;
@ -201,6 +215,7 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst)
}
value = (u32)i;
}
// based on HW tests
// FPRF is not affected
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
@ -213,36 +228,46 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst)
void Interpreter::fmrx(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fabsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = fabs(rPS0(_inst.FB));
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnabsx(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnegx(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fselx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB);
// This is a binary instruction. Does not alter FPSCR
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
// !!! warning !!!
@ -266,7 +291,9 @@ void Interpreter::fmulx(UGeckoInstruction _inst)
FPSCR.FI = 0; // are these flags important?
FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmulsx(UGeckoInstruction _inst)
{
@ -276,7 +303,9 @@ void Interpreter::fmulsx(UGeckoInstruction _inst)
FPSCR.FI = 0;
FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmaddx(UGeckoInstruction _inst)
@ -284,7 +313,9 @@ void Interpreter::fmaddx(UGeckoInstruction _inst)
double result = ForceDouble(NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
rPS0(_inst.FD) = result;
UpdateFPRF(result);
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmaddsx(UGeckoInstruction _inst)
@ -294,7 +325,9 @@ void Interpreter::fmaddsx(UGeckoInstruction _inst)
FPSCR.FI = d_value != rPS0(_inst.FD);
FPSCR.FR = 0;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
@ -302,21 +335,32 @@ void Interpreter::faddx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = ForceDouble(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::faddsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fdivx(UGeckoInstruction _inst)
{
double a = rPS0(_inst.FA);
double b = rPS0(_inst.FB);
if (a != a) rPS0(_inst.FD) = a;
else if (b != b) rPS0(_inst.FD) = b;
if (a != a)
{
rPS0(_inst.FD) = a;
}
else if (b != b)
{
rPS0(_inst.FD) = b;
}
else
{
rPS0(_inst.FD) = ForceDouble(a / b);
@ -339,16 +383,25 @@ void Interpreter::fdivx(UGeckoInstruction _inst)
}
}
UpdateFPRF(rPS0(_inst.FD));
// FR,FI,OX,UX???
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fdivsx(UGeckoInstruction _inst)
{
double a = rPS0(_inst.FA);
double b = rPS0(_inst.FB);
double res;
if (a != a) res = a;
else if (b != b) res = b;
if (a != a)
{
res = a;
}
else if (b != b)
{
res = b;
}
else
{
res = ForceSingle(a / b);
@ -370,9 +423,12 @@ void Interpreter::fdivsx(UGeckoInstruction _inst)
}
}
}
rPS0(_inst.FD) = rPS1(_inst.FD) = res;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
// Single precision only.
@ -380,17 +436,22 @@ void Interpreter::fresx(UGeckoInstruction _inst)
{
double b = rPS0(_inst.FB);
rPS0(_inst.FD) = rPS1(_inst.FD) = ApproximateReciprocal(b);
if (b == 0.0)
{
SetFPException(FPSCR_ZX);
}
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::frsqrtex(UGeckoInstruction _inst)
{
double b = rPS0(_inst.FB);
if (b < 0.0)
{
SetFPException(FPSCR_VXSQRT);
@ -399,45 +460,59 @@ void Interpreter::frsqrtex(UGeckoInstruction _inst)
{
SetFPException(FPSCR_ZX);
}
rPS0(_inst.FD) = ApproximateReciprocalSquareRoot(b);
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmsubx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = ForceDouble(NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
rPS0(_inst.FD) = ForceDouble(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fmsubsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) =
ForceSingle( NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
ForceSingle(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnmaddx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = ForceDouble(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnmaddsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) =
ForceSingle(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fnmsubx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = ForceDouble(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
// fnmsubsx does not handle QNAN properly - see NI_msub
@ -446,21 +521,27 @@ void Interpreter::fnmsubsx(UGeckoInstruction _inst)
rPS0(_inst.FD) = rPS1(_inst.FD) =
ForceSingle(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fsubx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = ForceDouble(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fsubsx(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::fsqrtx(UGeckoInstruction _inst)
@ -468,10 +549,15 @@ void Interpreter::fsqrtx(UGeckoInstruction _inst)
// GEKKO is not supposed to support this instruction.
// PanicAlert("fsqrtx");
double b = rPS0(_inst.FB);
if (b < 0.0) {
if (b < 0.0)
{
FPSCR.VXSQRT = 1;
}
rPS0(_inst.FD) = sqrt(b);
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}

View File

@ -95,10 +95,17 @@ void Interpreter::cmpli(UGeckoInstruction _inst)
u32 a = m_GPR[_inst.RA];
u32 b = _inst.UIMM;
int f;
if (a < b) f = 0x8;
else if (a > b) f = 0x4;
else f = 0x2; //equals
if (GetXER_SO()) f |= 0x1;
if (a < b)
f = 0x8;
else if (a > b)
f = 0x4;
else
f = 0x2; //equals
if (GetXER_SO())
f |= 0x1;
SetCRField(_inst.CRFD, f);
}
@ -170,14 +177,18 @@ void Interpreter::rlwimix(UGeckoInstruction _inst)
{
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
m_GPR[_inst.RA] = (m_GPR[_inst.RA] & ~mask) | (_rotl(m_GPR[_inst.RS],_inst.SH) & mask);
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::rlwinmx(UGeckoInstruction _inst)
{
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS],_inst.SH) & mask;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::rlwnmx(UGeckoInstruction _inst)
@ -185,21 +196,24 @@ void Interpreter::rlwnmx(UGeckoInstruction _inst)
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS], m_GPR[_inst.RB] & 0x1F) & mask;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::andx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = m_GPR[_inst.RS] & m_GPR[_inst.RB];
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::andcx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = m_GPR[_inst.RS] & ~m_GPR[_inst.RB];
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::cmp(UGeckoInstruction _inst)
@ -207,10 +221,16 @@ void Interpreter::cmp(UGeckoInstruction _inst)
s32 a = (s32)m_GPR[_inst.RA];
s32 b = (s32)m_GPR[_inst.RB];
int fTemp = 0x8; // a < b
// if (a < b) fTemp = 0x8; else
if (a > b) fTemp = 0x4;
else if (a == b) fTemp = 0x2;
if (GetXER_SO()) PanicAlert("cmp getting overflow flag"); // fTemp |= 0x1
// if (a < b) fTemp = 0x8; else
if (a > b)
fTemp = 0x4;
else if (a == b)
fTemp = 0x2;
if (GetXER_SO())
PanicAlert("cmp getting overflow flag"); // fTemp |= 0x1
SetCRField(_inst.CRFD, fTemp);
}
@ -221,9 +241,14 @@ void Interpreter::cmpl(UGeckoInstruction _inst)
u32 fTemp = 0x8; // a < b
// if (a < b) fTemp = 0x8;else
if (a > b) fTemp = 0x4;
else if (a == b) fTemp = 0x2;
if (GetXER_SO()) PanicAlert("cmpl getting overflow flag"); // fTemp |= 0x1;
if (a > b)
fTemp = 0x4;
else if (a == b)
fTemp = 0x2;
if (GetXER_SO())
PanicAlert("cmpl getting overflow flag"); // fTemp |= 0x1;
SetCRField(_inst.CRFD, fTemp);
}
@ -231,61 +256,74 @@ void Interpreter::cntlzwx(UGeckoInstruction _inst)
{
u32 val = m_GPR[_inst.RS];
u32 mask = 0x80000000;
int i = 0;
for (; i < 32; i++, mask >>= 1)
{
if (val & mask)
break;
}
m_GPR[_inst.RA] = i;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::eqvx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] ^ m_GPR[_inst.RB]);
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::extsbx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = (u32)(s32)(s8)m_GPR[_inst.RS];
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::extshx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = (u32)(s32)(s16)m_GPR[_inst.RS];
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::nandx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] & m_GPR[_inst.RB]);
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::norx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] | m_GPR[_inst.RB]);
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::orx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = m_GPR[_inst.RS] | m_GPR[_inst.RB];
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::orcx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = m_GPR[_inst.RS] | (~m_GPR[_inst.RB]);
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::slwx(UGeckoInstruction _inst)
@ -293,12 +331,14 @@ void Interpreter::slwx(UGeckoInstruction _inst)
u32 amount = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : m_GPR[_inst.RS] << amount;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::srawx(UGeckoInstruction _inst)
{
int rb = m_GPR[_inst.RB];
if (rb & 0x20)
{
if (m_GPR[_inst.RS] & 0x80000000)
@ -330,7 +370,8 @@ void Interpreter::srawx(UGeckoInstruction _inst)
}
}
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::srawix(UGeckoInstruction _inst)
@ -353,7 +394,8 @@ void Interpreter::srawix(UGeckoInstruction _inst)
m_GPR[_inst.RA] = m_GPR[_inst.RS];
}
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::srwx(UGeckoInstruction _inst)
@ -361,7 +403,8 @@ void Interpreter::srwx(UGeckoInstruction _inst)
u32 amount = m_GPR[_inst.RB];
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> (amount & 0x1f));
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::tw(UGeckoInstruction _inst)
@ -388,15 +431,19 @@ void Interpreter::xorx(UGeckoInstruction _inst)
{
m_GPR[_inst.RA] = m_GPR[_inst.RS] ^ m_GPR[_inst.RB];
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RA]);
}
void Interpreter::addx(UGeckoInstruction _inst)
{
m_GPR[_inst.RD] = m_GPR[_inst.RA] + m_GPR[_inst.RB];
if (_inst.OE) PanicAlert("OE: addx");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: addx");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::addcx(UGeckoInstruction _inst)
@ -406,8 +453,11 @@ void Interpreter::addcx(UGeckoInstruction _inst)
m_GPR[_inst.RD] = a + b;
SetCarry(Helper_Carry(a,b));
if (_inst.OE) PanicAlert("OE: addcx");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: addcx");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::addex(UGeckoInstruction _inst)
@ -418,8 +468,11 @@ void Interpreter::addex(UGeckoInstruction _inst)
m_GPR[_inst.RD] = a + b + carry;
SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry)));
if (_inst.OE) PanicAlert("OE: addex");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: addex");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::addmex(UGeckoInstruction _inst)
@ -429,8 +482,11 @@ void Interpreter::addmex(UGeckoInstruction _inst)
m_GPR[_inst.RD] = a + carry - 1;
SetCarry(Helper_Carry(a, carry - 1));
if (_inst.OE) PanicAlert("OE: addmex");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: addmex");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::addzex(UGeckoInstruction _inst)
@ -440,28 +496,38 @@ void Interpreter::addzex(UGeckoInstruction _inst)
m_GPR[_inst.RD] = a + carry;
SetCarry(Helper_Carry(a, carry));
if (_inst.OE) PanicAlert("OE: addzex");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: addzex");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::divwx(UGeckoInstruction _inst)
{
s32 a = m_GPR[_inst.RA];
s32 b = m_GPR[_inst.RB];
if (b == 0 || ((u32)a == 0x80000000 && b == -1))
{
if (_inst.OE)
{
// should set OV
PanicAlert("OE: divwx");
}
if (((u32)a & 0x80000000) && b == 0)
m_GPR[_inst.RD] = -1;
else
m_GPR[_inst.RD] = 0;
}
else
{
m_GPR[_inst.RD] = (u32)(a / b);
}
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
@ -473,14 +539,20 @@ void Interpreter::divwux(UGeckoInstruction _inst)
if (b == 0)
{
if (_inst.OE)
{
// should set OV
PanicAlert("OE: divwux");
}
m_GPR[_inst.RD] = 0;
}
else
{
m_GPR[_inst.RD] = a / b;
}
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::mulhwx(UGeckoInstruction _inst)
@ -489,7 +561,9 @@ void Interpreter::mulhwx(UGeckoInstruction _inst)
u32 b = m_GPR[_inst.RB];
u32 d = (u32)((u64)(((s64)(s32)a * (s64)(s32)b) ) >> 32); // This can be done better. Not in plain C/C++ though.
m_GPR[_inst.RD] = d;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::mulhwux(UGeckoInstruction _inst)
@ -498,7 +572,9 @@ void Interpreter::mulhwux(UGeckoInstruction _inst)
u32 b = m_GPR[_inst.RB];
u32 d = (u32)(((u64)a * (u64)b) >> 32);
m_GPR[_inst.RD] = d;
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::mullwx(UGeckoInstruction _inst)
@ -508,26 +584,36 @@ void Interpreter::mullwx(UGeckoInstruction _inst)
u32 d = (u32)((s32)a * (s32)b);
m_GPR[_inst.RD] = d;
if (_inst.OE) PanicAlert("OE: mullwx");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: mullwx");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::negx(UGeckoInstruction _inst)
{
m_GPR[_inst.RD] = (~m_GPR[_inst.RA]) + 1;
if (m_GPR[_inst.RD] == 0x80000000)
{
if (_inst.OE) PanicAlert("OE: negx");
if (_inst.OE)
PanicAlert("OE: negx");
}
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::subfx(UGeckoInstruction _inst)
{
m_GPR[_inst.RD] = m_GPR[_inst.RB] - m_GPR[_inst.RA];
if (_inst.OE) PanicAlert("OE: subfx");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: subfx");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::subfcx(UGeckoInstruction _inst)
@ -537,8 +623,11 @@ void Interpreter::subfcx(UGeckoInstruction _inst)
m_GPR[_inst.RD] = b - a;
SetCarry(a == 0 || Helper_Carry(b, 0-a));
if (_inst.OE) PanicAlert("OE: subfcx");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: subfcx");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
void Interpreter::subfex(UGeckoInstruction _inst)
@ -549,8 +638,11 @@ void Interpreter::subfex(UGeckoInstruction _inst)
m_GPR[_inst.RD] = (~a) + b + carry;
SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry));
if (_inst.OE) PanicAlert("OE: subfex");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: subfex");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
// sub from minus one
@ -561,8 +653,11 @@ void Interpreter::subfmex(UGeckoInstruction _inst)
m_GPR[_inst.RD] = (~a) + carry - 1;
SetCarry(Helper_Carry(~a, carry - 1));
if (_inst.OE) PanicAlert("OE: subfmex");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: subfmex");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}
// sub from zero
@ -573,6 +668,9 @@ void Interpreter::subfzex(UGeckoInstruction _inst)
m_GPR[_inst.RD] = (~a) + carry;
SetCarry(Helper_Carry(~a, carry));
if (_inst.OE) PanicAlert("OE: subfzex");
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
if (_inst.OE)
PanicAlert("OE: subfzex");
if (_inst.Rc)
Helper_UpdateCR0(m_GPR[_inst.RD]);
}

View File

@ -788,9 +788,12 @@ void Interpreter::stwcxd(UGeckoInstruction _inst)
{
// Stores Word Conditional indeXed
u32 uAddress;
if (g_bReserve) {
if (g_bReserve)
{
uAddress = Helper_Get_EA_X(_inst);
if (uAddress == g_reserveAddr) {
if (uAddress == g_reserveAddr)
{
Memory::Write_U32(m_GPR[_inst.RS], uAddress);
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
{

View File

@ -142,13 +142,15 @@ void Interpreter::psq_l(UGeckoInstruction _inst)
(m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;
int c = 4;
if ((ldType == QUANTIZE_U8) || (ldType == QUANTIZE_S8)) c = 0x1;
if ((ldType == QUANTIZE_U16) || (ldType == QUANTIZE_S16)) c = 0x2;
if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8)
c = 0x1;
else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16)
c = 0x2;
if (_inst.W == 0)
{
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
float ps1 = Helper_Dequantize(EA+c, ldType, ldScale);
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
float ps1 = Helper_Dequantize(EA + c, ldType, ldScale);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
@ -158,7 +160,7 @@ void Interpreter::psq_l(UGeckoInstruction _inst)
}
else
{
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
@ -176,13 +178,15 @@ void Interpreter::psq_lu(UGeckoInstruction _inst)
const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12;
int c = 4;
if ((ldType == 4) || (ldType == 6)) c = 0x1;
if ((ldType == 5) || (ldType == 7)) c = 0x2;
if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8)
c = 0x1;
else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16)
c = 0x2;
if (_inst.W == 0)
{
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
float ps1 = Helper_Dequantize( EA+c, ldType, ldScale );
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
float ps1 = Helper_Dequantize(EA + c, ldType, ldScale);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
@ -192,7 +196,7 @@ void Interpreter::psq_lu(UGeckoInstruction _inst)
}
else
{
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
@ -212,17 +216,19 @@ void Interpreter::psq_st(UGeckoInstruction _inst)
(m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;
int c = 4;
if ((stType == 4) || (stType == 6)) c = 0x1;
if ((stType == 5) || (stType == 7)) c = 0x2;
if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
c = 0x1;
else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
c = 0x2;
if (_inst.W == 0)
{
Helper_Quantize( EA, rPS0(_inst.RS), stType, stScale );
Helper_Quantize( EA+c, rPS1(_inst.RS), stType, stScale );
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
}
else
{
Helper_Quantize( EA, rPS0(_inst.RS), stType, stScale );
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
}
}
@ -234,17 +240,19 @@ void Interpreter::psq_stu(UGeckoInstruction _inst)
const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12;
int c = 4;
if ((stType == 4) || (stType == 6)) c = 0x1;
if ((stType == 5) || (stType == 7)) c = 0x2;
if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
c = 0x1;
else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
c = 0x2;
if (_inst.W == 0)
{
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale);
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
}
else
{
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
}
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
@ -261,13 +269,15 @@ void Interpreter::psq_lx(UGeckoInstruction _inst)
const u32 EA = _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB];
int c = 4;
if ((ldType == 4) || (ldType == 6)) c = 0x1;
if ((ldType == 5) || (ldType == 7)) c = 0x2;
if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8)
c = 0x1;
else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16)
c = 0x2;
if (_inst.Wx == 0)
{
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
float ps1 = Helper_Dequantize( EA+c, ldType, ldScale );
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
float ps1 = Helper_Dequantize(EA + c, ldType, ldScale);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
@ -279,7 +289,7 @@ void Interpreter::psq_lx(UGeckoInstruction _inst)
}
else
{
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
float ps1 = 1.0f;
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
@ -300,17 +310,19 @@ void Interpreter::psq_stx(UGeckoInstruction _inst)
const u32 EA = _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB];
int c = 4;
if ((stType == 4) || (stType == 6)) c = 0x1;
if ((stType == 5) || (stType == 7)) c = 0x2;
if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
c = 0x1;
else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
c = 0x2;
if (_inst.Wx == 0)
{
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale);
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
}
else
{
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
}
}
@ -322,13 +334,15 @@ void Interpreter::psq_lux(UGeckoInstruction _inst)
const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB];
int c = 4;
if ((ldType == 4) || (ldType == 6)) c = 0x1;
if ((ldType == 5) || (ldType == 7)) c = 0x2;
if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8)
c = 0x1;
else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16)
c = 0x2;
if (_inst.Wx == 0)
{
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
float ps1 = Helper_Dequantize( EA+c, ldType, ldScale );
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
float ps1 = Helper_Dequantize(EA + c, ldType, ldScale);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
@ -338,7 +352,7 @@ void Interpreter::psq_lux(UGeckoInstruction _inst)
}
else
{
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{
return;
@ -357,17 +371,19 @@ void Interpreter::psq_stux(UGeckoInstruction _inst)
const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB];
int c = 4;
if ((stType == 4) || (stType == 6)) c = 0x1;
if ((stType == 5) || (stType == 7)) c = 0x2;
if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
c = 0x1;
else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
c = 0x2;
if (_inst.Wx == 0)
{
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale);
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
}
else
{
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
}
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
{

View File

@ -15,35 +15,45 @@ void Interpreter::ps_sel(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS0(_inst.FA) >= -0.0 ? rPS0(_inst.FC) : rPS0(_inst.FB);
rPS1(_inst.FD) = rPS1(_inst.FA) >= -0.0 ? rPS1(_inst.FC) : rPS1(_inst.FB);
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_neg(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
riPS1(_inst.FD) = riPS1(_inst.FB) ^ (1ULL << 63);
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_mr(UGeckoInstruction _inst)
{
rPS0(_inst.FD) = rPS0(_inst.FB);
rPS1(_inst.FD) = rPS1(_inst.FB);
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_nabs(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
riPS1(_inst.FD) = riPS1(_inst.FB) | (1ULL << 63);
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_abs(UGeckoInstruction _inst)
{
riPS0(_inst.FD) = riPS0(_inst.FB) &~ (1ULL << 63);
riPS1(_inst.FD) = riPS1(_inst.FB) &~ (1ULL << 63);
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
// These are just moves, double is OK.
@ -53,7 +63,9 @@ void Interpreter::ps_merge00(UGeckoInstruction _inst)
double p1 = rPS0(_inst.FB);
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_merge01(UGeckoInstruction _inst)
@ -62,7 +74,9 @@ void Interpreter::ps_merge01(UGeckoInstruction _inst)
double p1 = rPS1(_inst.FB);
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_merge10(UGeckoInstruction _inst)
@ -71,7 +85,9 @@ void Interpreter::ps_merge10(UGeckoInstruction _inst)
double p1 = rPS0(_inst.FB);
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_merge11(UGeckoInstruction _inst)
@ -80,7 +96,9 @@ void Interpreter::ps_merge11(UGeckoInstruction _inst)
double p1 = rPS1(_inst.FB);
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
// From here on, the real deal.
@ -94,8 +112,14 @@ void Interpreter::ps_div(UGeckoInstruction _inst)
double b = rPS0(_inst.FB);
double &res = rPS0(_inst.FD);
if (a != a) res = a;
else if (b != b) res = b;
if (a != a)
{
res = a;
}
else if (b != b)
{
res = b;
}
else
{
if (b == 0.0)
@ -132,8 +156,14 @@ void Interpreter::ps_div(UGeckoInstruction _inst)
double b = rPS1(_inst.FB);
double &res = rPS1(_inst.FD);
if (a != a) res = a;
else if (b != b) res = b;
if (a != a)
{
res = a;
}
else if (b != b)
{
res = b;
}
else
{
if (b == 0.0)
@ -166,7 +196,9 @@ void Interpreter::ps_div(UGeckoInstruction _inst)
SetFPException(ex_mask);
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_res(UGeckoInstruction _inst)
@ -174,14 +206,18 @@ void Interpreter::ps_res(UGeckoInstruction _inst)
// this code is based on the real hardware tests
double a = rPS0(_inst.FB);
double b = rPS1(_inst.FB);
if (a == 0.0 || b == 0.0)
{
SetFPException(FPSCR_ZX);
}
rPS0(_inst.FD) = ApproximateReciprocal(a);
rPS1(_inst.FD) = ApproximateReciprocal(b);
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_rsqrte(UGeckoInstruction _inst)
@ -200,7 +236,9 @@ void Interpreter::ps_rsqrte(UGeckoInstruction _inst)
rPS1(_inst.FD) = ForceSingle(ApproximateReciprocalSquareRoot(rPS1(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
@ -209,7 +247,9 @@ void Interpreter::ps_sub(UGeckoInstruction _inst)
rPS0(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_sub(rPS1(_inst.FA), rPS1(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_add(UGeckoInstruction _inst)
@ -217,7 +257,9 @@ void Interpreter::ps_add(UGeckoInstruction _inst)
rPS0(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_add(rPS1(_inst.FA), rPS1(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_mul(UGeckoInstruction _inst)
@ -225,7 +267,9 @@ void Interpreter::ps_mul(UGeckoInstruction _inst)
rPS0(_inst.FD) = ForceSingle(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC)));
rPS1(_inst.FD) = ForceSingle(NI_mul(rPS1(_inst.FA), rPS1(_inst.FC)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
@ -234,7 +278,9 @@ void Interpreter::ps_msub(UGeckoInstruction _inst)
rPS0(_inst.FD) = ForceSingle(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_msub(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_madd(UGeckoInstruction _inst)
@ -242,7 +288,9 @@ void Interpreter::ps_madd(UGeckoInstruction _inst)
rPS0(_inst.FD) = ForceSingle(NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
rPS1(_inst.FD) = ForceSingle(NI_madd(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB)));
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_nmsub(UGeckoInstruction _inst)
@ -250,7 +298,9 @@ void Interpreter::ps_nmsub(UGeckoInstruction _inst)
rPS0(_inst.FD) = ForceSingle( -NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ) );
rPS1(_inst.FD) = ForceSingle( -NI_msub( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) );
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_nmadd(UGeckoInstruction _inst)
@ -258,7 +308,9 @@ void Interpreter::ps_nmadd(UGeckoInstruction _inst)
rPS0(_inst.FD) = ForceSingle( -NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ) );
rPS1(_inst.FD) = ForceSingle( -NI_madd( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) );
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_sum0(UGeckoInstruction _inst)
@ -268,7 +320,9 @@ void Interpreter::ps_sum0(UGeckoInstruction _inst)
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_sum1(UGeckoInstruction _inst)
@ -278,7 +332,9 @@ void Interpreter::ps_sum1(UGeckoInstruction _inst)
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
UpdateFPRF(rPS1(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_muls0(UGeckoInstruction _inst)
@ -288,7 +344,9 @@ void Interpreter::ps_muls0(UGeckoInstruction _inst)
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_muls1(UGeckoInstruction _inst)
@ -298,7 +356,9 @@ void Interpreter::ps_muls1(UGeckoInstruction _inst)
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_madds0(UGeckoInstruction _inst)
@ -308,7 +368,9 @@ void Interpreter::ps_madds0(UGeckoInstruction _inst)
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_madds1(UGeckoInstruction _inst)
@ -318,7 +380,9 @@ void Interpreter::ps_madds1(UGeckoInstruction _inst)
rPS0(_inst.FD) = p0;
rPS1(_inst.FD) = p1;
UpdateFPRF(rPS0(_inst.FD));
if (_inst.Rc) Helper_UpdateCR1();
if (_inst.Rc)
Helper_UpdateCR1();
}
void Interpreter::ps_cmpu0(UGeckoInstruction _inst)

View File

@ -54,7 +54,8 @@ void Interpreter::mtfsb0x(UGeckoInstruction _inst)
FPSCR.Hex &= ~b;
FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc");
if (_inst.Rc)
PanicAlert("mtfsb0x: inst_.Rc");
}
void Interpreter::mtfsb1x(UGeckoInstruction _inst)
@ -67,7 +68,8 @@ void Interpreter::mtfsb1x(UGeckoInstruction _inst)
FPSCR.Hex |= b;
FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc");
if (_inst.Rc)
PanicAlert("mtfsb1x: inst_.Rc");
}
void Interpreter::mtfsfix(UGeckoInstruction _inst)
@ -83,7 +85,8 @@ void Interpreter::mtfsfix(UGeckoInstruction _inst)
FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc");
if (_inst.Rc)
PanicAlert("mtfsfix: inst_.Rc");
}
void Interpreter::mtfsfx(UGeckoInstruction _inst)
@ -103,7 +106,8 @@ void Interpreter::mtfsfx(UGeckoInstruction _inst)
FPSCR.Hex = (FPSCR.Hex & ~m) | ((u32)(riPS0(_inst.FB)) & m);
FPSCRtoFPUSettings(FPSCR);
if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc");
if (_inst.Rc)
PanicAlert("mtfsfx: inst_.Rc");
}
void Interpreter::mcrxr(UGeckoInstruction _inst)
@ -129,10 +133,12 @@ void Interpreter::mtcrf(UGeckoInstruction _inst)
{
//TODO: use lookup table? probably not worth it
u32 mask = 0;
for (int i = 0; i < 8; i++) {
for (int i = 0; i < 8; i++)
{
if (crm & (1 << i))
mask |= 0xF << (i*4);
}
SetCR((GetCR() & ~mask) | (m_GPR[_inst.RS] & mask));
}
}
@ -165,7 +171,8 @@ void Interpreter::mtmsr(UGeckoInstruction _inst)
// Segment registers. MMU control.
static void SetSR(int index, u32 value) {
static void SetSR(int index, u32 value)
{
DEBUG_LOG(POWERPC, "%08x: MMU: Segment register %i set to %08x", PowerPC::ppcState.pc, index, value);
PowerPC::ppcState.sr[index] = value;
}
@ -406,7 +413,8 @@ void Interpreter::mcrfs(UGeckoInstruction _inst)
UpdateFPSCR();
u32 fpflags = ((FPSCR.Hex >> (4 * (7 - _inst.CRFS))) & 0xF);
switch (_inst.CRFS) {
switch (_inst.CRFS)
{
case 0:
FPSCR.FX = 0;
FPSCR.OX = 0;
@ -443,5 +451,7 @@ void Interpreter::mffsx(UGeckoInstruction _inst)
UpdateFPSCR();
riPS0(_inst.FD) = (u64)FPSCR.Hex;
if (_inst.Rc) PanicAlert("mffsx: inst_.Rc");
if (_inst.Rc)
PanicAlert("mffsx: inst_.Rc");
}

View File

@ -488,7 +488,9 @@ void InitTables()
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
for (auto& tpl : table63_2)
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
if (m_numInstructions >= 512) {
if (m_numInstructions >= 512)
{
PanicAlert("m_allInstructions underdimensioned");
}