Interpreter_Paired: Handle signaling NaNs within ps_res and ps_rsqrte
Like regular fres and frsqrte, these also signal whether or not either of the inputs are signaling NaNs.
This commit is contained in:
parent
d05c2ef90d
commit
d6bafbfaaf
|
@ -115,8 +115,8 @@ void Interpreter::ps_div(UGeckoInstruction inst)
|
||||||
void Interpreter::ps_res(UGeckoInstruction inst)
|
void Interpreter::ps_res(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
// this code is based on the real hardware tests
|
// this code is based on the real hardware tests
|
||||||
double a = rPS0(inst.FB);
|
const double a = rPS0(inst.FB);
|
||||||
double b = rPS1(inst.FB);
|
const double b = rPS1(inst.FB);
|
||||||
|
|
||||||
if (a == 0.0 || b == 0.0)
|
if (a == 0.0 || b == 0.0)
|
||||||
{
|
{
|
||||||
|
@ -125,6 +125,13 @@ void Interpreter::ps_res(UGeckoInstruction inst)
|
||||||
FPSCR.FR = 0;
|
FPSCR.FR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
||||||
|
{
|
||||||
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
rPS0(inst.FD) = Common::ApproximateReciprocal(a);
|
rPS0(inst.FD) = Common::ApproximateReciprocal(a);
|
||||||
rPS1(inst.FD) = Common::ApproximateReciprocal(b);
|
rPS1(inst.FD) = Common::ApproximateReciprocal(b);
|
||||||
PowerPC::UpdateFPRF(rPS0(inst.FD));
|
PowerPC::UpdateFPRF(rPS0(inst.FD));
|
||||||
|
@ -135,22 +142,32 @@ void Interpreter::ps_res(UGeckoInstruction inst)
|
||||||
|
|
||||||
void Interpreter::ps_rsqrte(UGeckoInstruction inst)
|
void Interpreter::ps_rsqrte(UGeckoInstruction inst)
|
||||||
{
|
{
|
||||||
if (rPS0(inst.FB) == 0.0 || rPS1(inst.FB) == 0.0)
|
const double ps0 = rPS0(inst.FB);
|
||||||
|
const double ps1 = rPS1(inst.FB);
|
||||||
|
|
||||||
|
if (ps0 == 0.0 || ps1 == 0.0)
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_ZX);
|
SetFPException(FPSCR_ZX);
|
||||||
FPSCR.FI = 0;
|
FPSCR.FI = 0;
|
||||||
FPSCR.FR = 0;
|
FPSCR.FR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rPS0(inst.FB) < 0.0 || rPS1(inst.FB) < 0.0)
|
if (ps0 < 0.0 || ps1 < 0.0)
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_VXSQRT);
|
SetFPException(FPSCR_VXSQRT);
|
||||||
FPSCR.FI = 0;
|
FPSCR.FI = 0;
|
||||||
FPSCR.FR = 0;
|
FPSCR.FR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rPS0(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(rPS0(inst.FB)));
|
if (Common::IsSNAN(ps0) || Common::IsSNAN(ps1))
|
||||||
rPS1(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(rPS1(inst.FB)));
|
{
|
||||||
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rPS0(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(ps0));
|
||||||
|
rPS1(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(ps1));
|
||||||
|
|
||||||
PowerPC::UpdateFPRF(rPS0(inst.FD));
|
PowerPC::UpdateFPRF(rPS0(inst.FD));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue