diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index c76c39acd..5900f0594 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -2400,7 +2400,10 @@ void OpDispatchBuilder::BTOp(OpcodeArgs, uint32_t SrcIndex, BTAction Action) { unsigned LshrSize = std::max(IR::OpSizeToSize(OpSize::i32Bit), Size / 8); auto BitSelect = (Size == (LshrSize * 8)) ? Src : _And(OpSize::i64Bit, Src, _Constant(Mask)); - // OF/SF/ZF/AF/PF undefined. + // OF/SF/AF/PF undefined. ZF must be preserved. We choose to preserve OF/SF + // too since we just use an rmif to insert into CF directly. We could + // optimize perhaps. + // // Set CF before the action to save a move, except for complements where we // can reuse the invert. if (Action != BTAction::BTComplement) { @@ -2408,7 +2411,8 @@ void OpDispatchBuilder::BTOp(OpcodeArgs, uint32_t SrcIndex, BTAction Action) { Value = _Lshr(IR::SizeToOpSize(LshrSize), Value, BitSelect); } - SetCFDirect_InvalidateNZV(Value, ConstantShift, Value); + SetRFLAG(Value, X86State::RFLAG_CF_RAW_LOC, ConstantShift, true); + CFInverted = false; } switch (Action) { @@ -2441,7 +2445,9 @@ void OpDispatchBuilder::BTOp(OpcodeArgs, uint32_t SrcIndex, BTAction Action) { Value = Dest; } - SetCFInverted_InvalidateNZV(Value, ConstantShift, true); + SetRFLAG(Value, X86State::RFLAG_CF_RAW_LOC, ConstantShift, true); + CFInverted = true; + StoreResult(GPRClass, Op, Dest, OpSize::iInvalid); break; } diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 4372b0592..1f71c34e9 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -1735,27 +1735,6 @@ private: CFInverted = true; } - // As above but with - // - // x - 1 - // - // If x = 0, hardware C is not set. If x = 1, hardware C is set. - void SetCFInverted_InvalidateNZV(Ref Value, unsigned ValueOffset = 0, bool MustMask = false) { - if (CTX->HostFeatures.SupportsFlagM) { - // This turns into a single rmif - SetCFInverted(Value, ValueOffset, MustMask); - } else { - // Do math on flagm - if (ValueOffset || MustMask) { - Value = _Bfe(OpSize::i64Bit, 1, ValueOffset, Value); - } - - HandleNZCVWrite(); - _SubNZCV(OpSize::i32Bit, Value, _InlineConstant(1)); - CFInverted = true; - } - } - void SetCFInverted(Ref Value, unsigned ValueOffset = 0, bool MustMask = false) { SetRFLAG(Value, X86State::RFLAG_CF_RAW_LOC, ValueOffset, MustMask); CFInverted = true; diff --git a/unittests/ASM/FEX_bugs/BT_flags.asm b/unittests/ASM/FEX_bugs/BT_flags.asm new file mode 100644 index 000000000..468b84788 --- /dev/null +++ b/unittests/ASM/FEX_bugs/BT_flags.asm @@ -0,0 +1,44 @@ +%ifdef CONFIG +{ + "RegData": { + "RAX": "0xcafe" + } +} +%endif + +mov ebx, 137 +mov rdx, 0xe0000000 + +%macro case 1 + ; set zero flag + xor eax, eax + + ; zero flag should still be set after bt + %1 ebx, 1 + jnz .bad + %1 dword [rdx], ebx + jnz .bad + + ; now clear the zero flag + add eax, 1 + + ; zero flag should still be clear after bt + %1 eax, 1 + jz .bad + %1 dword [rdx], ebx + jz .bad +%endmacro + +; Repeat for each bitwise op +case bt +case btc +case bts +case btr + +.good: +mov rax, 0xcafe +hlt + +.bad: +mov rax, 0xdeadbeef +hlt diff --git a/unittests/InstructionCountCI/FlagM/HotBlocks.json b/unittests/InstructionCountCI/FlagM/HotBlocks.json index 0f314aab2..62b3e7400 100644 --- a/unittests/InstructionCountCI/FlagM/HotBlocks.json +++ b/unittests/InstructionCountCI/FlagM/HotBlocks.json @@ -292,7 +292,7 @@ }, "bytemark huffman 1": { "x86InstructionCount": 18, - "ExpectedInstructionCount": 24, + "ExpectedInstructionCount": 23, "x86Insts": [ "mov r9,rdx", "mov r8,rcx", @@ -322,12 +322,11 @@ "mov w15, w10", "and w15, w15, #0x7", "lsr w20, w14, w15", - "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "rmif x20, #63, #nzCv", "add x12, x12, x12, lsl #2", "add x20, x6, #0x10 (16)", "add x12, x20, x12, lsl #2", - "csel x12, x13, x12, hs", + "csel x12, x13, x12, lo", "ldr w20, [x12]", "sxtw x12, w20", "add x10, x10, #0x1 (1)", diff --git a/unittests/InstructionCountCI/FlagM/Secondary.json b/unittests/InstructionCountCI/FlagM/Secondary.json index cc2f6f476..179a659fe 100644 --- a/unittests/InstructionCountCI/FlagM/Secondary.json +++ b/unittests/InstructionCountCI/FlagM/Secondary.json @@ -561,8 +561,8 @@ "ExpectedArm64ASM": [ "and x20, x6, #0xf", "lsr w20, w4, w20", - "ubfx x20, x20, #0, #1", - "cmp wzr, w20" + "rmif x20, #63, #nzCv", + "cfinv" ] }, "bt [rax], bx": { @@ -582,8 +582,8 @@ "Comment": "0x0f 0xa3", "ExpectedArm64ASM": [ "lsr w20, w4, w6", - "ubfx x20, x20, #0, #1", - "cmp wzr, w20" + "rmif x20, #63, #nzCv", + "cfinv" ] }, "bt [rax], ebx": { @@ -603,8 +603,8 @@ "Comment": "0x0f 0xa3", "ExpectedArm64ASM": [ "lsr x20, x4, x6", - "ubfx x20, x20, #0, #1", - "cmp wzr, w20" + "rmif x20, #63, #nzCv", + "cfinv" ] }, "bt [rax], rbx": { @@ -855,12 +855,12 @@ "ExpectedArm64ASM": [ "and x20, x6, #0xf", "lsr w21, w4, w20", - "ubfx x21, x21, #0, #1", - "cmp wzr, w21", + "rmif x21, #63, #nzCv", "mov w21, #0x1", "lsl w20, w21, w20", "orr w20, w4, w20", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "cfinv" ] }, "bts [rax], bx": { @@ -884,11 +884,11 @@ "Comment": "0x0f 0xab", "ExpectedArm64ASM": [ "lsr w20, w4, w6", - "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "rmif x20, #63, #nzCv", "mov w20, #0x1", "lsl w20, w20, w6", - "orr w4, w4, w20" + "orr w4, w4, w20", + "cfinv" ] }, "bts [rax], ebx": { @@ -912,11 +912,11 @@ "Comment": "0x0f 0xab", "ExpectedArm64ASM": [ "lsr x20, x4, x6", - "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "rmif x20, #63, #nzCv", "mov w20, #0x1", "lsl x20, x20, x6", - "orr x4, x4, x20" + "orr x4, x4, x20", + "cfinv" ] }, "bts [rax], rbx": { @@ -1178,12 +1178,12 @@ "ExpectedArm64ASM": [ "and x20, x6, #0xf", "lsr w21, w4, w20", - "ubfx x21, x21, #0, #1", - "cmp wzr, w21", + "rmif x21, #63, #nzCv", "mov w21, #0x1", "lsl w20, w21, w20", "bic w20, w4, w20", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "cfinv" ] }, "btr [rax], bx": { @@ -1207,11 +1207,11 @@ "Comment": "0x0f 0xb3", "ExpectedArm64ASM": [ "lsr w20, w4, w6", - "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "rmif x20, #63, #nzCv", "mov w20, #0x1", "lsl w20, w20, w6", - "bic w4, w4, w20" + "bic w4, w4, w20", + "cfinv" ] }, "btr [rax], ebx": { @@ -1235,11 +1235,11 @@ "Comment": "0x0f 0xb3", "ExpectedArm64ASM": [ "lsr x20, x4, x6", - "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "rmif x20, #63, #nzCv", "mov w20, #0x1", "lsl x20, x20, x6", - "bic x4, x4, x20" + "bic x4, x4, x20", + "cfinv" ] }, "btr [rax], rbx": { diff --git a/unittests/InstructionCountCI/FlagM/SecondaryGroup.json b/unittests/InstructionCountCI/FlagM/SecondaryGroup.json index 2acddd30d..7cb070a27 100644 --- a/unittests/InstructionCountCI/FlagM/SecondaryGroup.json +++ b/unittests/InstructionCountCI/FlagM/SecondaryGroup.json @@ -26,48 +26,48 @@ "ExpectedInstructionCount": 2, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20" + "rmif x4, #63, #nzCv", + "cfinv" ] }, "bt eax, 0": { "ExpectedInstructionCount": 2, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20" + "rmif x4, #63, #nzCv", + "cfinv" ] }, "bt rax, 0": { "ExpectedInstructionCount": 2, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20" + "rmif x4, #63, #nzCv", + "cfinv" ] }, "bt ax, 15": { "ExpectedInstructionCount": 2, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ - "ubfx x20, x4, #15, #1", - "cmp wzr, w20" + "rmif x4, #14, #nzCv", + "cfinv" ] }, "bt eax, 31": { "ExpectedInstructionCount": 2, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ - "ubfx x20, x4, #31, #1", - "cmp wzr, w20" + "rmif x4, #30, #nzCv", + "cfinv" ] }, "bt rax, 63": { "ExpectedInstructionCount": 2, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ - "lsr x20, x4, #63", - "cmp wzr, w20" + "rmif x4, #62, #nzCv", + "cfinv" ] }, "bt word [rax], 0": { @@ -131,56 +131,56 @@ "ExpectedInstructionCount": 4, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20", + "rmif x4, #63, #nzCv", "orr w20, w4, #0x1", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "cfinv" ] }, "bts eax, 0": { "ExpectedInstructionCount": 3, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20", - "orr w4, w4, #0x1" + "rmif x4, #63, #nzCv", + "orr w4, w4, #0x1", + "cfinv" ] }, "bts rax, 0": { "ExpectedInstructionCount": 3, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20", - "orr x4, x4, #0x1" + "rmif x4, #63, #nzCv", + "orr x4, x4, #0x1", + "cfinv" ] }, "bts ax, 15": { "ExpectedInstructionCount": 4, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ - "ubfx x20, x4, #15, #1", - "cmp wzr, w20", + "rmif x4, #14, #nzCv", "orr w20, w4, #0x8000", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "cfinv" ] }, "bts eax, 31": { "ExpectedInstructionCount": 3, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ - "ubfx x20, x4, #31, #1", - "cmp wzr, w20", - "orr w4, w4, #0x80000000" + "rmif x4, #30, #nzCv", + "orr w4, w4, #0x80000000", + "cfinv" ] }, "bts rax, 63": { "ExpectedInstructionCount": 3, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ - "lsr x20, x4, #63", - "cmp wzr, w20", - "orr x4, x4, #0x8000000000000000" + "rmif x4, #62, #nzCv", + "orr x4, x4, #0x8000000000000000", + "cfinv" ] }, "bts word [rax], 0": { @@ -325,56 +325,56 @@ "ExpectedInstructionCount": 4, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20", + "rmif x4, #63, #nzCv", "and w20, w4, #0xfffffffe", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "cfinv" ] }, "btr eax, 0": { "ExpectedInstructionCount": 3, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20", - "and w4, w4, #0xfffffffe" + "rmif x4, #63, #nzCv", + "and w4, w4, #0xfffffffe", + "cfinv" ] }, "btr rax, 0": { "ExpectedInstructionCount": 3, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ - "ubfx x20, x4, #0, #1", - "cmp wzr, w20", - "and x4, x4, #0xfffffffffffffffe" + "rmif x4, #63, #nzCv", + "and x4, x4, #0xfffffffffffffffe", + "cfinv" ] }, "btr ax, 15": { "ExpectedInstructionCount": 4, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ - "ubfx x20, x4, #15, #1", - "cmp wzr, w20", + "rmif x4, #14, #nzCv", "and w20, w4, #0xffff7fff", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "cfinv" ] }, "btr eax, 31": { "ExpectedInstructionCount": 3, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ - "ubfx x20, x4, #31, #1", - "cmp wzr, w20", - "and w4, w4, #0x7fffffff" + "rmif x4, #30, #nzCv", + "and w4, w4, #0x7fffffff", + "cfinv" ] }, "btr rax, 63": { "ExpectedInstructionCount": 3, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ - "lsr x20, x4, #63", - "cmp wzr, w20", - "and x4, x4, #0x7fffffffffffffff" + "rmif x4, #62, #nzCv", + "and x4, x4, #0x7fffffffffffffff", + "cfinv" ] }, "btr word [rax], 0": { diff --git a/unittests/InstructionCountCI/Secondary.json b/unittests/InstructionCountCI/Secondary.json index ea07b7dbb..819f2bb41 100644 --- a/unittests/InstructionCountCI/Secondary.json +++ b/unittests/InstructionCountCI/Secondary.json @@ -1389,13 +1389,16 @@ ] }, "bt ax, bx": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 7, "Comment": "0x0f 0xa3", "ExpectedArm64ASM": [ "and x20, x6, #0xf", "lsr w20, w4, w20", "ubfx x20, x20, #0, #1", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt [rax], bx": { @@ -1414,12 +1417,15 @@ ] }, "bt eax, ebx": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "0x0f 0xa3", "ExpectedArm64ASM": [ "lsr w20, w4, w6", "ubfx x20, x20, #0, #1", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt [rax], ebx": { @@ -1438,12 +1444,15 @@ ] }, "bt rax, rbx": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "0x0f 0xa3", "ExpectedArm64ASM": [ "lsr x20, x4, x6", "ubfx x20, x20, #0, #1", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt [rax], rbx": { @@ -1776,17 +1785,20 @@ ] }, "bts ax, bx": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 11, "Comment": "0x0f 0xab", "ExpectedArm64ASM": [ "and x20, x6, #0xf", "lsr w21, w4, w20", "ubfx x21, x21, #0, #1", - "cmp wzr, w21", + "mrs x22, nzcv", + "bfi w22, w21, #29, #1", "mov w21, #0x1", "lsl w20, w21, w20", "orr w20, w4, w20", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "eor w20, w22, #0x20000000", + "msr nzcv, x20" ] }, "bts [rax], bx": { @@ -1809,15 +1821,18 @@ ] }, "bts eax, ebx": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 9, "Comment": "0x0f 0xab", "ExpectedArm64ASM": [ "lsr w20, w4, w6", "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", "mov w20, #0x1", "lsl w20, w20, w6", - "orr w4, w4, w20" + "orr w4, w4, w20", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bts [rax], ebx": { @@ -1840,15 +1855,18 @@ ] }, "bts rax, rbx": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 9, "Comment": "0x0f 0xab", "ExpectedArm64ASM": [ "lsr x20, x4, x6", "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", "mov w20, #0x1", "lsl x20, x20, x6", - "orr x4, x4, x20" + "orr x4, x4, x20", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bts [rax], rbx": { @@ -2059,17 +2077,20 @@ ] }, "btr ax, bx": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 11, "Comment": "0x0f 0xb3", "ExpectedArm64ASM": [ "and x20, x6, #0xf", "lsr w21, w4, w20", "ubfx x21, x21, #0, #1", - "cmp wzr, w21", + "mrs x22, nzcv", + "bfi w22, w21, #29, #1", "mov w21, #0x1", "lsl w20, w21, w20", "bic w20, w4, w20", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "eor w20, w22, #0x20000000", + "msr nzcv, x20" ] }, "btr [rax], bx": { @@ -2092,15 +2113,18 @@ ] }, "btr eax, ebx": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 9, "Comment": "0x0f 0xb3", "ExpectedArm64ASM": [ "lsr w20, w4, w6", "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", "mov w20, #0x1", "lsl w20, w20, w6", - "bic w4, w4, w20" + "bic w4, w4, w20", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "btr [rax], ebx": { @@ -2123,15 +2147,18 @@ ] }, "btr rax, rbx": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 9, "Comment": "0x0f 0xb3", "ExpectedArm64ASM": [ "lsr x20, x4, x6", "ubfx x20, x20, #0, #1", - "cmp wzr, w20", + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", "mov w20, #0x1", "lsl x20, x20, x6", - "bic x4, x4, x20" + "bic x4, x4, x20", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "btr [rax], rbx": { @@ -2280,7 +2307,7 @@ ] }, "btc ax, bx": { - "ExpectedInstructionCount": 8, + "ExpectedInstructionCount": 10, "Comment": "0x0f 0xbb", "ExpectedArm64ASM": [ "and x20, x6, #0xf", @@ -2289,8 +2316,10 @@ "eor w21, w4, w21", "lsr w20, w21, w20", "ubfx x20, x20, #0, #1", - "cmp w20, #0x1 (1)", - "bfxil x4, x21, #0, #16" + "mrs x22, nzcv", + "bfi w22, w20, #29, #1", + "bfxil x4, x21, #0, #16", + "msr nzcv, x22" ] }, "btc [rax], bx": { @@ -2313,7 +2342,7 @@ ] }, "btc eax, ebx": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 8, "Comment": "0x0f 0xbb", "ExpectedArm64ASM": [ "mov w20, #0x1", @@ -2321,7 +2350,9 @@ "eor w4, w4, w20", "lsr w20, w4, w6", "ubfx x20, x20, #0, #1", - "cmp w20, #0x1 (1)" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "msr nzcv, x21" ] }, "btc [rax], ebx": { @@ -2344,7 +2375,7 @@ ] }, "btc rax, rbx": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 8, "Comment": "0x0f 0xbb", "ExpectedArm64ASM": [ "mov w20, #0x1", @@ -2352,7 +2383,9 @@ "eor x4, x4, x20", "lsr x20, x4, x6", "ubfx x20, x20, #0, #1", - "cmp w20, #0x1 (1)" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "msr nzcv, x21" ] }, "btc [rax], rbx": { diff --git a/unittests/InstructionCountCI/SecondaryGroup.json b/unittests/InstructionCountCI/SecondaryGroup.json index f2b88bfac..f8decc988 100644 --- a/unittests/InstructionCountCI/SecondaryGroup.json +++ b/unittests/InstructionCountCI/SecondaryGroup.json @@ -23,51 +23,69 @@ ] }, "bt ax, 0": { - "ExpectedInstructionCount": 2, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt eax, 0": { - "ExpectedInstructionCount": 2, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt rax, 0": { - "ExpectedInstructionCount": 2, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt ax, 15": { - "ExpectedInstructionCount": 2, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ "ubfx x20, x4, #15, #1", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt eax, 31": { - "ExpectedInstructionCount": 2, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ "ubfx x20, x4, #31, #1", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt rax, 63": { - "ExpectedInstructionCount": 2, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /4", "ExpectedArm64ASM": [ "lsr x20, x4, #63", - "cmp wzr, w20" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bt word [rax], 0": { @@ -146,59 +164,77 @@ ] }, "bts ax, 0": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 7, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20", + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", "orr w20, w4, #0x1", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bts eax, 0": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20", - "orr w4, w4, #0x1" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "orr w4, w4, #0x1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bts rax, 0": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20", - "orr x4, x4, #0x1" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "orr x4, x4, #0x1", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bts ax, 15": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 7, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ "ubfx x20, x4, #15, #1", - "cmp wzr, w20", + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", "orr w20, w4, #0x8000", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bts eax, 31": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ "ubfx x20, x4, #31, #1", - "cmp wzr, w20", - "orr w4, w4, #0x80000000" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "orr w4, w4, #0x80000000", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bts rax, 63": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /5", "ExpectedArm64ASM": [ "lsr x20, x4, #63", - "cmp wzr, w20", - "orr x4, x4, #0x8000000000000000" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "orr x4, x4, #0x8000000000000000", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "bts word [rax], 0": { @@ -376,59 +412,77 @@ ] }, "btr ax, 0": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 7, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20", + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", "and w20, w4, #0xfffffffe", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "btr eax, 0": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20", - "and w4, w4, #0xfffffffe" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "and w4, w4, #0xfffffffe", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "btr rax, 0": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ "ubfx x20, x4, #0, #1", - "cmp wzr, w20", - "and x4, x4, #0xfffffffffffffffe" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "and x4, x4, #0xfffffffffffffffe", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "btr ax, 15": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 7, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ "ubfx x20, x4, #15, #1", - "cmp wzr, w20", + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", "and w20, w4, #0xffff7fff", - "bfxil x4, x20, #0, #16" + "bfxil x4, x20, #0, #16", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "btr eax, 31": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ "ubfx x20, x4, #31, #1", - "cmp wzr, w20", - "and w4, w4, #0x7fffffff" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "and w4, w4, #0x7fffffff", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "btr rax, 63": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /6", "ExpectedArm64ASM": [ "lsr x20, x4, #63", - "cmp wzr, w20", - "and x4, x4, #0x7fffffffffffffff" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "and x4, x4, #0x7fffffffffffffff", + "eor w20, w21, #0x20000000", + "msr nzcv, x20" ] }, "btr word [rax], 0": { @@ -606,59 +660,71 @@ ] }, "btc ax, 0": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /7", "ExpectedArm64ASM": [ "eor w20, w4, #0x1", "ubfx x21, x20, #0, #1", - "cmp w21, #0x1 (1)", - "bfxil x4, x20, #0, #16" + "mrs x22, nzcv", + "bfi w22, w21, #29, #1", + "bfxil x4, x20, #0, #16", + "msr nzcv, x22" ] }, "btc eax, 0": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /7", "ExpectedArm64ASM": [ "eor w4, w4, #0x1", "ubfx x20, x4, #0, #1", - "cmp w20, #0x1 (1)" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "msr nzcv, x21" ] }, "btc rax, 0": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /7", "ExpectedArm64ASM": [ "eor x4, x4, #0x1", "ubfx x20, x4, #0, #1", - "cmp w20, #0x1 (1)" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "msr nzcv, x21" ] }, "btc ax, 15": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 6, "Comment": "GROUP8 0x0F 0xBA /7", "ExpectedArm64ASM": [ "eor w20, w4, #0x8000", "ubfx x21, x20, #15, #1", - "cmp w21, #0x1 (1)", - "bfxil x4, x20, #0, #16" + "mrs x22, nzcv", + "bfi w22, w21, #29, #1", + "bfxil x4, x20, #0, #16", + "msr nzcv, x22" ] }, "btc eax, 31": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /7", "ExpectedArm64ASM": [ "eor w4, w4, #0x80000000", "ubfx x20, x4, #31, #1", - "cmp w20, #0x1 (1)" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "msr nzcv, x21" ] }, "btc rax, 63": { - "ExpectedInstructionCount": 3, + "ExpectedInstructionCount": 5, "Comment": "GROUP8 0x0F 0xBA /7", "ExpectedArm64ASM": [ "eor x4, x4, #0x8000000000000000", "lsr x20, x4, #63", - "cmp w20, #0x1 (1)" + "mrs x21, nzcv", + "bfi w21, w20, #29, #1", + "msr nzcv, x21" ] }, "btc word [rax], 0": {