From b89e4b52581df8785d593e15c7ad6ee6d0eaebed Mon Sep 17 00:00:00 2001 From: Markus Wick Date: Fri, 11 Aug 2017 16:41:23 +0200 Subject: [PATCH] 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. --- .../Core/PowerPC/Interpreter/Interpreter.h | 1 - .../Interpreter/Interpreter_Integer.cpp | 23 +++++++++++++------ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h index 0ce65ba149..a10251cc36 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.h @@ -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); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index 65b8547b98..e8731b8c2a 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -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)