Interpreter_FloatingPoint: Don't store to destination in frsqrte if VE or ZE is set and a relevant exception occurs

As explained within commit a08ad82ace, if
an invalid exception occurs and VE is set, then the destination register
should remain unchanged. Ditto for when ZE is set and a zero divide
exception occurs.
This commit is contained in:
Lioncash 2018-06-02 15:26:26 -04:00
parent 8d1b2f9cae
commit b71a9e658f
1 changed files with 10 additions and 7 deletions

View File

@ -422,36 +422,39 @@ void Interpreter::fresx(UGeckoInstruction inst)
void Interpreter::frsqrtex(UGeckoInstruction inst) void Interpreter::frsqrtex(UGeckoInstruction inst)
{ {
const double b = rPS0(inst.FB); const double b = rPS0(inst.FB);
const double result = Common::ApproximateReciprocalSquareRoot(b);
const auto compute_result = [inst](double value) {
const double result = Common::ApproximateReciprocalSquareRoot(value);
rPS0(inst.FD) = result;
PowerPC::UpdateFPRF(result);
};
if (b < 0.0) if (b < 0.0)
{ {
SetFPException(FPSCR_VXSQRT); SetFPException(FPSCR_VXSQRT);
if (FPSCR.VE == 0) if (FPSCR.VE == 0)
PowerPC::UpdateFPRF(result); compute_result(b);
} }
else if (b == 0.0) else if (b == 0.0)
{ {
SetFPException(FPSCR_ZX); SetFPException(FPSCR_ZX);
if (FPSCR.ZE == 0) if (FPSCR.ZE == 0)
PowerPC::UpdateFPRF(result); compute_result(b);
} }
else if (Common::IsSNAN(b)) else if (Common::IsSNAN(b))
{ {
SetFPException(FPSCR_VXSNAN); SetFPException(FPSCR_VXSNAN);
if (FPSCR.VE == 0) if (FPSCR.VE == 0)
PowerPC::UpdateFPRF(result); compute_result(b);
} }
else else
{ {
PowerPC::UpdateFPRF(result); compute_result(b);
} }
rPS0(inst.FD) = result;
if (inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();
} }