OpcodeDispatcher: Safely clobber NZCV in FCOMIF64

Also fix a small typo that broke the !flagm2 path.
This commit is contained in:
Billy Laws committed 2025-04-16 13:06:37 +01:00
1 parent 94499ed8fc
commit 416267a238
2 files changed
+16 -16

No files matched your search

@@ -2103,28 +2103,28 @@ private:
// Set x87 comparison flags based on the result set by Arm FCMP. Clobbers
// NZCV on flagm2 platforms.
void ConvertNZCVToX87() {
Ref V = GetRFLAG(FEXCore::X86State::RFLAG_OF_RAW_LOC);
LOGMAN_THROW_A_FMT(NZCVDirty && CachedNZCV, "NZCV must be saved");
Ref V = _NZCVSelect(OpSize::i32Bit, CondForNZCVBit(FEXCore::X86State::RFLAG_OF_RAW_LOC, false), _Constant(1), _Constant(0));
if (CTX->HostFeatures.SupportsFlagM2) {
LOGMAN_THROW_A_FMT(!NZCVDirty, "only expected after fcmp");
// Convert to x86 flags, saves us from or'ing after.
_AXFlag(Invalid());
CFInverted = true;
// Copy the values.
SetRFLAG<FEXCore::X86State::X87FLAG_C0_LOC>(GetRFLAG(FEXCore::X86State::RFLAG_CF_RAW_LOC));
SetRFLAG<FEXCore::X86State::X87FLAG_C3_LOC>(GetRFLAG(FEXCore::X86State::RFLAG_ZF_RAW_LOC));
} else {
Ref Z = GetRFLAG(FEXCore::X86State::RFLAG_ZF_RAW_LOC);
Ref N = GetRFLAG(FEXCore::X86State::RFLAG_SF_RAW_LOC);
SetRFLAG<FEXCore::X86State::X87FLAG_C0_LOC>(_Or(OpSize::i32Bit, N, V));
SetRFLAG<FEXCore::X86State::X87FLAG_C3_LOC>(_Or(OpSize::i32Bit, Z, V));
}
// CF is inverted after FCMP
Ref C = _NZCVSelect(OpSize::i32Bit, CondForNZCVBit(FEXCore::X86State::RFLAG_CF_RAW_LOC, true), _Constant(1), _Constant(0));
Ref Z = _NZCVSelect(OpSize::i32Bit, CondForNZCVBit(FEXCore::X86State::RFLAG_ZF_RAW_LOC, false), _Constant(1), _Constant(0));
if (!CTX->HostFeatures.SupportsFlagM2) {
C = _Or(OpSize::i32Bit, C, V);
Z = _Or(OpSize::i32Bit, Z, V);
}
SetRFLAG<FEXCore::X86State::X87FLAG_C0_LOC>(C);
SetRFLAG<FEXCore::X86State::X87FLAG_C1_LOC>(_Constant(0));
SetRFLAG<FEXCore::X86State::X87FLAG_C2_LOC>(V);
SetRFLAG<FEXCore::X86State::X87FLAG_C3_LOC>(Z);
}
// Helper to store a variable shift and calculate its flags for a variable
@@ -314,7 +314,7 @@ void OpDispatchBuilder::FSUBF64(OpcodeArgs, IR::OpSize Width, bool Integer, bool
void OpDispatchBuilder::FTSTF64(OpcodeArgs) {
// We are going to clobber NZCV, make sure it's in a GPR first.
GetNZCV();
SaveNZCV();
// Now we do our comparison.
_F80StackTest(0);
@@ -349,7 +349,7 @@ void OpDispatchBuilder::FCOMIF64(OpcodeArgs, IR::OpSize Width, bool Integer, OpD
if (WhichFlags == FCOMIFlags::FLAGS_X87) {
// We are going to clobber NZCV, make sure it's in a GPR first.
GetNZCV();
SaveNZCV();
_F80CmpValue(b);
ConvertNZCVToX87();