diff --git a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp index 48a683a28..f9fc2ff3b 100644 --- a/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp +++ b/FEXCore/Source/Interface/Core/JIT/VectorOps.cpp @@ -4631,6 +4631,81 @@ DEF_OP(VFNMLS) { } } +DEF_OP(VBlendImm) { + LOGMAN_THROW_A_FMT(HostSupportsSVE128 || HostSupportsSVE256, "Host must support SVE to use {}", __func__); + + auto Op = IROp->C(); + const auto OpSize = IROp->Size; + const auto Is256Bit = OpSize == IR::OpSize::i256Bit; + const auto SubRegSize = ConvertSubRegSize8(IROp); + const auto ElementSize = IROp->ElementSize; + const auto Selector = Op->Selector; + + const auto GoverningPredicate = Is256Bit ? PRED_TMP_32B : PRED_TMP_16B; + + const auto Dst = GetVReg(Node); + const auto LHS = GetVReg(Op->LHS); + const auto RHS = GetVReg(Op->RHS); + const auto DstIsNonAliasing = Dst != LHS && Dst != RHS; + + // Silly case where two blending sources are the same. + if (LHS == RHS) { + if (DstIsNonAliasing) { + mov(SubRegSize, Dst.Z(), GoverningPredicate.Merging(), LHS.Z()); + } + return; + } + + // We'll need to expand our selector to match its predicate equivalent. + // The lowest bit of each predicate element being set to 1 signifies + // that it's enabled. + const auto MakePredicateMask = [ElementSize, Is256Bit, OpSize](uint16_t Imm) { + if (ElementSize == IR::OpSize::i8Bit) { + // Since we use a u16 selector, we have enough bits for every byte in a + // 128-bit lane, so we don't need to do anything here except replicate the + // bits in the event of 256-bit. + return Is256Bit ? uint32_t(Imm) << 16 | Imm : Imm; + } + + uint32_t Mask = 0; + const auto DataSize = IR::OpSizeToSize(ElementSize); + const auto NumElements = IR::NumElements(OpSize, ElementSize); + for (uint32_t i = 0; i < NumElements; i++) { + if (((Imm >> i) & 1) != 0) { + Mask |= 1U << (DataSize * i); + } + } + return Mask; + }; + + // Our predicate that we'll be firing our constructed bitmask into. + constexpr auto Predicate = ARMEmitter::PReg::p0.Merging(); + + // TODO: We can completely eliminate this via PMOV in SVE2.1 + ARMEmitter::ForwardLabel AfterLabel; + ARMEmitter::BackwardLabel ConstantLabel; + (void)b(&AfterLabel); + (void)Bind(&ConstantLabel); + const auto PredicateMask = MakePredicateMask(Selector); + if (Dst == RHS) { + dc32(~PredicateMask); + } else { + dc32(PredicateMask); + } + (void)Bind(&AfterLabel); + (void)adr(TMP1, &ConstantLabel); + ldr(Predicate, TMP1); + + if (Dst == LHS) { + mov(SubRegSize, LHS.Z(), Predicate, RHS.Z()); + } else if (Dst == RHS) { + mov(SubRegSize, RHS.Z(), Predicate, LHS.Z()); + } else { + mov(SubRegSize, Dst.Z(), GoverningPredicate.Merging(), LHS.Z()); + mov(SubRegSize, Dst.Z(), Predicate, RHS.Z()); + } +} + DEF_OP(VFCopySign) { auto Op = IROp->C(); const auto OpSize = IROp->Size; diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp index b3c70bdcf..f5cffe898 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher/Vector.cpp @@ -5108,15 +5108,12 @@ void OpDispatchBuilder::VPERMQOp(OpcodeArgs) { } 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; + if (VecSize == OpSize::i256Bit) { + return _VBlendImm(VecSize, ElementSize, Src1, Src2, Selector); + } 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; + const auto Mask = (1U << ElementsPerLane) - 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. @@ -5133,7 +5130,7 @@ Ref OpDispatchBuilder::VBLENDOpImpl(IR::OpSize VecSize, IR::OpSize ElementSize, // 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 NumSrc1Bits = ElementsPerLane - NumSrc2Bits; const auto IsUsingSrc1 = NumSrc1Bits >= NumSrc2Bits; Ref Result = IsUsingSrc1 ? Src1 : Src2; Ref Source = IsUsingSrc1 ? Src2 : Src1; diff --git a/FEXCore/Source/Interface/IR/IR.json b/FEXCore/Source/Interface/IR/IR.json index 115a0d3e7..3327ac022 100644 --- a/FEXCore/Source/Interface/IR/IR.json +++ b/FEXCore/Source/Interface/IR/IR.json @@ -2564,6 +2564,24 @@ "DestSize": "RegisterSize", "ElementSize": "ElementSize", "TiedSource": 2 + }, + "FPR = VBlendImm OpSize:#RegisterSize, OpSize:#ElementSize, FPR:$LHS, FPR:$RHS, u16:$Selector": { + "Desc": [ + "Functions the same way an immediate blend operation on x86 would.", + "That is: (e.g. using 16-bit elements)", + " if (Selector[0] == 1)", + " Dst[15:0] = RHS[15:0]", + " else", + " Dst[15:0] = LHS[15:0]", + " ", + "", + "Note that like x86, due to the selector size, the operation of this IR op", + "uses a 128-bit lane granularity, so each blending selector independently operates", + "on each 128-bit element that composes the vector." + ], + "DestSize": "RegisterSize", + "ElementSize": "ElementSize", + "TiedSource": 0 } }, "Conv": { diff --git a/unittests/InstructionCountCI/VEX_map3.json b/unittests/InstructionCountCI/VEX_map3.json index 9c2595e41..d7d8aa2c3 100644 --- a/unittests/InstructionCountCI/VEX_map3.json +++ b/unittests/InstructionCountCI/VEX_map3.json @@ -664,235 +664,101 @@ ] }, "vpblendd ymm0, ymm1, ymm2, 00110011b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "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, z18.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, z18.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, z18.s[5]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #1", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.s, p7/m, z17.s", + "mov z16.s, p0/m, z18.s" ] }, "vpblendd ymm0, ymm1, ymm2, 00001111b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "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, z18.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, z18.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, z18.s[3]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #-1", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "b #+0x8", + "udf #0x1111", + "adr x0,", + "ldr p0, [x0]", + "mov z16.s, p7/m, z17.s", + "mov z16.s, p0/m, z18.s" ] }, "vpblendd ymm0, ymm1, ymm2, 01010101b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "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, z18.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, z18.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, z18.s[6]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #2", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.s, p7/m, z17.s", + "mov z16.s, p0/m, z18.s" ] }, "vpblendd ymm0, ymm1, ymm2, 10101010b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.s, z18.s[1]", - "mov z2.d, z17.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, z18.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, z18.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, z18.s[7]", - "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" + "b #+0x8", + "adr x16,", + "adr x0,", + "ldr p0, [x0]", + "mov z16.s, p7/m, z17.s", + "mov z16.s, p0/m, z18.s" ] }, "vpblendd ymm0, ymm1, ymm2, 11001100b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.s, z18.s[2]", - "mov z2.d, z17.d", - "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[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, z18.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", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #3", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "b #+0x8", + "add w0, w8, #0x4 (4)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.s, p7/m, z17.s", + "mov z16.s, p0/m, z18.s" ] }, "vpblendd ymm0, ymm1, ymm2, 11011001b": { - "ExpectedInstructionCount": 20, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.s, z17.s[1]", - "mov z2.d, z18.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, 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[5]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #1", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "b #+0x8", + "add w1, w0, #0x44 (68)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.s, p7/m, z17.s", + "mov z16.s, p0/m, z18.s" ] }, "vpblendd ymm0, ymm1, ymm2, 11110000b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x02 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.s, z18.s[4]", - "mov z2.d, z17.d", - "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, z18.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, z18.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", - "index z0.s, #-4, #1", - "cmpeq p0.s, p7/z, z0.s, #3", - "mov z16.s, p0/m, z1.s", - "msr nzcv, x0" + "b #+0x8", + "add w0, w0, #0x440 (1088)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.s, p7/m, z17.s", + "mov z16.s, p0/m, z18.s" ] }, "vpblendd ymm0, ymm1, ymm2, 11111111b": { @@ -1956,25 +1822,17 @@ ] }, "vblendps ymm0, ymm1, ymm2, 10000001b": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0c 256-bit" ], "ExpectedArm64ASM": [ - "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, z18.s[7]", - "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" + "b #+0x8", + "adr x1,", + "adr x0,", + "ldr p0, [x0]", + "mov z16.s, p7/m, z17.s", + "mov z16.s, p0/m, z18.s" ] }, "vblendps ymm0, ymm1, ymm2, 11111111b": { @@ -2034,255 +1892,199 @@ ] }, "vblendpd ymm0, ymm1, ymm2, 0001b": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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 z16.d, p0/m, z1.d", - "msr nzcv, x0" + "b #+0x8", + "udf #0x1", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 0010b": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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 z16.d, p0/m, z1.d", - "msr nzcv, x0" + "b #+0x8", + "udf #0x100", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 0011b": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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]", - "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" + "b #+0x8", + "udf #0x101", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 0100b": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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 z16.d, p0/m, z1.d", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 0101b": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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[2]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 0110b": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.d, #-2, #1", - "cmpeq p0.d, p7/z, z0.d, #0", - "mov z16.d, p0/m, z1.d", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 0111b": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z17.d[3]", - "mov z16.d, z18.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" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 1000b": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.d, z18.d[3]", - "mov z16.d, z17.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" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 1001b": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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[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" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 1010b": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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[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" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 1011b": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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 z16.d, p0/m, z1.d", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 1100b": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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", - "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" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 1101b": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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 z16.d, p0/m, z1.d", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 1110b": { - "ExpectedInstructionCount": 7, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0d 256-bit" ], "ExpectedArm64ASM": [ - "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 z16.d, p0/m, z1.d", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.d, p7/m, z17.d", + "mov z16.d, p0/m, z18.d" ] }, "vblendpd ymm0, ymm1, ymm2, 1111b": { @@ -2413,279 +2215,87 @@ ] }, "vpblendw ymm0, ymm1, ymm2, 00000001b": { - "ExpectedInstructionCount": 14, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0e 256-bit" ], "ExpectedArm64ASM": [ - "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, z18.h[8]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #0", - "mov z16.h, p0/m, z1.h", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.h, p7/m, z17.h", + "mov z16.h, p0/m, z18.h" ] }, "vpblendw ymm0, ymm1, ymm2, 01110011b": { - "ExpectedInstructionCount": 38, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0e 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.h, z17.h[2]", - "mov z2.d, z18.d", - "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[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, 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[15]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #7", - "mov z16.h, p0/m, z1.h", - "msr nzcv, x0" + "b #+0x8", + "b #+0x4145414", + "adr x0,", + "ldr p0, [x0]", + "mov z16.h, p7/m, z17.h", + "mov z16.h, p0/m, z18.h" ] }, "vpblendw ymm0, ymm1, ymm2, 01110111b": { - "ExpectedInstructionCount": 26, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0e 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.h, z17.h[3]", - "mov z2.d, z18.d", - "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[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, 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[15]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #7", - "mov z16.h, p0/m, z1.h", - "msr nzcv, x0" + "b #+0x8", + "b #+0x4545454", + "adr x0,", + "ldr p0, [x0]", + "mov z16.h, p7/m, z17.h", + "mov z16.h, p0/m, z18.h" ] }, "vpblendw ymm0, ymm1, ymm2, 00110011b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0e 256-bit" ], "ExpectedArm64ASM": [ - "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, z18.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, z18.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, z18.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, 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, z18.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, z18.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, z18.h[13]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #5", - "mov z16.h, p0/m, z1.h", - "msr nzcv, x0" + "b #+0x8", + "unallocated (Unallocated)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.h, p7/m, z17.h", + "mov z16.h, p0/m, z18.h" ] }, "vpblendw ymm0, ymm1, ymm2, 01010101b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0e 256-bit" ], "ExpectedArm64ASM": [ - "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, z18.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, z18.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, z18.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, 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, z18.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, z18.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, z18.h[14]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #6", - "mov z16.h, p0/m, z1.h", - "msr nzcv, x0" + "b #+0x8", + "add w17, w8, #0x444 (1092)", + "adr x0,", + "ldr p0, [x0]", + "mov z16.h, p7/m, z17.h", + "mov z16.h, p0/m, z18.h" ] }, "vpblendw ymm0, ymm1, ymm2, 10101010b": { - "ExpectedInstructionCount": 50, + "ExpectedInstructionCount": 6, "Comment": [ "Map 3 0b01 0x0e 256-bit" ], "ExpectedArm64ASM": [ - "mov z1.h, z18.h[1]", - "mov z2.d, z17.d", - "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, z18.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, z18.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, z18.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[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, z18.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, z18.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, z18.h[15]", - "mov z16.d, z2.d", - "mrs x0, nzcv", - "index z0.h, #-8, #1", - "cmpeq p0.h, p7/z, z0.h, #7", - "mov z16.h, p0/m, z1.h", - "msr nzcv, x0" + "b #+0x8", + "smlalt z4.h, z2.b, z4.b", + "adr x0,", + "ldr p0, [x0]", + "mov z16.h, p7/m, z17.h", + "mov z16.h, p0/m, z18.h" ] }, "vpblendw ymm0, ymm1, ymm2, 11111111b": {