From c7544719e2722dbb3df3881e4f65b7ee7ca945f7 Mon Sep 17 00:00:00 2001 From: Tillmann Karras Date: Wed, 10 Jun 2015 14:23:43 +0200 Subject: [PATCH] Interpreter: optimize NaN checks NaNs always propagate, so we can get away with only checking for NaN inputs in the rare case that the result is NaN (as already done in Jit64::HandleNaNs()). --- .../PowerPC/Interpreter/Interpreter_FPUtils.h | 29 +++++++++++-------- 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h index 795bab7b0e..90990b69d4 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_FPUtils.h @@ -83,11 +83,11 @@ inline double Force25Bit(double d) inline double NI_mul(double a, double b) { - if (a != a) return a; - if (b != b) return b; double t = a * b; if (t != t) { + if (a != a) return a; + if (b != b) return b; SetFPException(FPSCR_VXIMZ); return PPC_NAN; } @@ -96,11 +96,11 @@ inline double NI_mul(double a, double b) inline double NI_add(double a, double b) { - if (a != a) return a; - if (b != b) return b; double t = a + b; if (t != t) { + if (a != a) return a; + if (b != b) return b; SetFPException(FPSCR_VXISI); return PPC_NAN; } @@ -109,31 +109,35 @@ inline double NI_add(double a, double b) inline double NI_sub(double a, double b) { - if (a != a) return a; - if (b != b) return b; double t = a - b; if (t != t) { + if (a != a) return a; + if (b != b) return b; SetFPException(FPSCR_VXISI); return PPC_NAN; } return t; } +// 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, bool negate = false) { - if (a != a) return a; - if (b != b) return b; - if (c != c) return c; double t = a * c; if (t != t) { + if (a != a) return a; + if (b != b) return b; // ! + if (c != c) return c; SetFPException(FPSCR_VXIMZ); return PPC_NAN; } t = t + b; if (t != t) { + if (b != b) return b; SetFPException(FPSCR_VXISI); return PPC_NAN; } @@ -142,12 +146,12 @@ inline double NI_madd(double a, double c, double b, bool negate = false) inline double NI_msub(double a, double c, double b, bool negate = false) { - if (a != a) return a; - if (b != b) return b; - if (c != c) return c; double t = a * c; if (t != t) { + if (a != a) return a; + if (b != b) return b; // ! + if (c != c) return c; SetFPException(FPSCR_VXIMZ); return PPC_NAN; } @@ -155,6 +159,7 @@ inline double NI_msub(double a, double c, double b, bool negate = false) t = t - b; if (t != t) { + if (b != b) return b; SetFPException(FPSCR_VXISI); return PPC_NAN; }