From 3efac9646c804b1b62593e69bd01f79faed8a8a9 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 27 Sep 2023 10:00:46 -0400 Subject: [PATCH 1/3] OpcodeDispatcher: Optimize ASCII flags Make the zeroing of undefined NZCV more obvious. Mitigates regressions from future work. Signed-off-by: Alyssa Rosenzweig --- FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 14efbfbe8..9bf94e3f8 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -3602,7 +3602,7 @@ void OpDispatchBuilder::AAAOp(OpcodeArgs) { { auto NewAX = _And(OpSize::i64Bit, AX, _Constant(0xFF0F)); StoreGPRRegister(X86State::REG_RAX, NewAX, 2); - SetRFLAG(_Constant(0)); + ZeroNZCV(); SetAF(0); CalculateDeferredFlags(); _Jump(EndBlock); @@ -3614,6 +3614,7 @@ void OpDispatchBuilder::AAAOp(OpcodeArgs) { auto NewAX = _Add(OpSize::i64Bit, AX, _Constant(0x106)); auto Result = _And(OpSize::i64Bit, NewAX, _Constant(0xFF0F)); StoreGPRRegister(X86State::REG_RAX, Result, 2); + ZeroNZCV(); SetRFLAG(_Constant(1)); SetAF(1); CalculateDeferredFlags(); @@ -3641,7 +3642,7 @@ void OpDispatchBuilder::AASOp(OpcodeArgs) { { auto NewAX = _And(OpSize::i64Bit, AX, _Constant(0xFF0F)); StoreGPRRegister(X86State::REG_RAX, NewAX, 2); - SetRFLAG(_Constant(0)); + ZeroNZCV(); SetAF(0); CalculateDeferredFlags(); _Jump(EndBlock); @@ -3653,6 +3654,7 @@ void OpDispatchBuilder::AASOp(OpcodeArgs) { NewAX = _Sub(OpSize::i64Bit, NewAX, _Constant(0x100)); auto Result = _And(OpSize::i64Bit, NewAX, _Constant(0xFF0F)); StoreGPRRegister(X86State::REG_RAX, Result, 2); + ZeroNZCV(); SetRFLAG(_Constant(1)); SetAF(1); CalculateDeferredFlags(); @@ -3675,8 +3677,7 @@ void OpDispatchBuilder::AAMOp(OpcodeArgs) { // Update Flags AL = LoadGPRRegister(X86State::REG_RAX, 1); - SetRFLAG(_Select(FEXCore::IR::COND_UGE, _And(OpSize::i64Bit, AL, _Constant(0x80)), _Constant(0), _Constant(1), _Constant(0))); - SetRFLAG(_Select(FEXCore::IR::COND_EQ, _And(OpSize::i64Bit, AL, _Constant(0xFF)), _Constant(0), _Constant(1), _Constant(0))); + SetNZ_ZeroCV(1, AL); CalculatePF(AL); _InvalidateFlags(1u << X86State::RFLAG_AF_LOC); } @@ -3693,8 +3694,7 @@ void OpDispatchBuilder::AADOp(OpcodeArgs) { // Update Flags AL = LoadGPRRegister(X86State::REG_RAX, 1); - SetRFLAG(_Select(FEXCore::IR::COND_UGE, _And(OpSize::i64Bit, AL, _Constant(0x80)), _Constant(0), _Constant(1), _Constant(0))); - SetRFLAG(_Select(FEXCore::IR::COND_EQ, _And(OpSize::i64Bit, AL, _Constant(0xFF)), _Constant(0), _Constant(1), _Constant(0))); + SetNZ_ZeroCV(1, AL); CalculatePF(AL); _InvalidateFlags(1u << X86State::RFLAG_AF_LOC); } From 711583aa76b76055a25ded58069ed7807a58dd17 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 27 Sep 2023 10:53:09 -0400 Subject: [PATCH 2/3] OpcodeDispatcher: Optimize PTEST flags Zero NZCV first to avoid RMW. Signed-off-by: Alyssa Rosenzweig --- FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 3b5c6513c..289c1b2df 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -4248,14 +4248,13 @@ void OpDispatchBuilder::PTestOp(OpcodeArgs) { Test2, ZeroConst, OneConst, ZeroConst); // Careful, these flags are different between {V,}PTEST and VTESTP{S,D} + ZeroNZCV(); SetRFLAG(Test1); SetRFLAG(Test2); uint32_t FlagsMaskToZero = (1U << X86State::RFLAG_PF_LOC) | - (1U << X86State::RFLAG_AF_LOC) | - (1U << X86State::RFLAG_SF_LOC) | - (1U << X86State::RFLAG_OF_LOC); + (1U << X86State::RFLAG_AF_LOC); ZeroMultipleFlags(FlagsMaskToZero); } From 2e32e1367df1c64eb11757fcedfcfc8f8bf3810e Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Wed, 27 Sep 2023 10:36:44 -0400 Subject: [PATCH 3/3] InstCountCI: Update Signed-off-by: Alyssa Rosenzweig --- unittests/InstructionCountCI/H0F38.json | 4 +- .../InstructionCountCI/Primary_32Bit.json | 76 +++++++------------ unittests/InstructionCountCI/VEX_map2.json | 8 +- 3 files changed, 29 insertions(+), 59 deletions(-) diff --git a/unittests/InstructionCountCI/H0F38.json b/unittests/InstructionCountCI/H0F38.json index 0b2c19c3a..ab50cb0d4 100644 --- a/unittests/InstructionCountCI/H0F38.json +++ b/unittests/InstructionCountCI/H0F38.json @@ -416,7 +416,7 @@ ] }, "ptest xmm0, xmm1": { - "ExpectedInstructionCount": 21, + "ExpectedInstructionCount": 19, "Optimal": "No", "Comment": [ "0x66 0x0f 0x38 0x17" @@ -438,8 +438,6 @@ "cset x21, eq", "lsl x20, x20, #30", "orr w20, w20, w21, lsl #29", - "mov w21, #0x90000000", - "bic x20, x20, x21", "strb w23, [x28, #706]", "strb w22, [x28, #708]", "str w20, [x28, #728]" diff --git a/unittests/InstructionCountCI/Primary_32Bit.json b/unittests/InstructionCountCI/Primary_32Bit.json index 038c7703d..f6d3b79f5 100644 --- a/unittests/InstructionCountCI/Primary_32Bit.json +++ b/unittests/InstructionCountCI/Primary_32Bit.json @@ -215,7 +215,7 @@ ] }, "aaa": { - "ExpectedInstructionCount": 28, + "ExpectedInstructionCount": 26, "Optimal": "No", "Comment": "0x37", "ExpectedArm64ASM": [ @@ -229,28 +229,26 @@ "cmp x21, #0x9 (9)", "cset x21, hi", "orr x20, x20, x21", - "cbnz x20, #+0x24", + "cbnz x20, #+0x20", "mov w20, #0xff0f", "and x20, x22, x20", "bfxil w4, w20, #0, #16", "mov w20, #0x0", - "mov w21, #0x0", "strb w20, [x28, #708]", - "str w21, [x28, #728]", - "b #+0x28", + "str w20, [x28, #728]", + "b #+0x24", "add x20, x22, #0x106 (262)", "mov w21, #0xff0f", "and x20, x20, x21", "bfxil w4, w20, #0, #16", - "ldr w20, [x28, #728]", - "orr w20, w20, #0x20000000", + "mov w20, #0x20000000", "mov w21, #0x10", "strb w21, [x28, #708]", "str w20, [x28, #728]" ] }, "aas": { - "ExpectedInstructionCount": 29, + "ExpectedInstructionCount": 27, "Optimal": "No", "Comment": "0x3f", "ExpectedArm64ASM": [ @@ -264,22 +262,20 @@ "cmp x21, #0x9 (9)", "cset x21, hi", "orr x20, x20, x21", - "cbnz x20, #+0x24", + "cbnz x20, #+0x20", "mov w20, #0xff0f", "and x20, x22, x20", "bfxil w4, w20, #0, #16", "mov w20, #0x0", - "mov w21, #0x0", "strb w20, [x28, #708]", - "str w21, [x28, #728]", - "b #+0x2c", + "str w20, [x28, #728]", + "b #+0x28", "sub x20, x22, #0x6 (6)", "sub x20, x20, #0x100 (256)", "mov w21, #0xff0f", "and x20, x20, x21", "bfxil w4, w20, #0, #16", - "ldr w20, [x28, #728]", - "orr w20, w20, #0x20000000", + "mov w20, #0x20000000", "mov w21, #0x10", "strb w21, [x28, #708]", "str w20, [x28, #728]" @@ -440,7 +436,7 @@ ] }, "aam": { - "ExpectedInstructionCount": 19, + "ExpectedInstructionCount": 14, "Optimal": "No", "Comment": "0xd4", "ExpectedArm64ASM": [ @@ -453,20 +449,15 @@ "add x20, x21, x20", "bfxil w4, w20, #0, #16", "uxtb w20, w4", - "and x21, x20, #0x80", - "cmp x21, #0x0 (0)", - "cset x21, hs", - "lsl x21, x21, #31", - "and x22, x20, #0xff", - "cmp x22, #0x0 (0)", - "cset x22, eq", - "orr w21, w21, w22, lsl #30", + "lsl w21, w20, #24", + "tst w21, w21", + "mrs x21, nzcv", "strb w20, [x28, #706]", "str w21, [x28, #728]" ] }, "aad": { - "ExpectedInstructionCount": 19, + "ExpectedInstructionCount": 14, "Optimal": "No", "Comment": "0xd5", "ExpectedArm64ASM": [ @@ -479,20 +470,15 @@ "and x20, x20, #0xff", "bfxil w4, w20, #0, #16", "uxtb w20, w4", - "and x21, x20, #0x80", - "cmp x21, #0x0 (0)", - "cset x21, hs", - "lsl x21, x21, #31", - "and x22, x20, #0xff", - "cmp x22, #0x0 (0)", - "cset x22, eq", - "orr w21, w21, w22, lsl #30", + "lsl w21, w20, #24", + "tst w21, w21", + "mrs x21, nzcv", "strb w20, [x28, #706]", "str w21, [x28, #728]" ] }, "db 0xd4, 0x40": { - "ExpectedInstructionCount": 19, + "ExpectedInstructionCount": 14, "Optimal": "No", "Comment": [ "aam with a different immediate byte base", @@ -508,20 +494,15 @@ "add x20, x21, x20", "bfxil w4, w20, #0, #16", "uxtb w20, w4", - "and x21, x20, #0x80", - "cmp x21, #0x0 (0)", - "cset x21, hs", - "lsl x21, x21, #31", - "and x22, x20, #0xff", - "cmp x22, #0x0 (0)", - "cset x22, eq", - "orr w21, w21, w22, lsl #30", + "lsl w21, w20, #24", + "tst w21, w21", + "mrs x21, nzcv", "strb w20, [x28, #706]", "str w21, [x28, #728]" ] }, "db 0xd5, 0x40": { - "ExpectedInstructionCount": 18, + "ExpectedInstructionCount": 13, "Optimal": "No", "Comment": [ "aad with a different immediate byte base", @@ -536,14 +517,9 @@ "and x20, x20, #0xff", "bfxil w4, w20, #0, #16", "uxtb w20, w4", - "and x21, x20, #0x80", - "cmp x21, #0x0 (0)", - "cset x21, hs", - "lsl x21, x21, #31", - "and x22, x20, #0xff", - "cmp x22, #0x0 (0)", - "cset x22, eq", - "orr w21, w21, w22, lsl #30", + "lsl w21, w20, #24", + "tst w21, w21", + "mrs x21, nzcv", "strb w20, [x28, #706]", "str w21, [x28, #728]" ] diff --git a/unittests/InstructionCountCI/VEX_map2.json b/unittests/InstructionCountCI/VEX_map2.json index d2e11b4e1..26a4217ef 100644 --- a/unittests/InstructionCountCI/VEX_map2.json +++ b/unittests/InstructionCountCI/VEX_map2.json @@ -791,7 +791,7 @@ ] }, "vptest xmm0, xmm1": { - "ExpectedInstructionCount": 23, + "ExpectedInstructionCount": 21, "Optimal": "No", "Comment": [ "Map 2 0b01 0x16 128-bit" @@ -815,15 +815,13 @@ "cset x21, eq", "lsl x20, x20, #30", "orr w20, w20, w21, lsl #29", - "mov w21, #0x90000000", - "bic x20, x20, x21", "strb w23, [x28, #706]", "strb w22, [x28, #708]", "str w20, [x28, #728]" ] }, "vptest ymm0, ymm1": { - "ExpectedInstructionCount": 31, + "ExpectedInstructionCount": 29, "Optimal": "No", "Comment": [ "Map 2 0b01 0x16 256-bit" @@ -855,8 +853,6 @@ "cset x21, eq", "lsl x20, x20, #30", "orr w20, w20, w21, lsl #29", - "mov w21, #0x90000000", - "bic x20, x20, x21", "strb w23, [x28, #706]", "strb w22, [x28, #708]", "str w20, [x28, #728]"