From 3e63d7104634c719956e1f518cd64ded622a1eb5 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sun, 3 Jun 2018 07:51:03 -0400 Subject: [PATCH] Gekko: Add helper function for clearing both FPSCR.FI and FPSCR.FR --- Source/Core/Core/PowerPC/Gekko.h | 6 +++ .../PowerPC/Interpreter/Interpreter_FPUtils.h | 54 +++++++------------ .../Interpreter/Interpreter_FloatingPoint.cpp | 24 +++------ .../Interpreter/Interpreter_Paired.cpp | 15 ++---- 4 files changed, 37 insertions(+), 62 deletions(-) diff --git a/Source/Core/Core/PowerPC/Gekko.h b/Source/Core/Core/PowerPC/Gekko.h index a046b883c2..ca083b1219 100644 --- a/Source/Core/Core/PowerPC/Gekko.h +++ b/Source/Core/Core/PowerPC/Gekko.h @@ -476,6 +476,12 @@ union UReg_FPSCR UReg_FPSCR() = default; explicit UReg_FPSCR(u32 hex_) : Hex{hex_} {} + + void ClearFIFR() + { + FI = 0; + FR = 0; + } }; // Hardware Implementation-Dependent Register 0 diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h index 666ca2bffb..ed15cef6da 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h @@ -105,8 +105,7 @@ inline double NI_mul(double a, double b) if (Common::IsSNAN(a) || Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (std::isnan(a)) @@ -115,8 +114,7 @@ inline double NI_mul(double a, double b) return MakeQuiet(b); SetFPException(FPSCR_VXIMZ); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); return PPC_NAN; } return t; @@ -131,8 +129,7 @@ inline double NI_div(double a, double b) if (Common::IsSNAN(a) || Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (std::isnan(a)) @@ -145,21 +142,18 @@ inline double NI_div(double a, double b) if (a == 0.0) { SetFPException(FPSCR_VXZDZ); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } else { SetFPException(FPSCR_ZX); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } } else if (std::isinf(a) && std::isinf(b)) { SetFPException(FPSCR_VXIDI); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } return PPC_NAN; @@ -177,8 +171,7 @@ inline double NI_add(double a, double b) if (Common::IsSNAN(a) || Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (std::isnan(a)) @@ -187,8 +180,7 @@ inline double NI_add(double a, double b) return MakeQuiet(b); SetFPException(FPSCR_VXISI); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); return PPC_NAN; } @@ -204,8 +196,7 @@ inline double NI_sub(double a, double b) if (Common::IsSNAN(a) || Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (std::isnan(a)) @@ -214,8 +205,7 @@ inline double NI_sub(double a, double b) return MakeQuiet(b); SetFPException(FPSCR_VXISI); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); return PPC_NAN; } @@ -234,8 +224,7 @@ inline double NI_madd(double a, double c, double b) if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (std::isnan(a)) @@ -246,8 +235,7 @@ inline double NI_madd(double a, double c, double b) return MakeQuiet(c); SetFPException(FPSCR_VXIMZ); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); return PPC_NAN; } @@ -258,16 +246,14 @@ inline double NI_madd(double a, double c, double b) if (Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (std::isnan(b)) return MakeQuiet(b); SetFPException(FPSCR_VXISI); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); return PPC_NAN; } @@ -283,8 +269,7 @@ inline double NI_msub(double a, double c, double b) if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (std::isnan(a)) @@ -295,8 +280,7 @@ inline double NI_msub(double a, double c, double b) return MakeQuiet(c); SetFPException(FPSCR_VXIMZ); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); return PPC_NAN; } @@ -307,16 +291,14 @@ inline double NI_msub(double a, double c, double b) if (Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (std::isnan(b)) return MakeQuiet(b); SetFPException(FPSCR_VXISI); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); return PPC_NAN; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index acf7c93afb..32f78343e9 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -92,8 +92,7 @@ void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode) const double di = i; if (di == b) { - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } else { @@ -105,8 +104,7 @@ void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode) if (exception_occurred) { - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (!exception_occurred || FPSCR.VE == 0) @@ -285,8 +283,7 @@ void Interpreter::frspx(UGeckoInstruction inst) // round to single PowerPC::UpdateFPRF(b); } - SetFI(0); - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } else { @@ -397,8 +394,7 @@ void Interpreter::fresx(UGeckoInstruction inst) if (b == 0.0) { SetFPException(FPSCR_ZX); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); if (FPSCR.ZE == 0) compute_result(b); @@ -406,8 +402,7 @@ void Interpreter::fresx(UGeckoInstruction inst) else if (Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); if (FPSCR.VE == 0) compute_result(b); @@ -434,8 +429,7 @@ void Interpreter::frsqrtex(UGeckoInstruction inst) if (b < 0.0) { SetFPException(FPSCR_VXSQRT); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); if (FPSCR.VE == 0) compute_result(b); @@ -443,8 +437,7 @@ void Interpreter::frsqrtex(UGeckoInstruction inst) else if (b == 0.0) { SetFPException(FPSCR_ZX); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); if (FPSCR.ZE == 0) compute_result(b); @@ -452,8 +445,7 @@ void Interpreter::frsqrtex(UGeckoInstruction inst) else if (Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); if (FPSCR.VE == 0) compute_result(b); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index 44145195e5..380c9ac103 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -121,15 +121,13 @@ void Interpreter::ps_res(UGeckoInstruction inst) if (a == 0.0 || b == 0.0) { SetFPException(FPSCR_ZX); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (Common::IsSNAN(a) || Common::IsSNAN(b)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } rPS0(inst.FD) = Common::ApproximateReciprocal(a); @@ -148,22 +146,19 @@ void Interpreter::ps_rsqrte(UGeckoInstruction inst) if (ps0 == 0.0 || ps1 == 0.0) { SetFPException(FPSCR_ZX); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (ps0 < 0.0 || ps1 < 0.0) { SetFPException(FPSCR_VXSQRT); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } if (Common::IsSNAN(ps0) || Common::IsSNAN(ps1)) { SetFPException(FPSCR_VXSNAN); - FPSCR.FI = 0; - FPSCR.FR = 0; + FPSCR.ClearFIFR(); } rPS0(inst.FD) = ForceSingle(Common::ApproximateReciprocalSquareRoot(ps0));