Interpreter: Fix cmpi.

cmpi shall compare two signed 32 bit values. The used difference a-b
may overflow and so the resulting 32 bit value can't represent it.
A correct way would be cr = s64(a) - s64(b) and it should be done in
this way in the JITs, but the Interpreter shall implement the most
readable way.

Also drops the now unused helper function.
This commit is contained in:
Markus Wick 2017-08-11 16:41:23 +02:00
parent 5767309670
commit b89e4b5258
2 changed files with 16 additions and 8 deletions

View File

@ -287,7 +287,6 @@ private:
// flag helper
static void Helper_UpdateCR0(u32 value);
static void Helper_UpdateCR1();
static void Helper_UpdateCRx(int x, u32 value);
// address helper
static u32 Helper_Get_EA(const UGeckoInstruction inst);

View File

@ -11,17 +11,12 @@
#include "Core/PowerPC/PowerPC.h"
void Interpreter::Helper_UpdateCR0(u32 value)
{
Helper_UpdateCRx(0, value);
}
void Interpreter::Helper_UpdateCRx(int idx, u32 value)
{
s64 sign_extended = (s64)(s32)value;
u64 cr_val = (u64)sign_extended;
cr_val = (cr_val & ~(1ull << 61)) | ((u64)GetXER_SO() << 61);
PowerPC::ppcState.cr_val[idx] = cr_val;
PowerPC::ppcState.cr_val[0] = cr_val;
}
u32 Interpreter::Helper_Carry(u32 value1, u32 value2)
@ -89,7 +84,21 @@ void Interpreter::andis_rc(UGeckoInstruction inst)
void Interpreter::cmpi(UGeckoInstruction inst)
{
Helper_UpdateCRx(inst.CRFD, rGPR[inst.RA] - inst.SIMM_16);
s32 a = rGPR[inst.RA];
s32 b = inst.SIMM_16;
int f;
if (a < b)
f = 0x8;
else if (a > b)
f = 0x4;
else
f = 0x2; // equals
if (GetXER_SO())
f |= 0x1;
SetCRField(inst.CRFD, f);
}
void Interpreter::cmpli(UGeckoInstruction inst)