From f129c936e7d4fea9733c59cace277cc7d1d642b3 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 19 Mar 2018 10:28:28 -0400 Subject: [PATCH 1/3] PowerPC: Add functions for getting and setting the XER OV bit While we're at it, change GetXER_SO's return value to u32 to prevent potential sign bit wonkyness given we're performing bit arithmetic. --- Source/Core/Core/PowerPC/PowerPC.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 2b3fe8a98e..5b74df1a58 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -417,14 +417,25 @@ inline void SetXER(UReg_XER new_xer) PowerPC::ppcState.xer_so_ov = (new_xer.SO << 1) + new_xer.OV; } -inline int GetXER_SO() +inline u32 GetXER_SO() { return PowerPC::ppcState.xer_so_ov >> 1; } -inline void SetXER_SO(int value) +inline void SetXER_SO(bool value) { - PowerPC::ppcState.xer_so_ov |= value << 1; + PowerPC::ppcState.xer_so_ov |= static_cast(value) << 1; +} + +inline u32 GetXER_OV() +{ + return PowerPC::ppcState.xer_so_ov & 1; +} + +inline void SetXER_OV(bool value) +{ + PowerPC::ppcState.xer_so_ov |= static_cast(value); + SetXER_SO(value); } void UpdateFPRF(double dvalue); From 675d2fb77401a0372f82e5ca74e09ed4ce6e77ba Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 19 Mar 2018 11:17:44 -0400 Subject: [PATCH 2/3] Interpreter_Integer: Set the overflow flag if the OE bit is set for divw and divwu divw and divwu won't panic now if the OE bit is set for these instructions. --- .../Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index e8731b8c2a..3475eb4073 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -499,8 +499,7 @@ void Interpreter::divwx(UGeckoInstruction inst) { if (inst.OE) { - // should set OV - PanicAlert("OE: divwx"); + SetXER_OV(true); } if (((u32)a & 0x80000000) && b == 0) @@ -526,8 +525,7 @@ void Interpreter::divwux(UGeckoInstruction inst) { if (inst.OE) { - // should set OV - PanicAlert("OE: divwux"); + SetXER_OV(true); } rGPR[inst.RD] = 0; From 2fa0cb91a150e221cde870b5bda82c8ad48f8496 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 19 Mar 2018 11:29:21 -0400 Subject: [PATCH 3/3] Interpreter_Integer: Set the overflow flag if the OE bit is set for neg Also amends the condition that was being checked. Previously it was checking if the destination register value was 0x80000000, however it's actually the source register that should be checked. --- .../Core/PowerPC/Interpreter/Interpreter_Integer.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index 3475eb4073..cfd6d3992f 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -580,16 +580,15 @@ void Interpreter::mullwx(UGeckoInstruction inst) void Interpreter::negx(UGeckoInstruction inst) { - rGPR[inst.RD] = (~rGPR[inst.RA]) + 1; + const u32 a = rGPR[inst.RA]; - if (rGPR[inst.RD] == 0x80000000) - { - if (inst.OE) - PanicAlert("OE: negx"); - } + rGPR[inst.RD] = (~a) + 1; if (inst.Rc) Helper_UpdateCR0(rGPR[inst.RD]); + + if (inst.OE && a == 0x80000000) + SetXER_OV(true); } void Interpreter::subfx(UGeckoInstruction inst)