[llvm] 1e4f82c - [AArch64]SME2 Multi-single vector SVE Destructive 2 and 4 Registers

Caroline Concatto via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 21 06:02:32 PDT 2022


Author: Caroline Concatto
Date: 2022-10-21T14:01:29+01:00
New Revision: 1e4f82c2578cf5045ffeda6c425d6d262a401e29

URL: https://github.com/llvm/llvm-project/commit/1e4f82c2578cf5045ffeda6c425d6d262a401e29
DIFF: https://github.com/llvm/llvm-project/commit/1e4f82c2578cf5045ffeda6c425d6d262a401e29.diff

LOG: [AArch64]SME2 Multi-single vector SVE Destructive 2 and 4 Registers

This patch adds the assembly/disassembly for the following instructions:
  ADD (to vector): Add replicated single vector to multi-vector with multi-vector result.
  SQDMULH (multiple and single vector): Multi-vector signed saturating doubling multiply high by vector.
for 2 and 4 ZA SVE registers.

The reference can be found here:

https://developer.arm.com/documentation/ddi0602/2022-09

It also adds more size for the multiple register tuple:
  ZZ_b_mul_r,  ZZ_h_mul_r,
  ZZZZ_b_mul_r,  ZZZZ_h_mul_r,
for 8 bits and 16 bits with 2 and 4 ZA registers.

Depends on: D135468

With a fix for Mips for this test:
llvm/test/MC/Mips/mips64r6/valid.s

Differential Revision: https://reviews.llvm.org/D135563

Added: 
    llvm/test/MC/AArch64/SME2/sqdmulh-diagnostics.s
    llvm/test/MC/AArch64/SME2/sqdmulh.s

Modified: 
    llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
    llvm/lib/Target/AArch64/AArch64RegisterInfo.td
    llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
    llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
    llvm/lib/Target/AArch64/SMEInstrFormats.td
    llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
    llvm/test/MC/AArch64/SME2/add-diagnostics.s
    llvm/test/MC/AArch64/SME2/add.s
    llvm/utils/TableGen/AsmMatcherEmitter.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
index 7bc5d42009514..2b58208a4ff4d 100644
--- a/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
+++ b/llvm/include/llvm/MC/MCParser/MCTargetAsmParser.h
@@ -459,13 +459,12 @@ class MCTargetAsmParser : public MCAsmParserExtension {
   virtual void convertToMapAndConstraints(unsigned Kind,
                                           const OperandVector &Operands) = 0;
 
-  /// Returns whether two registers are equal and is used by the tied-operands
-  /// checks in the AsmMatcher. This method can be overridden allow e.g. a
-  /// sub- or super-register as the tied operand.
-  virtual bool regsEqual(const MCParsedAsmOperand &Op1,
-                         const MCParsedAsmOperand &Op2) const {
-    assert(Op1.isReg() && Op2.isReg() && "Operands not all regs");
-    return Op1.getReg() == Op2.getReg();
+  /// Returns whether two operands are registers and are equal. This is used
+  /// by the tied-operands checks in the AsmMatcher. This method can be
+  /// overridden to allow e.g. a sub- or super-register as the tied operand.
+  virtual bool areEqualRegs(const MCParsedAsmOperand &Op1,
+                            const MCParsedAsmOperand &Op2) const {
+    return Op1.isReg() && Op2.isReg() && Op1.getReg() == Op2.getReg();
   }
 
   // Return whether this parser uses assignment statements with equals tokens

diff  --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
index 4fce066b90524..cd2cc308a5e4d 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td
@@ -957,10 +957,12 @@ def ZPR3b8  : ZPRRegOp<"b", ZPRAsmOp3b8,  ElementSizeB, ZPR_3b>;
 def ZPR3b16 : ZPRRegOp<"h", ZPRAsmOp3b16, ElementSizeH, ZPR_3b>;
 def ZPR3b32 : ZPRRegOp<"s", ZPRAsmOp3b32, ElementSizeS, ZPR_3b>;
 
+def ZPRAsmOp4b8   : ZPRAsmOperand<"Vector4bB", 8,  "_4b">;
 def ZPRAsmOp4b16  : ZPRAsmOperand<"Vector4bH", 16, "_4b">;
 def ZPRAsmOp4b32  : ZPRAsmOperand<"Vector4bS", 32, "_4b">;
 def ZPRAsmOp4b64  : ZPRAsmOperand<"Vector4bD", 64, "_4b">;
 
+def ZPR4b8  : ZPRRegOp<"b", ZPRAsmOp4b8,  ElementSizeB, ZPR_4b>;
 def ZPR4b16 : ZPRRegOp<"h", ZPRAsmOp4b16, ElementSizeH, ZPR_4b>;
 def ZPR4b32 : ZPRRegOp<"s", ZPRAsmOp4b32, ElementSizeS, ZPR_4b>;
 def ZPR4b64 : ZPRRegOp<"d", ZPRAsmOp4b64, ElementSizeD, ZPR_4b>;
@@ -1095,6 +1097,14 @@ class ZPRVectorListMul<int ElementWidth, int NumRegs> : ZPRVectorList<ElementWid
 
 let EncoderMethod = "EncodeRegAsMultipleOf<2>",
     DecoderMethod = "DecodeZPR2Mul2RegisterClass" in {
+  def ZZ_b_mul_r : RegisterOperand<ZPR2Mul2, "printTypedVectorList<0,'b'>"> {
+    let ParserMatchClass = ZPRVectorListMul<8, 2>;
+  }
+
+  def ZZ_h_mul_r : RegisterOperand<ZPR2Mul2, "printTypedVectorList<0,'h'>"> {
+    let ParserMatchClass = ZPRVectorListMul<16, 2>;
+  }
+
   def ZZ_s_mul_r : RegisterOperand<ZPR2Mul2, "printTypedVectorList<0,'s'>"> {
     let ParserMatchClass = ZPRVectorListMul<32, 2>;
   }
@@ -1106,6 +1116,14 @@ let EncoderMethod = "EncodeRegAsMultipleOf<2>",
 
 let EncoderMethod = "EncodeRegAsMultipleOf<4>",
     DecoderMethod = "DecodeZPR4Mul4RegisterClass" in {
+  def ZZZZ_b_mul_r : RegisterOperand<ZPR4Mul4, "printTypedVectorList<0,'b'>"> {
+    let ParserMatchClass = ZPRVectorListMul<8, 4>;
+  }
+
+  def ZZZZ_h_mul_r : RegisterOperand<ZPR4Mul4, "printTypedVectorList<0,'h'>"> {
+    let ParserMatchClass = ZPRVectorListMul<16, 4>;
+  }
+
   def ZZZZ_s_mul_r : RegisterOperand<ZPR4Mul4, "printTypedVectorList<0,'s'>"> {
     let ParserMatchClass = ZPRVectorListMul<32, 4>;
   }

diff  --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index c966983e5bb61..414aca583fe3f 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -266,6 +266,12 @@ defm FMLS_VG2_M2ZZ_S  : sme2_mla_add_sub_array_vg2_single_S<"fmls", 0b01>;
 defm FMLS_VG4_M4ZZ_S  : sme2_mla_add_sub_array_vg4_single_S<"fmls", 0b01>;
 defm FMLS_VG2_M2Z2Z_S : sme2_mla_add_sub_array_vg2_multi_S<"fmls", 0b01>;
 defm FMLS_VG4_M4Z4Z_S : sme2_mla_add_sub_array_vg4_multi_S<"fmls", 0b01>;
+
+defm ADD_VG2_2ZZ  : sme2_sqdmulh_add_vector_vg2_single<"add", 0b011000>;
+defm ADD_VG4_4ZZ  : sme2_sqdmulh_add_vector_vg4_single<"add", 0b011000>;
+
+defm SQDMULH_2ZZ : sme2_sqdmulh_add_vector_vg2_single<"sqdmulh", 0b100000>;
+defm SQDMULH_4ZZ : sme2_sqdmulh_add_vector_vg4_single<"sqdmulh", 0b100000>;
 }
 
 

diff  --git a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
index 2d0d9838c5c6e..022f2973571d6 100644
--- a/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
+++ b/llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
@@ -303,8 +303,8 @@ class AArch64AsmParser : public MCTargetAsmParser {
     setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
   }
 
-  bool regsEqual(const MCParsedAsmOperand &Op1,
-                 const MCParsedAsmOperand &Op2) const override;
+  bool areEqualRegs(const MCParsedAsmOperand &Op1,
+                    const MCParsedAsmOperand &Op2) const override;
   bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                         SMLoc NameLoc, OperandVector &Operands) override;
   bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
@@ -1143,6 +1143,8 @@ class AArch64Operand : public MCParsedAsmOperand {
     return Kind == k_Register;
   }
 
+  bool isVectorList() const { return Kind == k_VectorList; }
+
   bool isScalarReg() const {
     return Kind == k_Register && Reg.Kind == RegKind::Scalar;
   }
@@ -4530,13 +4532,21 @@ bool AArch64AsmParser::parseRegisterInRange(unsigned &Out, unsigned Base,
   return false;
 }
 
-bool AArch64AsmParser::regsEqual(const MCParsedAsmOperand &Op1,
-                                 const MCParsedAsmOperand &Op2) const {
+bool AArch64AsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
+                                    const MCParsedAsmOperand &Op2) const {
   auto &AOp1 = static_cast<const AArch64Operand&>(Op1);
   auto &AOp2 = static_cast<const AArch64Operand&>(Op2);
+
+  if (AOp1.isVectorList() && AOp2.isVectorList())
+    return AOp1.getVectorListCount() == AOp2.getVectorListCount() &&
+           AOp1.getVectorListStart() == AOp2.getVectorListStart();
+
+  if (!AOp1.isReg() || !AOp2.isReg())
+    return false;
+
   if (AOp1.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg &&
       AOp2.getRegEqualityTy() == RegConstraintEqualityTy::EqualsReg)
-    return MCTargetAsmParser::regsEqual(Op1, Op2);
+    return MCTargetAsmParser::areEqualRegs(Op1, Op2);
 
   assert(AOp1.isScalarReg() && AOp2.isScalarReg() &&
          "Testing equality of non-scalar registers not supported");
@@ -5177,10 +5187,12 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
                                       OperandVector &Operands) {
   switch (ErrCode) {
   case Match_InvalidTiedOperand: {
-    RegConstraintEqualityTy EqTy =
-        static_cast<const AArch64Operand &>(*Operands[ErrorInfo])
-            .getRegEqualityTy();
-    switch (EqTy) {
+    auto &Op = static_cast<const AArch64Operand &>(*Operands[ErrorInfo]);
+    if (Op.isVectorList())
+      return Error(Loc, "operand must match destination register list");
+
+    assert(Op.isReg() && "Unexpected operand type");
+    switch (Op.getRegEqualityTy()) {
     case RegConstraintEqualityTy::EqualsSubReg:
       return Error(Loc, "operand must be 64-bit form of destination register");
     case RegConstraintEqualityTy::EqualsSuperReg:
@@ -5471,6 +5483,9 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
     return Error(Loc, "Invalid restricted vector register, expected z0.h..z7.h");
   case Match_InvalidZPR_3b32:
     return Error(Loc, "Invalid restricted vector register, expected z0.s..z7.s");
+  case Match_InvalidZPR_4b8:
+    return Error(Loc,
+                 "Invalid restricted vector register, expected z0.b..z15.b");
   case Match_InvalidZPR_4b16:
     return Error(Loc, "Invalid restricted vector register, expected z0.h..z15.h");
   case Match_InvalidZPR_4b32:
@@ -5526,11 +5541,15 @@ bool AArch64AsmParser::showMatchError(SMLoc Loc, unsigned ErrCode,
     return Error(Loc, "operand must be a register in range [w12, w15]");
   case Match_InvalidMatrixIndexGPR32_8_11:
     return Error(Loc, "operand must be a register in range [w8, w11]");
+  case Match_InvalidSVEVectorListMul2x8:
+  case Match_InvalidSVEVectorListMul2x16:
   case Match_InvalidSVEVectorListMul2x32:
   case Match_InvalidSVEVectorListMul2x64:
     return Error(Loc, "Invalid vector list, expected list with 2 consecutive "
                       "SVE vectors, where the first vector is a multiple of 2 "
                       "and with matching element types");
+  case Match_InvalidSVEVectorListMul4x8:
+  case Match_InvalidSVEVectorListMul4x16:
   case Match_InvalidSVEVectorListMul4x32:
   case Match_InvalidSVEVectorListMul4x64:
     return Error(Loc, "Invalid vector list, expected list with 4 consecutive "
@@ -6042,6 +6061,7 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidZPR_3b8:
   case Match_InvalidZPR_3b16:
   case Match_InvalidZPR_3b32:
+  case Match_InvalidZPR_4b8:
   case Match_InvalidZPR_4b16:
   case Match_InvalidZPR_4b32:
   case Match_InvalidZPR_4b64:
@@ -6073,8 +6093,12 @@ bool AArch64AsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_InvalidSVCR:
   case Match_InvalidMatrixIndexGPR32_12_15:
   case Match_InvalidMatrixIndexGPR32_8_11:
+  case Match_InvalidSVEVectorListMul2x8:
+  case Match_InvalidSVEVectorListMul2x16:
   case Match_InvalidSVEVectorListMul2x32:
   case Match_InvalidSVEVectorListMul2x64:
+  case Match_InvalidSVEVectorListMul4x8:
+  case Match_InvalidSVEVectorListMul4x16:
   case Match_InvalidSVEVectorListMul4x32:
   case Match_InvalidSVEVectorListMul4x64:
   case Match_MSR:

diff  --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 69ba23d78c48a..c5d62ec3b2154 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -1337,3 +1337,60 @@ multiclass sme2_mla_add_sub_array_vg4_multi_D<string mnemonic, bits<2> op>{
   def : InstAlias<mnemonic # "\t$ZAd[$Rv, $imm3], $Zn, $Zm",
                  (!cast<Instruction>(NAME) MatrixOp64:$ZAd,  MatrixIndexGPR32Op8_11:$Rv, sme_elm_idx0_7:$imm3, ZZZZ_d_mul_r:$Zn, ZZZZ_d_mul_r:$Zm), 0>;
 }
+
+//===----------------------------------------------------------------------===//
+// SME2 Multi-vector - Multiple and Single SVE Destructive
+// Two and Four registers
+
+class sme2_sqdmulh_add_vector_vg2_single<bits<2> sz, bits<6> op,
+                                         RegisterOperand vector_ty,
+                                         ZPRRegOp zpr_ty, string mnemonic>
+    : I<(outs vector_ty:$Zdn), (ins vector_ty:$_Zdn, zpr_ty:$Zm),
+        mnemonic, "\t$Zdn, $_Zdn, $Zm",
+        "", []>, Sched<[]> {
+  bits<4> Zm;
+  bits<4> Zdn;
+  let Inst{31-24} = 0b11000001;
+  let Inst{23-22} = sz;
+  let Inst{21-20} = 0b10;
+  let Inst{19-16} = Zm;
+  let Inst{15-11} = 0b10100;
+  let Inst{10-5}  = op;
+  let Inst{4-1}   = Zdn;
+  let Inst{0}     = 0b0;
+  let Constraints = "$Zdn = $_Zdn";
+}
+
+multiclass sme2_sqdmulh_add_vector_vg2_single<string mnemonic, bits<6> op> {
+  def _B : sme2_sqdmulh_add_vector_vg2_single<0b00, op, ZZ_b_mul_r, ZPR4b8, mnemonic>;
+  def _H : sme2_sqdmulh_add_vector_vg2_single<0b01, op, ZZ_h_mul_r, ZPR4b16, mnemonic>;
+  def _S : sme2_sqdmulh_add_vector_vg2_single<0b10, op, ZZ_s_mul_r, ZPR4b32, mnemonic>;
+  def _D : sme2_sqdmulh_add_vector_vg2_single<0b11, op, ZZ_d_mul_r, ZPR4b64, mnemonic>;
+}
+
+class sme2_sqdmulh_add_vector_vg4_single<bits<2> sz, bits<6> op,
+                                         RegisterOperand vector_ty,
+                                         ZPRRegOp zpr_ty, string mnemonic>
+    : I<(outs vector_ty:$Zdn), (ins vector_ty:$_Zdn, zpr_ty:$Zm),
+        mnemonic, "\t$Zdn, $_Zdn, $Zm",
+        "", []>, Sched<[]> {
+  bits<4> Zm;
+  bits<3> Zdn;
+  let Inst{31-24} = 0b11000001;
+  let Inst{23-22} = sz;
+  let Inst{21-20} = 0b10;
+  let Inst{19-16} = Zm;
+  let Inst{15-11} = 0b10101;
+  let Inst{10-5}  = op;
+  let Inst{4-2}   = Zdn;
+  let Inst{1-0}   = 0b00;
+  let Constraints = "$Zdn = $_Zdn";
+}
+
+multiclass sme2_sqdmulh_add_vector_vg4_single<string mnemonic, bits<6> op> {
+  def _B : sme2_sqdmulh_add_vector_vg4_single<0b00, op, ZZZZ_b_mul_r, ZPR4b8, mnemonic>;
+  def _H : sme2_sqdmulh_add_vector_vg4_single<0b01, op, ZZZZ_h_mul_r, ZPR4b16, mnemonic>;
+  def _S : sme2_sqdmulh_add_vector_vg4_single<0b10, op, ZZZZ_s_mul_r, ZPR4b32, mnemonic>;
+  def _D : sme2_sqdmulh_add_vector_vg4_single<0b11, op, ZZZZ_d_mul_r, ZPR4b64, mnemonic>;
+}
+

diff  --git a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
index 5ce8ffd954e62..bab887f60c92a 100644
--- a/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
+++ b/llvm/lib/Target/Mips/AsmParser/MipsAsmParser.cpp
@@ -790,6 +790,9 @@ class MipsAsmParser : public MCTargetAsmParser {
       return MipsMCExpr::create(MipsMCExpr::MEK_TPREL_LO, E, Ctx);
     }
   }
+
+  bool areEqualRegs(const MCParsedAsmOperand &Op1,
+                    const MCParsedAsmOperand &Op2) const override;
 };
 
 /// MipsOperand - Instances of this class represent a parsed Mips machine
@@ -5939,6 +5942,9 @@ bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
   case Match_MissingFeature:
     Error(IDLoc, "instruction requires a CPU feature not currently enabled");
     return true;
+  case Match_InvalidTiedOperand:
+    Error(IDLoc, "operand must match destination register");
+    return true;
   case Match_InvalidOperand: {
     SMLoc ErrorLoc = IDLoc;
     if (ErrorInfo != ~0ULL) {
@@ -6928,6 +6934,19 @@ bool MipsAsmParser::parseBracketSuffix(StringRef Name,
 static std::string MipsMnemonicSpellCheck(StringRef S, const FeatureBitset &FBS,
                                           unsigned VariantID = 0);
 
+bool MipsAsmParser::areEqualRegs(const MCParsedAsmOperand &Op1,
+                                 const MCParsedAsmOperand &Op2) const {
+  // This target-overriden function exists to maintain current behaviour for
+  // e.g.
+  //   dahi    $3, $3, 0x5678
+  // as tested in test/MC/Mips/mips64r6/valid.s.
+  // FIXME: Should this test actually fail with an error? If so, then remove
+  // this overloaded method.
+  if (!Op1.isReg() || !Op2.isReg())
+    return true;
+  return Op1.getReg() == Op2.getReg();
+}
+
 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
                                      SMLoc NameLoc, OperandVector &Operands) {
   MCAsmParser &Parser = getParser();

diff  --git a/llvm/test/MC/AArch64/SME2/add-diagnostics.s b/llvm/test/MC/AArch64/SME2/add-diagnostics.s
index f9029d0231c1d..9feb2b497bb67 100644
--- a/llvm/test/MC/AArch64/SME2/add-diagnostics.s
+++ b/llvm/test/MC/AArch64/SME2/add-diagnostics.s
@@ -41,7 +41,6 @@ add     za.s[w7, 0], {z0.s - z1.s}, {z2.s - z3.s}
 // CHECK-NEXT: add     za.s[w7, 0], {z0.s - z1.s}, {z2.s - z3.s}
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:$
 
-
 // --------------------------------------------------------------------------//
 // Invalid Matrix Operand
 
@@ -81,7 +80,6 @@ add za.d[w11, 7, vgx4], {z12.d-z15.d}, {z9.d-z12.d}
 // CHECK-NEXT: add za.d[w11, 7, vgx4], {z12.d-z15.d}, {z9.d-z12.d}
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
 
-
 add za.s[w10, 3], {z10.b-z11.b}, {z20.b-z21.b}
 // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
 // CHECK-NEXT: add za.s[w10, 3], {z10.b-z11.b}, {z20.b-z21.b}
@@ -91,3 +89,32 @@ add     za.d[w11, 7], {z28.h - z31.h}, {z28.h - z31.h}
 // CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
 // CHECK-NEXT: add     za.d[w11, 7], {z28.h - z31.h}, {z28.h - z31.h}
 // CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// The tied operands must match, even for vector groups.
+
+add {z0.s-z1.s}, {z2.s-z3.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register list
+// CHECK-NEXT: add {z0.s-z1.s}, {z2.s-z3.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+add {z0.s,z1.s}, {z2.s,z3.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register list
+// CHECK-NEXT: add {z0.s,z1.s}, {z2.s,z3.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+add {z0.s,z1.s}, {z0.s,z2.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: registers must be sequential
+// CHECK-NEXT: add {z0.s,z1.s}, {z0.s,z2.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+add {z0.s,z1.s}, {z0.s,z1.s,z2.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: add {z0.s,z1.s}, {z0.s,z1.s,z2.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+add {z0.s,z1.s}, {z0.d,z1.d}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: add {z0.s,z1.s}, {z0.d,z1.d}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+

diff  --git a/llvm/test/MC/AArch64/SME2/add.s b/llvm/test/MC/AArch64/SME2/add.s
index 43e686248263d..89aa78793d390 100644
--- a/llvm/test/MC/AArch64/SME2/add.s
+++ b/llvm/test/MC/AArch64/SME2/add.s
@@ -12,6 +12,31 @@
 // RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
 
 
+add     {z0.h, z1.h}, {z0.h, z1.h}, z0.h  // 11000001-01100000-10100011-00000000
+// CHECK-INST: add     { z0.h, z1.h }, { z0.h, z1.h }, z0.h
+// CHECK-ENCODING: [0x00,0xa3,0x60,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c160a300 <unknown>
+
+add     {z20.h, z21.h}, {z20.h, z21.h}, z5.h  // 11000001-01100101-10100011-00010100
+// CHECK-INST: add     { z20.h, z21.h }, { z20.h, z21.h }, z5.h
+// CHECK-ENCODING: [0x14,0xa3,0x65,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c165a314 <unknown>
+
+add     {z22.h, z23.h}, {z22.h, z23.h}, z8.h  // 11000001-01101000-10100011-00010110
+// CHECK-INST: add     { z22.h, z23.h }, { z22.h, z23.h }, z8.h
+// CHECK-ENCODING: [0x16,0xa3,0x68,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c168a316 <unknown>
+
+add     {z30.h, z31.h}, {z30.h, z31.h}, z15.h  // 11000001-01101111-10100011-00011110
+// CHECK-INST: add     { z30.h, z31.h }, { z30.h, z31.h }, z15.h
+// CHECK-ENCODING: [0x1e,0xa3,0x6f,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c16fa31e <unknown>
+
+
 add     za.s[w8, 0, vgx2], {z0.s, z1.s}, z0.s  // 11000001, 00100000, 00011000, 00010000
 // CHECK-INST: add     za.s[w8, 0, vgx2], { z0.s, z1.s }, z0.s
 // CHECK-ENCODING: [0x10,0x18,0x20,0xc1]
@@ -157,6 +182,31 @@ add     za.s[w9, 7], {z12.s - z13.s}, z11.s  // 11000001-00101011-00111001-10010
 // CHECK-UNKNOWN: c12b3997 <unknown>
 
 
+add     {z0.s-z1.s}, {z0.s-z1.s}, z0.s  // 11000001-10100000-10100011-00000000
+// CHECK-INST: add     { z0.s, z1.s }, { z0.s, z1.s }, z0.s
+// CHECK-ENCODING: [0x00,0xa3,0xa0,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a0a300 <unknown>
+
+add     {z20.s-z21.s}, {z20.s-z21.s}, z5.s  // 11000001-10100101-10100011-00010100
+// CHECK-INST: add     { z20.s, z21.s }, { z20.s, z21.s }, z5.s
+// CHECK-ENCODING: [0x14,0xa3,0xa5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a5a314 <unknown>
+
+add     {z22.s-z23.s}, {z22.s-z23.s}, z8.s  // 11000001-10101000-10100011-00010110
+// CHECK-INST: add     { z22.s, z23.s }, { z22.s, z23.s }, z8.s
+// CHECK-ENCODING: [0x16,0xa3,0xa8,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a8a316 <unknown>
+
+add     {z30.s-z31.s}, {z30.s-z31.s}, z15.s  // 11000001-10101111-10100011-00011110
+// CHECK-INST: add     { z30.s, z31.s }, { z30.s, z31.s }, z15.s
+// CHECK-ENCODING: [0x1e,0xa3,0xaf,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1afa31e <unknown>
+
+
 add     za.s[w8, 0, vgx2], {z0.s, z1.s}, {z0.s, z1.s}  // 11000001, 10100000, 00011000, 00010000
 // CHECK-INST: add     za.s[w8, 0, vgx2], { z0.s, z1.s }, { z0.s, z1.s }
 // CHECK-ENCODING: [0x10,0x18,0xa0,0xc1]
@@ -447,6 +497,31 @@ add     za.d[w9, 7], {z12.d - z13.d}, z11.d  // 11000001-01101011-00111001-10010
 // CHECK-UNKNOWN: c16b3997 <unknown>
 
 
+add     {z0.d-z1.d}, {z0.d-z1.d}, z0.d  // 11000001-11100000-10100011-00000000
+// CHECK-INST: add     { z0.d, z1.d }, { z0.d, z1.d }, z0.d
+// CHECK-ENCODING: [0x00,0xa3,0xe0,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e0a300 <unknown>
+
+add     {z20.d-z21.d}, {z20.d-z21.d}, z5.d  // 11000001-11100101-10100011-00010100
+// CHECK-INST: add     { z20.d, z21.d }, { z20.d, z21.d }, z5.d
+// CHECK-ENCODING: [0x14,0xa3,0xe5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e5a314 <unknown>
+
+add     {z22.d-z23.d}, {z22.d-z23.d}, z8.d  // 11000001-11101000-10100011-00010110
+// CHECK-INST: add     { z22.d, z23.d }, { z22.d, z23.d }, z8.d
+// CHECK-ENCODING: [0x16,0xa3,0xe8,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e8a316 <unknown>
+
+add     {z30.d-z31.d}, {z30.d-z31.d}, z15.d  // 11000001-11101111-10100011-00011110
+// CHECK-INST: add     { z30.d, z31.d }, { z30.d, z31.d }, z15.d
+// CHECK-ENCODING: [0x1e,0xa3,0xef,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1efa31e <unknown>
+
+
 add     za.d[w8, 0, vgx2], {z0.d, z1.d}, {z0.d, z1.d}  // 11000001, 11100000, 00011000, 00010000
 // CHECK-INST: add     za.d[w8, 0, vgx2], { z0.d, z1.d }, { z0.d, z1.d }
 // CHECK-ENCODING: [0x10,0x18,0xe0,0xc1]
@@ -519,6 +594,7 @@ add     za.d[w8, 1], {z0.d - z1.d}, {z30.d - z31.d}  // 11000001-11111110-000110
 // CHECK-ERROR: instruction requires: sme2
 // CHECK-UNKNOWN: c1fe1811 <unknown>
 
+
 add     za.d[w10, 0, vgx2], {z18.d, z19.d}, {z20.d, z21.d}  // 11000001, 11110100, 01011010, 01010000
 // CHECK-INST: add     za.d[w10, 0, vgx2], { z18.d, z19.d }, { z20.d, z21.d }
 // CHECK-ENCODING: [0x50,0x5a,0xf4,0xc1]
@@ -592,7 +668,57 @@ add     za.d[w9, 7], {z12.d - z13.d}, {z10.d - z11.d}  // 11000001-11101010-0011
 // CHECK-UNKNOWN: c1ea3997 <unknown>
 
 
-add     za.s[w8, 0, vgx4], {z0.s - z3.s}, z0.s  // 11000001-00110000-00011000-00010000
+add     {z0.b-z1.b}, {z0.b-z1.b}, z0.b  // 11000001-00100000-10100011-00000000
+// CHECK-INST: add     { z0.b, z1.b }, { z0.b, z1.b }, z0.b
+// CHECK-ENCODING: [0x00,0xa3,0x20,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c120a300 <unknown>
+
+add     {z20.b-z21.b}, {z20.b-z21.b}, z5.b  // 11000001-00100101-10100011-00010100
+// CHECK-INST: add     { z20.b, z21.b }, { z20.b, z21.b }, z5.b
+// CHECK-ENCODING: [0x14,0xa3,0x25,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c125a314 <unknown>
+
+add     {z22.b-z23.b}, {z22.b-z23.b}, z8.b  // 11000001-00101000-10100011-00010110
+// CHECK-INST: add     { z22.b, z23.b }, { z22.b, z23.b }, z8.b
+// CHECK-ENCODING: [0x16,0xa3,0x28,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c128a316 <unknown>
+
+add     {z30.b-z31.b}, {z30.b-z31.b}, z15.b  // 11000001-00101111-10100011-00011110
+// CHECK-INST: add     { z30.b, z31.b }, { z30.b, z31.b }, z15.b
+// CHECK-ENCODING: [0x1e,0xa3,0x2f,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c12fa31e <unknown>
+
+
+add     {z0.h - z3.h}, {z0.h - z3.h}, z0.h  // 11000001-01100000-10101011-00000000
+// CHECK-INST: add     { z0.h - z3.h }, { z0.h - z3.h }, z0.h
+// CHECK-ENCODING: [0x00,0xab,0x60,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c160ab00 <unknown>
+
+add     {z20.h - z23.h}, {z20.h - z23.h}, z5.h  // 11000001-01100101-10101011-00010100
+// CHECK-INST: add     { z20.h - z23.h }, { z20.h - z23.h }, z5.h
+// CHECK-ENCODING: [0x14,0xab,0x65,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c165ab14 <unknown>
+
+add     {z20.h - z23.h}, {z20.h - z23.h}, z8.h  // 11000001-01101000-10101011-00010100
+// CHECK-INST: add     { z20.h - z23.h }, { z20.h - z23.h }, z8.h
+// CHECK-ENCODING: [0x14,0xab,0x68,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c168ab14 <unknown>
+
+add     {z28.h - z31.h}, {z28.h - z31.h}, z15.h  // 11000001-01101111-10101011-00011100
+// CHECK-INST: add     { z28.h - z31.h }, { z28.h - z31.h }, z15.h
+// CHECK-ENCODING: [0x1c,0xab,0x6f,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c16fab1c <unknown>
+
+
+add     za.s[w8, 0, vgx4], {z0.s-z3.s}, z0.s  // 11000001-00110000-00011000-00010000
 // CHECK-INST: add     za.s[w8, 0, vgx4], { z0.s - z3.s }, z0.s
 // CHECK-ENCODING: [0x10,0x18,0x30,0xc1]
 // CHECK-ERROR: instruction requires: sme2
@@ -737,7 +863,38 @@ add     za.s[w9, 7], {z12.s - z15.s}, z11.s  // 11000001-00111011-00111001-10010
 // CHECK-UNKNOWN: c13b3997 <unknown>
 
 
-add     za.s[w8, 0], {z0.s - z3.s}, {z0.s - z3.s}  // 11000001-10100001-00011000-00010000
+add     {z0.s-z3.s}, {z0.s-z3.s}, z0.s  // 11000001-10100000-10101011-00000000
+// CHECK-INST: add     { z0.s - z3.s }, { z0.s - z3.s }, z0.s
+// CHECK-ENCODING: [0x00,0xab,0xa0,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a0ab00 <unknown>
+
+add     {z20.s-z23.s}, {z20.s-z23.s}, z5.s  // 11000001-10100101-10101011-00010100
+// CHECK-INST: add     { z20.s - z23.s }, { z20.s - z23.s }, z5.s
+// CHECK-ENCODING: [0x14,0xab,0xa5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a5ab14 <unknown>
+
+add     {z20.s-z23.s}, {z20.s-z23.s}, z8.s  // 11000001-10101000-10101011-00010100
+// CHECK-INST: add     { z20.s - z23.s }, { z20.s - z23.s }, z8.s
+// CHECK-ENCODING: [0x14,0xab,0xa8,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a8ab14 <unknown>
+
+add     {z28.s-z31.s}, {z28.s-z31.s}, z15.s  // 11000001-10101111-10101011-00011100
+// CHECK-INST: add     { z28.s - z31.s }, { z28.s - z31.s }, z15.s
+// CHECK-ENCODING: [0x1c,0xab,0xaf,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1afab1c <unknown>
+
+
+add     za.s[w8, 0, vgx4], {z0.s-z3.s}, {z0.s-z3.s}  // 11000001-10100001-00011000-00010000
+// CHECK-INST: add     za.s[w8, 0, vgx4], { z0.s - z3.s }, { z0.s - z3.s }
+// CHECK-ENCODING: [0x10,0x18,0xa1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a11810 <unknown>
+
+add     za.s[w8, 0], {z0.s-z3.s}, {z0.s-z3.s}  // 11000001-10100001-00011000-00010000
 // CHECK-INST: add     za.s[w8, 0, vgx4], { z0.s - z3.s }, { z0.s - z3.s }
 // CHECK-ENCODING: [0x10,0x18,0xa1,0xc1]
 // CHECK-ERROR: instruction requires: sme2
@@ -1164,3 +1321,199 @@ add     za.d[w9, 7], {z12.d - z15.d}, {z8.d - z11.d}  // 11000001-11101001-00111
 // CHECK-ENCODING: [0x97,0x39,0xe9,0xc1]
 // CHECK-ERROR: instruction requires: sme2
 // CHECK-UNKNOWN: c1e93997 <unknown>
+
+
+add     {z0.d-z3.d}, {z0.d-z3.d}, z0.d  // 11000001-11100000-10101011-00000000
+// CHECK-INST: add     { z0.d - z3.d }, { z0.d - z3.d }, z0.d
+// CHECK-ENCODING: [0x00,0xab,0xe0,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e0ab00 <unknown>
+
+add     {z20.d-z23.d}, {z20.d-z23.d}, z5.d  // 11000001-11100101-10101011-00010100
+// CHECK-INST: add     { z20.d - z23.d }, { z20.d - z23.d }, z5.d
+// CHECK-ENCODING: [0x14,0xab,0xe5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e5ab14 <unknown>
+
+add     {z20.d-z23.d}, {z20.d-z23.d}, z8.d  // 11000001-11101000-10101011-00010100
+// CHECK-INST: add     { z20.d - z23.d }, { z20.d - z23.d }, z8.d
+// CHECK-ENCODING: [0x14,0xab,0xe8,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e8ab14 <unknown>
+
+add     {z28.d-z31.d}, {z28.d-z31.d}, z15.d  // 11000001-11101111-10101011-00011100
+// CHECK-INST: add     { z28.d - z31.d }, { z28.d - z31.d }, z15.d
+// CHECK-ENCODING: [0x1c,0xab,0xef,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1efab1c <unknown>
+
+
+add     za.d[w8, 0, vgx4], {z0.d-z3.d}, {z0.d-z3.d}  // 11000001-11100001-00011000-00010000
+// CHECK-INST: add     za.d[w8, 0, vgx4], { z0.d - z3.d }, { z0.d - z3.d }
+// CHECK-ENCODING: [0x10,0x18,0xe1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e11810 <unknown>
+
+add     za.d[w8, 0], {z0.d - z3.d}, {z0.d - z3.d}  // 11000001-11100001-00011000-00010000
+// CHECK-INST: add     za.d[w8, 0, vgx4], { z0.d - z3.d }, { z0.d - z3.d }
+// CHECK-ENCODING: [0x10,0x18,0xe1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e11810 <unknown>
+
+add     za.d[w10, 5, vgx4], {z8.d - z11.d}, {z20.d - z23.d}  // 11000001-11110101-01011001-00010101
+// CHECK-INST: add     za.d[w10, 5, vgx4], { z8.d - z11.d }, { z20.d - z23.d }
+// CHECK-ENCODING: [0x15,0x59,0xf5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1f55915 <unknown>
+
+add     za.d[w10, 5], {z8.d - z11.d}, {z20.d - z23.d}  // 11000001-11110101-01011001-00010101
+// CHECK-INST: add     za.d[w10, 5, vgx4], { z8.d - z11.d }, { z20.d - z23.d }
+// CHECK-ENCODING: [0x15,0x59,0xf5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1f55915 <unknown>
+
+add     za.d[w11, 7, vgx4], {z12.d - z15.d}, {z8.d - z11.d}  // 11000001-11101001-01111001-10010111
+// CHECK-INST: add     za.d[w11, 7, vgx4], { z12.d - z15.d }, { z8.d - z11.d }
+// CHECK-ENCODING: [0x97,0x79,0xe9,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e97997 <unknown>
+
+add     za.d[w11, 7], {z12.d - z15.d}, {z8.d - z11.d}  // 11000001-11101001-01111001-10010111
+// CHECK-INST: add     za.d[w11, 7, vgx4], { z12.d - z15.d }, { z8.d - z11.d }
+// CHECK-ENCODING: [0x97,0x79,0xe9,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e97997 <unknown>
+
+add     za.d[w11, 7, vgx4], {z28.d - z31.d}, {z28.d - z31.d}  // 11000001-11111101-01111011-10010111
+// CHECK-INST: add     za.d[w11, 7, vgx4], { z28.d - z31.d }, { z28.d - z31.d }
+// CHECK-ENCODING: [0x97,0x7b,0xfd,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1fd7b97 <unknown>
+
+add     za.d[w11, 7], {z28.d - z31.d}, {z28.d - z31.d}  // 11000001-11111101-01111011-10010111
+// CHECK-INST: add     za.d[w11, 7, vgx4], { z28.d - z31.d }, { z28.d - z31.d }
+// CHECK-ENCODING: [0x97,0x7b,0xfd,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1fd7b97 <unknown>
+
+add     za.d[w8, 5, vgx4], {z16.d - z19.d}, {z16.d - z19.d}  // 11000001-11110001-00011010-00010101
+// CHECK-INST: add     za.d[w8, 5, vgx4], { z16.d - z19.d }, { z16.d - z19.d }
+// CHECK-ENCODING: [0x15,0x1a,0xf1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1f11a15 <unknown>
+
+add     za.d[w8, 5], {z16.d - z19.d}, {z16.d - z19.d}  // 11000001-11110001-00011010-00010101
+// CHECK-INST: add     za.d[w8, 5, vgx4], { z16.d - z19.d }, { z16.d - z19.d }
+// CHECK-ENCODING: [0x15,0x1a,0xf1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1f11a15 <unknown>
+
+add     za.d[w8, 1, vgx4], {z0.d - z3.d}, {z28.d - z31.d}  // 11000001-11111101-00011000-00010001
+// CHECK-INST: add     za.d[w8, 1, vgx4], { z0.d - z3.d }, { z28.d - z31.d }
+// CHECK-ENCODING: [0x11,0x18,0xfd,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1fd1811 <unknown>
+
+add     za.d[w8, 1], {z0.d - z3.d}, {z28.d - z31.d}  // 11000001-11111101-00011000-00010001
+// CHECK-INST: add     za.d[w8, 1, vgx4], { z0.d - z3.d }, { z28.d - z31.d }
+// CHECK-ENCODING: [0x11,0x18,0xfd,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1fd1811 <unknown>
+
+add     za.d[w10, 0, vgx4], {z16.d - z19.d}, {z20.d - z23.d}  // 11000001-11110101-01011010-00010000
+// CHECK-INST: add     za.d[w10, 0, vgx4], { z16.d - z19.d }, { z20.d - z23.d }
+// CHECK-ENCODING: [0x10,0x5a,0xf5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1f55a10 <unknown>
+
+add     za.d[w10, 0], {z16.d - z19.d}, {z20.d - z23.d}  // 11000001-11110101-01011010-00010000
+// CHECK-INST: add     za.d[w10, 0, vgx4], { z16.d - z19.d }, { z20.d - z23.d }
+// CHECK-ENCODING: [0x10,0x5a,0xf5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1f55a10 <unknown>
+
+add     za.d[w8, 0, vgx4], {z12.d - z15.d}, {z0.d - z3.d}  // 11000001-11100001-00011001-10010000
+// CHECK-INST: add     za.d[w8, 0, vgx4], { z12.d - z15.d }, { z0.d - z3.d }
+// CHECK-ENCODING: [0x90,0x19,0xe1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e11990 <unknown>
+
+add     za.d[w8, 0], {z12.d - z15.d}, {z0.d - z3.d}  // 11000001-11100001-00011001-10010000
+// CHECK-INST: add     za.d[w8, 0, vgx4], { z12.d - z15.d }, { z0.d - z3.d }
+// CHECK-ENCODING: [0x90,0x19,0xe1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e11990 <unknown>
+
+add     za.d[w10, 1, vgx4], {z0.d - z3.d}, {z24.d - z27.d}  // 11000001-11111001-01011000-00010001
+// CHECK-INST: add     za.d[w10, 1, vgx4], { z0.d - z3.d }, { z24.d - z27.d }
+// CHECK-ENCODING: [0x11,0x58,0xf9,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1f95811 <unknown>
+
+add     za.d[w10, 1], {z0.d - z3.d}, {z24.d - z27.d}  // 11000001-11111001-01011000-00010001
+// CHECK-INST: add     za.d[w10, 1, vgx4], { z0.d - z3.d }, { z24.d - z27.d }
+// CHECK-ENCODING: [0x11,0x58,0xf9,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1f95811 <unknown>
+
+add     za.d[w8, 5, vgx4], {z20.d - z23.d}, {z28.d - z31.d}  // 11000001-11111101-00011010-10010101
+// CHECK-INST: add     za.d[w8, 5, vgx4], { z20.d - z23.d }, { z28.d - z31.d }
+// CHECK-ENCODING: [0x95,0x1a,0xfd,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1fd1a95 <unknown>
+
+add     za.d[w8, 5], {z20.d - z23.d}, {z28.d - z31.d}  // 11000001-11111101-00011010-10010101
+// CHECK-INST: add     za.d[w8, 5, vgx4], { z20.d - z23.d }, { z28.d - z31.d }
+// CHECK-ENCODING: [0x95,0x1a,0xfd,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1fd1a95 <unknown>
+
+add     za.d[w11, 2, vgx4], {z8.d - z11.d}, {z0.d - z3.d}  // 11000001-11100001-01111001-00010010
+// CHECK-INST: add     za.d[w11, 2, vgx4], { z8.d - z11.d }, { z0.d - z3.d }
+// CHECK-ENCODING: [0x12,0x79,0xe1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e17912 <unknown>
+
+add     za.d[w11, 2], {z8.d - z11.d}, {z0.d - z3.d}  // 11000001-11100001-01111001-00010010
+// CHECK-INST: add     za.d[w11, 2, vgx4], { z8.d - z11.d }, { z0.d - z3.d }
+// CHECK-ENCODING: [0x12,0x79,0xe1,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e17912 <unknown>
+
+add     za.d[w9, 7, vgx4], {z12.d - z15.d}, {z8.d - z11.d}  // 11000001-11101001-00111001-10010111
+// CHECK-INST: add     za.d[w9, 7, vgx4], { z12.d - z15.d }, { z8.d - z11.d }
+// CHECK-ENCODING: [0x97,0x39,0xe9,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e93997 <unknown>
+
+add     za.d[w9, 7], {z12.d - z15.d}, {z8.d - z11.d}  // 11000001-11101001-00111001-10010111
+// CHECK-INST: add     za.d[w9, 7, vgx4], { z12.d - z15.d }, { z8.d - z11.d }
+// CHECK-ENCODING: [0x97,0x39,0xe9,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e93997 <unknown>
+
+
+add     {z0.b-z3.b}, {z0.b-z3.b}, z0.b  // 11000001-00100000-10101011-00000000
+// CHECK-INST: add     { z0.b - z3.b }, { z0.b - z3.b }, z0.b
+// CHECK-ENCODING: [0x00,0xab,0x20,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c120ab00 <unknown>
+
+add     {z20.b-z23.b}, {z20.b-z23.b}, z5.b  // 11000001-00100101-10101011-00010100
+// CHECK-INST: add     { z20.b - z23.b }, { z20.b - z23.b }, z5.b
+// CHECK-ENCODING: [0x14,0xab,0x25,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c125ab14 <unknown>
+
+add     {z20.b-z23.b}, {z20.b-z23.b}, z8.b  // 11000001-00101000-10101011-00010100
+// CHECK-INST: add     { z20.b - z23.b }, { z20.b - z23.b }, z8.b
+// CHECK-ENCODING: [0x14,0xab,0x28,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c128ab14 <unknown>
+
+add     {z28.b-z31.b}, {z28.b-z31.b}, z15.b  // 11000001-00101111-10101011-00011100
+// CHECK-INST: add     { z28.b - z31.b }, { z28.b - z31.b }, z15.b
+// CHECK-ENCODING: [0x1c,0xab,0x2f,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c12fab1c <unknown>
+

diff  --git a/llvm/test/MC/AArch64/SME2/sqdmulh-diagnostics.s b/llvm/test/MC/AArch64/SME2/sqdmulh-diagnostics.s
new file mode 100644
index 0000000000000..2020d5d550bd4
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/sqdmulh-diagnostics.s
@@ -0,0 +1,79 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+sme-i64 2>&1 < %s | FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid vector list
+
+sqdmulh {z0.h-z2.h}, {z0.h-z1.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sqdmulh {z0.h-z2.h}, {z0.h-z1.h}, z0.h
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z28.s-z31.s}, {z0.s-z4.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+// CHECK-NEXT: sqdmulh {z28.s-z31.s}, {z0.s-z4.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z1.d-z4.d}, {z0.d-z3.d}, z0.d
+// 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: sqdmulh {z1.d-z4.d}, {z0.d-z3.d}, z0.d
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z28.b-z29.b}, {z1.b-z2.b}, z15.b
+// 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: sqdmulh {z28.b-z29.b}, {z1.b-z2.b}, z15.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z28.h-z29.h}, {z1.h-z2.h}, z15.b
+// 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: sqdmulh {z28.h-z29.h}, {z1.h-z2.h}, z15.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid single vector register
+
+sqdmulh {z28.b-z29.b}, {z0.b-z1.b}, z16.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.b..z15.b
+// CHECK-NEXT: sqdmulh {z28.b-z29.b}, {z0.b-z1.b}, z16.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid register suffix
+
+sqdmulh {z0.d-z3.d}, {z0.d-z3.d}, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.d..z15.d
+// CHECK-NEXT: sqdmulh {z0.d-z3.d}, {z0.d-z3.d}, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z0.d-z3.h}, {z0.d-z3.d}, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: mismatched register size suffix
+// CHECK-NEXT: sqdmulh {z0.d-z3.h}, {z0.d-z3.d}, z0.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// The tied operands must match, even for vector groups.
+
+sqdmulh {z0.s-z1.s}, {z2.s-z3.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register list
+// CHECK-NEXT: sqdmulh {z0.s-z1.s}, {z2.s-z3.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z0.s,z1.s}, {z2.s,z3.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must match destination register list
+// CHECK-NEXT: sqdmulh {z0.s,z1.s}, {z2.s,z3.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z0.s,z1.s}, {z0.s,z2.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: registers must be sequential
+// CHECK-NEXT: sqdmulh {z0.s,z1.s}, {z0.s,z2.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z0.s,z1.s}, {z0.s,z1.s,z2.s}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sqdmulh {z0.s,z1.s}, {z0.s,z1.s,z2.s}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sqdmulh {z0.s,z1.s}, {z0.d,z1.d}, z15.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sqdmulh {z0.s,z1.s}, {z0.d,z1.d}, z15.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+

diff  --git a/llvm/test/MC/AArch64/SME2/sqdmulh.s b/llvm/test/MC/AArch64/SME2/sqdmulh.s
new file mode 100644
index 0000000000000..2c26ba4385247
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/sqdmulh.s
@@ -0,0 +1,212 @@
+// 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
+
+
+sqdmulh {z0.h - z1.h}, {z0.h - z1.h}, z0.h  // 11000001-01100000-10100100-00000000
+// CHECK-INST: sqdmulh { z0.h, z1.h }, { z0.h, z1.h }, z0.h
+// CHECK-ENCODING: [0x00,0xa4,0x60,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c160a400 <unknown>
+
+sqdmulh {z20.h - z21.h}, {z20.h - z21.h}, z5.h  // 11000001-01100101-10100100-00010100
+// CHECK-INST: sqdmulh { z20.h, z21.h }, { z20.h, z21.h }, z5.h
+// CHECK-ENCODING: [0x14,0xa4,0x65,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c165a414 <unknown>
+
+sqdmulh {z22.h - z23.h}, {z22.h - z23.h}, z8.h  // 11000001-01101000-10100100-00010110
+// CHECK-INST: sqdmulh { z22.h, z23.h }, { z22.h, z23.h }, z8.h
+// CHECK-ENCODING: [0x16,0xa4,0x68,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c168a416 <unknown>
+
+sqdmulh {z30.h - z31.h}, {z30.h - z31.h}, z15.h  // 11000001-01101111-10100100-00011110
+// CHECK-INST: sqdmulh { z30.h, z31.h }, { z30.h, z31.h }, z15.h
+// CHECK-ENCODING: [0x1e,0xa4,0x6f,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c16fa41e <unknown>
+
+
+sqdmulh {z0.s - z1.s}, {z0.s - z1.s}, z0.s  // 11000001-10100000-10100100-00000000
+// CHECK-INST: sqdmulh { z0.s, z1.s }, { z0.s, z1.s }, z0.s
+// CHECK-ENCODING: [0x00,0xa4,0xa0,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a0a400 <unknown>
+
+sqdmulh {z20.s - z21.s}, {z20.s - z21.s}, z5.s  // 11000001-10100101-10100100-00010100
+// CHECK-INST: sqdmulh { z20.s, z21.s }, { z20.s, z21.s }, z5.s
+// CHECK-ENCODING: [0x14,0xa4,0xa5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a5a414 <unknown>
+
+sqdmulh {z22.s - z23.s}, {z22.s - z23.s}, z8.s  // 11000001-10101000-10100100-00010110
+// CHECK-INST: sqdmulh { z22.s, z23.s }, { z22.s, z23.s }, z8.s
+// CHECK-ENCODING: [0x16,0xa4,0xa8,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a8a416 <unknown>
+
+sqdmulh {z30.s - z31.s}, {z30.s - z31.s}, z15.s  // 11000001-10101111-10100100-00011110
+// CHECK-INST: sqdmulh { z30.s, z31.s }, { z30.s, z31.s }, z15.s
+// CHECK-ENCODING: [0x1e,0xa4,0xaf,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1afa41e <unknown>
+
+
+sqdmulh {z0.d - z1.d}, {z0.d - z1.d}, z0.d  // 11000001-11100000-10100100-00000000
+// CHECK-INST: sqdmulh { z0.d, z1.d }, { z0.d, z1.d }, z0.d
+// CHECK-ENCODING: [0x00,0xa4,0xe0,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e0a400 <unknown>
+
+sqdmulh {z20.d - z21.d}, {z20.d - z21.d}, z5.d  // 11000001-11100101-10100100-00010100
+// CHECK-INST: sqdmulh { z20.d, z21.d }, { z20.d, z21.d }, z5.d
+// CHECK-ENCODING: [0x14,0xa4,0xe5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e5a414 <unknown>
+
+sqdmulh {z22.d - z23.d}, {z22.d - z23.d}, z8.d  // 11000001-11101000-10100100-00010110
+// CHECK-INST: sqdmulh { z22.d, z23.d }, { z22.d, z23.d }, z8.d
+// CHECK-ENCODING: [0x16,0xa4,0xe8,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e8a416 <unknown>
+
+sqdmulh {z30.d - z31.d}, {z30.d - z31.d}, z15.d  // 11000001-11101111-10100100-00011110
+// CHECK-INST: sqdmulh { z30.d, z31.d }, { z30.d, z31.d }, z15.d
+// CHECK-ENCODING: [0x1e,0xa4,0xef,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1efa41e <unknown>
+
+
+sqdmulh {z0.b - z1.b}, {z0.b - z1.b}, z0.b  // 11000001-00100000-10100100-00000000
+// CHECK-INST: sqdmulh { z0.b, z1.b }, { z0.b, z1.b }, z0.b
+// CHECK-ENCODING: [0x00,0xa4,0x20,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c120a400 <unknown>
+
+sqdmulh {z20.b - z21.b}, {z20.b - z21.b}, z5.b  // 11000001-00100101-10100100-00010100
+// CHECK-INST: sqdmulh { z20.b, z21.b }, { z20.b, z21.b }, z5.b
+// CHECK-ENCODING: [0x14,0xa4,0x25,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c125a414 <unknown>
+
+sqdmulh {z22.b - z23.b}, {z22.b - z23.b}, z8.b  // 11000001-00101000-10100100-00010110
+// CHECK-INST: sqdmulh { z22.b, z23.b }, { z22.b, z23.b }, z8.b
+// CHECK-ENCODING: [0x16,0xa4,0x28,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c128a416 <unknown>
+
+sqdmulh {z30.b - z31.b}, {z30.b - z31.b}, z15.b  // 11000001-00101111-10100100-00011110
+// CHECK-INST: sqdmulh { z30.b, z31.b }, { z30.b, z31.b }, z15.b
+// CHECK-ENCODING: [0x1e,0xa4,0x2f,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c12fa41e <unknown>
+
+
+sqdmulh {z0.h - z3.h}, {z0.h - z3.h}, z0.h  // 11000001-01100000-10101100-00000000
+// CHECK-INST: sqdmulh { z0.h - z3.h }, { z0.h - z3.h }, z0.h
+// CHECK-ENCODING: [0x00,0xac,0x60,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c160ac00 <unknown>
+
+sqdmulh {z20.h - z23.h}, {z20.h - z23.h}, z5.h  // 11000001-01100101-10101100-00010100
+// CHECK-INST: sqdmulh { z20.h - z23.h }, { z20.h - z23.h }, z5.h
+// CHECK-ENCODING: [0x14,0xac,0x65,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c165ac14 <unknown>
+
+sqdmulh {z20.h - z23.h}, {z20.h - z23.h}, z8.h  // 11000001-01101000-10101100-00010100
+// CHECK-INST: sqdmulh { z20.h - z23.h }, { z20.h - z23.h }, z8.h
+// CHECK-ENCODING: [0x14,0xac,0x68,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c168ac14 <unknown>
+
+sqdmulh {z28.h - z31.h}, {z28.h - z31.h}, z15.h  // 11000001-01101111-10101100-00011100
+// CHECK-INST: sqdmulh { z28.h - z31.h }, { z28.h - z31.h }, z15.h
+// CHECK-ENCODING: [0x1c,0xac,0x6f,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c16fac1c <unknown>
+
+
+sqdmulh {z0.s - z3.s}, {z0.s - z3.s}, z0.s  // 11000001-10100000-10101100-00000000
+// CHECK-INST: sqdmulh { z0.s - z3.s }, { z0.s - z3.s }, z0.s
+// CHECK-ENCODING: [0x00,0xac,0xa0,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a0ac00 <unknown>
+
+sqdmulh {z20.s - z23.s}, {z20.s - z23.s}, z5.s  // 11000001-10100101-10101100-00010100
+// CHECK-INST: sqdmulh { z20.s - z23.s }, { z20.s - z23.s }, z5.s
+// CHECK-ENCODING: [0x14,0xac,0xa5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a5ac14 <unknown>
+
+sqdmulh {z20.s - z23.s}, {z20.s - z23.s}, z8.s  // 11000001-10101000-10101100-00010100
+// CHECK-INST: sqdmulh { z20.s - z23.s }, { z20.s - z23.s }, z8.s
+// CHECK-ENCODING: [0x14,0xac,0xa8,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1a8ac14 <unknown>
+
+sqdmulh {z28.s - z31.s}, {z28.s - z31.s}, z15.s  // 11000001-10101111-10101100-00011100
+// CHECK-INST: sqdmulh { z28.s - z31.s }, { z28.s - z31.s }, z15.s
+// CHECK-ENCODING: [0x1c,0xac,0xaf,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1afac1c <unknown>
+
+
+sqdmulh {z0.d - z3.d}, {z0.d - z3.d}, z0.d  // 11000001-11100000-10101100-00000000
+// CHECK-INST: sqdmulh { z0.d - z3.d }, { z0.d - z3.d }, z0.d
+// CHECK-ENCODING: [0x00,0xac,0xe0,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e0ac00 <unknown>
+
+sqdmulh {z20.d - z23.d}, {z20.d - z23.d}, z5.d  // 11000001-11100101-10101100-00010100
+// CHECK-INST: sqdmulh { z20.d - z23.d }, { z20.d - z23.d }, z5.d
+// CHECK-ENCODING: [0x14,0xac,0xe5,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e5ac14 <unknown>
+
+sqdmulh {z20.d - z23.d}, {z20.d - z23.d}, z8.d  // 11000001-11101000-10101100-00010100
+// CHECK-INST: sqdmulh { z20.d - z23.d }, { z20.d - z23.d }, z8.d
+// CHECK-ENCODING: [0x14,0xac,0xe8,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1e8ac14 <unknown>
+
+sqdmulh {z28.d - z31.d}, {z28.d - z31.d}, z15.d  // 11000001-11101111-10101100-00011100
+// CHECK-INST: sqdmulh { z28.d - z31.d }, { z28.d - z31.d }, z15.d
+// CHECK-ENCODING: [0x1c,0xac,0xef,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c1efac1c <unknown>
+
+
+sqdmulh {z0.b - z3.b}, {z0.b - z3.b}, z0.b  // 11000001-00100000-10101100-00000000
+// CHECK-INST: sqdmulh { z0.b - z3.b }, { z0.b - z3.b }, z0.b
+// CHECK-ENCODING: [0x00,0xac,0x20,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c120ac00 <unknown>
+
+sqdmulh {z20.b - z23.b}, {z20.b - z23.b}, z5.b  // 11000001-00100101-10101100-00010100
+// CHECK-INST: sqdmulh { z20.b - z23.b }, { z20.b - z23.b }, z5.b
+// CHECK-ENCODING: [0x14,0xac,0x25,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c125ac14 <unknown>
+
+sqdmulh {z20.b - z23.b}, {z20.b - z23.b}, z8.b  // 11000001-00101000-10101100-00010100
+// CHECK-INST: sqdmulh { z20.b - z23.b }, { z20.b - z23.b }, z8.b
+// CHECK-ENCODING: [0x14,0xac,0x28,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c128ac14 <unknown>
+
+sqdmulh {z28.b - z31.b}, {z28.b - z31.b}, z15.b  // 11000001-00101111-10101100-00011100
+// CHECK-INST: sqdmulh { z28.b - z31.b }, { z28.b - z31.b }, z15.b
+// CHECK-ENCODING: [0x1c,0xac,0x2f,0xc1]
+// CHECK-ERROR: instruction requires: sme2
+// CHECK-UNKNOWN: c12fac1c <unknown>

diff  --git a/llvm/utils/TableGen/AsmMatcherEmitter.cpp b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
index 151212c55fad7..852ef5a8c3b3d 100644
--- a/llvm/utils/TableGen/AsmMatcherEmitter.cpp
+++ b/llvm/utils/TableGen/AsmMatcherEmitter.cpp
@@ -3029,11 +3029,9 @@ static void emitAsmTiedOperandConstraints(CodeGenTarget &Target,
   OS << "      if (OpndNum1 != OpndNum2) {\n";
   OS << "        auto &SrcOp1 = Operands[OpndNum1];\n";
   OS << "        auto &SrcOp2 = Operands[OpndNum2];\n";
-  OS << "        if (SrcOp1->isReg() && SrcOp2->isReg()) {\n";
-  OS << "          if (!AsmParser.regsEqual(*SrcOp1, *SrcOp2)) {\n";
-  OS << "            ErrorInfo = OpndNum2;\n";
-  OS << "            return false;\n";
-  OS << "          }\n";
+  OS << "        if (!AsmParser.areEqualRegs(*SrcOp1, *SrcOp2)) {\n";
+  OS << "          ErrorInfo = OpndNum2;\n";
+  OS << "          return false;\n";
   OS << "        }\n";
   OS << "      }\n";
   OS << "      break;\n";


        


More information about the llvm-commits mailing list