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()).
This commit is contained in:
Tillmann Karras 2015-06-10 14:23:43 +02:00
parent 9b8eb55cd4
commit c7544719e2
1 changed files with 17 additions and 12 deletions

View File

@ -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;
}