From 67914157cb61cf6c7408f88708f00ed02a9a2d31 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 13 Sep 2023 13:29:41 -0700 Subject: [PATCH 1/2] OpcodeDispatcher: Optimize shufpd This one is very satisfying since there are only four variants and each one of them converts to a single instruction. Needs #3088 merged first --- .../Interface/Core/OpcodeDispatcher/Vector.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 9d90c46b7..e59defac6 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -1392,6 +1392,24 @@ OrderedNode* OpDispatchBuilder::SHUFOpImpl(OpcodeArgs, size_t ElementSize, break; } } + else { + switch (Shuffle & 0b11) { + case 0b00: + // Low 64-bits of each source interleaved. + return _VZip(DstSize, ElementSize, Src1Node, Src2Node); + case 0b01: + // Upper 64-bits of Src1 in lower bits + // Lower 64-bits of Src2 in upper bits. + return _VExtr(DstSize, 1, Src2Node, Src1Node, 8); + case 0b10: + // Lower 32-bits of Src1 in lower bits. + // Upper 64-bits of Src2 in upper bits. + return _VInsElement(DstSize, ElementSize, 1, 1, Src1Node, Src2Node); + case 0b11: + // Upper 64-bits of each source interleaved. + return _VZip2(DstSize, ElementSize, Src1Node, Src2Node); + } + } for (uint8_t Element = 0; Element < NumElements; ++Element) { const auto SrcIndex = Shuffle & SelectionMask; From 853ded7df7ea7939b4aae6fa6b95be9ce6f569e4 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Wed, 13 Sep 2023 13:30:37 -0700 Subject: [PATCH 2/2] InstcountCI: Update for optimized shufpd --- .../InstructionCountCI/Secondary_OpSize.json | 88 +++++-------------- unittests/InstructionCountCI/VEX_map1.json | 10 +-- 2 files changed, 28 insertions(+), 70 deletions(-) diff --git a/unittests/InstructionCountCI/Secondary_OpSize.json b/unittests/InstructionCountCI/Secondary_OpSize.json index cb6373d36..6bb2b2e2f 100644 --- a/unittests/InstructionCountCI/Secondary_OpSize.json +++ b/unittests/InstructionCountCI/Secondary_OpSize.json @@ -954,107 +954,67 @@ ] }, "shufpd xmm0, xmm1, 00b": { - "ExpectedInstructionCount": 6, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "0x66 0x0f 0xc6", "ExpectedArm64ASM": [ - "mov v0.16b, v16.16b", - "mov v0.d[0], v16.d[0]", - "mov v2.16b, v0.16b", - "mov v0.16b, v2.16b", - "mov v0.d[1], v17.d[0]", - "mov v16.16b, v0.16b" + "zip1 v16.2d, v16.2d, v17.2d" ] }, "shufpd xmm0, xmm1, 01b": { - "ExpectedInstructionCount": 6, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "0x66 0x0f 0xc6", "ExpectedArm64ASM": [ - "mov v0.16b, v16.16b", - "mov v0.d[0], v16.d[1]", - "mov v2.16b, v0.16b", - "mov v0.16b, v2.16b", - "mov v0.d[1], v17.d[0]", - "mov v16.16b, v0.16b" + "ext v16.16b, v16.16b, v17.16b, #8" ] }, "shufpd xmm0, xmm1, 10b": { - "ExpectedInstructionCount": 6, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "0x66 0x0f 0xc6", "ExpectedArm64ASM": [ - "mov v0.16b, v16.16b", - "mov v0.d[0], v16.d[0]", - "mov v2.16b, v0.16b", - "mov v0.16b, v2.16b", - "mov v0.d[1], v17.d[1]", - "mov v16.16b, v0.16b" + "mov v16.d[1], v17.d[1]" ] }, "shufpd xmm0, xmm1, 11b": { - "ExpectedInstructionCount": 6, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "0x66 0x0f 0xc6", "ExpectedArm64ASM": [ - "mov v0.16b, v16.16b", - "mov v0.d[0], v16.d[1]", - "mov v2.16b, v0.16b", - "mov v0.16b, v2.16b", - "mov v0.d[1], v17.d[1]", - "mov v16.16b, v0.16b" + "zip2 v16.2d, v16.2d, v17.2d" ] }, "shufpd xmm1, xmm0, 00b": { - "ExpectedInstructionCount": 6, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "0x66 0x0f 0xc6", "ExpectedArm64ASM": [ - "mov v0.16b, v17.16b", - "mov v0.d[0], v17.d[0]", - "mov v2.16b, v0.16b", - "mov v0.16b, v2.16b", - "mov v0.d[1], v16.d[0]", - "mov v17.16b, v0.16b" + "zip1 v17.2d, v17.2d, v16.2d" ] }, "shufpd xmm1, xmm0, 01b": { - "ExpectedInstructionCount": 6, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "0x66 0x0f 0xc6", "ExpectedArm64ASM": [ - "mov v0.16b, v17.16b", - "mov v0.d[0], v17.d[1]", - "mov v2.16b, v0.16b", - "mov v0.16b, v2.16b", - "mov v0.d[1], v16.d[0]", - "mov v17.16b, v0.16b" + "ext v17.16b, v17.16b, v16.16b, #8" ] }, "shufpd xmm1, xmm0, 10b": { - "ExpectedInstructionCount": 6, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "0x66 0x0f 0xc6", "ExpectedArm64ASM": [ - "mov v0.16b, v17.16b", - "mov v0.d[0], v17.d[0]", - "mov v2.16b, v0.16b", - "mov v0.16b, v2.16b", - "mov v0.d[1], v16.d[1]", - "mov v17.16b, v0.16b" + "mov v17.d[1], v16.d[1]" ] }, "shufpd xmm1, xmm0, 11b": { - "ExpectedInstructionCount": 6, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": "0x66 0x0f 0xc6", "ExpectedArm64ASM": [ - "mov v0.16b, v17.16b", - "mov v0.d[0], v17.d[1]", - "mov v2.16b, v0.16b", - "mov v0.16b, v2.16b", - "mov v0.d[1], v16.d[1]", - "mov v17.16b, v0.16b" + "zip2 v17.2d, v17.2d, v16.2d" ] }, "addsubpd xmm0, xmm1": { diff --git a/unittests/InstructionCountCI/VEX_map1.json b/unittests/InstructionCountCI/VEX_map1.json index a668a252d..69da3703f 100644 --- a/unittests/InstructionCountCI/VEX_map1.json +++ b/unittests/InstructionCountCI/VEX_map1.json @@ -3393,7 +3393,7 @@ ] }, "vshufpd xmm0, xmm1, xmm2, 0b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": [ "Map 1 0b01 0xC6 128-bit" @@ -3401,8 +3401,7 @@ "ExpectedArm64ASM": [ "mov z2.d, p7/m, z17.d", "mov z3.d, p7/m, z18.d", - "mov v2.d[0], v2.d[0]", - "mov v2.d[1], v3.d[0]", + "zip1 v2.2d, v2.2d, v3.2d", "mov v2.16b, v2.16b", "mov z16.d, p7/m, z2.d" ] @@ -3438,7 +3437,7 @@ ] }, "vshufpd xmm0, xmm1, xmm2, 1b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 5, "Optimal": "No", "Comment": [ "Map 1 0b01 0xC6 128-bit" @@ -3446,8 +3445,7 @@ "ExpectedArm64ASM": [ "mov z2.d, p7/m, z17.d", "mov z3.d, p7/m, z18.d", - "mov v2.d[0], v2.d[1]", - "mov v2.d[1], v3.d[0]", + "ext v2.16b, v2.16b, v3.16b, #8", "mov v2.16b, v2.16b", "mov z16.d, p7/m, z2.d" ]