Interpreter_FloatingPoint: Handle SNaNs properly in frsp

If FPSCR[VE] is set, a result isn't supposed to be written to the destination,
just the FPSCR[VXSNAN] bit gets set, and FPSCR[FR] and FPSCR[FI] get set to zero.

If FPSCR[VE] isn't set, then we do write out a result, however, the FPSCR[FPRF]
field is updated to signify a QNaN (yes, a QNaN, the FPRF field doesn't have
a bit configuration for SNaNs).
This commit is contained in:
Lioncash 2018-04-12 01:40:55 -04:00
parent bbd1bb8eaa
commit 965b963a6f
No known key found for this signature in database
GPG Key ID: 4E3C3CC1031BA9C7

View File

@ -272,12 +272,31 @@ void Interpreter::fselx(UGeckoInstruction inst)
// PS1 is said to be undefined // PS1 is said to be undefined
void Interpreter::frspx(UGeckoInstruction inst) // round to single void Interpreter::frspx(UGeckoInstruction inst) // round to single
{ {
double b = rPS0(inst.FB); const double b = rPS0(inst.FB);
double rounded = ForceSingle(b); const double rounded = ForceSingle(b);
SetFI(b != rounded);
FPSCR.FR = fabs(rounded) > fabs(b); if (MathUtil::IsSNAN(b))
PowerPC::UpdateFPRF(rounded); {
rPS0(inst.FD) = rPS1(inst.FD) = rounded; SetFPException(FPSCR_VXSNAN);
if (FPSCR.VE == 0)
{
rPS0(inst.FD) = rounded;
rPS1(inst.FD) = rounded;
PowerPC::UpdateFPRF(b);
}
SetFI(0);
FPSCR.FR = 0;
}
else
{
SetFI(b != rounded);
FPSCR.FR = fabs(rounded) > fabs(b);
PowerPC::UpdateFPRF(rounded);
rPS0(inst.FD) = rounded;
rPS1(inst.FD) = rounded;
}
if (inst.Rc) if (inst.Rc)
Helper_UpdateCR1(); Helper_UpdateCR1();