Merge pull request #6485 from lioncash/flag-unset

PowerPC: Properly unset the overflow bit
This commit is contained in:
Anthony 2018-03-21 21:14:05 -07:00 committed by GitHub
commit ea821760e1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 19 additions and 21 deletions

View File

@ -492,16 +492,12 @@ void Interpreter::addzex(UGeckoInstruction inst)
void Interpreter::divwx(UGeckoInstruction inst) void Interpreter::divwx(UGeckoInstruction inst)
{ {
s32 a = rGPR[inst.RA]; const s32 a = rGPR[inst.RA];
s32 b = rGPR[inst.RB]; const s32 b = rGPR[inst.RB];
const bool overflow = b == 0 || ((u32)a == 0x80000000 && b == -1);
if (b == 0 || ((u32)a == 0x80000000 && b == -1)) if (overflow)
{ {
if (inst.OE)
{
SetXER_OV(true);
}
if (((u32)a & 0x80000000) && b == 0) if (((u32)a & 0x80000000) && b == 0)
rGPR[inst.RD] = UINT32_MAX; rGPR[inst.RD] = UINT32_MAX;
else else
@ -512,22 +508,21 @@ void Interpreter::divwx(UGeckoInstruction inst)
rGPR[inst.RD] = (u32)(a / b); rGPR[inst.RD] = (u32)(a / b);
} }
if (inst.OE)
SetXER_OV(overflow);
if (inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
void Interpreter::divwux(UGeckoInstruction inst) void Interpreter::divwux(UGeckoInstruction inst)
{ {
u32 a = rGPR[inst.RA]; const u32 a = rGPR[inst.RA];
u32 b = rGPR[inst.RB]; const u32 b = rGPR[inst.RB];
const bool overflow = b == 0;
if (b == 0) if (overflow)
{ {
if (inst.OE)
{
SetXER_OV(true);
}
rGPR[inst.RD] = 0; rGPR[inst.RD] = 0;
} }
else else
@ -535,6 +530,9 @@ void Interpreter::divwux(UGeckoInstruction inst)
rGPR[inst.RD] = a / b; rGPR[inst.RD] = a / b;
} }
if (inst.OE)
SetXER_OV(overflow);
if (inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
} }
@ -572,8 +570,8 @@ void Interpreter::mullwx(UGeckoInstruction inst)
rGPR[inst.RD] = static_cast<u32>(result); rGPR[inst.RD] = static_cast<u32>(result);
if (inst.OE && (result < -0x80000000LL || result > 0x7FFFFFFFLL)) if (inst.OE)
SetXER_OV(true); SetXER_OV(result < -0x80000000LL || result > 0x7FFFFFFFLL);
if (inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
@ -588,8 +586,8 @@ void Interpreter::negx(UGeckoInstruction inst)
if (inst.Rc) if (inst.Rc)
Helper_UpdateCR0(rGPR[inst.RD]); Helper_UpdateCR0(rGPR[inst.RD]);
if (inst.OE && a == 0x80000000) if (inst.OE)
SetXER_OV(true); SetXER_OV(a == 0x80000000);
} }
void Interpreter::subfx(UGeckoInstruction inst) void Interpreter::subfx(UGeckoInstruction inst)

View File

@ -434,7 +434,7 @@ inline u32 GetXER_OV()
inline void SetXER_OV(bool value) inline void SetXER_OV(bool value)
{ {
PowerPC::ppcState.xer_so_ov |= static_cast<u32>(value); PowerPC::ppcState.xer_so_ov = (PowerPC::ppcState.xer_so_ov & 0xFE) | static_cast<u32>(value);
SetXER_SO(value); SetXER_SO(value);
} }