diff options
| author | Lioncash <mathew1800@gmail.com> | 2018-06-02 20:13:30 -0400 |
|---|---|---|
| committer | Lioncash <mathew1800@gmail.com> | 2018-06-02 20:18:51 -0400 |
| commit | 468efb7243a50652bb17f68cd384523faa90f2ef (patch) | |
| tree | b630a4b08ec4604a1dbc41e5247495fac3bf2f4a /Source/Core | |
| parent | 0f7370a22c67bf668fff165ac0bcff2dfc0eceb8 (diff) | |
Interpreter_FPUtils: Unset FPSCR.FI and FPSCR.FR if an invalid operation occurs in NI_* functions
If an invalid operation occurs, FI and FR bits are defined to be cleared
to zero for arithmetic operations.
Diffstat (limited to 'Source/Core')
| -rw-r--r-- | Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h index abc798d220..666ca2bffb 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h @@ -103,7 +103,11 @@ inline double NI_mul(double a, double b) if (std::isnan(t)) { if (Common::IsSNAN(a) || Common::IsSNAN(b)) + { SetFPException(FPSCR_VXSNAN); + FPSCR.FI = 0; + FPSCR.FR = 0; + } if (std::isnan(a)) return MakeQuiet(a); @@ -111,6 +115,8 @@ inline double NI_mul(double a, double b) return MakeQuiet(b); SetFPException(FPSCR_VXIMZ); + FPSCR.FI = 0; + FPSCR.FR = 0; return PPC_NAN; } return t; @@ -123,7 +129,11 @@ inline double NI_div(double a, double b) if (std::isnan(t)) { if (Common::IsSNAN(a) || Common::IsSNAN(b)) + { SetFPException(FPSCR_VXSNAN); + FPSCR.FI = 0; + FPSCR.FR = 0; + } if (std::isnan(a)) return MakeQuiet(a); @@ -135,6 +145,8 @@ inline double NI_div(double a, double b) if (a == 0.0) { SetFPException(FPSCR_VXZDZ); + FPSCR.FI = 0; + FPSCR.FR = 0; } else { @@ -146,6 +158,8 @@ inline double NI_div(double a, double b) else if (std::isinf(a) && std::isinf(b)) { SetFPException(FPSCR_VXIDI); + FPSCR.FI = 0; + FPSCR.FR = 0; } return PPC_NAN; @@ -161,7 +175,11 @@ inline double NI_add(double a, double b) if (std::isnan(t)) { if (Common::IsSNAN(a) || Common::IsSNAN(b)) + { SetFPException(FPSCR_VXSNAN); + FPSCR.FI = 0; + FPSCR.FR = 0; + } if (std::isnan(a)) return MakeQuiet(a); @@ -169,6 +187,8 @@ inline double NI_add(double a, double b) return MakeQuiet(b); SetFPException(FPSCR_VXISI); + FPSCR.FI = 0; + FPSCR.FR = 0; return PPC_NAN; } @@ -182,7 +202,11 @@ inline double NI_sub(double a, double b) if (std::isnan(t)) { if (Common::IsSNAN(a) || Common::IsSNAN(b)) + { SetFPException(FPSCR_VXSNAN); + FPSCR.FI = 0; + FPSCR.FR = 0; + } if (std::isnan(a)) return MakeQuiet(a); @@ -190,6 +214,8 @@ inline double NI_sub(double a, double b) return MakeQuiet(b); SetFPException(FPSCR_VXISI); + FPSCR.FI = 0; + FPSCR.FR = 0; return PPC_NAN; } @@ -206,7 +232,11 @@ inline double NI_madd(double a, double c, double b) if (std::isnan(t)) { if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c)) + { SetFPException(FPSCR_VXSNAN); + FPSCR.FI = 0; + FPSCR.FR = 0; + } if (std::isnan(a)) return MakeQuiet(a); @@ -216,6 +246,8 @@ inline double NI_madd(double a, double c, double b) return MakeQuiet(c); SetFPException(FPSCR_VXIMZ); + FPSCR.FI = 0; + FPSCR.FR = 0; return PPC_NAN; } @@ -224,12 +256,18 @@ inline double NI_madd(double a, double c, double b) if (std::isnan(t)) { if (Common::IsSNAN(b)) + { SetFPException(FPSCR_VXSNAN); + FPSCR.FI = 0; + FPSCR.FR = 0; + } if (std::isnan(b)) return MakeQuiet(b); SetFPException(FPSCR_VXISI); + FPSCR.FI = 0; + FPSCR.FR = 0; return PPC_NAN; } @@ -243,7 +281,11 @@ inline double NI_msub(double a, double c, double b) if (std::isnan(t)) { if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c)) + { SetFPException(FPSCR_VXSNAN); + FPSCR.FI = 0; + FPSCR.FR = 0; + } if (std::isnan(a)) return MakeQuiet(a); @@ -253,6 +295,8 @@ inline double NI_msub(double a, double c, double b) return MakeQuiet(c); SetFPException(FPSCR_VXIMZ); + FPSCR.FI = 0; + FPSCR.FR = 0; return PPC_NAN; } @@ -261,12 +305,18 @@ inline double NI_msub(double a, double c, double b) if (std::isnan(t)) { if (Common::IsSNAN(b)) + { SetFPException(FPSCR_VXSNAN); + FPSCR.FI = 0; + FPSCR.FR = 0; + } if (std::isnan(b)) return MakeQuiet(b); SetFPException(FPSCR_VXISI); + FPSCR.FI = 0; + FPSCR.FR = 0; return PPC_NAN; } |
