mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-15 00:39:23 +01:00
Interpreter: Use std::fma for emulating FMA
This is more accurate to the original hardware's rounding behavior.
This commit is contained in:
parent
ff08b85740
commit
9bc5bd83a9
@ -238,7 +238,7 @@ inline FPResult NI_sub(UReg_FPSCR* fpscr, double a, double b)
|
|||||||
// inputs are checked for NaN is still a, b, c.
|
// inputs are checked for NaN is still a, b, c.
|
||||||
inline FPResult NI_madd(UReg_FPSCR* fpscr, double a, double c, double b)
|
inline FPResult NI_madd(UReg_FPSCR* fpscr, double a, double c, double b)
|
||||||
{
|
{
|
||||||
FPResult result{a * c};
|
FPResult result{std::fma(a, c, b)};
|
||||||
|
|
||||||
if (std::isnan(result.value))
|
if (std::isnan(result.value))
|
||||||
{
|
{
|
||||||
@ -263,27 +263,7 @@ inline FPResult NI_madd(UReg_FPSCR* fpscr, double a, double c, double b)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.SetException(fpscr, FPSCR_VXIMZ);
|
result.SetException(fpscr, std::isnan(a * c) ? FPSCR_VXIMZ : FPSCR_VXISI);
|
||||||
result.value = PPC_NAN;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.value += b;
|
|
||||||
|
|
||||||
if (std::isnan(result.value))
|
|
||||||
{
|
|
||||||
if (Common::IsSNAN(b))
|
|
||||||
result.SetException(fpscr, FPSCR_VXSNAN);
|
|
||||||
|
|
||||||
fpscr->ClearFIFR();
|
|
||||||
|
|
||||||
if (std::isnan(b))
|
|
||||||
{
|
|
||||||
result.value = MakeQuiet(b);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.SetException(fpscr, FPSCR_VXISI);
|
|
||||||
result.value = PPC_NAN;
|
result.value = PPC_NAN;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -296,7 +276,7 @@ inline FPResult NI_madd(UReg_FPSCR* fpscr, double a, double c, double b)
|
|||||||
|
|
||||||
inline FPResult NI_msub(UReg_FPSCR* fpscr, double a, double c, double b)
|
inline FPResult NI_msub(UReg_FPSCR* fpscr, double a, double c, double b)
|
||||||
{
|
{
|
||||||
FPResult result{a * c};
|
FPResult result{std::fma(a, c, -b)};
|
||||||
|
|
||||||
if (std::isnan(result.value))
|
if (std::isnan(result.value))
|
||||||
{
|
{
|
||||||
@ -321,27 +301,7 @@ inline FPResult NI_msub(UReg_FPSCR* fpscr, double a, double c, double b)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
result.SetException(fpscr, FPSCR_VXIMZ);
|
result.SetException(fpscr, std::isnan(a * c) ? FPSCR_VXIMZ : FPSCR_VXISI);
|
||||||
result.value = PPC_NAN;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.value -= b;
|
|
||||||
|
|
||||||
if (std::isnan(result.value))
|
|
||||||
{
|
|
||||||
if (Common::IsSNAN(b))
|
|
||||||
result.SetException(fpscr, FPSCR_VXSNAN);
|
|
||||||
|
|
||||||
fpscr->ClearFIFR();
|
|
||||||
|
|
||||||
if (std::isnan(b))
|
|
||||||
{
|
|
||||||
result.value = MakeQuiet(b);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result.SetException(fpscr, FPSCR_VXISI);
|
|
||||||
result.value = PPC_NAN;
|
result.value = PPC_NAN;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user