From a69daa2524303c97a30b499f378c45f77300b205 Mon Sep 17 00:00:00 2001 From: Paris Oplopoios <21157395+OFFTKP@users.noreply.github.com> Date: Sat, 22 Aug 2026 15:34:13 +0300 Subject: [PATCH 1/2] unittests/ASM: Test BLSR/BLSMSK CF flag --- unittests/ASM/VEX/blsmsk_2.asm | 16 ++++++++++++++++ unittests/ASM/VEX/blsr_2.asm | 16 ++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 unittests/ASM/VEX/blsmsk_2.asm create mode 100644 unittests/ASM/VEX/blsr_2.asm diff --git a/unittests/ASM/VEX/blsmsk_2.asm b/unittests/ASM/VEX/blsmsk_2.asm new file mode 100644 index 000000000..9c6c89c32 --- /dev/null +++ b/unittests/ASM/VEX/blsmsk_2.asm @@ -0,0 +1,16 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0xFFFFFFFF", + "RCX": "1" + }, + "HostFeatures": ["BMI1"] +} +%endif + +mov rbx, 0xFFFFFFFF00000000 +blsmsk eax, ebx +setc cl +movzx rcx, cl + +hlt diff --git a/unittests/ASM/VEX/blsr_2.asm b/unittests/ASM/VEX/blsr_2.asm new file mode 100644 index 000000000..eba7e9410 --- /dev/null +++ b/unittests/ASM/VEX/blsr_2.asm @@ -0,0 +1,16 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0", + "RCX": "1" + }, + "HostFeatures": ["BMI1"] +} +%endif + +mov rbx, 0xFFFFFFFF00000000 +blsr eax, ebx +setc cl +movzx rcx, cl + +hlt From 635befb4c802432897a7a5bd28e6755f29c044a4 Mon Sep 17 00:00:00 2001 From: Paris Oplopoios <21157395+OFFTKP@users.noreply.github.com> Date: Sat, 22 Aug 2026 15:47:50 +0300 Subject: [PATCH 2/2] FEXCore: Fix CF calculation for BLSMSK and BLSR for 32-bit operands --- FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 4 ++-- unittests/InstructionCountCI/FlagM/VEX_map_group.json | 4 ++-- unittests/InstructionCountCI/VEX_map_group.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 31f9eddc0..01d43168f 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -1774,7 +1774,7 @@ void OpDispatchBuilder::BLSMSKBMIOp(OpcodeArgs) { InvalidatePF_AF(); // CF set according to the Src - auto CFInv = To01(OpSize::i64Bit, Src); + auto CFInv = To01(Size, Src); // The output of BLSMSK is always nonzero, so TST will clear Z (along with C // and O) while setting S. @@ -1792,7 +1792,7 @@ void OpDispatchBuilder::BLSRBMIOp(OpcodeArgs) { StoreResultGPR(Op, Result); - auto CFInv = To01(OpSize::i64Bit, Src); + auto CFInv = To01(Size, Src); SetNZ_ZeroCV(Size, Result); SetCFInverted(CFInv); diff --git a/unittests/InstructionCountCI/FlagM/VEX_map_group.json b/unittests/InstructionCountCI/FlagM/VEX_map_group.json index d720aeff7..6865eea36 100644 --- a/unittests/InstructionCountCI/FlagM/VEX_map_group.json +++ b/unittests/InstructionCountCI/FlagM/VEX_map_group.json @@ -19,7 +19,7 @@ "ExpectedArm64ASM": [ "sub w20, w6, #0x1 (1)", "and w4, w20, w6", - "cmp x6, #0x0 (0)", + "cmp w6, #0x0 (0)", "cset x20, ne", "cmp w4, #0x0 (0)", "rmif x20, #63, #nzCv" @@ -47,7 +47,7 @@ "ExpectedArm64ASM": [ "sub w20, w6, #0x1 (1)", "eor w4, w20, w6", - "cmp x6, #0x0 (0)", + "cmp w6, #0x0 (0)", "cset x20, ne", "cmp w4, #0x0 (0)", "rmif x20, #63, #nzCv" diff --git a/unittests/InstructionCountCI/VEX_map_group.json b/unittests/InstructionCountCI/VEX_map_group.json index 41a6afed8..113ff9703 100644 --- a/unittests/InstructionCountCI/VEX_map_group.json +++ b/unittests/InstructionCountCI/VEX_map_group.json @@ -605,7 +605,7 @@ "ExpectedArm64ASM": [ "sub w20, w6, #0x1 (1)", "and w4, w20, w6", - "cmp x6, #0x0 (0)", + "cmp w6, #0x0 (0)", "cset x20, ne", "cmp w4, #0x0 (0)", "mrs x21, nzcv", @@ -637,7 +637,7 @@ "ExpectedArm64ASM": [ "sub w20, w6, #0x1 (1)", "eor w4, w20, w6", - "cmp x6, #0x0 (0)", + "cmp w6, #0x0 (0)", "cset x20, ne", "cmp w4, #0x0 (0)", "mrs x21, nzcv",