From fd3546a99945a33b0056db4e7aaa1ec772db134d Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Fri, 29 May 2026 19:17:13 -0700 Subject: [PATCH] arm64ec: Single instruction optimization in EC map lookup We can merge the lsr+and in to a single lsr by 18 and then use ldr with LSL of 3 to accomplish the same result. Modern Cortex doesn't even generate an additional integer pipeline uop for this ldr+lsl instruction anymore. --- FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp | 5 ++--- Source/Windows/ARM64EC/Module.S | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp b/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp index d32e9f0d0..5ef80d5ee 100644 --- a/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp +++ b/FEXCore/Source/Interface/Core/Dispatcher/Dispatcher.cpp @@ -153,9 +153,8 @@ void Dispatcher::EmitDispatcher() { ldr(TMP1, ARMEmitter::XReg::x18, TEB_PEB_OFFSET); ldr(TMP1, TMP1, PEB_EC_CODE_BITMAP_OFFSET); - lsr(ARMEmitter::Size::i64Bit, TMP2, RipReg, 15); - and_(ARMEmitter::Size::i64Bit, TMP2, TMP2, 0x1fffffffffff8); - ldr(TMP1, TMP1, TMP2, ARMEmitter::ExtendedType::LSL_64, 0); + lsr(ARMEmitter::Size::i64Bit, TMP2, RipReg, 18); + ldr(TMP1, TMP1, TMP2, ARMEmitter::ExtendedType::LSL_64, 3); lsr(ARMEmitter::Size::i64Bit, TMP2, RipReg, 12); lsrv(ARMEmitter::Size::i64Bit, TMP1, TMP1, TMP2); (void)tbz(TMP1, 0, &l_NotECCode); diff --git a/Source/Windows/ARM64EC/Module.S b/Source/Windows/ARM64EC/Module.S index 365931332..4c18172ea 100644 --- a/Source/Windows/ARM64EC/Module.S +++ b/Source/Windows/ARM64EC/Module.S @@ -18,9 +18,8 @@ check_target_ec: // Check if target is in fact x86 code ldr x16, [x18, #0x60] // TEB->PEB ldr x16, [x16, #0x368] // PEB->EcCodeBitMap - lsr x17, x9, #15 - and x17, x17, #0x1fffffffffff8 - ldr x16, [x16, x17] + lsr x17, x9, #18 + ldr x16, [x16, x17, lsl #3] lsr x17, x9, #12 lsr x16, x16, x17 tbnz x16, #0, ExitFunctionEC