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; 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" ]