Interpreter_FloatingPoint: Handle NaN flag setting within fctiw and fctiwz
If a NaN of any type is passed as the operand to either of these instructions, we shouldn't go down the regular code path, as we end up potentially setting the wrong flags. For example, we wouldn't set the FPSCR.VXCVI bit properly. We'd also set FPSCR.FI, when in actuality it should be unset. If an SNaN is passed as an operand, we also need to set the FPSCR.VXSNAN bit as well. The flag setting behavior for these can be found in Appendix C.4.2 in PowerPC Microprocessor Family: The Programming Environments Manual for 32 and 64-bit Microprocessors.
This commit is contained in:
parent
0125d9b099
commit
8c4aa133ca
|
@ -22,13 +22,27 @@ enum class RoundingMode
|
|||
TowardsNegativeInfinity = 0b11
|
||||
};
|
||||
|
||||
// Note that the convert to integer operation is defined
|
||||
// in Appendix C.4.2 in PowerPC Microprocessor Family:
|
||||
// The Programming Environments Manual for 32 and 64-bit Microprocessors
|
||||
void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode)
|
||||
{
|
||||
const double b = rPS0(inst.FB);
|
||||
u32 value;
|
||||
|
||||
if (b > static_cast<double>(0x7fffffff))
|
||||
if (std::isnan(b))
|
||||
{
|
||||
if (Common::IsSNAN(b))
|
||||
SetFPException(FPSCR_VXSNAN);
|
||||
|
||||
value = 0x80000000;
|
||||
SetFPException(FPSCR_VXCVI);
|
||||
FPSCR.FI = 0;
|
||||
FPSCR.FR = 0;
|
||||
}
|
||||
else if (b > static_cast<double>(0x7fffffff))
|
||||
{
|
||||
// Positive large operand or +inf
|
||||
value = 0x7fffffff;
|
||||
SetFPException(FPSCR_VXCVI);
|
||||
FPSCR.FI = 0;
|
||||
|
@ -36,6 +50,7 @@ void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode)
|
|||
}
|
||||
else if (b < -static_cast<double>(0x80000000))
|
||||
{
|
||||
// Negative large operand or -inf
|
||||
value = 0x80000000;
|
||||
SetFPException(FPSCR_VXCVI);
|
||||
FPSCR.FI = 0;
|
||||
|
@ -84,6 +99,7 @@ void ConvertToInteger(UGeckoInstruction inst, RoundingMode rounding_mode)
|
|||
}
|
||||
else
|
||||
{
|
||||
// Also sets FPSCR[XX]
|
||||
SetFI(1);
|
||||
FPSCR.FR = fabs(di) > fabs(b);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue