mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-14 11:01:01 +02:00
FEXCore: Emulate EFLAGS.TF
When set - either via POPF or a thread context operation - the trap flag raises a single step exception after the execution of each instruction. As e.g. a JUMP instruction with TF set will raise an exception at the jump target. Handle this on the FEX side by storing both the flag itself (in bit 0) and a 'block exceptions' flag (in bit 1, inverted). Each generated block when TF is set is then forced to a single instruction with logic to raise the exception at the start. Initially after setting TF exceptions are blocked, then at the start of the block they are unblocked so that after the instruction executes an exception is raised at the start of the next block.
This commit is contained in:
1 parent
6c035a0d61
commit
981c3009ee
12 files changed
+167
-34
No files matched your search
@@ -415,7 +415,7 @@ static ARM64_NT_CONTEXT StoreStateToPackedECContext(FEXCore::Core::InternalThrea
|
||||
// See HandleGuestException
|
||||
uint32_t EFlags = CTX->ReconstructCompactedEFLAGS(Thread, false, nullptr, 0);
|
||||
ECContext.Cpsr = 0;
|
||||
ECContext.Cpsr |= (EFlags & (1U << FEXCore::X86State::RFLAG_TF_LOC)) ? (1U << 21) : 0;
|
||||
ECContext.Cpsr |= (EFlags & (1U << FEXCore::X86State::RFLAG_TF_RAW_LOC)) ? (1U << 21) : 0;
|
||||
ECContext.Cpsr |= (EFlags & (1U << FEXCore::X86State::RFLAG_OF_RAW_LOC)) ? (1U << 28) : 0;
|
||||
ECContext.Cpsr |= (EFlags & (1U << FEXCore::X86State::RFLAG_CF_RAW_LOC)) ? (1U << 29) : 0;
|
||||
ECContext.Cpsr |= (EFlags & (1U << FEXCore::X86State::RFLAG_ZF_RAW_LOC)) ? (1U << 30) : 0;
|
||||
@@ -445,7 +445,7 @@ static void RethrowGuestException(const EXCEPTION_RECORD& Rec, ARM64_NT_CONTEXT&
|
||||
// Current ARM64EC windows can only restore NZCV+SS when returning from an exception and other flags are left untouched from the handler context.
|
||||
// TODO: Can extend wine to support this by mapping the remaining EFlags into reserved cpsr members.
|
||||
uint32_t EFlags = CTX->ReconstructCompactedEFLAGS(Thread, false, nullptr, 0);
|
||||
EFlags &= ~(1 << FEXCore::X86State::RFLAG_TF_LOC);
|
||||
EFlags &= ~(1 << FEXCore::X86State::RFLAG_TF_RAW_LOC);
|
||||
CTX->SetFlagsFromCompactedEFLAGS(Thread, EFlags);
|
||||
|
||||
Args->Rec = FEX::Windows::HandleGuestException(Fault, Rec, Args->Context.Pc, Args->Context.X8);
|
||||
@@ -510,7 +510,7 @@ extern "C" void SyncThreadContext(CONTEXT* Context) {
|
||||
// This is advisable over dropping their values as thread suspend/resume uses this function, and that can happen at any point in guest code.
|
||||
static constexpr uint32_t ECValidEFlagsMask {(1U << FEXCore::X86State::RFLAG_OF_RAW_LOC) | (1U << FEXCore::X86State::RFLAG_CF_RAW_LOC) |
|
||||
(1U << FEXCore::X86State::RFLAG_ZF_RAW_LOC) | (1U << FEXCore::X86State::RFLAG_SF_RAW_LOC) |
|
||||
(1U << FEXCore::X86State::RFLAG_TF_LOC)};
|
||||
(1U << FEXCore::X86State::RFLAG_TF_RAW_LOC)};
|
||||
|
||||
uint32_t StateEFlags = CTX->ReconstructCompactedEFLAGS(Thread, false, nullptr, 0);
|
||||
Context->EFlags = (Context->EFlags & ECValidEFlagsMask) | (StateEFlags & ~ECValidEFlagsMask);
|
||||
|
||||
Reference in new issue
Block a user