Interpreter_FPUtils: Unset FPSCR.FI and FPSCR.FR if an invalid operation occurs in NI_* functions
If an invalid operation occurs, FI and FR bits are defined to be cleared to zero for arithmetic operations.
This commit is contained in:
parent
0f7370a22c
commit
468efb7243
|
@ -103,7 +103,11 @@ inline double NI_mul(double a, double b)
|
||||||
if (std::isnan(t))
|
if (std::isnan(t))
|
||||||
{
|
{
|
||||||
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
||||||
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::isnan(a))
|
if (std::isnan(a))
|
||||||
return MakeQuiet(a);
|
return MakeQuiet(a);
|
||||||
|
@ -111,6 +115,8 @@ inline double NI_mul(double a, double b)
|
||||||
return MakeQuiet(b);
|
return MakeQuiet(b);
|
||||||
|
|
||||||
SetFPException(FPSCR_VXIMZ);
|
SetFPException(FPSCR_VXIMZ);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
return PPC_NAN;
|
return PPC_NAN;
|
||||||
}
|
}
|
||||||
return t;
|
return t;
|
||||||
|
@ -123,7 +129,11 @@ inline double NI_div(double a, double b)
|
||||||
if (std::isnan(t))
|
if (std::isnan(t))
|
||||||
{
|
{
|
||||||
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
||||||
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::isnan(a))
|
if (std::isnan(a))
|
||||||
return MakeQuiet(a);
|
return MakeQuiet(a);
|
||||||
|
@ -135,6 +145,8 @@ inline double NI_div(double a, double b)
|
||||||
if (a == 0.0)
|
if (a == 0.0)
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_VXZDZ);
|
SetFPException(FPSCR_VXZDZ);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -146,6 +158,8 @@ inline double NI_div(double a, double b)
|
||||||
else if (std::isinf(a) && std::isinf(b))
|
else if (std::isinf(a) && std::isinf(b))
|
||||||
{
|
{
|
||||||
SetFPException(FPSCR_VXIDI);
|
SetFPException(FPSCR_VXIDI);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return PPC_NAN;
|
return PPC_NAN;
|
||||||
|
@ -161,7 +175,11 @@ inline double NI_add(double a, double b)
|
||||||
if (std::isnan(t))
|
if (std::isnan(t))
|
||||||
{
|
{
|
||||||
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
||||||
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::isnan(a))
|
if (std::isnan(a))
|
||||||
return MakeQuiet(a);
|
return MakeQuiet(a);
|
||||||
|
@ -169,6 +187,8 @@ inline double NI_add(double a, double b)
|
||||||
return MakeQuiet(b);
|
return MakeQuiet(b);
|
||||||
|
|
||||||
SetFPException(FPSCR_VXISI);
|
SetFPException(FPSCR_VXISI);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
return PPC_NAN;
|
return PPC_NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,7 +202,11 @@ inline double NI_sub(double a, double b)
|
||||||
if (std::isnan(t))
|
if (std::isnan(t))
|
||||||
{
|
{
|
||||||
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
if (Common::IsSNAN(a) || Common::IsSNAN(b))
|
||||||
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::isnan(a))
|
if (std::isnan(a))
|
||||||
return MakeQuiet(a);
|
return MakeQuiet(a);
|
||||||
|
@ -190,6 +214,8 @@ inline double NI_sub(double a, double b)
|
||||||
return MakeQuiet(b);
|
return MakeQuiet(b);
|
||||||
|
|
||||||
SetFPException(FPSCR_VXISI);
|
SetFPException(FPSCR_VXISI);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
return PPC_NAN;
|
return PPC_NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,7 +232,11 @@ inline double NI_madd(double a, double c, double b)
|
||||||
if (std::isnan(t))
|
if (std::isnan(t))
|
||||||
{
|
{
|
||||||
if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c))
|
if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c))
|
||||||
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::isnan(a))
|
if (std::isnan(a))
|
||||||
return MakeQuiet(a);
|
return MakeQuiet(a);
|
||||||
|
@ -216,6 +246,8 @@ inline double NI_madd(double a, double c, double b)
|
||||||
return MakeQuiet(c);
|
return MakeQuiet(c);
|
||||||
|
|
||||||
SetFPException(FPSCR_VXIMZ);
|
SetFPException(FPSCR_VXIMZ);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
return PPC_NAN;
|
return PPC_NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,12 +256,18 @@ inline double NI_madd(double a, double c, double b)
|
||||||
if (std::isnan(t))
|
if (std::isnan(t))
|
||||||
{
|
{
|
||||||
if (Common::IsSNAN(b))
|
if (Common::IsSNAN(b))
|
||||||
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::isnan(b))
|
if (std::isnan(b))
|
||||||
return MakeQuiet(b);
|
return MakeQuiet(b);
|
||||||
|
|
||||||
SetFPException(FPSCR_VXISI);
|
SetFPException(FPSCR_VXISI);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
return PPC_NAN;
|
return PPC_NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,7 +281,11 @@ inline double NI_msub(double a, double c, double b)
|
||||||
if (std::isnan(t))
|
if (std::isnan(t))
|
||||||
{
|
{
|
||||||
if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c))
|
if (Common::IsSNAN(a) || Common::IsSNAN(b) || Common::IsSNAN(c))
|
||||||
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::isnan(a))
|
if (std::isnan(a))
|
||||||
return MakeQuiet(a);
|
return MakeQuiet(a);
|
||||||
|
@ -253,6 +295,8 @@ inline double NI_msub(double a, double c, double b)
|
||||||
return MakeQuiet(c);
|
return MakeQuiet(c);
|
||||||
|
|
||||||
SetFPException(FPSCR_VXIMZ);
|
SetFPException(FPSCR_VXIMZ);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
return PPC_NAN;
|
return PPC_NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,12 +305,18 @@ inline double NI_msub(double a, double c, double b)
|
||||||
if (std::isnan(t))
|
if (std::isnan(t))
|
||||||
{
|
{
|
||||||
if (Common::IsSNAN(b))
|
if (Common::IsSNAN(b))
|
||||||
|
{
|
||||||
SetFPException(FPSCR_VXSNAN);
|
SetFPException(FPSCR_VXSNAN);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (std::isnan(b))
|
if (std::isnan(b))
|
||||||
return MakeQuiet(b);
|
return MakeQuiet(b);
|
||||||
|
|
||||||
SetFPException(FPSCR_VXISI);
|
SetFPException(FPSCR_VXISI);
|
||||||
|
FPSCR.FI = 0;
|
||||||
|
FPSCR.FR = 0;
|
||||||
return PPC_NAN;
|
return PPC_NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue