Merge pull request #6470 from lioncash/ov-flag

Interpreter: Handle setting the overflow flag when the OE bit is set in divw, divwu, and neg
This commit is contained in:
Markus Wick 2018-03-20 11:08:12 +01:00 committed by GitHub
commit 35bfa64dfc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 21 additions and 13 deletions

View File

@ -499,8 +499,7 @@ void Interpreter::divwx(UGeckoInstruction inst)
{ {
if (inst.OE) if (inst.OE)
{ {
// should set OV SetXER_OV(true);
PanicAlert("OE: divwx");
} }
if (((u32)a & 0x80000000) && b == 0) if (((u32)a & 0x80000000) && b == 0)
@ -526,8 +525,7 @@ void Interpreter::divwux(UGeckoInstruction inst)
{ {
if (inst.OE) if (inst.OE)
{ {
// should set OV SetXER_OV(true);
PanicAlert("OE: divwux");
} }
rGPR[inst.RD] = 0; rGPR[inst.RD] = 0;
@ -582,16 +580,15 @@ void Interpreter::mullwx(UGeckoInstruction inst)
void Interpreter::negx(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) rGPR[inst.RD] = (~a) + 1;
{
if (inst.OE)
PanicAlert("OE: negx");
}
if (inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
if (inst.OE && a == 0x80000000)
SetXER_OV(true);
} }
void Interpreter::subfx(UGeckoInstruction inst) void Interpreter::subfx(UGeckoInstruction inst)

View File

@ -417,14 +417,25 @@ inline void SetXER(UReg_XER new_xer)
PowerPC::ppcState.xer_so_ov = (new_xer.SO << 1) + new_xer.OV; 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; 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<u32>(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<u32>(value);
SetXER_SO(value);
} }
void UpdateFPRF(double dvalue); void UpdateFPRF(double dvalue);