Interpreter_FPUtils: Set FPSCR.VXSNAN if any operand to NI_madd is a signaling NaN

If any operand is a signaling NaN, we need to signify this by setting
the VXSNAN bit.

Fixes NaN flag setting for fmadd, fmadds, fnmadd, fnmadds, ps_madd,
ps_nmadd, ps_madds0, and ps_madds1
This commit is contained in:
Lioncash 2018-05-27 16:17:58 -04:00
parent b18dd442f7
commit 3ebd713c33
1 changed files with 12 additions and 0 deletions

View File

@ -190,25 +190,37 @@ inline double NI_sub(double a, double b)
inline double NI_madd(double a, double c, double b) inline double NI_madd(double a, double c, double b)
{ {
double t = a * c; double t = a * c;
if (std::isnan(t)) if (std::isnan(t))
{ {
if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c))
SetFPException(FPSCR_VXSNAN);
if (std::isnan(a)) if (std::isnan(a))
return MakeQuiet(a); return MakeQuiet(a);
if (std::isnan(b)) if (std::isnan(b))
return MakeQuiet(b); // ! return MakeQuiet(b); // !
if (std::isnan(c)) if (std::isnan(c))
return MakeQuiet(c); return MakeQuiet(c);
SetFPException(FPSCR_VXIMZ); SetFPException(FPSCR_VXIMZ);
return PPC_NAN; return PPC_NAN;
} }
t += b; t += b;
if (std::isnan(t)) if (std::isnan(t))
{ {
if (Common::IsSNAN(b))
SetFPException(FPSCR_VXSNAN);
if (std::isnan(b)) if (std::isnan(b))
return MakeQuiet(b); return MakeQuiet(b);
SetFPException(FPSCR_VXISI); SetFPException(FPSCR_VXISI);
return PPC_NAN; return PPC_NAN;
} }
return t; return t;
} }