summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2018-06-02 20:47:16 -0400
committerLioncash <mathew1800@gmail.com>2018-06-02 20:47:18 -0400
commitd6bafbfaaf0cfb62222fad52b4e64c419c61ec42 (patch)
tree4f577e0d496c7c7842bd162b7bbb8e31f201025d /Source
parentd05c2ef90dc2ae94d21aac5d61960dcb50160c35 (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.cpp29
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));