From bf702850a94c1aed3b3bf2d381b7ac22e86fbb0a Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 9 Nov 2023 11:32:27 -0400 Subject: [PATCH 1/3] InstCountCI: Add not bh case Signed-off-by: Alyssa Rosenzweig --- unittests/InstructionCountCI/PrimaryGroup.json | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/unittests/InstructionCountCI/PrimaryGroup.json b/unittests/InstructionCountCI/PrimaryGroup.json index 243558d0f..7e6f4524c 100644 --- a/unittests/InstructionCountCI/PrimaryGroup.json +++ b/unittests/InstructionCountCI/PrimaryGroup.json @@ -3383,6 +3383,16 @@ "bfxil x7, x20, #0, #8" ] }, + "not bh": { + "ExpectedInstructionCount": 3, + "Optimal": "No", + "Comment": "GROUP2 0xf6 /2", + "ExpectedArm64ASM": [ + "ubfx w20, w7, #8, #8", + "eor x20, x20, #0xff", + "bfi x7, x20, #8, #8" + ] + }, "neg bl": { "ExpectedInstructionCount": 14, "Optimal": "No", From 1ce3c16b30ff76d767f1a844929879d0d40aa6fb Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 9 Nov 2023 10:26:03 -0400 Subject: [PATCH 2/3] OpcodeDispatcher: Make "not" not garbage Signed-off-by: Alyssa Rosenzweig --- .../Interface/Core/OpcodeDispatcher.cpp | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index 90f20e0f6..b67c2b9d9 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -3357,11 +3357,39 @@ void OpDispatchBuilder::NOTOp(OpcodeArgs) { OrderedNode *DestMem = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false}); DestMem = AppendSegmentOffset(DestMem, Op->Flags); _AtomicXor(IR::SizeToOpSize(Size), MaskConst, DestMem); - } - else { + } else if (!Op->Dest.IsGPR()) { + // GPR version plays fast and loose with sizes, be safe for memory tho. OrderedNode *Src = LoadSource(GPRClass, Op, Op->Dest, Op->Flags); Src = _Xor(OpSize::i64Bit, Src, MaskConst); StoreResult(GPRClass, Op, Src, -1); + } else { + // Specially handle high bits so we can invert in place with the correct + // mask and a larger type. + auto Dest = Op->Dest; + if (Dest.Data.GPR.HighBits) { + LOGMAN_THROW_A_FMT(Size == 1, "Only 8-bit GPRs get high bits"); + MaskConst = _Constant(0xFF00); + Dest.Data.GPR.HighBits = false; + } + + // Always load full size, we explicitly want the upper bits to get the + // insert behaviour for free/implicitly. + const uint8_t GPRSize = CTX->GetGPRSize(); + OrderedNode *Src = LoadSource_WithOpSize(GPRClass, Op, Dest, GPRSize, Op->Flags); + + // For 8/16-bit, use 64-bit invert so we invert in place, while getting + // insert behaviour. For 32-bit, use 32-bit invert to zero the upper bits. + unsigned EffectiveSize = Size == 4 ? 4 : GPRSize; + + // If we're inverting the whole thing, use Not instead of Xor to save a constant. + if (Size >= 4) + Src = _Not(IR::SizeToOpSize(EffectiveSize), Src); + else + Src = _Xor(IR::SizeToOpSize(EffectiveSize), Src, MaskConst); + + // Always store 64-bit, the Not/Xor correctly handle the upper bits and this + // way we can delete the store. + StoreResult_WithOpSize(GPRClass, Op, Dest, Src, GPRSize, -1); } } From 03087a55ba4d72987a957d588f6a5fd12536ebe0 Mon Sep 17 00:00:00 2001 From: Alyssa Rosenzweig Date: Thu, 9 Nov 2023 11:20:31 -0400 Subject: [PATCH 3/3] InstCountCI: Update Signed-off-by: Alyssa Rosenzweig --- .../FlagM/PrimaryGroup.json | 8 ++-- .../InstructionCountCI/PrimaryGroup.json | 39 +++++++------------ 2 files changed, 18 insertions(+), 29 deletions(-) diff --git a/unittests/InstructionCountCI/FlagM/PrimaryGroup.json b/unittests/InstructionCountCI/FlagM/PrimaryGroup.json index 16c476b72..6575db180 100644 --- a/unittests/InstructionCountCI/FlagM/PrimaryGroup.json +++ b/unittests/InstructionCountCI/FlagM/PrimaryGroup.json @@ -3371,13 +3371,11 @@ ] }, "not bl": { - "ExpectedInstructionCount": 3, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "GROUP2 0xf6 /2", "ExpectedArm64ASM": [ - "uxtb w20, w7", - "eor x20, x20, #0xff", - "bfxil x7, x20, #0, #8" + "eor x7, x7, #0xff" ] }, "neg bl": { diff --git a/unittests/InstructionCountCI/PrimaryGroup.json b/unittests/InstructionCountCI/PrimaryGroup.json index 7e6f4524c..e3adf6a61 100644 --- a/unittests/InstructionCountCI/PrimaryGroup.json +++ b/unittests/InstructionCountCI/PrimaryGroup.json @@ -3374,23 +3374,19 @@ ] }, "not bl": { - "ExpectedInstructionCount": 3, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "GROUP2 0xf6 /2", "ExpectedArm64ASM": [ - "uxtb w20, w7", - "eor x20, x20, #0xff", - "bfxil x7, x20, #0, #8" + "eor x7, x7, #0xff" ] }, "not bh": { - "ExpectedInstructionCount": 3, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "GROUP2 0xf6 /2", "ExpectedArm64ASM": [ - "ubfx w20, w7, #8, #8", - "eor x20, x20, #0xff", - "bfi x7, x20, #8, #8" + "eor x7, x7, #0xff00" ] }, "neg bl": { @@ -3566,32 +3562,27 @@ ] }, "not bx": { - "ExpectedInstructionCount": 3, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "GROUP2 0xf7 /1", "ExpectedArm64ASM": [ - "uxth w20, w7", - "eor x20, x20, #0xffff", - "bfxil x7, x20, #0, #16" + "eor x7, x7, #0xffff" ] }, "not ebx": { - "ExpectedInstructionCount": 3, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "GROUP2 0xf7 /1", "ExpectedArm64ASM": [ - "mov w20, w7", - "eor x20, x20, #0xffffffff", - "mov w7, w20" + "mvn w7, w7" ] }, "not rbx": { - "ExpectedInstructionCount": 2, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "GROUP2 0xf7 /1", "ExpectedArm64ASM": [ - "mov x20, #0xffffffffffffffff", - "eor x7, x7, x20" + "mvn x7, x7" ] }, "neg bx": {