Core: Clean up coding style in the Interpreter
This commit is contained in:
parent
44f751f752
commit
8467c82f79
|
@ -18,7 +18,8 @@
|
||||||
#include "Core/PowerPC/GDBStub.h"
|
#include "Core/PowerPC/GDBStub.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace
|
||||||
|
{
|
||||||
u32 last_pc;
|
u32 last_pc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +33,11 @@ Interpreter::_interpreterInstruction Interpreter::m_opTable31[1024];
|
||||||
Interpreter::_interpreterInstruction Interpreter::m_opTable59[32];
|
Interpreter::_interpreterInstruction Interpreter::m_opTable59[32];
|
||||||
Interpreter::_interpreterInstruction Interpreter::m_opTable63[1024];
|
Interpreter::_interpreterInstruction Interpreter::m_opTable63[1024];
|
||||||
|
|
||||||
void Interpreter::RunTable4(UGeckoInstruction _inst) {m_opTable4 [_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::RunTable19(UGeckoInstruction _inst) { m_opTable19[_inst.SUBOP10](_inst); }
|
||||||
void Interpreter::RunTable31(UGeckoInstruction _inst) {m_opTable31[_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::RunTable59(UGeckoInstruction _inst) { m_opTable59[_inst.SUBOP5 ](_inst); }
|
||||||
void Interpreter::RunTable63(UGeckoInstruction _inst) {m_opTable63[_inst.SUBOP10](_inst);}
|
void Interpreter::RunTable63(UGeckoInstruction _inst) { m_opTable63[_inst.SUBOP10](_inst); }
|
||||||
|
|
||||||
void Interpreter::Init()
|
void Interpreter::Init()
|
||||||
{
|
{
|
||||||
|
@ -116,8 +117,8 @@ int Interpreter::SingleStepInner(void)
|
||||||
if (function == 0)
|
if (function == 0)
|
||||||
{
|
{
|
||||||
#ifdef USE_GDBSTUB
|
#ifdef USE_GDBSTUB
|
||||||
if (gdb_active() && gdb_bp_x(PC)) {
|
if (gdb_active() && gdb_bp_x(PC))
|
||||||
|
{
|
||||||
Host_UpdateDisasmDialog();
|
Host_UpdateDisasmDialog();
|
||||||
|
|
||||||
gdb_signal(SIGTRAP);
|
gdb_signal(SIGTRAP);
|
||||||
|
@ -260,8 +261,10 @@ void Interpreter::Run()
|
||||||
{
|
{
|
||||||
// Write space
|
// Write space
|
||||||
if (j > 0)
|
if (j > 0)
|
||||||
|
{
|
||||||
if (PCVec.at(j) != PCVec.at(j-1) + 4)
|
if (PCVec.at(j) != PCVec.at(j-1) + 4)
|
||||||
NOTICE_LOG(POWERPC, "");
|
NOTICE_LOG(POWERPC, "");
|
||||||
|
}
|
||||||
|
|
||||||
NOTICE_LOG(POWERPC, "PC: 0x%08x", PCVec.at(j));
|
NOTICE_LOG(POWERPC, "PC: 0x%08x", PCVec.at(j));
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ void Interpreter::bx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
if (_inst.LK)
|
if (_inst.LK)
|
||||||
LR = PC + 4;
|
LR = PC + 4;
|
||||||
|
|
||||||
if (_inst.AA)
|
if (_inst.AA)
|
||||||
NPC = SignExt26(_inst.LI << 2);
|
NPC = SignExt26(_inst.LI << 2);
|
||||||
else
|
else
|
||||||
|
@ -41,11 +42,13 @@ void Interpreter::bcx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
if (_inst.LK)
|
if (_inst.LK)
|
||||||
LR = PC + 4;
|
LR = PC + 4;
|
||||||
|
|
||||||
if (_inst.AA)
|
if (_inst.AA)
|
||||||
NPC = SignExt16(_inst.BD << 2);
|
NPC = SignExt16(_inst.BD << 2);
|
||||||
else
|
else
|
||||||
NPC = PC + SignExt16(_inst.BD << 2);
|
NPC = PC + SignExt16(_inst.BD << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EndBlock = true;
|
m_EndBlock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,6 +64,7 @@ void Interpreter::bcctrx(UGeckoInstruction _inst)
|
||||||
if (_inst.LK_3)
|
if (_inst.LK_3)
|
||||||
LR = PC + 4;
|
LR = PC + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EndBlock = true;
|
m_EndBlock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,6 +82,7 @@ void Interpreter::bclrx(UGeckoInstruction _inst)
|
||||||
if (_inst.LK_3)
|
if (_inst.LK_3)
|
||||||
LR = PC + 4;
|
LR = PC + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_EndBlock = true;
|
m_EndBlock = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,8 @@ const u64 PPC_NAN_U64 = 0x7ff8000000000000ull;
|
||||||
const double PPC_NAN = *(double* const)&PPC_NAN_U64;
|
const double PPC_NAN = *(double* const)&PPC_NAN_U64;
|
||||||
|
|
||||||
// the 4 less-significand bits in FPSCR[FPRF]
|
// the 4 less-significand bits in FPSCR[FPRF]
|
||||||
enum FPCC {
|
enum FPCC
|
||||||
|
{
|
||||||
FL = 8, // <
|
FL = 8, // <
|
||||||
FG = 4, // >
|
FG = 4, // >
|
||||||
FE = 2, // =
|
FE = 2, // =
|
||||||
|
@ -264,6 +265,7 @@ inline u64 ConvertToDouble(u32 _x)
|
||||||
frac <<= 1;
|
frac <<= 1;
|
||||||
exp -= 1;
|
exp -= 1;
|
||||||
} while ((frac & 0x00800000) == 0);
|
} while ((frac & 0x00800000) == 0);
|
||||||
|
|
||||||
return ((x & 0x80000000) << 32) | (exp << 52) | ((frac & 0x007fffff) << 29);
|
return ((x & 0x80000000) << 32) | (exp << 52) | ((frac & 0x007fffff) << 29);
|
||||||
}
|
}
|
||||||
else // QNaN, SNaN or Zero
|
else // QNaN, SNaN or Zero
|
||||||
|
@ -303,6 +305,7 @@ inline double ApproximateReciprocal(double val)
|
||||||
double valf;
|
double valf;
|
||||||
s64 vali;
|
s64 vali;
|
||||||
};
|
};
|
||||||
|
|
||||||
valf = val;
|
valf = val;
|
||||||
s64 mantissa = vali & ((1LL << 52) - 1);
|
s64 mantissa = vali & ((1LL << 52) - 1);
|
||||||
s64 sign = vali & (1ULL << 63);
|
s64 sign = vali & (1ULL << 63);
|
||||||
|
@ -312,6 +315,7 @@ inline double ApproximateReciprocal(double val)
|
||||||
if (mantissa == 0 && exponent == 0)
|
if (mantissa == 0 && exponent == 0)
|
||||||
return sign ? -std::numeric_limits<double>::infinity() :
|
return sign ? -std::numeric_limits<double>::infinity() :
|
||||||
std::numeric_limits<double>::infinity();
|
std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
// Special case NaN-ish numbers
|
// Special case NaN-ish numbers
|
||||||
if (exponent == (0x7FFLL << 52))
|
if (exponent == (0x7FFLL << 52))
|
||||||
{
|
{
|
||||||
|
@ -319,10 +323,12 @@ inline double ApproximateReciprocal(double val)
|
||||||
return sign ? -0.0 : 0.0;
|
return sign ? -0.0 : 0.0;
|
||||||
return 0.0 + valf;
|
return 0.0 + valf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case small inputs
|
// Special case small inputs
|
||||||
if (exponent < (895LL << 52))
|
if (exponent < (895LL << 52))
|
||||||
return sign ? -std::numeric_limits<float>::max() :
|
return sign ? -std::numeric_limits<float>::max() :
|
||||||
std::numeric_limits<float>::max();
|
std::numeric_limits<float>::max();
|
||||||
|
|
||||||
// Special case large inputs
|
// Special case large inputs
|
||||||
if (exponent >= (1149LL << 52))
|
if (exponent >= (1149LL << 52))
|
||||||
return sign ? -0.0f : 0.0f;
|
return sign ? -0.0f : 0.0f;
|
||||||
|
@ -379,10 +385,13 @@ inline double ApproximateReciprocalSquareRoot(double val)
|
||||||
{
|
{
|
||||||
if (sign)
|
if (sign)
|
||||||
return std::numeric_limits<double>::quiet_NaN();
|
return std::numeric_limits<double>::quiet_NaN();
|
||||||
|
|
||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0.0 + valf;
|
return 0.0 + valf;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Negative numbers return NaN
|
// Negative numbers return NaN
|
||||||
if (sign)
|
if (sign)
|
||||||
return std::numeric_limits<double>::quiet_NaN();
|
return std::numeric_limits<double>::quiet_NaN();
|
||||||
|
|
|
@ -87,6 +87,7 @@ void Interpreter::Helper_FloatCompareUnordered(UGeckoInstruction _inst, double f
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FPSCR.FPRF = compareResult;
|
FPSCR.FPRF = compareResult;
|
||||||
SetCRField(_inst.CRFD, compareResult);
|
SetCRField(_inst.CRFD, compareResult);
|
||||||
}
|
}
|
||||||
|
@ -106,6 +107,7 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
const double b = rPS0(_inst.FB);
|
const double b = rPS0(_inst.FB);
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
if (b > (double)0x7fffffff)
|
if (b > (double)0x7fffffff)
|
||||||
{
|
{
|
||||||
value = 0x7fffffff;
|
value = 0x7fffffff;
|
||||||
|
@ -129,7 +131,11 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double t = b + 0.5;
|
double t = b + 0.5;
|
||||||
i = (s32)t;
|
i = (s32)t;
|
||||||
if (t - i < 0 || (t - i == 0 && b > 0)) i--;
|
|
||||||
|
if (t - i < 0 || (t - i == 0 && b > 0))
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 1: // zero
|
case 1: // zero
|
||||||
|
@ -137,11 +143,17 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
|
||||||
break;
|
break;
|
||||||
case 2: // +inf
|
case 2: // +inf
|
||||||
i = (s32)b;
|
i = (s32)b;
|
||||||
if (b - i > 0) i++;
|
if (b - i > 0)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 3: // -inf
|
case 3: // -inf
|
||||||
i = (s32)b;
|
i = (s32)b;
|
||||||
if (b - i < 0) i--;
|
if (b - i < 0)
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
value = (u32)i;
|
value = (u32)i;
|
||||||
|
@ -157,6 +169,7 @@ void Interpreter::fctiwx(UGeckoInstruction _inst)
|
||||||
FPSCR.FR = fabs(di) > fabs(b);
|
FPSCR.FR = fabs(di) > fabs(b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// based on HW tests
|
// based on HW tests
|
||||||
// FPRF is not affected
|
// FPRF is not affected
|
||||||
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
|
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
|
||||||
|
@ -171,6 +184,7 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
const double b = rPS0(_inst.FB);
|
const double b = rPS0(_inst.FB);
|
||||||
u32 value;
|
u32 value;
|
||||||
|
|
||||||
if (b > (double)0x7fffffff)
|
if (b > (double)0x7fffffff)
|
||||||
{
|
{
|
||||||
value = 0x7fffffff;
|
value = 0x7fffffff;
|
||||||
|
@ -201,6 +215,7 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
value = (u32)i;
|
value = (u32)i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// based on HW tests
|
// based on HW tests
|
||||||
// FPRF is not affected
|
// FPRF is not affected
|
||||||
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
|
riPS0(_inst.FD) = 0xfff8000000000000ull | value;
|
||||||
|
@ -213,36 +228,46 @@ void Interpreter::fctiwzx(UGeckoInstruction _inst)
|
||||||
void Interpreter::fmrx(UGeckoInstruction _inst)
|
void Interpreter::fmrx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
riPS0(_inst.FD) = riPS0(_inst.FB);
|
riPS0(_inst.FD) = riPS0(_inst.FB);
|
||||||
|
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fabsx(UGeckoInstruction _inst)
|
void Interpreter::fabsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = fabs(rPS0(_inst.FB));
|
rPS0(_inst.FD) = fabs(rPS0(_inst.FB));
|
||||||
|
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fnabsx(UGeckoInstruction _inst)
|
void Interpreter::fnabsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
|
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
|
||||||
|
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fnegx(UGeckoInstruction _inst)
|
void Interpreter::fnegx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
|
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
|
||||||
|
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fselx(UGeckoInstruction _inst)
|
void Interpreter::fselx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB);
|
rPS0(_inst.FD) = (rPS0(_inst.FA) >= -0.0) ? rPS0(_inst.FC) : rPS0(_inst.FB);
|
||||||
|
|
||||||
// This is a binary instruction. Does not alter FPSCR
|
// This is a binary instruction. Does not alter FPSCR
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
// !!! warning !!!
|
// !!! warning !!!
|
||||||
|
@ -266,7 +291,9 @@ void Interpreter::fmulx(UGeckoInstruction _inst)
|
||||||
FPSCR.FI = 0; // are these flags important?
|
FPSCR.FI = 0; // are these flags important?
|
||||||
FPSCR.FR = 0;
|
FPSCR.FR = 0;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
void Interpreter::fmulsx(UGeckoInstruction _inst)
|
void Interpreter::fmulsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
|
@ -276,7 +303,9 @@ void Interpreter::fmulsx(UGeckoInstruction _inst)
|
||||||
FPSCR.FI = 0;
|
FPSCR.FI = 0;
|
||||||
FPSCR.FR = 0;
|
FPSCR.FR = 0;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fmaddx(UGeckoInstruction _inst)
|
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) ));
|
double result = ForceDouble(NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
|
||||||
rPS0(_inst.FD) = result;
|
rPS0(_inst.FD) = result;
|
||||||
UpdateFPRF(result);
|
UpdateFPRF(result);
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fmaddsx(UGeckoInstruction _inst)
|
void Interpreter::fmaddsx(UGeckoInstruction _inst)
|
||||||
|
@ -294,7 +325,9 @@ void Interpreter::fmaddsx(UGeckoInstruction _inst)
|
||||||
FPSCR.FI = d_value != rPS0(_inst.FD);
|
FPSCR.FI = d_value != rPS0(_inst.FD);
|
||||||
FPSCR.FR = 0;
|
FPSCR.FR = 0;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
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)));
|
rPS0(_inst.FD) = ForceDouble(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
void Interpreter::faddsx(UGeckoInstruction _inst)
|
void Interpreter::faddsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
|
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fdivx(UGeckoInstruction _inst)
|
void Interpreter::fdivx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double a = rPS0(_inst.FA);
|
double a = rPS0(_inst.FA);
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
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
|
else
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = ForceDouble(a / b);
|
rPS0(_inst.FD) = ForceDouble(a / b);
|
||||||
|
@ -339,16 +383,25 @@ void Interpreter::fdivx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
|
|
||||||
// FR,FI,OX,UX???
|
// FR,FI,OX,UX???
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
void Interpreter::fdivsx(UGeckoInstruction _inst)
|
void Interpreter::fdivsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double a = rPS0(_inst.FA);
|
double a = rPS0(_inst.FA);
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
double res;
|
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
|
else
|
||||||
{
|
{
|
||||||
res = ForceSingle(a / b);
|
res = ForceSingle(a / b);
|
||||||
|
@ -370,9 +423,12 @@ void Interpreter::fdivsx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) = res;
|
rPS0(_inst.FD) = rPS1(_inst.FD) = res;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Single precision only.
|
// Single precision only.
|
||||||
|
@ -380,17 +436,22 @@ void Interpreter::fresx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) = ApproximateReciprocal(b);
|
rPS0(_inst.FD) = rPS1(_inst.FD) = ApproximateReciprocal(b);
|
||||||
|
|
||||||
if (b == 0.0)
|
if (b == 0.0)
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_ZX);
|
SetFPException(FPSCR_ZX);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::frsqrtex(UGeckoInstruction _inst)
|
void Interpreter::frsqrtex(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
|
|
||||||
if (b < 0.0)
|
if (b < 0.0)
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_VXSQRT);
|
SetFPException(FPSCR_VXSQRT);
|
||||||
|
@ -399,45 +460,59 @@ void Interpreter::frsqrtex(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_ZX);
|
SetFPException(FPSCR_ZX);
|
||||||
}
|
}
|
||||||
|
|
||||||
rPS0(_inst.FD) = ApproximateReciprocalSquareRoot(b);
|
rPS0(_inst.FD) = ApproximateReciprocalSquareRoot(b);
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fmsubx(UGeckoInstruction _inst)
|
void Interpreter::fmsubx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = ForceDouble(NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
|
rPS0(_inst.FD) = ForceDouble(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fmsubsx(UGeckoInstruction _inst)
|
void Interpreter::fmsubsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
||||||
ForceSingle( NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ));
|
ForceSingle(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fnmaddx(UGeckoInstruction _inst)
|
void Interpreter::fnmaddx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = ForceDouble(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
rPS0(_inst.FD) = ForceDouble(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fnmaddsx(UGeckoInstruction _inst)
|
void Interpreter::fnmaddsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
||||||
ForceSingle(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
ForceSingle(-NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fnmsubx(UGeckoInstruction _inst)
|
void Interpreter::fnmsubx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = ForceDouble(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
rPS0(_inst.FD) = ForceDouble(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
// fnmsubsx does not handle QNAN properly - see NI_msub
|
// fnmsubsx does not handle QNAN properly - see NI_msub
|
||||||
|
@ -446,21 +521,27 @@ void Interpreter::fnmsubsx(UGeckoInstruction _inst)
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
rPS0(_inst.FD) = rPS1(_inst.FD) =
|
||||||
ForceSingle(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
ForceSingle(-NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fsubx(UGeckoInstruction _inst)
|
void Interpreter::fsubx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = ForceDouble(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
|
rPS0(_inst.FD) = ForceDouble(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fsubsx(UGeckoInstruction _inst)
|
void Interpreter::fsubsx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
|
rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::fsqrtx(UGeckoInstruction _inst)
|
void Interpreter::fsqrtx(UGeckoInstruction _inst)
|
||||||
|
@ -468,10 +549,15 @@ void Interpreter::fsqrtx(UGeckoInstruction _inst)
|
||||||
// GEKKO is not supposed to support this instruction.
|
// GEKKO is not supposed to support this instruction.
|
||||||
// PanicAlert("fsqrtx");
|
// PanicAlert("fsqrtx");
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
if (b < 0.0) {
|
|
||||||
|
if (b < 0.0)
|
||||||
|
{
|
||||||
FPSCR.VXSQRT = 1;
|
FPSCR.VXSQRT = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
rPS0(_inst.FD) = sqrt(b);
|
rPS0(_inst.FD) = sqrt(b);
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,10 +95,17 @@ void Interpreter::cmpli(UGeckoInstruction _inst)
|
||||||
u32 a = m_GPR[_inst.RA];
|
u32 a = m_GPR[_inst.RA];
|
||||||
u32 b = _inst.UIMM;
|
u32 b = _inst.UIMM;
|
||||||
int f;
|
int f;
|
||||||
if (a < b) f = 0x8;
|
|
||||||
else if (a > b) f = 0x4;
|
if (a < b)
|
||||||
else f = 0x2; //equals
|
f = 0x8;
|
||||||
if (GetXER_SO()) f |= 0x1;
|
else if (a > b)
|
||||||
|
f = 0x4;
|
||||||
|
else
|
||||||
|
f = 0x2; //equals
|
||||||
|
|
||||||
|
if (GetXER_SO())
|
||||||
|
f |= 0x1;
|
||||||
|
|
||||||
SetCRField(_inst.CRFD, f);
|
SetCRField(_inst.CRFD, f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,14 +177,18 @@ void Interpreter::rlwimix(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
|
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
|
||||||
m_GPR[_inst.RA] = (m_GPR[_inst.RA] & ~mask) | (_rotl(m_GPR[_inst.RS],_inst.SH) & mask);
|
m_GPR[_inst.RA] = (m_GPR[_inst.RA] & ~mask) | (_rotl(m_GPR[_inst.RS],_inst.SH) & mask);
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::rlwinmx(UGeckoInstruction _inst)
|
void Interpreter::rlwinmx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
|
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
|
||||||
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS],_inst.SH) & mask;
|
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS],_inst.SH) & mask;
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::rlwnmx(UGeckoInstruction _inst)
|
void Interpreter::rlwnmx(UGeckoInstruction _inst)
|
||||||
|
@ -185,21 +196,24 @@ void Interpreter::rlwnmx(UGeckoInstruction _inst)
|
||||||
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
|
u32 mask = Helper_Mask(_inst.MB,_inst.ME);
|
||||||
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS], m_GPR[_inst.RB] & 0x1F) & mask;
|
m_GPR[_inst.RA] = _rotl(m_GPR[_inst.RS], m_GPR[_inst.RB] & 0x1F) & mask;
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::andx(UGeckoInstruction _inst)
|
void Interpreter::andx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = m_GPR[_inst.RS] & m_GPR[_inst.RB];
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] & m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::andcx(UGeckoInstruction _inst)
|
void Interpreter::andcx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = m_GPR[_inst.RS] & ~m_GPR[_inst.RB];
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] & ~m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::cmp(UGeckoInstruction _inst)
|
void Interpreter::cmp(UGeckoInstruction _inst)
|
||||||
|
@ -207,10 +221,16 @@ void Interpreter::cmp(UGeckoInstruction _inst)
|
||||||
s32 a = (s32)m_GPR[_inst.RA];
|
s32 a = (s32)m_GPR[_inst.RA];
|
||||||
s32 b = (s32)m_GPR[_inst.RB];
|
s32 b = (s32)m_GPR[_inst.RB];
|
||||||
int fTemp = 0x8; // a < b
|
int fTemp = 0x8; // a < b
|
||||||
|
|
||||||
// if (a < b) fTemp = 0x8; else
|
// if (a < b) fTemp = 0x8; else
|
||||||
if (a > b) fTemp = 0x4;
|
if (a > b)
|
||||||
else if (a == b) fTemp = 0x2;
|
fTemp = 0x4;
|
||||||
if (GetXER_SO()) PanicAlert("cmp getting overflow flag"); // fTemp |= 0x1
|
else if (a == b)
|
||||||
|
fTemp = 0x2;
|
||||||
|
|
||||||
|
if (GetXER_SO())
|
||||||
|
PanicAlert("cmp getting overflow flag"); // fTemp |= 0x1
|
||||||
|
|
||||||
SetCRField(_inst.CRFD, fTemp);
|
SetCRField(_inst.CRFD, fTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,9 +241,14 @@ void Interpreter::cmpl(UGeckoInstruction _inst)
|
||||||
u32 fTemp = 0x8; // a < b
|
u32 fTemp = 0x8; // a < b
|
||||||
|
|
||||||
// if (a < b) fTemp = 0x8;else
|
// if (a < b) fTemp = 0x8;else
|
||||||
if (a > b) fTemp = 0x4;
|
if (a > b)
|
||||||
else if (a == b) fTemp = 0x2;
|
fTemp = 0x4;
|
||||||
if (GetXER_SO()) PanicAlert("cmpl getting overflow flag"); // fTemp |= 0x1;
|
else if (a == b)
|
||||||
|
fTemp = 0x2;
|
||||||
|
|
||||||
|
if (GetXER_SO())
|
||||||
|
PanicAlert("cmpl getting overflow flag"); // fTemp |= 0x1;
|
||||||
|
|
||||||
SetCRField(_inst.CRFD, fTemp);
|
SetCRField(_inst.CRFD, fTemp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,61 +256,74 @@ void Interpreter::cntlzwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
u32 val = m_GPR[_inst.RS];
|
u32 val = m_GPR[_inst.RS];
|
||||||
u32 mask = 0x80000000;
|
u32 mask = 0x80000000;
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (; i < 32; i++, mask >>= 1)
|
for (; i < 32; i++, mask >>= 1)
|
||||||
|
{
|
||||||
if (val & mask)
|
if (val & mask)
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
m_GPR[_inst.RA] = i;
|
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)
|
void Interpreter::eqvx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] ^ m_GPR[_inst.RB]);
|
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] ^ m_GPR[_inst.RB]);
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::extsbx(UGeckoInstruction _inst)
|
void Interpreter::extsbx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = (u32)(s32)(s8)m_GPR[_inst.RS];
|
m_GPR[_inst.RA] = (u32)(s32)(s8)m_GPR[_inst.RS];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::extshx(UGeckoInstruction _inst)
|
void Interpreter::extshx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = (u32)(s32)(s16)m_GPR[_inst.RS];
|
m_GPR[_inst.RA] = (u32)(s32)(s16)m_GPR[_inst.RS];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::nandx(UGeckoInstruction _inst)
|
void Interpreter::nandx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] & m_GPR[_inst.RB]);
|
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] & m_GPR[_inst.RB]);
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::norx(UGeckoInstruction _inst)
|
void Interpreter::norx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] | m_GPR[_inst.RB]);
|
m_GPR[_inst.RA] = ~(m_GPR[_inst.RS] | m_GPR[_inst.RB]);
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::orx(UGeckoInstruction _inst)
|
void Interpreter::orx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = m_GPR[_inst.RS] | m_GPR[_inst.RB];
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] | m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::orcx(UGeckoInstruction _inst)
|
void Interpreter::orcx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RA] = m_GPR[_inst.RS] | (~m_GPR[_inst.RB]);
|
m_GPR[_inst.RA] = m_GPR[_inst.RS] | (~m_GPR[_inst.RB]);
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::slwx(UGeckoInstruction _inst)
|
void Interpreter::slwx(UGeckoInstruction _inst)
|
||||||
|
@ -293,12 +331,14 @@ void Interpreter::slwx(UGeckoInstruction _inst)
|
||||||
u32 amount = m_GPR[_inst.RB];
|
u32 amount = m_GPR[_inst.RB];
|
||||||
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : m_GPR[_inst.RS] << amount;
|
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : m_GPR[_inst.RS] << amount;
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::srawx(UGeckoInstruction _inst)
|
void Interpreter::srawx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
int rb = m_GPR[_inst.RB];
|
int rb = m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (rb & 0x20)
|
if (rb & 0x20)
|
||||||
{
|
{
|
||||||
if (m_GPR[_inst.RS] & 0x80000000)
|
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)
|
void Interpreter::srawix(UGeckoInstruction _inst)
|
||||||
|
@ -353,7 +394,8 @@ void Interpreter::srawix(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RA] = m_GPR[_inst.RS];
|
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)
|
void Interpreter::srwx(UGeckoInstruction _inst)
|
||||||
|
@ -361,7 +403,8 @@ void Interpreter::srwx(UGeckoInstruction _inst)
|
||||||
u32 amount = m_GPR[_inst.RB];
|
u32 amount = m_GPR[_inst.RB];
|
||||||
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> (amount & 0x1f));
|
m_GPR[_inst.RA] = (amount & 0x20) ? 0 : (m_GPR[_inst.RS] >> (amount & 0x1f));
|
||||||
|
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RA]);
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RA]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::tw(UGeckoInstruction _inst)
|
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];
|
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)
|
void Interpreter::addx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RD] = m_GPR[_inst.RA] + m_GPR[_inst.RB];
|
m_GPR[_inst.RD] = m_GPR[_inst.RA] + m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: addx");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: addx");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::addcx(UGeckoInstruction _inst)
|
void Interpreter::addcx(UGeckoInstruction _inst)
|
||||||
|
@ -406,8 +453,11 @@ void Interpreter::addcx(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = a + b;
|
m_GPR[_inst.RD] = a + b;
|
||||||
SetCarry(Helper_Carry(a,b));
|
SetCarry(Helper_Carry(a,b));
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: addcx");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: addcx");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::addex(UGeckoInstruction _inst)
|
void Interpreter::addex(UGeckoInstruction _inst)
|
||||||
|
@ -418,8 +468,11 @@ void Interpreter::addex(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = a + b + carry;
|
m_GPR[_inst.RD] = a + b + carry;
|
||||||
SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry)));
|
SetCarry(Helper_Carry(a, b) || (carry != 0 && Helper_Carry(a + b, carry)));
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: addex");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: addex");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::addmex(UGeckoInstruction _inst)
|
void Interpreter::addmex(UGeckoInstruction _inst)
|
||||||
|
@ -429,8 +482,11 @@ void Interpreter::addmex(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = a + carry - 1;
|
m_GPR[_inst.RD] = a + carry - 1;
|
||||||
SetCarry(Helper_Carry(a, carry - 1));
|
SetCarry(Helper_Carry(a, carry - 1));
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: addmex");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: addmex");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::addzex(UGeckoInstruction _inst)
|
void Interpreter::addzex(UGeckoInstruction _inst)
|
||||||
|
@ -440,28 +496,38 @@ void Interpreter::addzex(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = a + carry;
|
m_GPR[_inst.RD] = a + carry;
|
||||||
SetCarry(Helper_Carry(a, carry));
|
SetCarry(Helper_Carry(a, carry));
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: addzex");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: addzex");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::divwx(UGeckoInstruction _inst)
|
void Interpreter::divwx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
s32 a = m_GPR[_inst.RA];
|
s32 a = m_GPR[_inst.RA];
|
||||||
s32 b = m_GPR[_inst.RB];
|
s32 b = m_GPR[_inst.RB];
|
||||||
|
|
||||||
if (b == 0 || ((u32)a == 0x80000000 && b == -1))
|
if (b == 0 || ((u32)a == 0x80000000 && b == -1))
|
||||||
{
|
{
|
||||||
if (_inst.OE)
|
if (_inst.OE)
|
||||||
|
{
|
||||||
// should set OV
|
// should set OV
|
||||||
PanicAlert("OE: divwx");
|
PanicAlert("OE: divwx");
|
||||||
|
}
|
||||||
|
|
||||||
if (((u32)a & 0x80000000) && b == 0)
|
if (((u32)a & 0x80000000) && b == 0)
|
||||||
m_GPR[_inst.RD] = -1;
|
m_GPR[_inst.RD] = -1;
|
||||||
else
|
else
|
||||||
m_GPR[_inst.RD] = 0;
|
m_GPR[_inst.RD] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_GPR[_inst.RD] = (u32)(a / b);
|
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 (b == 0)
|
||||||
{
|
{
|
||||||
if (_inst.OE)
|
if (_inst.OE)
|
||||||
|
{
|
||||||
// should set OV
|
// should set OV
|
||||||
PanicAlert("OE: divwux");
|
PanicAlert("OE: divwux");
|
||||||
|
}
|
||||||
|
|
||||||
m_GPR[_inst.RD] = 0;
|
m_GPR[_inst.RD] = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
m_GPR[_inst.RD] = a / b;
|
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)
|
void Interpreter::mulhwx(UGeckoInstruction _inst)
|
||||||
|
@ -489,7 +561,9 @@ void Interpreter::mulhwx(UGeckoInstruction _inst)
|
||||||
u32 b = m_GPR[_inst.RB];
|
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.
|
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;
|
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)
|
void Interpreter::mulhwux(UGeckoInstruction _inst)
|
||||||
|
@ -498,7 +572,9 @@ void Interpreter::mulhwux(UGeckoInstruction _inst)
|
||||||
u32 b = m_GPR[_inst.RB];
|
u32 b = m_GPR[_inst.RB];
|
||||||
u32 d = (u32)(((u64)a * (u64)b) >> 32);
|
u32 d = (u32)(((u64)a * (u64)b) >> 32);
|
||||||
m_GPR[_inst.RD] = d;
|
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)
|
void Interpreter::mullwx(UGeckoInstruction _inst)
|
||||||
|
@ -508,26 +584,36 @@ void Interpreter::mullwx(UGeckoInstruction _inst)
|
||||||
u32 d = (u32)((s32)a * (s32)b);
|
u32 d = (u32)((s32)a * (s32)b);
|
||||||
m_GPR[_inst.RD] = d;
|
m_GPR[_inst.RD] = d;
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: mullwx");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: mullwx");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::negx(UGeckoInstruction _inst)
|
void Interpreter::negx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RD] = (~m_GPR[_inst.RA]) + 1;
|
m_GPR[_inst.RD] = (~m_GPR[_inst.RA]) + 1;
|
||||||
|
|
||||||
if (m_GPR[_inst.RD] == 0x80000000)
|
if (m_GPR[_inst.RD] == 0x80000000)
|
||||||
{
|
{
|
||||||
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)
|
void Interpreter::subfx(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
m_GPR[_inst.RD] = m_GPR[_inst.RB] - m_GPR[_inst.RA];
|
m_GPR[_inst.RD] = m_GPR[_inst.RB] - m_GPR[_inst.RA];
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: subfx");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: subfx");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::subfcx(UGeckoInstruction _inst)
|
void Interpreter::subfcx(UGeckoInstruction _inst)
|
||||||
|
@ -537,8 +623,11 @@ void Interpreter::subfcx(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = b - a;
|
m_GPR[_inst.RD] = b - a;
|
||||||
SetCarry(a == 0 || Helper_Carry(b, 0-a));
|
SetCarry(a == 0 || Helper_Carry(b, 0-a));
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: subfcx");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: subfcx");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::subfex(UGeckoInstruction _inst)
|
void Interpreter::subfex(UGeckoInstruction _inst)
|
||||||
|
@ -549,8 +638,11 @@ void Interpreter::subfex(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = (~a) + b + carry;
|
m_GPR[_inst.RD] = (~a) + b + carry;
|
||||||
SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry));
|
SetCarry(Helper_Carry(~a, b) || Helper_Carry((~a) + b, carry));
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: subfex");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: subfex");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sub from minus one
|
// sub from minus one
|
||||||
|
@ -561,8 +653,11 @@ void Interpreter::subfmex(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = (~a) + carry - 1;
|
m_GPR[_inst.RD] = (~a) + carry - 1;
|
||||||
SetCarry(Helper_Carry(~a, carry - 1));
|
SetCarry(Helper_Carry(~a, carry - 1));
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: subfmex");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: subfmex");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// sub from zero
|
// sub from zero
|
||||||
|
@ -573,6 +668,9 @@ void Interpreter::subfzex(UGeckoInstruction _inst)
|
||||||
m_GPR[_inst.RD] = (~a) + carry;
|
m_GPR[_inst.RD] = (~a) + carry;
|
||||||
SetCarry(Helper_Carry(~a, carry));
|
SetCarry(Helper_Carry(~a, carry));
|
||||||
|
|
||||||
if (_inst.OE) PanicAlert("OE: subfzex");
|
if (_inst.OE)
|
||||||
if (_inst.Rc) Helper_UpdateCR0(m_GPR[_inst.RD]);
|
PanicAlert("OE: subfzex");
|
||||||
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR0(m_GPR[_inst.RD]);
|
||||||
}
|
}
|
||||||
|
|
|
@ -788,9 +788,12 @@ void Interpreter::stwcxd(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
// Stores Word Conditional indeXed
|
// Stores Word Conditional indeXed
|
||||||
u32 uAddress;
|
u32 uAddress;
|
||||||
if (g_bReserve) {
|
if (g_bReserve)
|
||||||
|
{
|
||||||
uAddress = Helper_Get_EA_X(_inst);
|
uAddress = Helper_Get_EA_X(_inst);
|
||||||
if (uAddress == g_reserveAddr) {
|
|
||||||
|
if (uAddress == g_reserveAddr)
|
||||||
|
{
|
||||||
Memory::Write_U32(m_GPR[_inst.RS], uAddress);
|
Memory::Write_U32(m_GPR[_inst.RS], uAddress);
|
||||||
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
if (!(PowerPC::ppcState.Exceptions & EXCEPTION_DSI))
|
||||||
{
|
{
|
||||||
|
|
|
@ -142,13 +142,15 @@ void Interpreter::psq_l(UGeckoInstruction _inst)
|
||||||
(m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;
|
(m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;
|
||||||
|
|
||||||
int c = 4;
|
int c = 4;
|
||||||
if ((ldType == QUANTIZE_U8) || (ldType == QUANTIZE_S8)) c = 0x1;
|
if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8)
|
||||||
if ((ldType == QUANTIZE_U16) || (ldType == QUANTIZE_S16)) c = 0x2;
|
c = 0x1;
|
||||||
|
else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16)
|
||||||
|
c = 0x2;
|
||||||
|
|
||||||
if (_inst.W == 0)
|
if (_inst.W == 0)
|
||||||
{
|
{
|
||||||
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
|
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
|
||||||
float ps1 = Helper_Dequantize(EA+c, ldType, ldScale);
|
float ps1 = Helper_Dequantize(EA + c, ldType, ldScale);
|
||||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -176,13 +178,15 @@ void Interpreter::psq_lu(UGeckoInstruction _inst)
|
||||||
const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12;
|
const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12;
|
||||||
|
|
||||||
int c = 4;
|
int c = 4;
|
||||||
if ((ldType == 4) || (ldType == 6)) c = 0x1;
|
if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8)
|
||||||
if ((ldType == 5) || (ldType == 7)) c = 0x2;
|
c = 0x1;
|
||||||
|
else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16)
|
||||||
|
c = 0x2;
|
||||||
|
|
||||||
if (_inst.W == 0)
|
if (_inst.W == 0)
|
||||||
{
|
{
|
||||||
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
|
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
|
||||||
float ps1 = Helper_Dequantize( EA+c, ldType, ldScale );
|
float ps1 = Helper_Dequantize(EA + c, ldType, ldScale);
|
||||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -192,7 +196,7 @@ void Interpreter::psq_lu(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
|
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
|
||||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -212,17 +216,19 @@ void Interpreter::psq_st(UGeckoInstruction _inst)
|
||||||
(m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;
|
(m_GPR[_inst.RA] + _inst.SIMM_12) : (u32)_inst.SIMM_12;
|
||||||
|
|
||||||
int c = 4;
|
int c = 4;
|
||||||
if ((stType == 4) || (stType == 6)) c = 0x1;
|
if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
|
||||||
if ((stType == 5) || (stType == 7)) c = 0x2;
|
c = 0x1;
|
||||||
|
else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
|
||||||
|
c = 0x2;
|
||||||
|
|
||||||
if (_inst.W == 0)
|
if (_inst.W == 0)
|
||||||
{
|
{
|
||||||
Helper_Quantize( EA, rPS0(_inst.RS), stType, stScale );
|
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
|
||||||
Helper_Quantize( EA+c, rPS1(_inst.RS), stType, stScale );
|
Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Helper_Quantize( EA, rPS0(_inst.RS), stType, stScale );
|
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,13 +240,15 @@ void Interpreter::psq_stu(UGeckoInstruction _inst)
|
||||||
const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12;
|
const u32 EA = m_GPR[_inst.RA] + _inst.SIMM_12;
|
||||||
|
|
||||||
int c = 4;
|
int c = 4;
|
||||||
if ((stType == 4) || (stType == 6)) c = 0x1;
|
if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
|
||||||
if ((stType == 5) || (stType == 7)) c = 0x2;
|
c = 0x1;
|
||||||
|
else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
|
||||||
|
c = 0x2;
|
||||||
|
|
||||||
if (_inst.W == 0)
|
if (_inst.W == 0)
|
||||||
{
|
{
|
||||||
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
|
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
|
||||||
Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale);
|
Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -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];
|
const u32 EA = _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB];
|
||||||
|
|
||||||
int c = 4;
|
int c = 4;
|
||||||
if ((ldType == 4) || (ldType == 6)) c = 0x1;
|
if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8)
|
||||||
if ((ldType == 5) || (ldType == 7)) c = 0x2;
|
c = 0x1;
|
||||||
|
else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16)
|
||||||
|
c = 0x2;
|
||||||
|
|
||||||
if (_inst.Wx == 0)
|
if (_inst.Wx == 0)
|
||||||
{
|
{
|
||||||
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
|
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
|
||||||
float ps1 = Helper_Dequantize( EA+c, ldType, ldScale );
|
float ps1 = Helper_Dequantize(EA + c, ldType, ldScale);
|
||||||
|
|
||||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||||
{
|
{
|
||||||
|
@ -279,7 +289,7 @@ void Interpreter::psq_lx(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
|
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
|
||||||
float ps1 = 1.0f;
|
float ps1 = 1.0f;
|
||||||
|
|
||||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||||
|
@ -300,13 +310,15 @@ void Interpreter::psq_stx(UGeckoInstruction _inst)
|
||||||
const u32 EA = _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB];
|
const u32 EA = _inst.RA ? (m_GPR[_inst.RA] + m_GPR[_inst.RB]) : m_GPR[_inst.RB];
|
||||||
|
|
||||||
int c = 4;
|
int c = 4;
|
||||||
if ((stType == 4) || (stType == 6)) c = 0x1;
|
if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
|
||||||
if ((stType == 5) || (stType == 7)) c = 0x2;
|
c = 0x1;
|
||||||
|
else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
|
||||||
|
c = 0x2;
|
||||||
|
|
||||||
if (_inst.Wx == 0)
|
if (_inst.Wx == 0)
|
||||||
{
|
{
|
||||||
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
|
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
|
||||||
Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale);
|
Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -322,13 +334,15 @@ void Interpreter::psq_lux(UGeckoInstruction _inst)
|
||||||
const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB];
|
const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB];
|
||||||
|
|
||||||
int c = 4;
|
int c = 4;
|
||||||
if ((ldType == 4) || (ldType == 6)) c = 0x1;
|
if (ldType == QUANTIZE_U8 || ldType == QUANTIZE_S8)
|
||||||
if ((ldType == 5) || (ldType == 7)) c = 0x2;
|
c = 0x1;
|
||||||
|
else if (ldType == QUANTIZE_U16 || ldType == QUANTIZE_S16)
|
||||||
|
c = 0x2;
|
||||||
|
|
||||||
if (_inst.Wx == 0)
|
if (_inst.Wx == 0)
|
||||||
{
|
{
|
||||||
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
|
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
|
||||||
float ps1 = Helper_Dequantize( EA+c, ldType, ldScale );
|
float ps1 = Helper_Dequantize(EA + c, ldType, ldScale);
|
||||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -338,7 +352,7 @@ void Interpreter::psq_lux(UGeckoInstruction _inst)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float ps0 = Helper_Dequantize( EA, ldType, ldScale );
|
float ps0 = Helper_Dequantize(EA, ldType, ldScale);
|
||||||
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
if (PowerPC::ppcState.Exceptions & EXCEPTION_DSI)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -357,13 +371,15 @@ void Interpreter::psq_stux(UGeckoInstruction _inst)
|
||||||
const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB];
|
const u32 EA = m_GPR[_inst.RA] + m_GPR[_inst.RB];
|
||||||
|
|
||||||
int c = 4;
|
int c = 4;
|
||||||
if ((stType == 4) || (stType == 6)) c = 0x1;
|
if (stType == QUANTIZE_U8 || stType == QUANTIZE_S8)
|
||||||
if ((stType == 5) || (stType == 7)) c = 0x2;
|
c = 0x1;
|
||||||
|
else if (stType == QUANTIZE_U16 || stType == QUANTIZE_S16)
|
||||||
|
c = 0x2;
|
||||||
|
|
||||||
if (_inst.Wx == 0)
|
if (_inst.Wx == 0)
|
||||||
{
|
{
|
||||||
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
|
Helper_Quantize(EA, rPS0(_inst.RS), stType, stScale);
|
||||||
Helper_Quantize(EA+c, rPS1(_inst.RS), stType, stScale);
|
Helper_Quantize(EA + c, rPS1(_inst.RS), stType, stScale);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,35 +15,45 @@ void Interpreter::ps_sel(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = rPS0(_inst.FA) >= -0.0 ? rPS0(_inst.FC) : rPS0(_inst.FB);
|
rPS0(_inst.FD) = rPS0(_inst.FA) >= -0.0 ? rPS0(_inst.FC) : rPS0(_inst.FB);
|
||||||
rPS1(_inst.FD) = rPS1(_inst.FA) >= -0.0 ? rPS1(_inst.FC) : rPS1(_inst.FB);
|
rPS1(_inst.FD) = rPS1(_inst.FA) >= -0.0 ? rPS1(_inst.FC) : rPS1(_inst.FB);
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_neg(UGeckoInstruction _inst)
|
void Interpreter::ps_neg(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
|
riPS0(_inst.FD) = riPS0(_inst.FB) ^ (1ULL << 63);
|
||||||
riPS1(_inst.FD) = riPS1(_inst.FB) ^ (1ULL << 63);
|
riPS1(_inst.FD) = riPS1(_inst.FB) ^ (1ULL << 63);
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_mr(UGeckoInstruction _inst)
|
void Interpreter::ps_mr(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
rPS0(_inst.FD) = rPS0(_inst.FB);
|
rPS0(_inst.FD) = rPS0(_inst.FB);
|
||||||
rPS1(_inst.FD) = rPS1(_inst.FB);
|
rPS1(_inst.FD) = rPS1(_inst.FB);
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_nabs(UGeckoInstruction _inst)
|
void Interpreter::ps_nabs(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
|
riPS0(_inst.FD) = riPS0(_inst.FB) | (1ULL << 63);
|
||||||
riPS1(_inst.FD) = riPS1(_inst.FB) | (1ULL << 63);
|
riPS1(_inst.FD) = riPS1(_inst.FB) | (1ULL << 63);
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_abs(UGeckoInstruction _inst)
|
void Interpreter::ps_abs(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
riPS0(_inst.FD) = riPS0(_inst.FB) &~ (1ULL << 63);
|
riPS0(_inst.FD) = riPS0(_inst.FB) &~ (1ULL << 63);
|
||||||
riPS1(_inst.FD) = riPS1(_inst.FB) &~ (1ULL << 63);
|
riPS1(_inst.FD) = riPS1(_inst.FB) &~ (1ULL << 63);
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are just moves, double is OK.
|
// These are just moves, double is OK.
|
||||||
|
@ -53,7 +63,9 @@ void Interpreter::ps_merge00(UGeckoInstruction _inst)
|
||||||
double p1 = rPS0(_inst.FB);
|
double p1 = rPS0(_inst.FB);
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_merge01(UGeckoInstruction _inst)
|
void Interpreter::ps_merge01(UGeckoInstruction _inst)
|
||||||
|
@ -62,7 +74,9 @@ void Interpreter::ps_merge01(UGeckoInstruction _inst)
|
||||||
double p1 = rPS1(_inst.FB);
|
double p1 = rPS1(_inst.FB);
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_merge10(UGeckoInstruction _inst)
|
void Interpreter::ps_merge10(UGeckoInstruction _inst)
|
||||||
|
@ -71,7 +85,9 @@ void Interpreter::ps_merge10(UGeckoInstruction _inst)
|
||||||
double p1 = rPS0(_inst.FB);
|
double p1 = rPS0(_inst.FB);
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_merge11(UGeckoInstruction _inst)
|
void Interpreter::ps_merge11(UGeckoInstruction _inst)
|
||||||
|
@ -80,7 +96,9 @@ void Interpreter::ps_merge11(UGeckoInstruction _inst)
|
||||||
double p1 = rPS1(_inst.FB);
|
double p1 = rPS1(_inst.FB);
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
// From here on, the real deal.
|
// From here on, the real deal.
|
||||||
|
@ -94,8 +112,14 @@ void Interpreter::ps_div(UGeckoInstruction _inst)
|
||||||
double b = rPS0(_inst.FB);
|
double b = rPS0(_inst.FB);
|
||||||
double &res = rPS0(_inst.FD);
|
double &res = rPS0(_inst.FD);
|
||||||
|
|
||||||
if (a != a) res = a;
|
if (a != a)
|
||||||
else if (b != b) res = b;
|
{
|
||||||
|
res = a;
|
||||||
|
}
|
||||||
|
else if (b != b)
|
||||||
|
{
|
||||||
|
res = b;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (b == 0.0)
|
if (b == 0.0)
|
||||||
|
@ -132,8 +156,14 @@ void Interpreter::ps_div(UGeckoInstruction _inst)
|
||||||
double b = rPS1(_inst.FB);
|
double b = rPS1(_inst.FB);
|
||||||
double &res = rPS1(_inst.FD);
|
double &res = rPS1(_inst.FD);
|
||||||
|
|
||||||
if (a != a) res = a;
|
if (a != a)
|
||||||
else if (b != b) res = b;
|
{
|
||||||
|
res = a;
|
||||||
|
}
|
||||||
|
else if (b != b)
|
||||||
|
{
|
||||||
|
res = b;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (b == 0.0)
|
if (b == 0.0)
|
||||||
|
@ -166,7 +196,9 @@ void Interpreter::ps_div(UGeckoInstruction _inst)
|
||||||
|
|
||||||
SetFPException(ex_mask);
|
SetFPException(ex_mask);
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_res(UGeckoInstruction _inst)
|
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
|
// this code is based on the real hardware tests
|
||||||
double a = rPS0(_inst.FB);
|
double a = rPS0(_inst.FB);
|
||||||
double b = rPS1(_inst.FB);
|
double b = rPS1(_inst.FB);
|
||||||
|
|
||||||
if (a == 0.0 || b == 0.0)
|
if (a == 0.0 || b == 0.0)
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_ZX);
|
SetFPException(FPSCR_ZX);
|
||||||
}
|
}
|
||||||
|
|
||||||
rPS0(_inst.FD) = ApproximateReciprocal(a);
|
rPS0(_inst.FD) = ApproximateReciprocal(a);
|
||||||
rPS1(_inst.FD) = ApproximateReciprocal(b);
|
rPS1(_inst.FD) = ApproximateReciprocal(b);
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_rsqrte(UGeckoInstruction _inst)
|
void Interpreter::ps_rsqrte(UGeckoInstruction _inst)
|
||||||
|
@ -200,7 +236,9 @@ void Interpreter::ps_rsqrte(UGeckoInstruction _inst)
|
||||||
rPS1(_inst.FD) = ForceSingle(ApproximateReciprocalSquareRoot(rPS1(_inst.FB)));
|
rPS1(_inst.FD) = ForceSingle(ApproximateReciprocalSquareRoot(rPS1(_inst.FB)));
|
||||||
|
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
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)));
|
rPS0(_inst.FD) = ForceSingle(NI_sub(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
rPS1(_inst.FD) = ForceSingle(NI_sub(rPS1(_inst.FA), rPS1(_inst.FB)));
|
rPS1(_inst.FD) = ForceSingle(NI_sub(rPS1(_inst.FA), rPS1(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_add(UGeckoInstruction _inst)
|
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)));
|
rPS0(_inst.FD) = ForceSingle(NI_add(rPS0(_inst.FA), rPS0(_inst.FB)));
|
||||||
rPS1(_inst.FD) = ForceSingle(NI_add(rPS1(_inst.FA), rPS1(_inst.FB)));
|
rPS1(_inst.FD) = ForceSingle(NI_add(rPS1(_inst.FA), rPS1(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_mul(UGeckoInstruction _inst)
|
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)));
|
rPS0(_inst.FD) = ForceSingle(NI_mul(rPS0(_inst.FA), rPS0(_inst.FC)));
|
||||||
rPS1(_inst.FD) = ForceSingle(NI_mul(rPS1(_inst.FA), rPS1(_inst.FC)));
|
rPS1(_inst.FD) = ForceSingle(NI_mul(rPS1(_inst.FA), rPS1(_inst.FC)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
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)));
|
rPS0(_inst.FD) = ForceSingle(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
rPS1(_inst.FD) = ForceSingle(NI_msub(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB)));
|
rPS1(_inst.FD) = ForceSingle(NI_msub(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_madd(UGeckoInstruction _inst)
|
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)));
|
rPS0(_inst.FD) = ForceSingle(NI_madd(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB)));
|
||||||
rPS1(_inst.FD) = ForceSingle(NI_madd(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB)));
|
rPS1(_inst.FD) = ForceSingle(NI_madd(rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB)));
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_nmsub(UGeckoInstruction _inst)
|
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) ) );
|
rPS0(_inst.FD) = ForceSingle( -NI_msub( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ) );
|
||||||
rPS1(_inst.FD) = ForceSingle( -NI_msub( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) );
|
rPS1(_inst.FD) = ForceSingle( -NI_msub( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) );
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_nmadd(UGeckoInstruction _inst)
|
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) ) );
|
rPS0(_inst.FD) = ForceSingle( -NI_madd( rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB) ) );
|
||||||
rPS1(_inst.FD) = ForceSingle( -NI_madd( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) );
|
rPS1(_inst.FD) = ForceSingle( -NI_madd( rPS1(_inst.FA), rPS1(_inst.FC), rPS1(_inst.FB) ) );
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_sum0(UGeckoInstruction _inst)
|
void Interpreter::ps_sum0(UGeckoInstruction _inst)
|
||||||
|
@ -268,7 +320,9 @@ void Interpreter::ps_sum0(UGeckoInstruction _inst)
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_sum1(UGeckoInstruction _inst)
|
void Interpreter::ps_sum1(UGeckoInstruction _inst)
|
||||||
|
@ -278,7 +332,9 @@ void Interpreter::ps_sum1(UGeckoInstruction _inst)
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
UpdateFPRF(rPS1(_inst.FD));
|
UpdateFPRF(rPS1(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_muls0(UGeckoInstruction _inst)
|
void Interpreter::ps_muls0(UGeckoInstruction _inst)
|
||||||
|
@ -288,7 +344,9 @@ void Interpreter::ps_muls0(UGeckoInstruction _inst)
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_muls1(UGeckoInstruction _inst)
|
void Interpreter::ps_muls1(UGeckoInstruction _inst)
|
||||||
|
@ -298,7 +356,9 @@ void Interpreter::ps_muls1(UGeckoInstruction _inst)
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_madds0(UGeckoInstruction _inst)
|
void Interpreter::ps_madds0(UGeckoInstruction _inst)
|
||||||
|
@ -308,7 +368,9 @@ void Interpreter::ps_madds0(UGeckoInstruction _inst)
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_madds1(UGeckoInstruction _inst)
|
void Interpreter::ps_madds1(UGeckoInstruction _inst)
|
||||||
|
@ -318,7 +380,9 @@ void Interpreter::ps_madds1(UGeckoInstruction _inst)
|
||||||
rPS0(_inst.FD) = p0;
|
rPS0(_inst.FD) = p0;
|
||||||
rPS1(_inst.FD) = p1;
|
rPS1(_inst.FD) = p1;
|
||||||
UpdateFPRF(rPS0(_inst.FD));
|
UpdateFPRF(rPS0(_inst.FD));
|
||||||
if (_inst.Rc) Helper_UpdateCR1();
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
Helper_UpdateCR1();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::ps_cmpu0(UGeckoInstruction _inst)
|
void Interpreter::ps_cmpu0(UGeckoInstruction _inst)
|
||||||
|
|
|
@ -54,7 +54,8 @@ void Interpreter::mtfsb0x(UGeckoInstruction _inst)
|
||||||
FPSCR.Hex &= ~b;
|
FPSCR.Hex &= ~b;
|
||||||
FPSCRtoFPUSettings(FPSCR);
|
FPSCRtoFPUSettings(FPSCR);
|
||||||
|
|
||||||
if (_inst.Rc) PanicAlert("mtfsb0x: inst_.Rc");
|
if (_inst.Rc)
|
||||||
|
PanicAlert("mtfsb0x: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::mtfsb1x(UGeckoInstruction _inst)
|
void Interpreter::mtfsb1x(UGeckoInstruction _inst)
|
||||||
|
@ -67,7 +68,8 @@ void Interpreter::mtfsb1x(UGeckoInstruction _inst)
|
||||||
FPSCR.Hex |= b;
|
FPSCR.Hex |= b;
|
||||||
FPSCRtoFPUSettings(FPSCR);
|
FPSCRtoFPUSettings(FPSCR);
|
||||||
|
|
||||||
if (_inst.Rc) PanicAlert("mtfsb1x: inst_.Rc");
|
if (_inst.Rc)
|
||||||
|
PanicAlert("mtfsb1x: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::mtfsfix(UGeckoInstruction _inst)
|
void Interpreter::mtfsfix(UGeckoInstruction _inst)
|
||||||
|
@ -83,7 +85,8 @@ void Interpreter::mtfsfix(UGeckoInstruction _inst)
|
||||||
|
|
||||||
FPSCRtoFPUSettings(FPSCR);
|
FPSCRtoFPUSettings(FPSCR);
|
||||||
|
|
||||||
if (_inst.Rc) PanicAlert("mtfsfix: inst_.Rc");
|
if (_inst.Rc)
|
||||||
|
PanicAlert("mtfsfix: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::mtfsfx(UGeckoInstruction _inst)
|
void Interpreter::mtfsfx(UGeckoInstruction _inst)
|
||||||
|
@ -103,7 +106,8 @@ void Interpreter::mtfsfx(UGeckoInstruction _inst)
|
||||||
FPSCR.Hex = (FPSCR.Hex & ~m) | ((u32)(riPS0(_inst.FB)) & m);
|
FPSCR.Hex = (FPSCR.Hex & ~m) | ((u32)(riPS0(_inst.FB)) & m);
|
||||||
FPSCRtoFPUSettings(FPSCR);
|
FPSCRtoFPUSettings(FPSCR);
|
||||||
|
|
||||||
if (_inst.Rc) PanicAlert("mtfsfx: inst_.Rc");
|
if (_inst.Rc)
|
||||||
|
PanicAlert("mtfsfx: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Interpreter::mcrxr(UGeckoInstruction _inst)
|
void Interpreter::mcrxr(UGeckoInstruction _inst)
|
||||||
|
@ -129,10 +133,12 @@ void Interpreter::mtcrf(UGeckoInstruction _inst)
|
||||||
{
|
{
|
||||||
//TODO: use lookup table? probably not worth it
|
//TODO: use lookup table? probably not worth it
|
||||||
u32 mask = 0;
|
u32 mask = 0;
|
||||||
for (int i = 0; i < 8; i++) {
|
for (int i = 0; i < 8; i++)
|
||||||
|
{
|
||||||
if (crm & (1 << i))
|
if (crm & (1 << i))
|
||||||
mask |= 0xF << (i*4);
|
mask |= 0xF << (i*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
SetCR((GetCR() & ~mask) | (m_GPR[_inst.RS] & mask));
|
SetCR((GetCR() & ~mask) | (m_GPR[_inst.RS] & mask));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,7 +171,8 @@ void Interpreter::mtmsr(UGeckoInstruction _inst)
|
||||||
|
|
||||||
// Segment registers. MMU control.
|
// 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);
|
DEBUG_LOG(POWERPC, "%08x: MMU: Segment register %i set to %08x", PowerPC::ppcState.pc, index, value);
|
||||||
PowerPC::ppcState.sr[index] = value;
|
PowerPC::ppcState.sr[index] = value;
|
||||||
}
|
}
|
||||||
|
@ -406,7 +413,8 @@ void Interpreter::mcrfs(UGeckoInstruction _inst)
|
||||||
|
|
||||||
UpdateFPSCR();
|
UpdateFPSCR();
|
||||||
u32 fpflags = ((FPSCR.Hex >> (4 * (7 - _inst.CRFS))) & 0xF);
|
u32 fpflags = ((FPSCR.Hex >> (4 * (7 - _inst.CRFS))) & 0xF);
|
||||||
switch (_inst.CRFS) {
|
switch (_inst.CRFS)
|
||||||
|
{
|
||||||
case 0:
|
case 0:
|
||||||
FPSCR.FX = 0;
|
FPSCR.FX = 0;
|
||||||
FPSCR.OX = 0;
|
FPSCR.OX = 0;
|
||||||
|
@ -443,5 +451,7 @@ void Interpreter::mffsx(UGeckoInstruction _inst)
|
||||||
|
|
||||||
UpdateFPSCR();
|
UpdateFPSCR();
|
||||||
riPS0(_inst.FD) = (u64)FPSCR.Hex;
|
riPS0(_inst.FD) = (u64)FPSCR.Hex;
|
||||||
if (_inst.Rc) PanicAlert("mffsx: inst_.Rc");
|
|
||||||
|
if (_inst.Rc)
|
||||||
|
PanicAlert("mffsx: inst_.Rc");
|
||||||
}
|
}
|
||||||
|
|
|
@ -488,7 +488,9 @@ void InitTables()
|
||||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||||
for (auto& tpl : table63_2)
|
for (auto& tpl : table63_2)
|
||||||
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
m_allInstructions[m_numInstructions++] = &tpl.opinfo;
|
||||||
if (m_numInstructions >= 512) {
|
|
||||||
|
if (m_numInstructions >= 512)
|
||||||
|
{
|
||||||
PanicAlert("m_allInstructions underdimensioned");
|
PanicAlert("m_allInstructions underdimensioned");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue