diff options
| author | Lioncash <mathew1800@gmail.com> | 2018-06-02 20:47:16 -0400 |
|---|---|---|
| committer | Lioncash <mathew1800@gmail.com> | 2018-06-02 20:47:18 -0400 |
| commit | d6bafbfaaf0cfb62222fad52b4e64c419c61ec42 (patch) | |
| tree | 4f577e0d496c7c7842bd162b7bbb8e31f201025d /Source | |
| parent | d05c2ef90dc2ae94d21aac5d61960dcb50160c35 (diff) | |
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.
Diffstat (limited to 'Source')
| -rw-r--r-- | Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index ce4dfd9568..44145195e5 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -115,8 +115,8 @@ void Interpreter::ps_div(UGeckoInstruction inst) void Interpreter::ps_res(UGeckoInstruction inst) { // this code is based on the real hardware tests - double a = rPS0(inst.FB); - double b = rPS1(inst.FB); + const double a = rPS0(inst.FB); + const double b = rPS1(inst.FB); if (a == 0.0 || b == 0.0) { @@ -125,6 +125,13 @@ void Interpreter::ps_res(UGeckoInstruction inst) 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); rPS1(inst.FD) = Common::ApproximateReciprocal(b); PowerPC::UpdateFPRF(rPS0(inst.FD)); @@ -135,22 +142,32 @@ void Interpreter::ps_res(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); FPSCR.FI = 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); FPSCR.FI = 0; FPSCR.FR = 0; } - rPS0(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(rPS0(inst.FB))); - rPS1(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(rPS1(inst.FB))); + if (Common::IsSNAN(ps0) || Common::IsSNAN(ps1)) + { + 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)); |
