diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index f441a6204..3c683d7ef 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -1781,137 +1781,113 @@ Ref OpDispatchBuilder::SHUFOpImpl(OpcodeArgs, IR::OpSize DstSize, IR::OpSize Ele Srcs[i] = Src2; } - Ref Dest = Src1; const uint8_t SelectionMask = NumElements - 1; const uint8_t ShiftAmount = std::popcount(SelectionMask); - if (Is256Bit) { - if (ElementSize == OpSize::i64Bit) { - if (Shuffle == 0) { - return _VTrn(DstSize, ElementSize, Src1, Src2); - } - if (Shuffle == 0b1111) { - return _VTrn2(DstSize, ElementSize, Src1, Src2); - } - } - - for (uint8_t Element = 0; Element < NumElements; ++Element) { - const auto SrcIndex1 = Shuffle & SelectionMask; - - // AVX differs the behavior of VSHUFPD and VSHUFPS. - // The same immediate bits are used for both lanes with VSHUFPS, - // but VSHUFPD uses different immediate bits for each lane. - const auto SrcIndex2 = ElementSize == OpSize::i32Bit ? SrcIndex1 : ((Shuffle >> 2) & SelectionMask); - - Ref Insert = _VInsElement(DstSize, ElementSize, Element, SrcIndex1, Dest, Srcs[Element]); - Dest = _VInsElement(DstSize, ElementSize, Element + NumElements, SrcIndex2 + NumElements, Insert, Srcs[Element]); - - Shuffle >>= ShiftAmount; - } - } else { - if (Src1 == Src2 && Shuffle == 0) { + const auto SingleLane = [&](Ref LHS, Ref RHS, uint32_t LaneShuffle) -> Ref { + if (LHS == RHS && LaneShuffle == 0) { // TODO: We can optimize significantly more shuffles when we know the sources match. // Special case broadcast element 0. - return _VDupElement(DstSize, ElementSize, Src1, Shuffle & SelectionMask); + return _VDupElement(DstSize, ElementSize, LHS, LaneShuffle & SelectionMask); } if (ElementSize == OpSize::i32Bit) { // We can shuffle optimally in a lot of cases. // TODO: We can optimize more of these cases. - switch (Shuffle) { + switch (LaneShuffle) { case 0b01'00'01'00: // Combining of low 64-bits. // Dest[63:0] = Src1[63:0] // Dest[127:64] = Src2[63:0] - return _VZip(DstSize, OpSize::i64Bit, Src1, Src2); + return _VZip(OpSize::i128Bit, OpSize::i64Bit, LHS, RHS); case 0b11'10'11'10: // Combining of high 64-bits. // Dest[63:0] = Src1[127:64] // Dest[127:64] = Src2[127:64] - return _VZip2(DstSize, OpSize::i64Bit, Src1, Src2); + return _VZip2(OpSize::i128Bit, OpSize::i64Bit, LHS, RHS); case 0b11'10'01'00: // Mixing Low and high elements // Dest[63:0] = Src1[63:0] // Dest[127:64] = Src2[127:64] - return _VInsElement(DstSize, OpSize::i64Bit, 1, 1, Src1, Src2); + return _VInsElement(OpSize::i128Bit, OpSize::i64Bit, 1, 1, LHS, RHS); case 0b01'00'11'10: // Mixing Low and high elements, inverse of above // Dest[63:0] = Src1[127:64] // Dest[127:64] = Src2[63:0] - return _VExtr(DstSize, OpSize::i8Bit, Src2, Src1, 8); + return _VExtr(OpSize::i128Bit, OpSize::i8Bit, RHS, LHS, 8); case 0b10'00'10'00: // Mixing even elements. // Dest[31:0] = Src1[31:0] // Dest[63:32] = Src1[95:64] // Dest[95:64] = Src2[31:0] // Dest[127:96] = Src2[95:64] - return _VUnZip(DstSize, ElementSize, Src1, Src2); + return _VUnZip(OpSize::i128Bit, ElementSize, LHS, RHS); case 0b11'01'11'01: // Mixing odd elements. // Dest[31:0] = Src1[63:32] // Dest[63:32] = Src1[127:96] // Dest[95:64] = Src2[63:32] // Dest[127:96] = Src2[127:96] - return _VUnZip2(DstSize, ElementSize, Src1, Src2); + return _VUnZip2(OpSize::i128Bit, ElementSize, LHS, RHS); case 0b11'10'00'00: case 0b11'10'01'01: case 0b11'10'10'10: case 0b11'10'11'11: { // Bottom elements duplicated, Top 64-bits inserted - auto DupSrc1 = _VDupElement(DstSize, ElementSize, Src1, Shuffle & 0b11); - return _VZip2(DstSize, OpSize::i64Bit, DupSrc1, Src2); + auto DupLHS = _VDupElement(OpSize::i128Bit, ElementSize, LHS, LaneShuffle & 0b11); + return _VZip2(OpSize::i128Bit, OpSize::i64Bit, DupLHS, RHS); } case 0b01'00'00'00: case 0b01'00'01'01: case 0b01'00'10'10: case 0b01'00'11'11: { // Bottom elements duplicated, Bottom 64-bits inserted - auto DupSrc1 = _VDupElement(DstSize, ElementSize, Src1, Shuffle & 0b11); - return _VZip(DstSize, OpSize::i64Bit, DupSrc1, Src2); + auto DupLHS = _VDupElement(OpSize::i128Bit, ElementSize, LHS, LaneShuffle & 0b11); + return _VZip(OpSize::i128Bit, OpSize::i64Bit, DupLHS, RHS); } case 0b00'00'01'00: case 0b01'01'01'00: case 0b10'10'01'00: case 0b11'11'01'00: { // Top elements duplicated, Bottom 64-bits inserted - auto DupSrc2 = _VDupElement(DstSize, ElementSize, Src2, (Shuffle >> 4) & 0b11); - return _VZip(DstSize, OpSize::i64Bit, Src1, DupSrc2); + auto DupRHS = _VDupElement(OpSize::i128Bit, ElementSize, RHS, (LaneShuffle >> 4) & 0b11); + return _VZip(OpSize::i128Bit, OpSize::i64Bit, LHS, DupRHS); } case 0b00'00'11'10: case 0b01'01'11'10: case 0b10'10'11'10: case 0b11'11'11'10: { // Top elements duplicated, Top 64-bits inserted - auto DupSrc2 = _VDupElement(DstSize, ElementSize, Src2, (Shuffle >> 4) & 0b11); - return _VZip2(DstSize, OpSize::i64Bit, Src1, DupSrc2); + auto DupRHS = _VDupElement(OpSize::i128Bit, ElementSize, RHS, (LaneShuffle >> 4) & 0b11); + return _VZip2(OpSize::i128Bit, OpSize::i64Bit, LHS, DupRHS); } case 0b01'00'01'11: { // TODO: This doesn't generate optimal code. // RA doesn't understand that Src1 is dead after VInsElement due to SRA class differences. // With RA fixes this would be 2 instructions. // Odd elements inverted, Low 64-bits inserted - Src1 = _VInsElement(DstSize, OpSize::i32Bit, 0, 3, Src1, Src1); - return _VZip(DstSize, OpSize::i64Bit, Src1, Src2); + auto InsLHS = _VInsElement(OpSize::i128Bit, OpSize::i32Bit, 0, 3, LHS, LHS); + return _VZip(OpSize::i128Bit, OpSize::i64Bit, InsLHS, RHS); } case 0b11'10'01'11: { // TODO: This doesn't generate optimal code. // RA doesn't understand that Src1 is dead after VInsElement due to SRA class differences. // With RA fixes this would be 2 instructions. // Odd elements inverted, Top 64-bits inserted - Src1 = _VInsElement(DstSize, OpSize::i32Bit, 0, 3, Src1, Src1); - return _VInsElement(DstSize, OpSize::i64Bit, 1, 1, Src1, Src2); + auto InsLHS = _VInsElement(OpSize::i128Bit, OpSize::i32Bit, 0, 3, LHS, LHS); + return _VInsElement(OpSize::i128Bit, OpSize::i64Bit, 1, 1, InsLHS, RHS); } case 0b01'00'00'01: { // Lower 32-bit elements inverted, low 64-bits inserted - Src1 = _VRev64(DstSize, OpSize::i32Bit, Src1); - return _VZip(DstSize, OpSize::i64Bit, Src1, Src2); + auto RevLHS = _VRev64(OpSize::i128Bit, OpSize::i32Bit, LHS); + return _VZip(OpSize::i128Bit, OpSize::i64Bit, RevLHS, RHS); } case 0b11'10'00'01: { // TODO: This doesn't generate optimal code. // RA doesn't understand that Src1 is dead after VInsElement due to SRA class differences. // With RA fixes this would be 2 instructions. // Lower 32-bit elements inverted, Top 64-bits inserted - Src1 = _VRev64(DstSize, OpSize::i32Bit, Src1); - return _VInsElement(DstSize, OpSize::i64Bit, 1, 1, Src1, Src2); + auto RevLHS = _VRev64(OpSize::i128Bit, OpSize::i32Bit, LHS); + return _VInsElement(OpSize::i128Bit, OpSize::i64Bit, 1, 1, RevLHS, RHS); } case 0b00'00'00'00: case 0b00'00'01'01: @@ -1930,43 +1906,69 @@ Ref OpDispatchBuilder::SHUFOpImpl(OpcodeArgs, IR::OpSize DstSize, IR::OpSize Ele case 0b11'11'10'10: case 0b11'11'11'11: { // Duplicate element in upper and lower across each 64-bit segment. - auto DupSrc1 = _VDupElement(DstSize, ElementSize, Src1, Shuffle & 0b11); - auto DupSrc2 = _VDupElement(DstSize, ElementSize, Src2, (Shuffle >> 4) & 0b11); - return _VZip(DstSize, OpSize::i64Bit, DupSrc1, DupSrc2); + auto DupSrc1 = _VDupElement(OpSize::i128Bit, ElementSize, LHS, LaneShuffle & 0b11); + auto DupSrc2 = _VDupElement(OpSize::i128Bit, ElementSize, RHS, (LaneShuffle >> 4) & 0b11); + return _VZip(OpSize::i128Bit, OpSize::i64Bit, DupSrc1, DupSrc2); } default: // Use a TBL2 operation to handle this implementation. - auto LookupIndexes = - LoadAndCacheIndexedNamedVectorConstant(DstSize, FEXCore::IR::IndexNamedVectorConstant::INDEXED_NAMED_VECTOR_SHUFPS, Shuffle * 16); - return _VTBL2(DstSize, Src1, Src2, LookupIndexes); + auto LookupIndexes = LoadAndCacheIndexedNamedVectorConstant( + OpSize::i128Bit, FEXCore::IR::IndexNamedVectorConstant::INDEXED_NAMED_VECTOR_SHUFPS, LaneShuffle * 16); + return _VTBL2(OpSize::i128Bit, LHS, RHS, LookupIndexes); } } else { - switch (Shuffle & 0b11) { + switch (LaneShuffle & 0b11) { case 0b00: // Low 64-bits of each source interleaved. - return _VZip(DstSize, ElementSize, Src1, Src2); + return _VZip(OpSize::i128Bit, ElementSize, LHS, RHS); case 0b01: // Upper 64-bits of Src1 in lower bits // Lower 64-bits of Src2 in upper bits. - return _VExtr(DstSize, OpSize::i8Bit, Src2, Src1, 8); + return _VExtr(OpSize::i128Bit, OpSize::i8Bit, RHS, LHS, 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, Src1, Src2); + return _VInsElement(OpSize::i128Bit, ElementSize, 1, 1, LHS, RHS); case 0b11: // Upper 64-bits of each source interleaved. - return _VZip2(DstSize, ElementSize, Src1, Src2); + return _VZip2(OpSize::i128Bit, ElementSize, LHS, RHS); } } + Ref Result = LHS; for (uint8_t Element = 0; Element < NumElements; ++Element) { - const auto SrcIndex = Shuffle & SelectionMask; - Dest = _VInsElement(DstSize, ElementSize, Element, SrcIndex, Dest, Srcs[Element]); - Shuffle >>= ShiftAmount; + const auto SrcIndex = LaneShuffle & SelectionMask; + Result = _VInsElement(OpSize::i128Bit, ElementSize, Element, SrcIndex, Result, Srcs[Element]); + LaneShuffle >>= ShiftAmount; } - } + return Result; + }; - return Dest; + if (Is256Bit) { + if (ElementSize == OpSize::i64Bit) { + if (Shuffle == 0) { + return _VTrn(DstSize, ElementSize, Src1, Src2); + } + if (Shuffle == 0b1111) { + return _VTrn2(DstSize, ElementSize, Src1, Src2); + } + } + + auto UpperLaneLHS = _VDupElement(OpSize::i256Bit, OpSize::i128Bit, Src1, 1); + auto UpperLaneRHS = _VDupElement(OpSize::i256Bit, OpSize::i128Bit, Src2, 1); + + // VSHUFPS uses the full immediate for each lane, where as VSHUFPD + // uses pairs for each operation. + const auto LowerShuffle = ElementSize == OpSize::i32Bit ? Shuffle : Shuffle & 0b11; + const auto UpperShuffle = ElementSize == OpSize::i32Bit ? Shuffle : (Shuffle >> 2) & 0b11; + + auto Lower = SingleLane(Src1, Src2, LowerShuffle); + auto Upper = SingleLane(UpperLaneLHS, UpperLaneRHS, UpperShuffle); + + return _VInsElement(OpSize::i256Bit, OpSize::i128Bit, 1, 0, Lower, Upper); + } else { + return SingleLane(Src1, Src2, Shuffle); + } } void OpDispatchBuilder::SHUFOp(OpcodeArgs, IR::OpSize ElementSize) { diff --git a/unittests/InstructionCountCI/VEX_map1.json b/unittests/InstructionCountCI/VEX_map1.json index 3e2d280ce..815d34685 100644 --- a/unittests/InstructionCountCI/VEX_map1.json +++ b/unittests/InstructionCountCI/VEX_map1.json @@ -2197,61 +2197,23 @@ ] }, "vshufps ymm0, ymm1, ymm2, 00b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 12, "Comment": [ "Map 1 0b00 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.s, s17", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-4", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z17.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #0", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s17", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-3", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z17.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #1", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s18", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-2", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z18.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #2", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s18", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-1", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z18.s[4]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #3", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "dup v4.4s, v17.s[0]", + "dup v5.4s, v18.s[0]", + "zip1 v4.2d, v4.2d, v5.2d", + "dup v2.4s, v2.s[0]", + "dup v3.4s, v3.s[0]", + "zip1 v2.2d, v2.2d, v3.2d", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufps xmm0, xmm1, xmm2, 01b": { @@ -2266,61 +2228,21 @@ ] }, "vshufps ymm0, ymm1, ymm2, 01b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 10, "Comment": [ "Map 1 0b00 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.s, z17.s[1]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-4", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z17.s[5]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #0", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s17", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-3", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z17.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #1", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s18", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-2", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z18.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #2", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s18", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-1", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z18.s[4]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #3", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "ldr x0, [x28, #2696]", + "ldr q4, [x0, #16]", + "tbl v5.16b, {v17.16b, v18.16b}, v4.16b", + "tbl v2.16b, {v2.16b, v3.16b}, v4.16b", + "mov z1.q, q2", + "mov z16.d, z5.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufps xmm0, xmm1, xmm2, 10b": { @@ -2335,61 +2257,21 @@ ] }, "vshufps ymm0, ymm1, ymm2, 10b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 10, "Comment": [ "Map 1 0b00 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.s, z17.s[2]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-4", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z17.s[6]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #0", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s17", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-3", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z17.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #1", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s18", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-2", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z18.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #2", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s18", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-1", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z18.s[4]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #3", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "ldr x0, [x28, #2696]", + "ldr q4, [x0, #32]", + "tbl v5.16b, {v17.16b, v18.16b}, v4.16b", + "tbl v2.16b, {v2.16b, v3.16b}, v4.16b", + "mov z1.q, q2", + "mov z16.d, z5.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufps xmm0, xmm1, xmm2, 11b": { @@ -2404,61 +2286,21 @@ ] }, "vshufps ymm0, ymm1, ymm2, 11b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 10, "Comment": [ "Map 1 0b00 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.s, z17.s[3]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-4", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z17.s[7]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #0", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s17", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-3", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z17.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #1", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s18", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-2", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z18.s[4]", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #2", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, s18", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-1", - "mov z2.s, p0/m, z1.s", - "msr nzcv, x0", - "mov z1.s, z18.s[4]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #3", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "ldr x0, [x28, #2696]", + "ldr q4, [x0, #48]", + "tbl v5.16b, {v17.16b, v18.16b}, v4.16b", + "tbl v2.16b, {v2.16b, v3.16b}, v4.16b", + "mov z1.q, q2", + "mov z16.d, z5.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd xmm0, xmm1, xmm2, 0b": { @@ -2489,479 +2331,231 @@ ] }, "vshufpd ymm0, ymm1, ymm2, 0001b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z17.d[1]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[2]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, d18", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[2]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "ext v4.16b, v17.16b, v18.16b, #8", + "zip1 v2.2d, v2.2d, v3.2d", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 0010b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 9, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, d17", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[2]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[1]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[2]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "mov v4.16b, v17.16b", + "mov v4.d[1], v18.d[1]", + "zip1 v2.2d, v2.2d, v3.2d", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 0011b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z17.d[1]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[2]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[1]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[2]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "zip2 v4.2d, v17.2d, v18.2d", + "zip1 v2.2d, v2.2d, v3.2d", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 0100b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, d17", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[3]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, d18", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[2]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "zip1 v4.2d, v17.2d, v18.2d", + "ext v2.16b, v2.16b, v3.16b, #8", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 0101b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z17.d[1]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[3]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, d18", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[2]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "ext v4.16b, v17.16b, v18.16b, #8", + "ext v2.16b, v2.16b, v3.16b, #8", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 0110b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 9, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, d17", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[3]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[1]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[2]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "mov v4.16b, v17.16b", + "mov v4.d[1], v18.d[1]", + "ext v2.16b, v2.16b, v3.16b, #8", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 0111b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z17.d[1]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[3]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[1]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[2]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "zip2 v4.2d, v17.2d, v18.2d", + "ext v2.16b, v2.16b, v3.16b, #8", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 1000b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, d17", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[2]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, d18", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[3]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "zip1 v4.2d, v17.2d, v18.2d", + "mov v2.d[1], v3.d[1]", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 1001b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z17.d[1]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[2]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, d18", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[3]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "ext v4.16b, v17.16b, v18.16b, #8", + "mov v2.d[1], v3.d[1]", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 1010b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 9, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, d17", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[2]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[1]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[3]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "mov v4.16b, v17.16b", + "mov v4.d[1], v18.d[1]", + "mov v2.d[1], v3.d[1]", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 1011b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z17.d[1]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[2]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[1]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[3]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "zip2 v4.2d, v17.2d, v18.2d", + "mov v2.d[1], v3.d[1]", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 1100b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, d17", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[3]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, d18", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[3]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "zip1 v4.2d, v17.2d, v18.2d", + "zip2 v2.2d, v2.2d, v3.2d", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 1101b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 8, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z17.d[1]", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[3]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, d18", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[3]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "ext v4.16b, v17.16b, v18.16b, #8", + "zip2 v2.2d, v2.2d, v3.2d", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 1110b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 9, "Comment": [ "Map 1 0b01 0xC6 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, d17", - "mov z2.d, z17.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-2", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z17.d[3]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[1]", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #-1", - "mov z2.d, p0/m, z1.d", - "msr nzcv, x0", - "mov z1.d, z18.d[3]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "mov z2.q, z17.q[1]", + "mov z3.q, z18.q[1]", + "mov v4.16b, v17.16b", + "mov v4.d[1], v18.d[1]", + "zip2 v2.2d, v2.2d, v3.2d", + "mov z1.q, q2", + "mov z16.d, z4.d", + "not p0.b, p7/z, p6.b", + "mov z16.b, p0/m, z1.b" ] }, "vshufpd ymm0, ymm1, ymm2, 1111b": {