diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -871,15 +871,16 @@ //****************************************************************************** // SVE predicate register classes. -class PPRClass : RegisterClass< +class PPRClass : RegisterClass< "AArch64", [ nxv16i1, nxv8i1, nxv4i1, nxv2i1, nxv1i1 ], 16, - (sequence "P%u", 0, lastreg)> { + (sequence "P%u", firstreg, lastreg)> { let Size = 16; } -def PPR : PPRClass<15>; -def PPR_3b : PPRClass<7>; // Restricted 3 bit SVE predicate register class. +def PPR : PPRClass<0, 15>; +def PPR_3b : PPRClass<0, 7>; // Restricted 3 bit SVE predicate register class. +def PPR_3b_p8_p15 : PPRClass<8, 15>; class PPRAsmOperand : AsmOperandClass { let Name = "SVE" # name # "Reg"; @@ -906,6 +907,29 @@ def PPR3bAny : PPRRegOp<"", PPRAsmOp3bAny, ElementSizeNone, PPR_3b>; + +// SME predicate-as-counter operand +class PNRAsmOperand + : PPRAsmOperand { + let PredicateMethod = "isSMEPredicateAsCounterRegOfWidth<" + # Width # ", " # "AArch64::" + # RegClass # "RegClassID>"; + let DiagnosticType = "InvalidSME" # name # "Reg"; + let ParserMethod = "tryParseSMEPredicateAsCounter"; +} + +class PNRP8_15RegOp + : PPRRegOp { + let PrintMethod = "printPredicateAsCounter<" # EltSize # ">"; + let EncoderMethod = "EncodePPR_3b_p8_p15"; + let DecoderMethod = "DecodePPR_3b_p8_p15RegisterClass"; +} + +def PNRAsmAny_p8_p15 : PNRAsmOperand<"PNPredicateAny_p8_p15", "PPR_3b_p8_p15", 0>; + +def PNRAny_p8_p15 : PNRP8_15RegOp<"", PNRAsmAny_p8_p15, 0, PPR_3b_p8_p15>; + + //****************************************************************************** // SVE vector register classes diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td --- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td +++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td @@ -475,6 +475,9 @@ defm FRINTP_2Z2Z: sme2_frint_vector_vg2_multi<"frintp", 0b001>; defm FRINTP_4Z4Z: sme2_frint_vector_vg4_multi<"frintp", 0b001>; +defm SEL_VG2_2ZP2Z2Z: sme2_sel_vector_vg2<"sel">; +defm SEL_VG4_4ZP4Z4Z: sme2_sel_vector_vg4<"sel">; + } diff --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp --- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp +++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp @@ -68,6 +68,7 @@ Scalar, NeonVector, SVEDataVector, + SMEPredicateAsCounter, SVEPredicateVector, Matrix }; @@ -265,6 +266,7 @@ template OperandMatchResultTy tryParseSVEDataVector(OperandVector &Operands); OperandMatchResultTy tryParseSVEPredicateVector(OperandVector &Operands); + OperandMatchResultTy tryParseSMEPredicateAsCounter(OperandVector &Operands); template OperandMatchResultTy tryParseVectorList(OperandVector &Operands, bool ExpectMatch = false); @@ -1197,6 +1199,22 @@ bool isMatrix() const { return Kind == k_MatrixRegister; } bool isMatrixTileList() const { return Kind == k_MatrixTileList; } + template bool isSMEVectorReg() const { + RegKind RK; + switch (Class) { + case AArch64::PPRRegClassID: + case AArch64::PPR_3bRegClassID: + case AArch64::PPR_3b_p8_p15RegClassID: + RK = RegKind::SMEPredicateAsCounter; + break; + default: + llvm_unreachable("Unsupport register class"); + } + + return (Kind == k_Register && Reg.Kind == RK) && + AArch64MCRegisterClasses[Class].contains(getReg()); + } + template bool isSVEVectorReg() const { RegKind RK; switch (Class) { @@ -1233,6 +1251,17 @@ return DiagnosticPredicateTy::NearMatch; } + template + DiagnosticPredicate isSMEPredicateAsCounterRegOfWidth() const { + if (Kind != k_Register || Reg.Kind != RegKind::SMEPredicateAsCounter) + return DiagnosticPredicateTy::NoMatch; + + if (isSMEVectorReg() && (Reg.ElementWidth == ElementWidth)) + return DiagnosticPredicateTy::Match; + + return DiagnosticPredicateTy::NearMatch; + } + template DiagnosticPredicate isSVEDataVectorRegOfWidth() const { if (Kind != k_Register || Reg.Kind != RegKind::SVEDataVector) @@ -2058,7 +2087,8 @@ unsigned ShiftAmount = 0, unsigned HasExplicitAmount = false) { assert((Kind == RegKind::NeonVector || Kind == RegKind::SVEDataVector || - Kind == RegKind::SVEPredicateVector) && + Kind == RegKind::SVEPredicateVector || + Kind == RegKind::SMEPredicateAsCounter) && "Invalid vector kind"); auto Op = CreateReg(RegNum, Kind, S, E, Ctx, EqualsReg, ExtTy, ShiftAmount, HasExplicitAmount); @@ -2477,6 +2507,7 @@ .Case(".d", {0, 64}) .Default({-1, -1}); break; + case RegKind::SMEPredicateAsCounter: case RegKind::SVEPredicateVector: case RegKind::SVEDataVector: case RegKind::Matrix: @@ -2561,6 +2592,27 @@ .Default(0); } +static unsigned matchSMEPredicateAsCounterRegName(StringRef Name) { + return StringSwitch(Name.lower()) + .Case("pn0", AArch64::P0) + .Case("pn1", AArch64::P1) + .Case("pn2", AArch64::P2) + .Case("pn3", AArch64::P3) + .Case("pn4", AArch64::P4) + .Case("pn5", AArch64::P5) + .Case("pn6", AArch64::P6) + .Case("pn7", AArch64::P7) + .Case("pn8", AArch64::P8) + .Case("pn9", AArch64::P9) + .Case("pn10", AArch64::P10) + .Case("pn11", AArch64::P11) + .Case("pn12", AArch64::P12) + .Case("pn13", AArch64::P13) + .Case("pn14", AArch64::P14) + .Case("pn15", AArch64::P15) + .Default(0); +} + static unsigned matchMatrixTileListRegName(StringRef Name) { return StringSwitch(Name.lower()) .Case("za0.d", AArch64::ZAD0) @@ -2704,6 +2756,9 @@ if ((RegNum = matchSVEPredicateVectorRegName(Name))) return Kind == RegKind::SVEPredicateVector ? RegNum : 0; + if ((RegNum = matchSMEPredicateAsCounterRegName(Name))) + return Kind == RegKind::SMEPredicateAsCounter ? RegNum : 0; + if ((RegNum = MatchNeonVectorRegName(Name))) return Kind == RegKind::NeonVector ? RegNum : 0; @@ -3809,6 +3864,60 @@ return MatchOperand_NoMatch; } +OperandMatchResultTy +AArch64AsmParser::tryParseSMEPredicateAsCounter(OperandVector &Operands) { + const SMLoc S = getLoc(); + StringRef Kind; + unsigned RegNum; + auto Res = + tryParseVectorRegister(RegNum, Kind, RegKind::SMEPredicateAsCounter); + if (Res != MatchOperand_Success) + return Res; + + const auto &KindRes = parseVectorKind(Kind, RegKind::SMEPredicateAsCounter); + if (!KindRes) + return MatchOperand_NoMatch; + + unsigned ElementWidth = KindRes->second; + Operands.push_back( + AArch64Operand::CreateVectorReg(RegNum, RegKind::SMEPredicateAsCounter, + ElementWidth, S, getLoc(), getContext())); + + // Check if register is followed by an index + OperandMatchResultTy ResIndex = tryParseVectorIndex(Operands); + if (ResIndex == MatchOperand_Success) + return MatchOperand_Success; + + // Not all predicates are followed by a '/z'. + MCAsmParser &Parser = getParser(); + if (Parser.getTok().isNot(AsmToken::Slash)) + return MatchOperand_Success; + + // But when they do they shouldn't have an element type suffix. + if (!Kind.empty()) { + Error(S, "not expecting size suffix"); + return MatchOperand_ParseFail; + } + + // Add a literal slash as operand + Operands.push_back(AArch64Operand::CreateToken("/", getLoc(), getContext())); + + Parser.Lex(); // Eat the slash. + + // Zeroing or merging? + auto Pred = Parser.getTok().getString().lower(); + if (Pred != "z") { + Error(getLoc(), "expecting 'z' predication"); + return MatchOperand_ParseFail; + } + + // Add zero token. + const char *ZM = "z"; + Operands.push_back(AArch64Operand::CreateToken(ZM, getLoc(), getContext())); + + Parser.Lex(); // Eat zero token. + return MatchOperand_Success; +} /// tryParseSVEPredicateVector - Parse a SVE predicate register operand. OperandMatchResultTy AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) { @@ -5613,6 +5722,9 @@ return Error(Loc, "invalid predicate register."); case Match_InvalidSVEPredicate3bAnyReg: return Error(Loc, "invalid restricted predicate register, expected p0..p7 (without element suffix)"); + case Match_InvalidSMEPNPredicateAny_p8_p15Reg: + return Error(Loc, "invalid restricted predicate-as-counter register " + "expected pn8..pn15"); case Match_InvalidSVEExactFPImmOperandHalfOne: return Error(Loc, "Invalid floating point constant, expected 0.5 or 1.0."); case Match_InvalidSVEExactFPImmOperandHalfTwo: @@ -6195,6 +6307,7 @@ case Match_InvalidSVEPredicateSReg: case Match_InvalidSVEPredicateDReg: case Match_InvalidSVEPredicate3bAnyReg: + case Match_InvalidSMEPNPredicateAny_p8_p15Reg: case Match_InvalidSVEExactFPImmOperandHalfOne: case Match_InvalidSVEExactFPImmOperandHalfTwo: case Match_InvalidSVEExactFPImmOperandZeroOne: diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -137,6 +137,9 @@ static DecodeStatus DecodePPR_3bRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, const MCDisassembler *Decoder); +static DecodeStatus +DecodePPR_3b_p8_p15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Address, + const MCDisassembler *Decoder); static DecodeStatus DecodeFixedPointScaleImm32(MCInst &Inst, unsigned Imm, uint64_t Address, @@ -712,6 +715,16 @@ return DecodePPRRegisterClass(Inst, RegNo, Addr, Decoder); } +static DecodeStatus +DecodePPR_3b_p8_p15RegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, + const MCDisassembler *Decoder) { + if (RegNo > 7) + return Fail; + + // Just reuse the PPR decode table + return DecodePPRRegisterClass(Inst, RegNo + 8, Addr, Decoder); +} + static DecodeStatus DecodeQQRegisterClass(MCInst &Inst, unsigned RegNo, uint64_t Addr, const MCDisassembler *Decoder) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.h @@ -182,6 +182,10 @@ const MCSubtargetInfo &STI, raw_ostream &O); void printSIMDType10Operand(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O); + template + void printPredicateAsCounter(const MCInst *MI, unsigned OpNum, + const MCSubtargetInfo &STI, raw_ostream &O); + template void printComplexRotationOp(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI, raw_ostream &O); diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64InstPrinter.cpp @@ -1193,6 +1193,26 @@ } } +template +void AArch64InstPrinter::printPredicateAsCounter(const MCInst *MI, + unsigned OpNum, + const MCSubtargetInfo &STI, + raw_ostream &O) { + unsigned Reg = MI->getOperand(OpNum).getReg(); + + assert(Reg <= AArch64::P15 && "Unsupported predicate register"); + O << "pn" << (Reg - AArch64::P0); + switch (EltSize) { + case 0: break; + case 8: O << ".b"; break; + case 16: O << ".h"; break; + case 32: O << ".s"; break; + case 64: O << ".d"; break; + default: + llvm_unreachable("Unsupported element size"); + } +} + void AArch64InstPrinter::printCondCode(const MCInst *MI, unsigned OpNum, const MCSubtargetInfo &STI, raw_ostream &O) { diff --git a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp --- a/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp +++ b/llvm/lib/Target/AArch64/MCTargetDesc/AArch64MCCodeEmitter.cpp @@ -190,6 +190,10 @@ SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; + uint32_t EncodePPR_3b_p8_p15(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const; + uint32_t EncodeMatrixTileListRegisterClass(const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const; @@ -533,6 +537,14 @@ return RegVal / Multiple; } +uint32_t +AArch64MCCodeEmitter::EncodePPR_3b_p8_p15(const MCInst &MI, unsigned OpIdx, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + auto RegOpnd = MI.getOperand(OpIdx).getReg(); + return RegOpnd - AArch64::P8; +} + uint32_t AArch64MCCodeEmitter::EncodeMatrixTileListRegisterClass( const MCInst &MI, unsigned OpIdx, SmallVectorImpl &Fixups, const MCSubtargetInfo &STI) const { diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td --- a/llvm/lib/Target/AArch64/SMEInstrFormats.td +++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td @@ -3499,3 +3499,59 @@ let Inst{1} = 0b0; } } + +//===----------------------------------------------------------------------===// +// SME2 Multi-vector - SVE Select +class sme2_sel_vector_vg24 sz, RegisterOperand vector_ty, + string mnemonic> + : I<(outs vector_ty:$Zd), + (ins PNRAny_p8_p15:$PNg, vector_ty:$Zn, vector_ty:$Zm), + mnemonic, "\t$Zd, $PNg, $Zn, $Zm", + "", []>, Sched<[]> { + bits<3> PNg; + let Inst{31-24} = 0b11000001; + let Inst{23-22} = sz; + let Inst{21} = 0b1; + let Inst{15-13} = 0b100; + let Inst{12-10} = PNg; + let Inst{5} = 0b0; + let Inst{0} = 0b0; +} + +class sme2_sel_vector_vg2 sz, RegisterOperand vector_ty, + string mnemonic> + : sme2_sel_vector_vg24 { + bits<4> Zm; + bits<4> Zn; + bits<4> Zd; + let Inst{20-17} = Zm; + let Inst{16} = 0b0; + let Inst{9-6} = Zn; + let Inst{4-1} = Zd; +} + +multiclass sme2_sel_vector_vg2{ + def _B : sme2_sel_vector_vg2<0b00, ZZ_b_mul_r, mnemonic>; + def _H : sme2_sel_vector_vg2<0b01, ZZ_h_mul_r, mnemonic>; + def _S : sme2_sel_vector_vg2<0b10, ZZ_s_mul_r, mnemonic>; + def _D : sme2_sel_vector_vg2<0b11, ZZ_d_mul_r, mnemonic>; +} +class sme2_sel_vector_vg4 sz, RegisterOperand vector_ty, + string mnemonic> + : sme2_sel_vector_vg24 { + bits<3> Zm; + bits<3> Zn; + bits<3> Zd; + let Inst{20-18} = Zm; + let Inst{17-16} = 0b01; + let Inst{9-7} = Zn; + let Inst{6} = 0b0; + let Inst{4-2} = Zd; + let Inst{1} = 0b0; +} +multiclass sme2_sel_vector_vg4 { + def _B : sme2_sel_vector_vg4<0b00, ZZZZ_b_mul_r, mnemonic>; + def _H : sme2_sel_vector_vg4<0b01, ZZZZ_h_mul_r, mnemonic>; + def _S : sme2_sel_vector_vg4<0b10, ZZZZ_s_mul_r, mnemonic>; + def _D : sme2_sel_vector_vg4<0b11, ZZZZ_d_mul_r, mnemonic>; +} diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-inline-asm.ll @@ -26,7 +26,7 @@ define i64 @asm_register_early_clobber() { ; CHECK-LABEL: name: asm_register_early_clobber ; CHECK: bb.1 (%ir-block.0): - ; CHECK: INLINEASM &"mov $0, 7; mov $1, 7", 1 /* sideeffect attdialect */, 1703947 /* regdef-ec:GPR64common */, def early-clobber %0, 1703947 /* regdef-ec:GPR64common */, def early-clobber %1, !0 + ; CHECK: INLINEASM &"mov $0, 7; mov $1, 7", 1 /* sideeffect attdialect */, 1769483 /* regdef-ec:GPR64common */, def early-clobber %0, 1769483 /* regdef-ec:GPR64common */, def early-clobber %1, !0 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY %0 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY %1 ; CHECK: [[ADD:%[0-9]+]]:_(s64) = G_ADD [[COPY]], [[COPY1]] @@ -54,7 +54,7 @@ define i32 @test_single_register_output() nounwind ssp { ; CHECK-LABEL: name: test_single_register_output ; CHECK: bb.1.entry: - ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %0 + ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %0 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY %0 ; CHECK: $w0 = COPY [[COPY]](s32) ; CHECK: RET_ReallyLR implicit $w0 @@ -66,7 +66,7 @@ define i64 @test_single_register_output_s64() nounwind ssp { ; CHECK-LABEL: name: test_single_register_output_s64 ; CHECK: bb.1.entry: - ; CHECK: INLINEASM &"mov $0, 7", 0 /* attdialect */, 1703946 /* regdef:GPR64common */, def %0 + ; CHECK: INLINEASM &"mov $0, 7", 0 /* attdialect */, 1769482 /* regdef:GPR64common */, def %0 ; CHECK: [[COPY:%[0-9]+]]:_(s64) = COPY %0 ; CHECK: $x0 = COPY [[COPY]](s64) ; CHECK: RET_ReallyLR implicit $x0 @@ -79,7 +79,7 @@ define float @test_multiple_register_outputs_same() #0 { ; CHECK-LABEL: name: test_multiple_register_outputs_same ; CHECK: bb.1 (%ir-block.0): - ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %0, 655370 /* regdef:GPR32common */, def %1 + ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %0, 720906 /* regdef:GPR32common */, def %1 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY %0 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY %1 ; CHECK: [[FADD:%[0-9]+]]:_(s32) = G_FADD [[COPY]], [[COPY1]] @@ -96,7 +96,7 @@ define double @test_multiple_register_outputs_mixed() #0 { ; CHECK-LABEL: name: test_multiple_register_outputs_mixed ; CHECK: bb.1 (%ir-block.0): - ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %0, 1507338 /* regdef:FPR64 */, def %1 + ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %0, 1572874 /* regdef:FPR64 */, def %1 ; CHECK: [[COPY:%[0-9]+]]:_(s32) = COPY %0 ; CHECK: [[COPY1:%[0-9]+]]:_(s64) = COPY %1 ; CHECK: $d0 = COPY [[COPY1]](s64) @@ -125,7 +125,7 @@ ; CHECK: liveins: $x0 ; ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK: INLINEASM &"mov ${0:w}, 32", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %1 + ; CHECK: INLINEASM &"mov ${0:w}, 32", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %1 ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY %1 ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY1]](s32) ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8) @@ -155,7 +155,7 @@ ; CHECK: bb.1 (%ir-block.0): ; CHECK: [[C:%[0-9]+]]:_(s64) = G_CONSTANT i64 42 ; CHECK: [[COPY:%[0-9]+]]:gpr64common = COPY [[C]](s64) - ; CHECK: INLINEASM &"mov x0, $0", 1 /* sideeffect attdialect */, 1703945 /* reguse:GPR64common */, [[COPY]] + ; CHECK: INLINEASM &"mov x0, $0", 1 /* sideeffect attdialect */, 1769481 /* reguse:GPR64common */, %0 ; CHECK: RET_ReallyLR call void asm sideeffect "mov x0, $0", "r"(i64 42) ret void @@ -189,7 +189,7 @@ ; CHECK: liveins: $x0 ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 ; CHECK: [[COPY1:%[0-9]+]]:gpr64common = COPY [[COPY]](p0) - ; CHECK: INLINEASM &"ldtrb ${0:w}, [$1]", 0 /* attdialect */, 655370 /* regdef:GPR32common */, def %1, 1703945 /* reguse:GPR64common */, [[COPY1]] + ; CHECK: INLINEASM &"ldtrb ${0:w}, [$1]", 0 /* attdialect */, 720906 /* regdef:GPR32common */, def %1, 1769481 /* reguse:GPR64common */, %2 ; CHECK: [[COPY2:%[0-9]+]]:_(s32) = COPY %1 ; CHECK: [[TRUNC:%[0-9]+]]:_(s8) = G_TRUNC [[COPY2]](s32) ; CHECK: [[ZEXT:%[0-9]+]]:_(s32) = G_ZEXT [[TRUNC]](s8) @@ -205,7 +205,7 @@ ; CHECK: bb.1 (%ir-block.0): ; CHECK: liveins: $x0 ; CHECK: [[COPY:%[0-9]+]]:_(p0) = COPY $x0 - ; CHECK: INLINEASM &"ldr $0, $1", 8 /* mayload attdialect */, 655370 /* regdef:GPR32common */, def %1, 262158 /* mem:m */, [[COPY]](p0) + ; CHECK: INLINEASM &"ldr $0, $1", 8 /* mayload attdialect */, 720906 /* regdef:GPR32common */, def %1, 262158 /* mem:m */, %0(p0) ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY %1 ; CHECK: $w0 = COPY [[COPY1]](s32) ; CHECK: RET_ReallyLR implicit $w0 @@ -219,7 +219,7 @@ ; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1 ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16) ; CHECK: [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32) - ; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 655370 /* regdef:GPR32common */, def %0, 655369 /* reguse:GPR32common */, [[COPY]] + ; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 720906 /* regdef:GPR32common */, def %0, 720905 /* reguse:GPR32common */, [[COPY]] ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY %0 ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32) ; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16) @@ -235,7 +235,7 @@ ; CHECK: [[C:%[0-9]+]]:_(s16) = G_CONSTANT i16 1 ; CHECK: [[ANYEXT:%[0-9]+]]:_(s32) = G_ANYEXT [[C]](s16) ; CHECK: [[COPY:%[0-9]+]]:gpr32common = COPY [[ANYEXT]](s32) - ; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 655370 /* regdef:GPR32common */, def %0, 2147483657 /* reguse tiedto:$0 */, [[COPY]](tied-def 3) + ; CHECK: INLINEASM &"", 1 /* sideeffect attdialect */, 720906 /* regdef:GPR32common */, def %0, 2147483657 /* reguse tiedto:$0 */, [[COPY]] ; CHECK: [[COPY1:%[0-9]+]]:_(s32) = COPY %0 ; CHECK: [[TRUNC:%[0-9]+]]:_(s16) = G_TRUNC [[COPY1]](s32) ; CHECK: [[ANYEXT1:%[0-9]+]]:_(s32) = G_ANYEXT [[TRUNC]](s16) diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll --- a/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll +++ b/llvm/test/CodeGen/AArch64/GlobalISel/irtranslator-unwind-inline-asm.ll @@ -69,7 +69,7 @@ ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: [[DEF:%[0-9]+]]:_(p0) = G_IMPLICIT_DEF ; CHECK-NEXT: [[COPY:%[0-9]+]]:gpr64common = COPY [[DEF]](p0) - ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 1703945 /* reguse:GPR64common */, [[COPY]] + ; CHECK-NEXT: INLINEASM &"", 1 /* sideeffect attdialect */, 1769481 /* reguse:GPR64common */, %0 ; CHECK-NEXT: G_BR %bb.2 ; CHECK-NEXT: {{ $}} ; CHECK-NEXT: bb.2.a: diff --git a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir --- a/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir +++ b/llvm/test/CodeGen/AArch64/GlobalISel/regbank-inlineasm.mir @@ -57,7 +57,7 @@ body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_reg_output - ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1310730 /* regdef:WSeqPairsClass_with_sube32_in_MatrixIndexGPR32_12_15 */, def %0 + ; CHECK: INLINEASM &"mov ${0:w}, 7", 0 /* attdialect */, 1310730 /* regdef:WSeqPairsClass_with_sube32_in_GPR32arg */, def %0 ; CHECK: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK: $w0 = COPY [[COPY]](s32) ; CHECK: RET_ReallyLR implicit $w0 @@ -75,7 +75,7 @@ body: | bb.1: ; CHECK-LABEL: name: inlineasm_virt_mixed_types - ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1310730 /* regdef:WSeqPairsClass_with_sube32_in_MatrixIndexGPR32_12_15 */, def %0, 2162698 /* regdef:FIXED_REGS */, def %1 + ; CHECK: INLINEASM &"mov $0, #0; mov $1, #0", 0 /* attdialect */, 1310730 /* regdef:WSeqPairsClass_with_sube32_in_GPR32arg */, def %0, 2162698 /* regdef:GPR64arg */, def %1 ; CHECK: [[COPY:%[0-9]+]]:gpr(s32) = COPY %0 ; CHECK: [[COPY1:%[0-9]+]]:fpr(s64) = COPY %1 ; CHECK: $d0 = COPY [[COPY1]](s64) diff --git a/llvm/test/MC/AArch64/SME2/sel-diagnostics.s b/llvm/test/MC/AArch64/SME2/sel-diagnostics.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/sel-diagnostics.s @@ -0,0 +1,37 @@ +// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 2>&1 < %s | FileCheck %s + +// --------------------------------------------------------------------------// +// Invalid vector list + +sel {z0.h-z2.h}, pn8, {z0.h-z1.h}, {z0.h-z1.h} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: sel {z0.h-z2.h}, pn8, {z0.h-z1.h}, {z0.h-z1.h} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sel {z28.s-z31.s}, pn15, {z26.s-z31.s}, {z28.s-z31.s} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors +// CHECK-NEXT: sel {z28.s-z31.s}, pn15, {z26.s-z31.s}, {z28.s-z31.s} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sel {z28.d-z31.d}, pn15, {z28.d-z31.d}, {z26.d-z31.d} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors +// CHECK-NEXT: sel {z28.d-z31.d}, pn15, {z28.d-z31.d}, {z26.d-z31.d} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sel {z1.b-z4.b}, pn8, {z0.b-z3.b}, {z0.b-z3.b} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 4 consecutive SVE vectors, where the first vector is a multiple of 4 and with matching element types +// CHECK-NEXT: sel {z1.b-z4.b}, pn8, {z0.b-z3.b}, {z0.b-z3.b} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +sel {z22.s-z23.s}, pn11, {z13.s-z14.s}, {z8.s-z9.s} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types +// CHECK-NEXT: sel {z22.s-z23.s}, pn11, {z13.s-z14.s}, {z8.s-z9.s} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: + +// --------------------------------------------------------------------------// +// Invalid Register Suffix + +sel {z0.h-z1.h}, pn8, {z0.h-z1.h}, {z0.s-z1.s} +// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction +// CHECK-NEXT: sel {z0.h-z1.h}, pn8, {z0.h-z1.h}, {z0.s-z1.s} +// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}: diff --git a/llvm/test/MC/AArch64/SME2/sel.s b/llvm/test/MC/AArch64/SME2/sel.s new file mode 100644 --- /dev/null +++ b/llvm/test/MC/AArch64/SME2/sel.s @@ -0,0 +1,213 @@ +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST +// RUN: not llvm-mc -triple=aarch64 -show-encoding < %s 2>&1 \ +// RUN: | FileCheck %s --check-prefix=CHECK-ERROR +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d --mattr=+sme2 - | FileCheck %s --check-prefix=CHECK-INST +// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2 < %s \ +// RUN: | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN +// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2 < %s \ +// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \ +// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2 -disassemble -show-encoding \ +// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST + + +sel {z0.h, z1.h}, pn8, {z0.h, z1.h}, {z0.h, z1.h} // 11000001-01100000-10000000-00000000 +// CHECK-INST: sel { z0.h, z1.h }, pn8, { z0.h, z1.h }, { z0.h, z1.h } +// CHECK-ENCODING: [0x00,0x80,0x60,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1608000 + +sel {z20.h, z21.h}, pn13, {z10.h, z11.h}, {z20.h, z21.h} // 11000001-01110100-10010101-01010100 +// CHECK-INST: sel { z20.h, z21.h }, pn13, { z10.h, z11.h }, { z20.h, z21.h } +// CHECK-ENCODING: [0x54,0x95,0x74,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1749554 + +sel {z22.h, z23.h}, pn11, {z12.h, z13.h}, {z8.h, z9.h} // 11000001-01101000-10001101-10010110 +// CHECK-INST: sel { z22.h, z23.h }, pn11, { z12.h, z13.h }, { z8.h, z9.h } +// CHECK-ENCODING: [0x96,0x8d,0x68,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1688d96 + +sel {z30.h, z31.h}, pn15, {z30.h, z31.h}, {z30.h, z31.h} // 11000001-01111110-10011111-11011110 +// CHECK-INST: sel { z30.h, z31.h }, pn15, { z30.h, z31.h }, { z30.h, z31.h } +// CHECK-ENCODING: [0xde,0x9f,0x7e,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c17e9fde + + +sel {z0.s, z1.s}, pn8, {z0.s, z1.s}, {z0.s, z1.s} // 11000001-10100000-10000000-00000000 +// CHECK-INST: sel { z0.s, z1.s }, pn8, { z0.s, z1.s }, { z0.s, z1.s } +// CHECK-ENCODING: [0x00,0x80,0xa0,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1a08000 + +sel {z20.s, z21.s}, pn13, {z10.s, z11.s}, {z20.s, z21.s} // 11000001-10110100-10010101-01010100 +// CHECK-INST: sel { z20.s, z21.s }, pn13, { z10.s, z11.s }, { z20.s, z21.s } +// CHECK-ENCODING: [0x54,0x95,0xb4,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1b49554 + +sel {z22.s, z23.s}, pn11, {z12.s, z13.s}, {z8.s, z9.s} // 11000001-10101000-10001101-10010110 +// CHECK-INST: sel { z22.s, z23.s }, pn11, { z12.s, z13.s }, { z8.s, z9.s } +// CHECK-ENCODING: [0x96,0x8d,0xa8,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1a88d96 + +sel {z30.s, z31.s}, pn15, {z30.s, z31.s}, {z30.s, z31.s} // 11000001-10111110-10011111-11011110 +// CHECK-INST: sel { z30.s, z31.s }, pn15, { z30.s, z31.s }, { z30.s, z31.s } +// CHECK-ENCODING: [0xde,0x9f,0xbe,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1be9fde + + +sel {z0.d, z1.d}, pn8, {z0.d, z1.d}, {z0.d, z1.d} // 11000001-11100000-10000000-00000000 +// CHECK-INST: sel { z0.d, z1.d }, pn8, { z0.d, z1.d }, { z0.d, z1.d } +// CHECK-ENCODING: [0x00,0x80,0xe0,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1e08000 + +sel {z20.d, z21.d}, pn13, {z10.d, z11.d}, {z20.d, z21.d} // 11000001-11110100-10010101-01010100 +// CHECK-INST: sel { z20.d, z21.d }, pn13, { z10.d, z11.d }, { z20.d, z21.d } +// CHECK-ENCODING: [0x54,0x95,0xf4,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1f49554 + +sel {z22.d, z23.d}, pn11, {z12.d, z13.d}, {z8.d, z9.d} // 11000001-11101000-10001101-10010110 +// CHECK-INST: sel { z22.d, z23.d }, pn11, { z12.d, z13.d }, { z8.d, z9.d } +// CHECK-ENCODING: [0x96,0x8d,0xe8,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1e88d96 + +sel {z30.d, z31.d}, pn15, {z30.d, z31.d}, {z30.d, z31.d} // 11000001-11111110-10011111-11011110 +// CHECK-INST: sel { z30.d, z31.d }, pn15, { z30.d, z31.d }, { z30.d, z31.d } +// CHECK-ENCODING: [0xde,0x9f,0xfe,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1fe9fde + + +sel {z0.b, z1.b}, pn8, {z0.b, z1.b}, {z0.b, z1.b} // 11000001-00100000-10000000-00000000 +// CHECK-INST: sel { z0.b, z1.b }, pn8, { z0.b, z1.b }, { z0.b, z1.b } +// CHECK-ENCODING: [0x00,0x80,0x20,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1208000 + +sel {z20.b, z21.b}, pn13, {z10.b, z11.b}, {z20.b, z21.b} // 11000001-00110100-10010101-01010100 +// CHECK-INST: sel { z20.b, z21.b }, pn13, { z10.b, z11.b }, { z20.b, z21.b } +// CHECK-ENCODING: [0x54,0x95,0x34,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1349554 + +sel {z22.b, z23.b}, pn11, {z12.b, z13.b}, {z8.b, z9.b} // 11000001-00101000-10001101-10010110 +// CHECK-INST: sel { z22.b, z23.b }, pn11, { z12.b, z13.b }, { z8.b, z9.b } +// CHECK-ENCODING: [0x96,0x8d,0x28,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1288d96 + +sel {z30.b, z31.b}, pn15, {z30.b, z31.b}, {z30.b, z31.b} // 11000001-00111110-10011111-11011110 +// CHECK-INST: sel { z30.b, z31.b }, pn15, { z30.b, z31.b }, { z30.b, z31.b } +// CHECK-ENCODING: [0xde,0x9f,0x3e,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c13e9fde + + +sel {z0.h - z3.h}, pn8, {z0.h - z3.h}, {z0.h - z3.h} // 11000001-01100001-10000000-00000000 +// CHECK-INST: sel { z0.h - z3.h }, pn8, { z0.h - z3.h }, { z0.h - z3.h } +// CHECK-ENCODING: [0x00,0x80,0x61,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1618000 + +sel {z20.h - z23.h}, pn13, {z8.h - z11.h}, {z20.h - z23.h} // 11000001-01110101-10010101-00010100 +// CHECK-INST: sel { z20.h - z23.h }, pn13, { z8.h - z11.h }, { z20.h - z23.h } +// CHECK-ENCODING: [0x14,0x95,0x75,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1759514 + +sel {z20.h - z23.h}, pn11, {z12.h - z15.h}, {z8.h - z11.h} // 11000001-01101001-10001101-10010100 +// CHECK-INST: sel { z20.h - z23.h }, pn11, { z12.h - z15.h }, { z8.h - z11.h } +// CHECK-ENCODING: [0x94,0x8d,0x69,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1698d94 + +sel {z28.h - z31.h}, pn15, {z28.h - z31.h}, {z28.h - z31.h} // 11000001-01111101-10011111-10011100 +// CHECK-INST: sel { z28.h - z31.h }, pn15, { z28.h - z31.h }, { z28.h - z31.h } +// CHECK-ENCODING: [0x9c,0x9f,0x7d,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c17d9f9c + + +sel {z0.s - z3.s}, pn8, {z0.s - z3.s}, {z0.s - z3.s} // 11000001-10100001-10000000-00000000 +// CHECK-INST: sel { z0.s - z3.s }, pn8, { z0.s - z3.s }, { z0.s - z3.s } +// CHECK-ENCODING: [0x00,0x80,0xa1,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1a18000 + +sel {z20.s - z23.s}, pn13, {z8.s - z11.s}, {z20.s - z23.s} // 11000001-10110101-10010101-00010100 +// CHECK-INST: sel { z20.s - z23.s }, pn13, { z8.s - z11.s }, { z20.s - z23.s } +// CHECK-ENCODING: [0x14,0x95,0xb5,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1b59514 + +sel {z20.s - z23.s}, pn11, {z12.s - z15.s}, {z8.s - z11.s} // 11000001-10101001-10001101-10010100 +// CHECK-INST: sel { z20.s - z23.s }, pn11, { z12.s - z15.s }, { z8.s - z11.s } +// CHECK-ENCODING: [0x94,0x8d,0xa9,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1a98d94 + +sel {z28.s - z31.s}, pn15, {z28.s - z31.s}, {z28.s - z31.s} // 11000001-10111101-10011111-10011100 +// CHECK-INST: sel { z28.s - z31.s }, pn15, { z28.s - z31.s }, { z28.s - z31.s } +// CHECK-ENCODING: [0x9c,0x9f,0xbd,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1bd9f9c + + +sel {z0.d - z3.d}, pn8, {z0.d - z3.d}, {z0.d - z3.d} // 11000001-11100001-10000000-00000000 +// CHECK-INST: sel { z0.d - z3.d }, pn8, { z0.d - z3.d }, { z0.d - z3.d } +// CHECK-ENCODING: [0x00,0x80,0xe1,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1e18000 + +sel {z20.d - z23.d}, pn13, {z8.d - z11.d}, {z20.d - z23.d} // 11000001-11110101-10010101-00010100 +// CHECK-INST: sel { z20.d - z23.d }, pn13, { z8.d - z11.d }, { z20.d - z23.d } +// CHECK-ENCODING: [0x14,0x95,0xf5,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1f59514 + +sel {z20.d - z23.d}, pn11, {z12.d - z15.d}, {z8.d - z11.d} // 11000001-11101001-10001101-10010100 +// CHECK-INST: sel { z20.d - z23.d }, pn11, { z12.d - z15.d }, { z8.d - z11.d } +// CHECK-ENCODING: [0x94,0x8d,0xe9,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1e98d94 + +sel {z28.d - z31.d}, pn15, {z28.d - z31.d}, {z28.d - z31.d} // 11000001-11111101-10011111-10011100 +// CHECK-INST: sel { z28.d - z31.d }, pn15, { z28.d - z31.d }, { z28.d - z31.d } +// CHECK-ENCODING: [0x9c,0x9f,0xfd,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1fd9f9c + + +sel {z0.b - z3.b}, pn8, {z0.b - z3.b}, {z0.b - z3.b} // 11000001-00100001-10000000-00000000 +// CHECK-INST: sel { z0.b - z3.b }, pn8, { z0.b - z3.b }, { z0.b - z3.b } +// CHECK-ENCODING: [0x00,0x80,0x21,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1218000 + +sel {z20.b - z23.b}, pn13, {z8.b - z11.b}, {z20.b - z23.b} // 11000001-00110101-10010101-00010100 +// CHECK-INST: sel { z20.b - z23.b }, pn13, { z8.b - z11.b }, { z20.b - z23.b } +// CHECK-ENCODING: [0x14,0x95,0x35,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1359514 + +sel {z20.b - z23.b}, pn11, {z12.b - z15.b}, {z8.b - z11.b} // 11000001-00101001-10001101-10010100 +// CHECK-INST: sel { z20.b - z23.b }, pn11, { z12.b - z15.b }, { z8.b - z11.b } +// CHECK-ENCODING: [0x94,0x8d,0x29,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c1298d94 + +sel {z28.b - z31.b}, pn15, {z28.b - z31.b}, {z28.b - z31.b} // 11000001-00111101-10011111-10011100 +// CHECK-INST: sel { z28.b - z31.b }, pn15, { z28.b - z31.b }, { z28.b - z31.b } +// CHECK-ENCODING: [0x9c,0x9f,0x3d,0xc1] +// CHECK-ERROR: instruction requires: sme2 +// CHECK-UNKNOWN: c13d9f9c +