Merge pull request #5595 from lioncash/pspd

AVX: Wire up lane helper for VSHUFPD/VSHUFPS
This commit is contained in:
Ryan Houdek authored and GitHub committed 2026-06-24 00:22:12 -07:00
commit 62ecdd650f
2 files changed
+244 -648

No files matched your search

@@ -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) {
+176 -582
View File
@@ -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": {