diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h index 1311f3958a..296b85959c 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h @@ -97,206 +97,280 @@ inline double MakeQuiet(double d) // these functions allow globally modify operations behaviour // also, these may be used to set flags like FR, FI, OX, UX -inline double NI_mul(double a, double b) +struct FPResult { - const double t = a * b; - if (std::isnan(t)) + bool HasNoInvalidExceptions() const { return (exception & FPSCR_VX_ANY) == 0; } + + void SetException(FPSCRExceptionFlag flag) + { + exception = flag; + SetFPException(flag); + } + + double value = 0.0; + FPSCRExceptionFlag exception{}; +}; + +inline FPResult NI_mul(double a, double b) +{ + FPResult result{a * b}; + + if (std::isnan(result.value)) { if (Common::IsSNAN(a) || Common::IsSNAN(b)) - SetFPException(FPSCR_VXSNAN); + { + result.SetException(FPSCR_VXSNAN); + } FPSCR.ClearFIFR(); if (std::isnan(a)) - return MakeQuiet(a); + { + result.value = MakeQuiet(a); + return result; + } if (std::isnan(b)) - return MakeQuiet(b); + { + result.value = MakeQuiet(b); + return result; + } - SetFPException(FPSCR_VXIMZ); - return PPC_NAN; + result.value = PPC_NAN; + result.SetException(FPSCR_VXIMZ); + return result; } - return t; + + return result; } -inline double NI_div(double a, double b) +inline FPResult NI_div(double a, double b) { - const double t = a / b; + FPResult result{a / b}; - if (std::isnan(t)) + if (std::isnan(result.value)) { if (Common::IsSNAN(a) || Common::IsSNAN(b)) - SetFPException(FPSCR_VXSNAN); + result.SetException(FPSCR_VXSNAN); FPSCR.ClearFIFR(); if (std::isnan(a)) - return MakeQuiet(a); + { + result.value = MakeQuiet(a); + return result; + } if (std::isnan(b)) - return MakeQuiet(b); + { + result.value = MakeQuiet(b); + return result; + } if (b == 0.0) { if (a == 0.0) { - SetFPException(FPSCR_VXZDZ); + result.SetException(FPSCR_VXZDZ); } else { - SetFPException(FPSCR_ZX); + result.SetException(FPSCR_ZX); } } else if (std::isinf(a) && std::isinf(b)) { - SetFPException(FPSCR_VXIDI); + result.SetException(FPSCR_VXIDI); } - return PPC_NAN; + result.value = PPC_NAN; + return result; } - return t; + return result; } -inline double NI_add(double a, double b) +inline FPResult NI_add(double a, double b) { - const double t = a + b; + FPResult result{a + b}; - if (std::isnan(t)) + if (std::isnan(result.value)) { if (Common::IsSNAN(a) || Common::IsSNAN(b)) - SetFPException(FPSCR_VXSNAN); + result.SetException(FPSCR_VXSNAN); FPSCR.ClearFIFR(); if (std::isnan(a)) - return MakeQuiet(a); + { + result.value = MakeQuiet(a); + return result; + } if (std::isnan(b)) - return MakeQuiet(b); + { + result.value = MakeQuiet(b); + return result; + } - SetFPException(FPSCR_VXISI); - return PPC_NAN; + result.SetException(FPSCR_VXISI); + result.value = PPC_NAN; + return result; } if (std::isinf(a) || std::isinf(b)) FPSCR.ClearFIFR(); - return t; + return result; } -inline double NI_sub(double a, double b) +inline FPResult NI_sub(double a, double b) { - const double t = a - b; + FPResult result{a - b}; - if (std::isnan(t)) + if (std::isnan(result.value)) { if (Common::IsSNAN(a) || Common::IsSNAN(b)) - SetFPException(FPSCR_VXSNAN); + result.SetException(FPSCR_VXSNAN); FPSCR.ClearFIFR(); if (std::isnan(a)) - return MakeQuiet(a); + { + result.value = MakeQuiet(a); + return result; + } if (std::isnan(b)) - return MakeQuiet(b); + { + result.value = MakeQuiet(b); + return result; + } - SetFPException(FPSCR_VXISI); - return PPC_NAN; + result.SetException(FPSCR_VXISI); + result.value = PPC_NAN; + return result; } if (std::isinf(a) || std::isinf(b)) FPSCR.ClearFIFR(); - return t; + return result; } // FMA instructions on PowerPC are weird: // They calculate (a * c) + b, but the order in which // inputs are checked for NaN is still a, b, c. -inline double NI_madd(double a, double c, double b) +inline FPResult NI_madd(double a, double c, double b) { - double t = a * c; + FPResult result{a * c}; - if (std::isnan(t)) + if (std::isnan(result.value)) { if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c)) - SetFPException(FPSCR_VXSNAN); + result.SetException(FPSCR_VXSNAN); FPSCR.ClearFIFR(); if (std::isnan(a)) - return MakeQuiet(a); + { + result.value = MakeQuiet(a); + return result; + } if (std::isnan(b)) - return MakeQuiet(b); // ! + { + result.value = MakeQuiet(b); // ! + return result; + } if (std::isnan(c)) - return MakeQuiet(c); + { + result.value = MakeQuiet(c); + return result; + } - SetFPException(FPSCR_VXIMZ); - return PPC_NAN; + result.SetException(FPSCR_VXIMZ); + result.value = PPC_NAN; + return result; } - t += b; + result.value += b; - if (std::isnan(t)) + if (std::isnan(result.value)) { if (Common::IsSNAN(b)) - SetFPException(FPSCR_VXSNAN); + result.SetException(FPSCR_VXSNAN); FPSCR.ClearFIFR(); if (std::isnan(b)) - return MakeQuiet(b); + { + result.value = MakeQuiet(b); + return result; + } - SetFPException(FPSCR_VXISI); - return PPC_NAN; + result.SetException(FPSCR_VXISI); + result.value = PPC_NAN; + return result; } if (std::isinf(a) || std::isinf(b) || std::isinf(c)) FPSCR.ClearFIFR(); - return t; + return result; } -inline double NI_msub(double a, double c, double b) +inline FPResult NI_msub(double a, double c, double b) { - double t = a * c; + FPResult result{a * c}; - if (std::isnan(t)) + if (std::isnan(result.value)) { if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c)) - SetFPException(FPSCR_VXSNAN); + result.SetException(FPSCR_VXSNAN); FPSCR.ClearFIFR(); if (std::isnan(a)) - return MakeQuiet(a); + { + result.value = MakeQuiet(a); + return result; + } if (std::isnan(b)) - return MakeQuiet(b); // ! + { + result.value = MakeQuiet(b); // ! + return result; + } if (std::isnan(c)) - return MakeQuiet(c); + { + result.value = MakeQuiet(c); + return result; + } - SetFPException(FPSCR_VXIMZ); - return PPC_NAN; + result.SetException(FPSCR_VXIMZ); + result.value = PPC_NAN; + return result; } - t -= b; + result.value -= b; - if (std::isnan(t)) + if (std::isnan(result.value)) { if (Common::IsSNAN(b)) - SetFPException(FPSCR_VXSNAN); + result.SetException(FPSCR_VXSNAN); FPSCR.ClearFIFR(); if (std::isnan(b)) - return MakeQuiet(b); + { + result.value = MakeQuiet(b); + return result; + } - SetFPException(FPSCR_VXISI); - return PPC_NAN; + result.SetException(FPSCR_VXISI); + result.value = PPC_NAN; + return result; } if (std::isinf(a) || std::isinf(b) || std::isinf(c)) FPSCR.ClearFIFR(); - return t; + return result; } // used by stfsXX instructions and ps_rsqrte diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index 5fe173dcbc..3a68997bf0 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -300,23 +300,35 @@ void Interpreter::frspx(UGeckoInstruction inst) // round to single void Interpreter::fmulx(UGeckoInstruction inst) { - rPS0(inst.FD) = ForceDouble(NI_mul(rPS0(inst.FA), rPS0(inst.FC))); - FPSCR.FI = 0; // are these flags important? - FPSCR.FR = 0; - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult product = NI_mul(rPS0(inst.FA), rPS0(inst.FC)); + + if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) + { + const double result = ForceDouble(product.value); + + rPS0(inst.FD) = result; + FPSCR.FI = 0; // are these flags important? + FPSCR.FR = 0; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); } void Interpreter::fmulsx(UGeckoInstruction inst) { - double c_value = Force25Bit(rPS0(inst.FC)); - double d_value = NI_mul(rPS0(inst.FA), c_value); - rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(d_value); - // FPSCR.FI = d_value != rPS0(_inst.FD); - FPSCR.FI = 0; - FPSCR.FR = 0; - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const double c_value = Force25Bit(rPS0(inst.FC)); + const FPResult d_value = NI_mul(rPS0(inst.FA), c_value); + + if (FPSCR.VE == 0 || d_value.HasNoInvalidExceptions()) + { + const double result = ForceSingle(d_value.value); + + rPS0(inst.FD) = rPS1(inst.FD) = result; + FPSCR.FI = 0; + FPSCR.FR = 0; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); @@ -324,9 +336,14 @@ void Interpreter::fmulsx(UGeckoInstruction inst) void Interpreter::fmaddx(UGeckoInstruction inst) { - double result = ForceDouble(NI_madd(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB))); - rPS0(inst.FD) = result; - PowerPC::UpdateFPRF(result); + const FPResult product = NI_madd(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)); + + if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) + { + const double result = ForceDouble(product.value); + rPS0(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); @@ -334,12 +351,18 @@ void Interpreter::fmaddx(UGeckoInstruction inst) void Interpreter::fmaddsx(UGeckoInstruction inst) { - double c_value = Force25Bit(rPS0(inst.FC)); - double d_value = NI_madd(rPS0(inst.FA), c_value, rPS0(inst.FB)); - rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(d_value); - FPSCR.FI = d_value != rPS0(inst.FD); - FPSCR.FR = 0; - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const double c_value = Force25Bit(rPS0(inst.FC)); + const FPResult d_value = NI_madd(rPS0(inst.FA), c_value, rPS0(inst.FB)); + + if (FPSCR.VE == 0 || d_value.HasNoInvalidExceptions()) + { + const double result = ForceSingle(d_value.value); + + rPS0(inst.FD) = rPS1(inst.FD) = result; + FPSCR.FI = d_value.value != result; + FPSCR.FR = 0; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); @@ -347,16 +370,28 @@ void Interpreter::fmaddsx(UGeckoInstruction inst) void Interpreter::faddx(UGeckoInstruction inst) { - rPS0(inst.FD) = ForceDouble(NI_add(rPS0(inst.FA), rPS0(inst.FB))); - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult sum = NI_add(rPS0(inst.FA), rPS0(inst.FB)); + + if (FPSCR.VE == 0 || sum.HasNoInvalidExceptions()) + { + const double result = ForceDouble(sum.value); + rPS0(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); } void Interpreter::faddsx(UGeckoInstruction inst) { - rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_add(rPS0(inst.FA), rPS0(inst.FB))); - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult sum = NI_add(rPS0(inst.FA), rPS0(inst.FB)); + + if (FPSCR.VE == 0 || sum.HasNoInvalidExceptions()) + { + const double result = ForceSingle(sum.value); + rPS0(inst.FD) = rPS1(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); @@ -364,8 +399,16 @@ void Interpreter::faddsx(UGeckoInstruction inst) void Interpreter::fdivx(UGeckoInstruction inst) { - rPS0(inst.FD) = ForceDouble(NI_div(rPS0(inst.FA), rPS0(inst.FB))); - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult quotient = NI_div(rPS0(inst.FA), rPS0(inst.FB)); + const bool not_divide_by_zero = FPSCR.ZE == 0 || quotient.exception != FPSCR_ZX; + const bool not_invalid = FPSCR.VE == 0 || quotient.HasNoInvalidExceptions(); + + if (not_divide_by_zero && not_invalid) + { + const double result = ForceDouble(quotient.value); + rPS0(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } // FR,FI,OX,UX??? if (inst.Rc) @@ -373,8 +416,16 @@ void Interpreter::fdivx(UGeckoInstruction inst) } void Interpreter::fdivsx(UGeckoInstruction inst) { - rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_div(rPS0(inst.FA), rPS0(inst.FB))); - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult quotient = NI_div(rPS0(inst.FA), rPS0(inst.FB)); + const bool not_divide_by_zero = FPSCR.ZE == 0 || quotient.exception != FPSCR_ZX; + const bool not_invalid = FPSCR.VE == 0 || quotient.HasNoInvalidExceptions(); + + if (not_divide_by_zero && not_invalid) + { + const double result = ForceSingle(quotient.value); + rPS0(inst.FD) = rPS1(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); @@ -465,20 +516,32 @@ void Interpreter::frsqrtex(UGeckoInstruction inst) Helper_UpdateCR1(); } -void Interpreter::fmsubx(UGeckoInstruction _inst) +void Interpreter::fmsubx(UGeckoInstruction inst) { - rPS0(_inst.FD) = ForceDouble(NI_msub(rPS0(_inst.FA), rPS0(_inst.FC), rPS0(_inst.FB))); - PowerPC::UpdateFPRF(rPS0(_inst.FD)); + const FPResult product = NI_msub(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)); - if (_inst.Rc) + if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) + { + const double result = ForceDouble(product.value); + rPS0(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } + + if (inst.Rc) Helper_UpdateCR1(); } void Interpreter::fmsubsx(UGeckoInstruction inst) { - double c_value = Force25Bit(rPS0(inst.FC)); - rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_msub(rPS0(inst.FA), c_value, rPS0(inst.FB))); - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const double c_value = Force25Bit(rPS0(inst.FC)); + const FPResult product = NI_msub(rPS0(inst.FA), c_value, rPS0(inst.FB)); + + if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) + { + const double result = ForceSingle(product.value); + rPS0(inst.FD) = rPS1(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); @@ -486,9 +549,14 @@ void Interpreter::fmsubsx(UGeckoInstruction inst) void Interpreter::fnmaddx(UGeckoInstruction inst) { - double result = ForceDouble(NI_madd(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB))); - rPS0(inst.FD) = std::isnan(result) ? result : -result; - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult product = NI_madd(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)); + + if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) + { + const double result = ForceDouble(product.value); + rPS0(inst.FD) = std::isnan(result) ? result : -result; + PowerPC::UpdateFPRF(rPS0(inst.FD)); + } if (inst.Rc) Helper_UpdateCR1(); @@ -496,10 +564,15 @@ void Interpreter::fnmaddx(UGeckoInstruction inst) void Interpreter::fnmaddsx(UGeckoInstruction inst) { - double c_value = Force25Bit(rPS0(inst.FC)); - double result = ForceSingle(NI_madd(rPS0(inst.FA), c_value, rPS0(inst.FB))); - rPS0(inst.FD) = rPS1(inst.FD) = std::isnan(result) ? result : -result; - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const double c_value = Force25Bit(rPS0(inst.FC)); + const FPResult product = NI_madd(rPS0(inst.FA), c_value, rPS0(inst.FB)); + + if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) + { + const double result = ForceSingle(product.value); + rPS0(inst.FD) = rPS1(inst.FD) = std::isnan(result) ? result : -result; + PowerPC::UpdateFPRF(rPS0(inst.FD)); + } if (inst.Rc) Helper_UpdateCR1(); @@ -507,9 +580,14 @@ void Interpreter::fnmaddsx(UGeckoInstruction inst) void Interpreter::fnmsubx(UGeckoInstruction inst) { - double result = ForceDouble(NI_msub(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB))); - rPS0(inst.FD) = std::isnan(result) ? result : -result; - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult product = NI_msub(rPS0(inst.FA), rPS0(inst.FC), rPS0(inst.FB)); + + if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) + { + const double result = ForceDouble(product.value); + rPS0(inst.FD) = std::isnan(result) ? result : -result; + PowerPC::UpdateFPRF(rPS0(inst.FD)); + } if (inst.Rc) Helper_UpdateCR1(); @@ -517,10 +595,15 @@ void Interpreter::fnmsubx(UGeckoInstruction inst) void Interpreter::fnmsubsx(UGeckoInstruction inst) { - double c_value = Force25Bit(rPS0(inst.FC)); - double result = ForceSingle(NI_msub(rPS0(inst.FA), c_value, rPS0(inst.FB))); - rPS0(inst.FD) = rPS1(inst.FD) = std::isnan(result) ? result : -result; - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const double c_value = Force25Bit(rPS0(inst.FC)); + const FPResult product = NI_msub(rPS0(inst.FA), c_value, rPS0(inst.FB)); + + if (FPSCR.VE == 0 || product.HasNoInvalidExceptions()) + { + const double result = ForceSingle(product.value); + rPS0(inst.FD) = rPS1(inst.FD) = std::isnan(result) ? result : -result; + PowerPC::UpdateFPRF(rPS0(inst.FD)); + } if (inst.Rc) Helper_UpdateCR1(); @@ -528,8 +611,14 @@ void Interpreter::fnmsubsx(UGeckoInstruction inst) void Interpreter::fsubx(UGeckoInstruction inst) { - rPS0(inst.FD) = ForceDouble(NI_sub(rPS0(inst.FA), rPS0(inst.FB))); - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult difference = NI_sub(rPS0(inst.FA), rPS0(inst.FB)); + + if (FPSCR.VE == 0 || difference.HasNoInvalidExceptions()) + { + const double result = ForceDouble(difference.value); + rPS0(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); @@ -537,8 +626,14 @@ void Interpreter::fsubx(UGeckoInstruction inst) void Interpreter::fsubsx(UGeckoInstruction inst) { - rPS0(inst.FD) = rPS1(inst.FD) = ForceSingle(NI_sub(rPS0(inst.FA), rPS0(inst.FB))); - PowerPC::UpdateFPRF(rPS0(inst.FD)); + const FPResult difference = NI_sub(rPS0(inst.FA), rPS0(inst.FB)); + + if (FPSCR.VE == 0 || difference.HasNoInvalidExceptions()) + { + const double result = ForceSingle(difference.value); + rPS0(inst.FD) = rPS1(inst.FD) = result; + PowerPC::UpdateFPRF(result); + } if (inst.Rc) Helper_UpdateCR1(); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index f3c55e7fc0..02df9993a9 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -104,8 +104,8 @@ void Interpreter::ps_merge11(UGeckoInstruction inst) // From here on, the real deal. void Interpreter::ps_div(UGeckoInstruction inst) { - rPS0(inst.FD) = ForceSingle(NI_div(rPS0(inst.FA), rPS0(inst.FB))); - rPS1(inst.FD) = ForceSingle(NI_div(rPS1(inst.FA), rPS1(inst.FB))); + rPS0(inst.FD) = ForceSingle(NI_div(rPS0(inst.FA), rPS0(inst.FB)).value); + rPS1(inst.FD) = ForceSingle(NI_div(rPS1(inst.FA), rPS1(inst.FB)).value); PowerPC::UpdateFPRF(rPS0(inst.FD)); if (inst.Rc) @@ -172,8 +172,8 @@ void Interpreter::ps_rsqrte(UGeckoInstruction inst) void Interpreter::ps_sub(UGeckoInstruction inst) { - rPS0(inst.FD) = ForceSingle(NI_sub(rPS0(inst.FA), rPS0(inst.FB))); - rPS1(inst.FD) = ForceSingle(NI_sub(rPS1(inst.FA), rPS1(inst.FB))); + rPS0(inst.FD) = ForceSingle(NI_sub(rPS0(inst.FA), rPS0(inst.FB)).value); + rPS1(inst.FD) = ForceSingle(NI_sub(rPS1(inst.FA), rPS1(inst.FB)).value); PowerPC::UpdateFPRF(rPS0(inst.FD)); if (inst.Rc) @@ -182,8 +182,8 @@ void Interpreter::ps_sub(UGeckoInstruction inst) void Interpreter::ps_add(UGeckoInstruction inst) { - rPS0(inst.FD) = ForceSingle(NI_add(rPS0(inst.FA), rPS0(inst.FB))); - rPS1(inst.FD) = ForceSingle(NI_add(rPS1(inst.FA), rPS1(inst.FB))); + rPS0(inst.FD) = ForceSingle(NI_add(rPS0(inst.FA), rPS0(inst.FB)).value); + rPS1(inst.FD) = ForceSingle(NI_add(rPS1(inst.FA), rPS1(inst.FB)).value); PowerPC::UpdateFPRF(rPS0(inst.FD)); if (inst.Rc) @@ -192,10 +192,10 @@ void Interpreter::ps_add(UGeckoInstruction inst) void Interpreter::ps_mul(UGeckoInstruction inst) { - double c0 = Force25Bit(rPS0(inst.FC)); - double c1 = Force25Bit(rPS1(inst.FC)); - rPS0(inst.FD) = ForceSingle(NI_mul(rPS0(inst.FA), c0)); - rPS1(inst.FD) = ForceSingle(NI_mul(rPS1(inst.FA), c1)); + const double c0 = Force25Bit(rPS0(inst.FC)); + const double c1 = Force25Bit(rPS1(inst.FC)); + rPS0(inst.FD) = ForceSingle(NI_mul(rPS0(inst.FA), c0).value); + rPS1(inst.FD) = ForceSingle(NI_mul(rPS1(inst.FA), c1).value); PowerPC::UpdateFPRF(rPS0(inst.FD)); if (inst.Rc) @@ -204,10 +204,10 @@ void Interpreter::ps_mul(UGeckoInstruction inst) void Interpreter::ps_msub(UGeckoInstruction inst) { - double c0 = Force25Bit(rPS0(inst.FC)); - double c1 = Force25Bit(rPS1(inst.FC)); - rPS0(inst.FD) = ForceSingle(NI_msub(rPS0(inst.FA), c0, rPS0(inst.FB))); - rPS1(inst.FD) = ForceSingle(NI_msub(rPS1(inst.FA), c1, rPS1(inst.FB))); + const double c0 = Force25Bit(rPS0(inst.FC)); + const double c1 = Force25Bit(rPS1(inst.FC)); + rPS0(inst.FD) = ForceSingle(NI_msub(rPS0(inst.FA), c0, rPS0(inst.FB)).value); + rPS1(inst.FD) = ForceSingle(NI_msub(rPS1(inst.FA), c1, rPS1(inst.FB)).value); PowerPC::UpdateFPRF(rPS0(inst.FD)); if (inst.Rc) @@ -216,10 +216,10 @@ void Interpreter::ps_msub(UGeckoInstruction inst) void Interpreter::ps_madd(UGeckoInstruction inst) { - double c0 = Force25Bit(rPS0(inst.FC)); - double c1 = Force25Bit(rPS1(inst.FC)); - rPS0(inst.FD) = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB))); - rPS1(inst.FD) = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB))); + const double c0 = Force25Bit(rPS0(inst.FC)); + const double c1 = Force25Bit(rPS1(inst.FC)); + rPS0(inst.FD) = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB)).value); + rPS1(inst.FD) = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB)).value); PowerPC::UpdateFPRF(rPS0(inst.FD)); if (inst.Rc) @@ -228,10 +228,10 @@ void Interpreter::ps_madd(UGeckoInstruction inst) void Interpreter::ps_nmsub(UGeckoInstruction inst) { - double c0 = Force25Bit(rPS0(inst.FC)); - double c1 = Force25Bit(rPS1(inst.FC)); - double result0 = ForceSingle(NI_msub(rPS0(inst.FA), c0, rPS0(inst.FB))); - double result1 = ForceSingle(NI_msub(rPS1(inst.FA), c1, rPS1(inst.FB))); + const double c0 = Force25Bit(rPS0(inst.FC)); + const double c1 = Force25Bit(rPS1(inst.FC)); + const double result0 = ForceSingle(NI_msub(rPS0(inst.FA), c0, rPS0(inst.FB)).value); + const double result1 = ForceSingle(NI_msub(rPS1(inst.FA), c1, rPS1(inst.FB)).value); rPS0(inst.FD) = std::isnan(result0) ? result0 : -result0; rPS1(inst.FD) = std::isnan(result1) ? result1 : -result1; PowerPC::UpdateFPRF(rPS0(inst.FD)); @@ -242,10 +242,10 @@ void Interpreter::ps_nmsub(UGeckoInstruction inst) void Interpreter::ps_nmadd(UGeckoInstruction inst) { - double c0 = Force25Bit(rPS0(inst.FC)); - double c1 = Force25Bit(rPS1(inst.FC)); - double result0 = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB))); - double result1 = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB))); + const double c0 = Force25Bit(rPS0(inst.FC)); + const double c1 = Force25Bit(rPS1(inst.FC)); + const double result0 = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB)).value); + const double result1 = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB)).value); rPS0(inst.FD) = std::isnan(result0) ? result0 : -result0; rPS1(inst.FD) = std::isnan(result1) ? result1 : -result1; PowerPC::UpdateFPRF(rPS0(inst.FD)); @@ -256,8 +256,8 @@ void Interpreter::ps_nmadd(UGeckoInstruction inst) void Interpreter::ps_sum0(UGeckoInstruction inst) { - double p0 = ForceSingle(NI_add(rPS0(inst.FA), rPS1(inst.FB))); - double p1 = ForceSingle(rPS1(inst.FC)); + const double p0 = ForceSingle(NI_add(rPS0(inst.FA), rPS1(inst.FB)).value); + const double p1 = ForceSingle(rPS1(inst.FC)); rPS0(inst.FD) = p0; rPS1(inst.FD) = p1; PowerPC::UpdateFPRF(rPS0(inst.FD)); @@ -268,8 +268,8 @@ void Interpreter::ps_sum0(UGeckoInstruction inst) void Interpreter::ps_sum1(UGeckoInstruction inst) { - double p0 = ForceSingle(rPS0(inst.FC)); - double p1 = ForceSingle(NI_add(rPS0(inst.FA), rPS1(inst.FB))); + const double p0 = ForceSingle(rPS0(inst.FC)); + const double p1 = ForceSingle(NI_add(rPS0(inst.FA), rPS1(inst.FB)).value); rPS0(inst.FD) = p0; rPS1(inst.FD) = p1; PowerPC::UpdateFPRF(rPS1(inst.FD)); @@ -280,9 +280,9 @@ void Interpreter::ps_sum1(UGeckoInstruction inst) void Interpreter::ps_muls0(UGeckoInstruction inst) { - double c0 = Force25Bit(rPS0(inst.FC)); - double p0 = ForceSingle(NI_mul(rPS0(inst.FA), c0)); - double p1 = ForceSingle(NI_mul(rPS1(inst.FA), c0)); + const double c0 = Force25Bit(rPS0(inst.FC)); + const double p0 = ForceSingle(NI_mul(rPS0(inst.FA), c0).value); + const double p1 = ForceSingle(NI_mul(rPS1(inst.FA), c0).value); rPS0(inst.FD) = p0; rPS1(inst.FD) = p1; PowerPC::UpdateFPRF(rPS0(inst.FD)); @@ -293,9 +293,9 @@ void Interpreter::ps_muls0(UGeckoInstruction inst) void Interpreter::ps_muls1(UGeckoInstruction inst) { - double c1 = Force25Bit(rPS1(inst.FC)); - double p0 = ForceSingle(NI_mul(rPS0(inst.FA), c1)); - double p1 = ForceSingle(NI_mul(rPS1(inst.FA), c1)); + const double c1 = Force25Bit(rPS1(inst.FC)); + const double p0 = ForceSingle(NI_mul(rPS0(inst.FA), c1).value); + const double p1 = ForceSingle(NI_mul(rPS1(inst.FA), c1).value); rPS0(inst.FD) = p0; rPS1(inst.FD) = p1; PowerPC::UpdateFPRF(rPS0(inst.FD)); @@ -306,9 +306,9 @@ void Interpreter::ps_muls1(UGeckoInstruction inst) void Interpreter::ps_madds0(UGeckoInstruction inst) { - double c0 = Force25Bit(rPS0(inst.FC)); - double p0 = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB))); - double p1 = ForceSingle(NI_madd(rPS1(inst.FA), c0, rPS1(inst.FB))); + const double c0 = Force25Bit(rPS0(inst.FC)); + const double p0 = ForceSingle(NI_madd(rPS0(inst.FA), c0, rPS0(inst.FB)).value); + const double p1 = ForceSingle(NI_madd(rPS1(inst.FA), c0, rPS1(inst.FB)).value); rPS0(inst.FD) = p0; rPS1(inst.FD) = p1; PowerPC::UpdateFPRF(rPS0(inst.FD)); @@ -319,9 +319,9 @@ void Interpreter::ps_madds0(UGeckoInstruction inst) void Interpreter::ps_madds1(UGeckoInstruction inst) { - double c1 = Force25Bit(rPS1(inst.FC)); - double p0 = ForceSingle(NI_madd(rPS0(inst.FA), c1, rPS0(inst.FB))); - double p1 = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB))); + const double c1 = Force25Bit(rPS1(inst.FC)); + const double p0 = ForceSingle(NI_madd(rPS0(inst.FA), c1, rPS0(inst.FB)).value); + const double p1 = ForceSingle(NI_madd(rPS1(inst.FA), c1, rPS1(inst.FB)).value); rPS0(inst.FD) = p0; rPS1(inst.FD) = p1; PowerPC::UpdateFPRF(rPS0(inst.FD));