From ef823ce82b4dfd23ddab8a01fd85ea687c2701b0 Mon Sep 17 00:00:00 2001 From: Billy Laws Date: Fri, 23 Aug 2024 21:29:25 +0000 Subject: [PATCH] OpcodeDispatcher: Allow x86 code to read CNTVCT on ARM64EC Required by newer insider preview versions, I noticed many crashes with this exception number and QueryPeformanceCounter in the backtrace, testing with XTA found it to not be passed through and instead write the host CNTVCT (unscaled) into RAX. No other registers seem to be affected. --- FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 9ac6a881f..705d24764 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -4665,6 +4665,15 @@ void OpDispatchBuilder::INTOp(OpcodeArgs) { return; } +#ifdef _M_ARM_64EC + // This is used when QueryPerformanceCounter is called on recent Windows versions, it causes CNTVCT to be written into RAX. + constexpr uint8_t GET_CNTVCT_LITERAL = 0x81; + if (Literal == GET_CNTVCT_LITERAL) { + StoreGPRRegister(X86State::REG_RAX, _CycleCounter()); + return; + } +#endif + Reason.ErrorRegister = Literal << 3 | (0b010); Reason.Signal = Core::FAULT_SIGSEGV; // GP is raised when task-gate isn't setup to be valid