From ca36ff0551456fffd98c769b0dc55e56b4fb25b6 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Thu, 25 Jun 2015 05:24:07 +0200 Subject: [PATCH] Interpreter: consolidate fdiv/fdivs/ps_div --- .../PowerPC/Interpreter/Interpreter_FPUtils.h | 22 +++++ .../Interpreter/Interpreter_FloatingPoint.cpp | 69 +------------- .../Interpreter/Interpreter_Paired.cpp | 93 +------------------ 3 files changed, 26 insertions(+), 158 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h index 5392cc7ee0..8fbd379c5b 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h @@ -95,6 +95,28 @@ inline double NI_mul(double a, double b) return t; } +inline double NI_div(double a, double b) +{ + double t = a / b; + if (std::isnan(t)) + { + if (std::isnan(a)) return a; + if (std::isnan(b)) return b; + if (b == 0.0) + { + SetFPException(FPSCR_ZX); + if (a == 0.0) + SetFPException(FPSCR_VXZDZ); + } + else if (std::isinf(a) && std::isinf(b)) + { + SetFPException(FPSCR_VXIDI); + } + return PPC_NAN; + } + return t; +} + inline double NI_add(double a, double b) { double t = a + b; diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp index c5eee4d0ea..fa4132c4ee 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FloatingPoint.cpp @@ -351,38 +351,7 @@ void Interpreter::faddsx(UGeckoInstruction _inst) void Interpreter::fdivx(UGeckoInstruction _inst) { - double a = rPS0(_inst.FA); - double b = rPS0(_inst.FB); - - if (a != a) - { - rPS0(_inst.FD) = a; - } - else if (b != b) - { - rPS0(_inst.FD) = b; - } - else - { - rPS0(_inst.FD) = ForceDouble(a / b); - if (b == 0.0) - { - if (a == 0.0) - { - SetFPException(FPSCR_VXZDZ); - rPS0(_inst.FD) = PPC_NAN; - } - SetFPException(FPSCR_ZX); - } - else - { - if (IsINF(a) && IsINF(b)) - { - SetFPException(FPSCR_VXIDI); - rPS0(_inst.FD) = PPC_NAN; - } - } - } + rPS0(_inst.FD) = ForceDouble(NI_div(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); // FR,FI,OX,UX??? @@ -391,41 +360,7 @@ void Interpreter::fdivx(UGeckoInstruction _inst) } void Interpreter::fdivsx(UGeckoInstruction _inst) { - double a = rPS0(_inst.FA); - double b = rPS0(_inst.FB); - double res; - - if (a != a) - { - res = a; - } - else if (b != b) - { - res = b; - } - else - { - res = ForceSingle(a / b); - if (b == 0.0) - { - if (a == 0.0) - { - SetFPException(FPSCR_VXZDZ); - res = PPC_NAN; - } - SetFPException(FPSCR_ZX); - } - else - { - if (IsINF(a) && IsINF(b)) - { - SetFPException(FPSCR_VXIDI); - res = PPC_NAN; - } - } - } - - rPS0(_inst.FD) = rPS1(_inst.FD) = res; + rPS0(_inst.FD) = rPS1(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp index 2c9656bd8f..fc56a4a33d 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Paired.cpp @@ -104,97 +104,8 @@ void Interpreter::ps_merge11(UGeckoInstruction _inst) // From here on, the real deal. void Interpreter::ps_div(UGeckoInstruction _inst) { - u32 ex_mask = 0; - - // PS0 - { - double a = rPS0(_inst.FA); - double b = rPS0(_inst.FB); - double &res = rPS0(_inst.FD); - - if (a != a) - { - res = a; - } - else if (b != b) - { - res = b; - } - else - { - if (b == 0.0) - { - ex_mask |= FPSCR_ZX; - if (rPS0(_inst.FA) == 0.0) - { - ex_mask |= FPSCR_VXZDZ; - res = PPC_NAN; - } - else - { - res = ForceSingle(a / b); - } - } - else - { - if (IsINF(a) && IsINF(b)) - { - ex_mask |= FPSCR_VXIDI; - res = PPC_NAN; - } - else - { - res = ForceSingle(a / b); - } - } - } - } - - // PS1 - { - double a = rPS1(_inst.FA); - double b = rPS1(_inst.FB); - double &res = rPS1(_inst.FD); - - if (a != a) - { - res = a; - } - else if (b != b) - { - res = b; - } - else - { - if (b == 0.0) - { - ex_mask |= FPSCR_ZX; - if (rPS0(_inst.FA) == 0.0) - { - ex_mask |= FPSCR_VXZDZ; - res = PPC_NAN; - } - else - { - res = ForceSingle(a / b); - } - } - else - { - if (IsINF(a) && IsINF(b)) - { - ex_mask |= FPSCR_VXIDI; - res = PPC_NAN; - } - else - { - res = ForceSingle(a / b); - } - } - } - } - - SetFPException(ex_mask); + rPS0(_inst.FD) = ForceSingle(NI_div(rPS0(_inst.FA), rPS0(_inst.FB))); + rPS1(_inst.FD) = ForceSingle(NI_div(rPS1(_inst.FA), rPS1(_inst.FB))); UpdateFPRF(rPS0(_inst.FD)); if (_inst.Rc)