OpDispatcher: Force a recheck of TF after POPF

The dispatcher/block linker will handle this, but if the instruction
following a POPF flag doesn't otherwise trigger one of those the
interrupt would be missed.
This commit is contained in:
Billy Laws committed 2025-09-02 22:21:42 +01:00
1 parent b98acdf97a
commit 2c883d7cdc
3 files changed
+14 -5

No files matched your search

@@ -146,6 +146,15 @@ DEF_OP(ExitFunction) {
} else {
stp<ARMEmitter::IndexType::PRE>(ARMEmitter::XReg::zr, ARMEmitter::XReg::zr, REG_CALLRET_SP, -0x10);
}
} else if (Op->Hint == IR::BranchHint::CheckTF) {
ARMEmitter::ForwardLabel TFUnset;
ldrb(TMP1, STATE_PTR(CpuStateFrame, State.flags[X86State::RFLAG_TF_RAW_LOC]));
cbz(ARMEmitter::Size::i32Bit, TMP1, &TFUnset);
LoadConstant(ARMEmitter::Size::i64Bit, TMP1, NewRIP);
str(TMP1, STATE, offsetof(FEXCore::Core::CpuStateFrame, State.rip));
ldr(TMP2, STATE, offsetof(FEXCore::Core::CpuStateFrame, Pointers.Common.DispatcherLoopTop));
blr(TMP2);
Bind(&TFUnset);
}
EmitLinkedBranch(NewRIP, Op->Hint == IR::BranchHint::Call);
@@ -3604,6 +3604,10 @@ void OpDispatchBuilder::POPFOp(OpcodeArgs) {
Src = _Or(OpSize::i64Bit, Src, Constant(0x202));
SetPackedRFLAG(false, Src);
auto NewRIP = GetRelocatedPC(Op);
ExitFunction(NewRIP, BranchHint::CheckTF);
BlockSetRIP = true;
}
void OpDispatchBuilder::NEGOp(OpcodeArgs) {
+1 -5
View File
@@ -621,11 +621,7 @@ enum class ShiftType : uint8_t {
ROR,
};
enum class BranchHint : uint8_t {
None = 0,
Call,
Return,
};
enum class BranchHint : uint8_t { None = 0, Call, Return, CheckTF };
// Converts a size stored as an integer in to an OpSize enum.