Skip to content

Commit

Permalink
Interpreter_Paired: Handle signaling NaNs within ps_res and ps_rsqrte
Browse files Browse the repository at this point in the history
Like regular fres and frsqrte, these also signal whether or not either
of the inputs are signaling NaNs.
  • Loading branch information
lioncash committed Jun 3, 2018
1 parent d05c2ef commit d6bafbf
Showing 1 changed file with 23 additions and 6 deletions.
29 changes: 23 additions & 6 deletions Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp
Expand Up @@ -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)
{ {
Expand All @@ -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));
Expand All @@ -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));


Expand Down

0 comments on commit d6bafbf

Please sign in to comment.