From a6e7fba433e7b90660ff4da55970fb72037375fa Mon Sep 17 00:00:00 2001 From: LC Date: Sun, 21 Jun 2026 18:09:53 -0400 Subject: [PATCH] AVX: Reduce inserts in VBLENDPS/VPBLENDD/VPBLENDW Lets us reduce inserts by seeing which bits in the selector mask indicates a particular source is used more than the other one, and then just uses that as the base to be inserted into, cutting down on overall insertion overhead. In some cases, this can be quite drastic, like with: vpblendw ymm0, ymm1, ymm2, 0b00000001 being cut down from 98 instructions to 14. --- .../Source/Interface/Core/OpcodeDispatcher.h | 2 +- .../Core/OpcodeDispatcher/Vector.cpp | 56 +- unittests/InstructionCountCI/VEX_map3.json | 652 +++--------------- 3 files changed, 141 insertions(+), 569 deletions(-) diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h index 27f35e5d4..ecfad62a5 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.h +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.h @@ -596,7 +596,7 @@ public: void VANDNOp(OpcodeArgs); - Ref VBLENDOpImpl(IR::OpSize VecSize, IR::OpSize ElementSize, Ref Src1, Ref Src2, Ref ZeroRegister, uint64_t Selector); + Ref VBLENDOpImpl(IR::OpSize VecSize, IR::OpSize ElementSize, Ref Src1, Ref Src2, uint64_t Selector); void VBLENDPDOp(OpcodeArgs); void VPBLENDDOp(OpcodeArgs); void VPBLENDWOp(OpcodeArgs); diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index 554d03522..5135cdfff 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -5009,15 +5009,48 @@ void OpDispatchBuilder::VPERMQOp(OpcodeArgs) { StoreResultFPR(Op, Result); } -Ref OpDispatchBuilder::VBLENDOpImpl(IR::OpSize VecSize, IR::OpSize ElementSize, Ref Src1, Ref Src2, Ref ZeroRegister, uint64_t Selector) { - const std::array Sources {Src1, Src2}; +Ref OpDispatchBuilder::VBLENDOpImpl(IR::OpSize VecSize, IR::OpSize ElementSize, Ref Src1, Ref Src2, uint64_t Selector) { + const auto IsWordElements = ElementSize == OpSize::i16Bit; + const auto Is256Bit = VecSize == OpSize::i256Bit; + + const auto ElementsPerLane = uint32_t(IR::NumElements(OpSize::i128Bit, ElementSize)); + + // PBLENDW uses the same immediate size for 128-bit and 256-bit + // while all the others double in size. + const auto MaskSize = Is256Bit && !IsWordElements ? ElementsPerLane * 2 : ElementsPerLane; + const auto Mask = (1U << MaskSize) - 1; + + // Now, we determine which mask portion has the higher population count. + // we use this to determine which source we use as the base to insert into. + // + // For example each even bit in a mask that is set, means that element in Src2 + // will be inserted into the destination. If that bit is not set, then it's + // the element in Src1 that will be inserted instead. + // + // If we have more bits incoming from a particular source, then we can reappropriate + // that source as the destination and only perform inserts from the other source + // where necessary, which reduces the overall amount of element insertions that + // need to take place. + // + // In the event we tie, then we can just use Src1 and only perform incoming insertions + // that come from Src2. + const auto NumSrc2Bits = uint32_t(std::popcount(Selector & Mask)); + const auto NumSrc1Bits = MaskSize - NumSrc2Bits; + const auto IsUsingSrc1 = NumSrc1Bits >= NumSrc2Bits; + Ref Result = IsUsingSrc1 ? Src1 : Src2; + Ref Source = IsUsingSrc1 ? Src2 : Src1; - Ref Result = ZeroRegister; const auto NumElements = IR::NumElements(VecSize, ElementSize); for (int i = 0; i < NumElements; i++) { const auto SelectorIndex = (Selector >> i) & 1; + if (IsUsingSrc1 && SelectorIndex == 0) { + continue; + } + if (!IsUsingSrc1 && SelectorIndex != 0) { + continue; + } - Result = _VInsElement(VecSize, ElementSize, i, i, Result, Sources[SelectorIndex]); + Result = _VInsElement(VecSize, ElementSize, i, i, Result, Source); } return Result; @@ -5044,8 +5077,7 @@ void OpDispatchBuilder::VBLENDPDOp(OpcodeArgs) { return; } - const auto ZeroRegister = LoadZeroVector(DstSize); - Ref Result = VBLENDOpImpl(DstSize, OpSize::i64Bit, Src1, Src2, ZeroRegister, Selector); + Ref Result = VBLENDOpImpl(DstSize, OpSize::i64Bit, Src1, Src2, Selector); StoreResultFPR(Op, Result); } @@ -5085,11 +5117,7 @@ void OpDispatchBuilder::VPBLENDDOp(OpcodeArgs) { return; } - const auto ZeroRegister = LoadZeroVector(DstSize); - Ref Result = VBLENDOpImpl(DstSize, OpSize::i32Bit, Src1, Src2, ZeroRegister, Selector); - if (!Is256Bit) { - Result = _VMov(OpSize::i128Bit, Result); - } + Ref Result = VBLENDOpImpl(DstSize, OpSize::i32Bit, Src1, Src2, Selector); StoreResultFPR(Op, Result); } @@ -5117,11 +5145,7 @@ void OpDispatchBuilder::VPBLENDWOp(OpcodeArgs) { // imm for the helper function to use. const auto NewSelector = Selector << 8 | Selector; - const auto ZeroRegister = LoadZeroVector(DstSize); - Ref Result = VBLENDOpImpl(DstSize, OpSize::i16Bit, Src1, Src2, ZeroRegister, NewSelector); - if (Is128Bit) { - Result = _VMov(OpSize::i128Bit, Result); - } + Ref Result = VBLENDOpImpl(DstSize, OpSize::i16Bit, Src1, Src2, NewSelector); StoreResultFPR(Op, Result); } diff --git a/unittests/InstructionCountCI/VEX_map3.json b/unittests/InstructionCountCI/VEX_map3.json index 21d03beda..54d5b878e 100644 --- a/unittests/InstructionCountCI/VEX_map3.json +++ b/unittests/InstructionCountCI/VEX_map3.json @@ -602,199 +602,155 @@ ] }, "vpblendd xmm0, xmm1, 0001b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 1, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v17.s[0]", - "mov v2.s[1], v16.s[1]", - "mov v2.s[2], v16.s[2]", - "mov v2.s[3], v16.s[3]", - "mov v16.16b, v2.16b" + "mov v16.s[0], v17.s[0]" ] }, "vpblendd xmm0, xmm1, 0010b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 1, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v16.s[0]", - "mov v2.s[1], v17.s[1]", - "mov v2.s[2], v16.s[2]", - "mov v2.s[3], v16.s[3]", - "mov v16.16b, v2.16b" + "mov v16.s[1], v17.s[1]" ] }, "vpblendd xmm0, xmm1, 0011b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 4, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", + "mov v2.16b, v16.16b", "mov v2.s[0], v17.s[0]", - "mov v2.s[1], v17.s[1]", - "mov v2.s[2], v16.s[2]", - "mov v2.s[3], v16.s[3]", - "mov v16.16b, v2.16b" + "mov v16.16b, v2.16b", + "mov v16.s[1], v17.s[1]" ] }, "vpblendd xmm0, xmm1, 0100b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 1, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v16.s[0]", - "mov v2.s[1], v16.s[1]", - "mov v2.s[2], v17.s[2]", - "mov v2.s[3], v16.s[3]", - "mov v16.16b, v2.16b" + "mov v16.s[2], v17.s[2]" ] }, "vpblendd xmm0, xmm1, 0101b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 4, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", + "mov v2.16b, v16.16b", "mov v2.s[0], v17.s[0]", - "mov v2.s[1], v16.s[1]", - "mov v2.s[2], v17.s[2]", - "mov v2.s[3], v16.s[3]", - "mov v16.16b, v2.16b" + "mov v16.16b, v2.16b", + "mov v16.s[2], v17.s[2]" ] }, "vpblendd xmm0, xmm1, 0110b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 4, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v16.s[0]", + "mov v2.16b, v16.16b", "mov v2.s[1], v17.s[1]", - "mov v2.s[2], v17.s[2]", - "mov v2.s[3], v16.s[3]", - "mov v16.16b, v2.16b" + "mov v16.16b, v2.16b", + "mov v16.s[2], v17.s[2]" ] }, "vpblendd xmm0, xmm1, 0111b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 3, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v17.s[0]", - "mov v2.s[1], v17.s[1]", - "mov v2.s[2], v17.s[2]", - "mov v2.s[3], v16.s[3]", - "mov v16.16b, v2.16b" + "mov v0.16b, v17.16b", + "mov v0.s[3], v16.s[3]", + "mov v16.16b, v0.16b" ] }, "vpblendd xmm0, xmm1, 1000b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 1, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v16.s[0]", - "mov v2.s[1], v16.s[1]", - "mov v2.s[2], v16.s[2]", - "mov v2.s[3], v17.s[3]", - "mov v16.16b, v2.16b" + "mov v16.s[3], v17.s[3]" ] }, "vpblendd xmm0, xmm1, 1001b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 4, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", + "mov v2.16b, v16.16b", "mov v2.s[0], v17.s[0]", - "mov v2.s[1], v16.s[1]", - "mov v2.s[2], v16.s[2]", - "mov v2.s[3], v17.s[3]", - "mov v16.16b, v2.16b" + "mov v16.16b, v2.16b", + "mov v16.s[3], v17.s[3]" ] }, "vpblendd xmm0, xmm1, 1010b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 4, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v16.s[0]", + "mov v2.16b, v16.16b", "mov v2.s[1], v17.s[1]", - "mov v2.s[2], v16.s[2]", - "mov v2.s[3], v17.s[3]", - "mov v16.16b, v2.16b" + "mov v16.16b, v2.16b", + "mov v16.s[3], v17.s[3]" ] }, "vpblendd xmm0, xmm1, 1011b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 3, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v17.s[0]", - "mov v2.s[1], v17.s[1]", - "mov v2.s[2], v16.s[2]", - "mov v2.s[3], v17.s[3]", - "mov v16.16b, v2.16b" + "mov v0.16b, v17.16b", + "mov v0.s[2], v16.s[2]", + "mov v16.16b, v0.16b" ] }, "vpblendd xmm0, xmm1, 1100b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 4, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v16.s[0]", - "mov v2.s[1], v16.s[1]", + "mov v2.16b, v16.16b", "mov v2.s[2], v17.s[2]", - "mov v2.s[3], v17.s[3]", - "mov v16.16b, v2.16b" + "mov v16.16b, v2.16b", + "mov v16.s[3], v17.s[3]" ] }, "vpblendd xmm0, xmm1, 1101b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 3, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v17.s[0]", - "mov v2.s[1], v16.s[1]", - "mov v2.s[2], v17.s[2]", - "mov v2.s[3], v17.s[3]", - "mov v16.16b, v2.16b" + "mov v0.16b, v17.16b", + "mov v0.s[1], v16.s[1]", + "mov v16.16b, v0.16b" ] }, "vpblendd xmm0, xmm1, 1110b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 3, "Comment": [ "Map 3 0b01 0x02 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v16.s[0]", - "mov v2.s[1], v17.s[1]", - "mov v2.s[2], v17.s[2]", - "mov v2.s[3], v17.s[3]", - "mov v16.16b, v2.16b" + "mov v0.16b, v17.16b", + "mov v0.s[0], v16.s[0]", + "mov v16.16b, v0.16b" ] }, "vpblendd xmm0, xmm1, 1111b": { @@ -814,112 +770,64 @@ "ExpectedArm64ASM": [] }, "vpblendd ymm0, ymm1, 01010101b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 26, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", "mov z1.s, s17", + "mov z2.d, z16.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, z16.s[1]", - "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[2]", "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, z16.s[3]", - "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, 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, z16.s[5]", - "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, z17.s[6]", - "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, z16.s[7]", "mov z16.d, z2.d", "mrs x0, nzcv", "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #3", + "cmpeq p0.s, p7/z, z0.s, #2", "mov z16.s, p0/m, z1.s", "msr nzcv, x0" ] }, "vpblendd ymm0, ymm1, 10101010b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 26, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.s, s16", - "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[1]", + "mov z2.d, z16.d", "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, z16.s[2]", - "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, z17.s[3]", "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, z16.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, z17.s[5]", "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, z16.s[6]", - "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, z17.s[7]", "mov z16.d, z2.d", "mrs x0, nzcv", @@ -2497,17 +2405,13 @@ ] }, "vblendps xmm0, xmm1, xmm2, 0001b": { - "ExpectedInstructionCount": 6, + "ExpectedInstructionCount": 2, "Comment": [ "Map 3 0b01 0x0c 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.s[0], v18.s[0]", - "mov v2.s[1], v17.s[1]", - "mov v2.s[2], v17.s[2]", - "mov v2.s[3], v17.s[3]", - "mov v16.16b, v2.16b" + "mov v16.16b, v17.16b", + "mov v16.s[0], v18.s[0]" ] }, "vblendps xmm0, xmm1, xmm2, 1111b": { @@ -2529,54 +2433,18 @@ ] }, "vblendps ymm0, ymm1, ymm2, 10000001b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 14, "Comment": [ "Map 3 0b01 0x0c 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", "mov z1.s, s18", + "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[1]", - "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[2]", - "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, z17.s[3]", - "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, 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, z17.s[5]", - "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, z17.s[6]", - "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[7]", "mov z16.d, z2.d", "mrs x0, nzcv", @@ -2605,26 +2473,22 @@ ] }, "vblendpd xmm0, xmm1, xmm2, 01b": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 2, "Comment": [ "Map 3 0b01 0x0d 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.d[0], v18.d[0]", - "mov v16.16b, v2.16b", - "mov v16.d[1], v17.d[1]" + "mov v16.16b, v17.16b", + "mov v16.d[0], v18.d[0]" ] }, "vblendpd xmm0, xmm1, xmm2, 10b": { - "ExpectedInstructionCount": 4, + "ExpectedInstructionCount": 2, "Comment": [ "Map 3 0b01 0x0d 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.d[0], v17.d[0]", - "mov v16.16b, v2.16b", + "mov v16.16b, v17.16b", "mov v16.d[1], v18.d[1]" ] }, @@ -2647,236 +2511,124 @@ ] }, "vblendpd ymm0, ymm1, ymm2, 0001b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 7, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", "mov z1.d, d18", + "mov z16.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[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, 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, z17.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" ] }, "vblendpd ymm0, ymm1, ymm2, 0010b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 7, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d17", - "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, z18.d[1]", + "mov z16.d, z17.d", "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, 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, z17.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" ] }, "vblendpd ymm0, ymm1, ymm2, 0011b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 14, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", "mov z1.d, d18", + "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, 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, 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, z17.d[3]", "mov z16.d, z2.d", "mrs x0, nzcv", "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", + "cmpeq p0.d, p7/z, z0.d, #-1", "mov z16.d, p0/m, z1.d", "msr nzcv, x0" ] }, "vblendpd ymm0, ymm1, ymm2, 0100b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 7, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d17", - "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[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, z17.d", "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, z17.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" ] }, "vblendpd ymm0, ymm1, ymm2, 0101b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 14, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", "mov z1.d, d18", + "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[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]", - "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, z17.d[3]", "mov z16.d, z2.d", "mrs x0, nzcv", "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", + "cmpeq p0.d, p7/z, z0.d, #0", "mov z16.d, p0/m, z1.d", "msr nzcv, x0" ] }, "vblendpd ymm0, ymm1, ymm2, 0110b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 14, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d17", - "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, z18.d[1]", + "mov z2.d, z17.d", "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]", - "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, z17.d[3]", "mov z16.d, z2.d", "mrs x0, nzcv", "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #1", + "cmpeq p0.d, p7/z, z0.d, #0", "mov z16.d, p0/m, z1.d", "msr nzcv, x0" ] }, "vblendpd ymm0, ymm1, ymm2, 0111b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 7, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d18", - "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, 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]", - "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, z17.d[3]", - "mov z16.d, z2.d", + "mov z16.d, z18.d", "mrs x0, nzcv", "index z0.d, #-2, #1", "cmpeq p0.d, p7/z, z0.d, #1", @@ -2885,32 +2637,13 @@ ] }, "vblendpd ymm0, ymm1, ymm2, 1000b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 7, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d17", - "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[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, 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[3]", - "mov z16.d, z2.d", + "mov z16.d, z17.d", "mrs x0, nzcv", "index z0.d, #-2, #1", "cmpeq p0.d, p7/z, z0.d, #1", @@ -2919,30 +2652,18 @@ ] }, "vblendpd ymm0, ymm1, ymm2, 1001b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 14, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", "mov z1.d, d18", + "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[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, 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[3]", "mov z16.d, z2.d", "mrs x0, nzcv", @@ -2953,30 +2674,18 @@ ] }, "vblendpd ymm0, ymm1, ymm2, 1010b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 14, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d17", - "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, z18.d[1]", + "mov z2.d, z17.d", "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, 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[3]", "mov z16.d, z2.d", "mrs x0, nzcv", @@ -2987,59 +2696,28 @@ ] }, "vblendpd ymm0, ymm1, ymm2, 1011b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 7, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d18", - "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, 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, z17.d[2]", + "mov z16.d, z18.d", "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[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" ] }, "vblendpd ymm0, ymm1, ymm2, 1100b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 14, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d17", - "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[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 z2.d, z17.d", "mrs x0, nzcv", "index z0.d, #-2, #1", "cmpeq p0.d, p7/z, z0.d, #0", @@ -3055,69 +2733,31 @@ ] }, "vblendpd ymm0, ymm1, ymm2, 1101b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 7, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov z1.d, d18", - "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[1]", + "mov z16.d, z18.d", "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]", - "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[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" ] }, "vblendpd ymm0, ymm1, ymm2, 1110b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 7, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", "mov z1.d, d17", + "mov z16.d, z18.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, 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]", - "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[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" ] @@ -3141,21 +2781,13 @@ ] }, "vpblendw xmm0, xmm1, xmm2, 00000001b": { - "ExpectedInstructionCount": 10, + "ExpectedInstructionCount": 2, "Comment": [ "Map 3 0b01 0x0e 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", - "mov v2.h[0], v18.h[0]", - "mov v2.h[1], v17.h[1]", - "mov v2.h[2], v17.h[2]", - "mov v2.h[3], v17.h[3]", - "mov v2.h[4], v17.h[4]", - "mov v2.h[5], v17.h[5]", - "mov v2.h[6], v17.h[6]", - "mov v2.h[7], v17.h[7]", - "mov v16.16b, v2.16b" + "mov v16.16b, v17.16b", + "mov v16.h[0], v18.h[0]" ] }, "vpblendw xmm0, xmm1, xmm2, 11111111b": { @@ -3177,107 +2809,23 @@ ] }, "vpblendw ymm0, ymm1, ymm2, 00000001b": { - "ExpectedInstructionCount": 98, + "ExpectedInstructionCount": 14, "Comment": [ "Map 3 0b01 0x0e 128-bit" ], "ExpectedArm64ASM": [ - "movi v2.2d, #0x0", "mov z1.h, h18", + "mov z2.d, z17.d", "mrs x0, nzcv", "index z0.h, #-8, #1", "cmpeq p0.h, p7/z, z0.h, #-8", "mov z2.h, p0/m, z1.h", "msr nzcv, x0", - "mov z1.h, z17.h[1]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #-7", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[2]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #-6", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[3]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #-5", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[4]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #-4", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[5]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #-3", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[6]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #-2", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[7]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #-1", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", "mov z1.h, z18.h[8]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #0", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[9]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #1", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[10]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #2", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[11]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #3", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[12]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #4", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[13]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #5", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[14]", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #6", - "mov z2.h, p0/m, z1.h", - "msr nzcv, x0", - "mov z1.h, z17.h[15]", "mov z16.d, z2.d", "mrs x0, nzcv", "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #7", + "cmpeq p0.h, p7/z, z0.h, #0", "mov z16.h, p0/m, z1.h", "msr nzcv, x0" ]