[AArch64][SME] Add SVE2 instructions added in SME
authorCullen Rhodes <cullen.rhodes@arm.com>
Mon, 19 Jul 2021 07:40:04 +0000 (07:40 +0000)
committerCullen Rhodes <cullen.rhodes@arm.com>
Mon, 19 Jul 2021 08:03:05 +0000 (08:03 +0000)
This patch adds support for the following instructions:

    SCLAMP, UCLAMP, REV, DUP (predicate)

The reference can be found here:
https://developer.arm.com/documentation/ddi0602/2021-06

Reviewed By: kmclaughlin

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

llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
llvm/lib/Target/AArch64/AsmParser/AArch64AsmParser.cpp
llvm/lib/Target/AArch64/SMEInstrFormats.td
llvm/test/MC/AArch64/SME/dup-diagnostics.s [new file with mode: 0644]
llvm/test/MC/AArch64/SME/dup.s [new file with mode: 0644]
llvm/test/MC/AArch64/SME/revd-diagnostics.s [new file with mode: 0644]
llvm/test/MC/AArch64/SME/revd.s [new file with mode: 0644]
llvm/test/MC/AArch64/SME/sclamp-diagnostics.s [new file with mode: 0644]
llvm/test/MC/AArch64/SME/sclamp.s [new file with mode: 0644]
llvm/test/MC/AArch64/SME/uclamp-diagnostics.s [new file with mode: 0644]
llvm/test/MC/AArch64/SME/uclamp.s [new file with mode: 0644]

index bc48ac6..2c1595b 100644 (file)
@@ -74,4 +74,15 @@ let Predicates = [HasSME] in {
 defm LD1_MXIPXX : sme_mem_ld_ss<"ld1">;
 defm ST1_MXIPXX : sme_mem_st_ss<"st1">;
 
+//===----------------------------------------------------------------------===//
+// SVE2 instructions
+//===----------------------------------------------------------------------===//
+
+def REVD_ZPmZ : sve2_int_perm_revd<"revd">;
+
+defm SCLAMP_ZZZ : sve2_clamp<"sclamp", 0b0>;
+defm UCLAMP_ZZZ : sve2_clamp<"uclamp", 0b1>;
+
+defm DUP_PPzPRI : sve2_int_perm_dup_p<"dup">;
+
 } // End let Predicates = [HasSME]
index 9f620aa..418ce74 100644 (file)
@@ -3567,6 +3567,13 @@ AArch64AsmParser::tryParseSVEPredicateVector(OperandVector &Operands) {
       RegNum, RegKind::SVEPredicateVector, ElementWidth, S,
       getLoc(), getContext()));
 
+  if (getLexer().is(AsmToken::LBrac)) {
+    // Indexed predicate, there's no comma so try parse the next operand
+    // immediately.
+    if (parseOperand(Operands, false, false))
+      return MatchOperand_NoMatch;
+  }
+
   // Not all predicates are followed by a '/m' or '/z'.
   MCAsmParser &Parser = getParser();
   if (Parser.getTok().isNot(AsmToken::Slash))
index c3eedb8..aca7693 100644 (file)
@@ -394,3 +394,108 @@ multiclass sme_mem_st_ss<string mnemonic> {
   defm _V : sme_mem_st_v_ss<mnemonic, /*is_col=*/0b1>;
 }
 
+//===----------------------------------------------------------------------===//
+// SVE2 Instructions
+//===----------------------------------------------------------------------===//
+
+class sve2_int_perm_revd<string asm>
+    : I<(outs ZPR128:$Zd), (ins ZPR128:$_Zd, PPR3bAny:$Pg, ZPR128:$Zn),
+        asm, "\t$Zd, $Pg/m, $Zn", "", []>,
+      Sched<[]> {
+  bits<5> Zd;
+  bits<3> Pg;
+  bits<5> Zn;
+  let Inst{31-24} = 0b00000101;
+  let Inst{23-22} = 0b00; // size
+  let Inst{21-13} = 0b101110100;
+  let Inst{12-10} = Pg;
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zd;
+
+  let Constraints = "$Zd = $_Zd";
+  let DestructiveInstType = DestructiveUnary;
+  let ElementSize = ZPR128.ElementSize;
+}
+
+class sve2_clamp<string asm, bits<2> sz, bit U, ZPRRegOp zpr_ty>
+    : I<(outs zpr_ty:$Zd), (ins zpr_ty:$Zn, zpr_ty:$Zm, zpr_ty:$_Zd),
+        asm, "\t$Zd, $Zn, $Zm", "", []>,
+      Sched<[]> {
+  bits<5> Zm;
+  bits<5> Zn;
+  bits<5> Zd;
+  let Inst{31-24} = 0b01000100;
+  let Inst{23-22} = sz;
+  let Inst{21}    = 0b0;
+  let Inst{20-16} = Zm;
+  let Inst{15-11} = 0b11000;
+  let Inst{10}    = U;
+  let Inst{9-5}   = Zn;
+  let Inst{4-0}   = Zd;
+
+  let Constraints = "$Zd = $_Zd";
+  let DestructiveInstType = DestructiveOther;
+  let ElementSize = zpr_ty.ElementSize;
+}
+
+multiclass sve2_clamp<string asm, bit U> {
+  def _B : sve2_clamp<asm, 0b00, U, ZPR8>;
+  def _H : sve2_clamp<asm, 0b01, U, ZPR16>;
+  def _S : sve2_clamp<asm, 0b10, U, ZPR32>;
+  def _D : sve2_clamp<asm, 0b11, U, ZPR64>;
+}
+
+class sve2_int_perm_dup_p<string asm, PPRRegOp ppr_ty, Operand imm_ty>
+    : I<(outs ppr_ty:$Pd), (ins PPRAny:$Pg, ppr_ty:$Pn,
+                                MatrixIndexGPR32Op12_15:$Rm, imm_ty:$imm),
+        asm, "\t$Pd, $Pg/z, $Pn[$Rm, $imm]", "", []>,
+      Sched<[]> {
+  bits<2> Rm;
+  bits<4> Pg;
+  bits<4> Pn;
+  bits<4> Pd;
+  let Inst{31-24} = 0b00100101;
+  let Inst{21}    = 0b1;
+  let Inst{17-16} = Rm;
+  let Inst{15-14} = 0b01;
+  let Inst{13-10} = Pg;
+  let Inst{9}     = 0b0;
+  let Inst{8-5}   = Pn;
+  let Inst{4}     = 0b0;
+  let Inst{3-0}   = Pd;
+}
+
+multiclass sve2_int_perm_dup_p<string asm> {
+  def _B : sve2_int_perm_dup_p<asm, PPR8, imm0_15> {
+    bits<4> imm;
+    let Inst{23-22} = imm{3-2};
+    let Inst{20-19} = imm{1-0};
+    let Inst{18}    = 0b1;
+  }
+  def _H : sve2_int_perm_dup_p<asm, PPR16, imm0_7> {
+    bits<3> imm;
+    let Inst{23-22} = imm{2-1};
+    let Inst{20}    = imm{0};
+    let Inst{19-18} = 0b10;
+  }
+  def _S : sve2_int_perm_dup_p<asm, PPR32, imm0_3> {
+    bits<2> imm;
+    let Inst{23-22} = imm{1-0};
+    let Inst{20-18} = 0b100;
+  }
+  def _D : sve2_int_perm_dup_p<asm, PPR64, imm0_1> {
+    bits<1> imm;
+    let Inst{23}    = imm;
+    let Inst{22}    = 0b1;
+    let Inst{20-18} = 0b000;
+  }
+
+  def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]",
+                  (!cast<Instruction>(NAME # _B) PPR8:$Pd, PPRAny:$Pg, PPR8:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>;
+  def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]",
+                  (!cast<Instruction>(NAME # _H) PPR16:$Pd, PPRAny:$Pg, PPR16:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>;
+  def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]",
+                  (!cast<Instruction>(NAME # _S) PPR32:$Pd, PPRAny:$Pg, PPR32:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>;
+  def : InstAlias<"dup\t$Pd, $Pg/z, $Pn[$Rm]",
+                  (!cast<Instruction>(NAME # _D) PPR64:$Pd, PPRAny:$Pg, PPR64:$Pn, MatrixIndexGPR32Op12_15:$Rm, 0), 1>;
+}
diff --git a/llvm/test/MC/AArch64/SME/dup-diagnostics.s b/llvm/test/MC/AArch64/SME/dup-diagnostics.s
new file mode 100644 (file)
index 0000000..ebc1fa1
--- /dev/null
@@ -0,0 +1,58 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+// wrong predication qualifier, expected /z.
+dup p0.b, p0/m, p0.b[w12]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: dup p0.b, p0/m, p0.b[w12]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// mismatched element type
+dup p0.b, p0/z, p0.h[w12]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register.
+// CHECK-NEXT: dup p0.b, p0/z, p0.h[w12]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// missing element type suffix
+dup p0.b, p0/z, p0[w12]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid predicate register.
+// CHECK-NEXT: dup p0.b, p0/z, p0[w12]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid index base register register (w12-w15)
+
+dup p0.b, p0/z, p0.b[w11]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: dup  p0.b, p0/z, p0.b[w11]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup p0.b, p0/z, p0.b[w16]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: dup  p0.b, p0/z, p0.b[w16]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediates
+
+dup p0.b, p0/z, p0.b[w12, #16]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 15].
+// CHECK-NEXT: dup  p0.b, p0/z, p0.b[w12, #16]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup p0.h, p0/z, p0.h[w12, #8]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 7].
+// CHECK-NEXT: dup  p0.h, p0/z, p0.h[w12, #8]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup p0.s, p0/z, p0.s[w12, #4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 3].
+// CHECK-NEXT: dup  p0.s, p0/z, p0.s[w12, #4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+dup p0.d, p0/z, p0.d[w12, #2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: immediate must be an integer in range [0, 1].
+// CHECK-NEXT: dup  p0.d, p0/z, p0.d[w12, #2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME/dup.s b/llvm/test/MC/AArch64/SME/dup.s
new file mode 100644 (file)
index 0000000..07d7170
--- /dev/null
@@ -0,0 +1,121 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %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=+sme < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \
+// RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// --------------------------------------------------------------------------//
+// 8-bit
+
+dup     p0.b, p0/z, p0.b[w12]
+// CHECK-INST: dup     p0.b, p0/z, p0.b[w12]
+// CHECK-ENCODING: [0x00,0x40,0x24,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 40 24 25 <unknown>
+
+dup     p5.b, p5/z, p10.b[w13, #6]
+// CHECK-INST: dup     p5.b, p5/z, p10.b[w13, #6]
+// CHECK-ENCODING: [0x45,0x55,0x75,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 45 55 75 25 <unknown>
+
+dup     p7.b, p11/z, p13.b[w12, #5]
+// CHECK-INST: dup     p7.b, p11/z, p13.b[w12, #5]
+// CHECK-ENCODING: [0xa7,0x6d,0x6c,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: a7 6d 6c 25 <unknown>
+
+dup     p15.b, p15/z, p15.b[w15, #15]
+// CHECK-INST: dup     p15.b, p15/z, p15.b[w15, #15]
+// CHECK-ENCODING: [0xef,0x7d,0xff,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ef 7d ff 25 <unknown>
+
+// --------------------------------------------------------------------------//
+// 16-bit
+
+dup     p0.h, p0/z, p0.h[w12]
+// CHECK-INST: dup     p0.h, p0/z, p0.h[w12]
+// CHECK-ENCODING: [0x00,0x40,0x28,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 40 28 25 <unknown>
+
+dup     p5.h, p5/z, p10.h[w13, #3]
+// CHECK-INST: dup     p5.h, p5/z, p10.h[w13, #3]
+// CHECK-ENCODING: [0x45,0x55,0x79,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 45 55 79 25 <unknown>
+
+dup     p7.h, p11/z, p13.h[w12, #2]
+// CHECK-INST: dup     p7.h, p11/z, p13.h[w12, #2]
+// CHECK-ENCODING: [0xa7,0x6d,0x68,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: a7 6d 68 25 <unknown>
+
+dup     p15.h, p15/z, p15.h[w15, #7]
+// CHECK-INST: dup     p15.h, p15/z, p15.h[w15, #7]
+// CHECK-ENCODING: [0xef,0x7d,0xfb,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ef 7d fb 25 <unknown>
+
+// --------------------------------------------------------------------------//
+// 32-bit
+
+dup     p0.s, p0/z, p0.s[w12]
+// CHECK-INST: dup     p0.s, p0/z, p0.s[w12]
+// CHECK-ENCODING: [0x00,0x40,0x30,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 40 30 25 <unknown>
+
+dup     p5.s, p5/z, p10.s[w13, #1]
+// CHECK-INST: dup     p5.s, p5/z, p10.s[w13, #1]
+// CHECK-ENCODING: [0x45,0x55,0x71,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 45 55 71 25 <unknown>
+
+dup     p7.s, p11/z, p13.s[w12, #1]
+// CHECK-INST: dup     p7.s, p11/z, p13.s[w12, #1]
+// CHECK-ENCODING: [0xa7,0x6d,0x70,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: a7 6d 70 25 <unknown>
+
+dup     p15.s, p15/z, p15.s[w15, #3]
+// CHECK-INST: dup     p15.s, p15/z, p15.s[w15, #3]
+// CHECK-ENCODING: [0xef,0x7d,0xf3,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ef 7d f3 25 <unknown>
+
+// --------------------------------------------------------------------------//
+// 64-bit
+
+dup     p0.d, p0/z, p0.d[w12]
+// CHECK-INST: dup     p0.d, p0/z, p0.d[w12]
+// CHECK-ENCODING: [0x00,0x40,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 40 60 25 <unknown>
+
+dup     p5.d, p5/z, p10.d[w13]
+// CHECK-INST: dup     p5.d, p5/z, p10.d[w13]
+// CHECK-ENCODING: [0x45,0x55,0x61,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 45 55 61 25 <unknown>
+
+dup     p7.d, p11/z, p13.d[w12]
+// CHECK-INST: dup     p7.d, p11/z, p13.d[w12]
+// CHECK-ENCODING: [0xa7,0x6d,0x60,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: a7 6d 60 25 <unknown>
+
+dup     p15.d, p15/z, p15.d[w15, #1]
+// CHECK-INST: dup     p15.d, p15/z, p15.d[w15, #1]
+// CHECK-ENCODING: [0xef,0x7d,0xe3,0x25]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ef 7d e3 25 <unknown>
diff --git a/llvm/test/MC/AArch64/SME/revd-diagnostics.s b/llvm/test/MC/AArch64/SME/revd-diagnostics.s
new file mode 100644 (file)
index 0000000..42205c2
--- /dev/null
@@ -0,0 +1,29 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Invalid predicate
+
+// invalid range (expected: p0-p7)
+revd z0.q, p8/m, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted predicate register, expected p0..p7 (without element suffix)
+// CHECK-NEXT: revd z0.q, p8/m, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// wrong predication qualifier, expected /m.
+revd z0.q, p0/z, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: revd z0.q, p0/z, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// ------------------------------------------------------------------------- //
+// Invalid ZPR element width
+
+revd z0.b, p0/m, z0.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd z0.b, p0/m, z0.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+revd z0.q, p0/m, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: revd z0.q, p0/m, z0.s
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME/revd.s b/llvm/test/MC/AArch64/SME/revd.s
new file mode 100644 (file)
index 0000000..023298e
--- /dev/null
@@ -0,0 +1,52 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %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=+sme < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \
+// RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+revd    z0.q, p0/m, z0.q
+// CHECK-INST: revd    z0.q, p0/m, z0.q
+// CHECK-ENCODING: [0x00,0x80,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 80 2e 05 <unknown>
+
+revd    z21.q, p5/m, z10.q
+// CHECK-INST: revd    z21.q, p5/m, z10.q
+// CHECK-ENCODING: [0x55,0x95,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 95 2e 05 <unknown>
+
+revd    z23.q, p3/m, z13.q
+// CHECK-INST: revd    z23.q, p3/m, z13.q
+// CHECK-ENCODING: [0xb7,0x8d,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 8d 2e 05 <unknown>
+
+revd    z31.q, p7/m, z31.q
+// CHECK-INST: revd    z31.q, p7/m, z31.q
+// CHECK-ENCODING: [0xff,0x9f,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff 9f 2e 05 <unknown>
+
+// --------------------------------------------------------------------------//
+// Test compatibility with MOVPRFX instruction.
+
+movprfx z21, z25
+// CHECK-INST: movprfx  z21, z25
+// CHECK-ENCODING: [0x35,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 35 bf 20 04 <unknown>
+
+revd    z21.q, p5/m, z10.q
+// CHECK-INST: revd    z21.q, p5/m, z10.q
+// CHECK-ENCODING: [0x55,0x95,0x2e,0x05]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 95 2e 05 <unknown>
diff --git a/llvm/test/MC/AArch64/SME/sclamp-diagnostics.s b/llvm/test/MC/AArch64/SME/sclamp-diagnostics.s
new file mode 100644 (file)
index 0000000..8a8a297
--- /dev/null
@@ -0,0 +1,23 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Mismatched element width
+
+sclamp z0.b, z1.h, z2.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: sclamp z0.b, z1.h, z2.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sclamp z0.b, z1.b, z2.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: sclamp z0.b, z1.b, z2.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Test incompatibility with predicated MOVPRFX instruction.
+
+movprfx z0.b, p0/z, z1.b
+sclamp z0.b, z1.b, z2.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx
+// CHECK-NEXT: sclamp z0.b, z1.b, z2.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME/sclamp.s b/llvm/test/MC/AArch64/SME/sclamp.s
new file mode 100644 (file)
index 0000000..e899e5c
--- /dev/null
@@ -0,0 +1,172 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %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=+sme < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \
+// RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// --------------------------------------------------------------------------//
+// 8-bit
+
+sclamp  z0.b, z0.b, z0.b
+// CHECK-INST: sclamp  z0.b, z0.b, z0.b
+// CHECK-ENCODING: [0x00,0xc0,0x00,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 c0 00 44 <unknown>
+
+sclamp  z21.b, z10.b, z21.b
+// CHECK-INST: sclamp  z21.b, z10.b, z21.b
+// CHECK-ENCODING: [0x55,0xc1,0x15,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 c1 15 44 <unknown>
+
+sclamp  z23.b, z13.b, z8.b
+// CHECK-INST: sclamp  z23.b, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0xc1,0x08,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c1 08 44 <unknown>
+
+sclamp  z31.b, z31.b, z31.b
+// CHECK-INST: sclamp  z31.b, z31.b, z31.b
+// CHECK-ENCODING: [0xff,0xc3,0x1f,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff c3 1f 44 <unknown>
+
+// --------------------------------------------------------------------------//
+// 16-bit
+
+sclamp  z0.h, z0.h, z0.h
+// CHECK-INST: sclamp  z0.h, z0.h, z0.h
+// CHECK-ENCODING: [0x00,0xc0,0x40,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 c0 40 44 <unknown>
+
+sclamp  z21.h, z10.h, z21.h
+// CHECK-INST: sclamp  z21.h, z10.h, z21.h
+// CHECK-ENCODING: [0x55,0xc1,0x55,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 c1 55 44 <unknown>
+
+sclamp  z23.h, z13.h, z8.h
+// CHECK-INST: sclamp  z23.h, z13.h, z8.h
+// CHECK-ENCODING: [0xb7,0xc1,0x48,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c1 48 44 <unknown>
+
+sclamp  z31.h, z31.h, z31.h
+// CHECK-INST: sclamp  z31.h, z31.h, z31.h
+// CHECK-ENCODING: [0xff,0xc3,0x5f,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff c3 5f 44 <unknown>
+
+// --------------------------------------------------------------------------//
+// 32-bit
+
+sclamp  z0.s, z0.s, z0.s
+// CHECK-INST: sclamp  z0.s, z0.s, z0.s
+// CHECK-ENCODING: [0x00,0xc0,0x80,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 c0 80 44 <unknown>
+
+sclamp  z21.s, z10.s, z21.s
+// CHECK-INST: sclamp  z21.s, z10.s, z21.s
+// CHECK-ENCODING: [0x55,0xc1,0x95,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 c1 95 44 <unknown>
+
+sclamp  z23.s, z13.s, z8.s
+// CHECK-INST: sclamp  z23.s, z13.s, z8.s
+// CHECK-ENCODING: [0xb7,0xc1,0x88,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c1 88 44 <unknown>
+
+sclamp  z31.s, z31.s, z31.s
+// CHECK-INST: sclamp  z31.s, z31.s, z31.s
+// CHECK-ENCODING: [0xff,0xc3,0x9f,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff c3 9f 44 <unknown>
+
+// --------------------------------------------------------------------------//
+// 64-bit
+
+sclamp  z0.d, z0.d, z0.d
+// CHECK-INST: sclamp  z0.d, z0.d, z0.d
+// CHECK-ENCODING: [0x00,0xc0,0xc0,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 c0 c0 44 <unknown>
+
+sclamp  z21.d, z10.d, z21.d
+// CHECK-INST: sclamp  z21.d, z10.d, z21.d
+// CHECK-ENCODING: [0x55,0xc1,0xd5,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 c1 d5 44 <unknown>
+
+sclamp  z23.d, z13.d, z8.d
+// CHECK-INST: sclamp  z23.d, z13.d, z8.d
+// CHECK-ENCODING: [0xb7,0xc1,0xc8,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c1 c8 44 <unknown>
+
+sclamp  z31.d, z31.d, z31.d
+// CHECK-INST: sclamp  z31.d, z31.d, z31.d
+// CHECK-ENCODING: [0xff,0xc3,0xdf,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff c3 df 44 <unknown>
+
+// --------------------------------------------------------------------------//
+// Test compatibility with MOVPRFX instruction.
+
+movprfx z23, z27
+// CHECK-INST: movprfx  z23, z27
+// CHECK-ENCODING: [0x77,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 77 bf 20 04 <unknown>
+
+sclamp  z23.b, z13.b, z8.b
+// CHECK-INST: sclamp  z23.b, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0xc1,0x08,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c1 08 44 <unknown>
+
+movprfx z23, z27
+// CHECK-INST: movprfx  z23, z27
+// CHECK-ENCODING: [0x77,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 77 bf 20 04 <unknown>
+
+sclamp  z23.h, z13.h, z8.h
+// CHECK-INST: sclamp  z23.h, z13.h, z8.h
+// CHECK-ENCODING: [0xb7,0xc1,0x48,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c1 48 44 <unknown>
+
+movprfx z23, z27
+// CHECK-INST: movprfx  z23, z27
+// CHECK-ENCODING: [0x77,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 77 bf 20 04 <unknown>
+
+sclamp  z23.s, z13.s, z8.s
+// CHECK-INST: sclamp  z23.s, z13.s, z8.s
+// CHECK-ENCODING: [0xb7,0xc1,0x88,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c1 88 44 <unknown>
+
+movprfx z23, z27
+// CHECK-INST: movprfx  z23, z27
+// CHECK-ENCODING: [0x77,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 77 bf 20 04 <unknown>
+
+sclamp  z23.d, z13.d, z8.d
+// CHECK-INST: sclamp  z23.d, z13.d, z8.d
+// CHECK-ENCODING: [0xb7,0xc1,0xc8,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c1 c8 44 <unknown>
diff --git a/llvm/test/MC/AArch64/SME/uclamp-diagnostics.s b/llvm/test/MC/AArch64/SME/uclamp-diagnostics.s
new file mode 100644 (file)
index 0000000..6b88e40
--- /dev/null
@@ -0,0 +1,23 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme 2>&1 < %s| FileCheck %s
+
+// ------------------------------------------------------------------------- //
+// Mismatched element width
+
+sclamp z0.b, z1.h, z2.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: sclamp z0.b, z1.h, z2.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sclamp z0.b, z1.b, z2.q
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid element width
+// CHECK-NEXT: sclamp z0.b, z1.b, z2.q
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Test incompatibility with predicated MOVPRFX instruction.
+
+movprfx z0.b, p0/z, z1.b
+uclamp z0.b, z1.b, z2.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: instruction is unpredictable when following a predicated movprfx, suggest using unpredicated movprfx
+// CHECK-NEXT: uclamp z0.b, z1.b, z2.b
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
diff --git a/llvm/test/MC/AArch64/SME/uclamp.s b/llvm/test/MC/AArch64/SME/uclamp.s
new file mode 100644 (file)
index 0000000..56b4e50
--- /dev/null
@@ -0,0 +1,172 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %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=+sme < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme < %s \
+// RUN:        | llvm-objdump -d - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// --------------------------------------------------------------------------//
+// 8-bit
+
+uclamp  z0.b, z0.b, z0.b
+// CHECK-INST: uclamp  z0.b, z0.b, z0.b
+// CHECK-ENCODING: [0x00,0xc4,0x00,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 c4 00 44 <unknown>
+
+uclamp  z21.b, z10.b, z21.b
+// CHECK-INST: uclamp  z21.b, z10.b, z21.b
+// CHECK-ENCODING: [0x55,0xc5,0x15,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 c5 15 44 <unknown>
+
+uclamp  z23.b, z13.b, z8.b
+// CHECK-INST: uclamp  z23.b, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0xc5,0x08,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c5 08 44 <unknown>
+
+uclamp  z31.b, z31.b, z31.b
+// CHECK-INST: uclamp  z31.b, z31.b, z31.b
+// CHECK-ENCODING: [0xff,0xc7,0x1f,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff c7 1f 44 <unknown>
+
+// --------------------------------------------------------------------------//
+// 16-bit
+
+uclamp  z0.h, z0.h, z0.h
+// CHECK-INST: uclamp  z0.h, z0.h, z0.h
+// CHECK-ENCODING: [0x00,0xc4,0x40,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 c4 40 44 <unknown>
+
+uclamp  z21.h, z10.h, z21.h
+// CHECK-INST: uclamp  z21.h, z10.h, z21.h
+// CHECK-ENCODING: [0x55,0xc5,0x55,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 c5 55 44 <unknown>
+
+uclamp  z23.h, z13.h, z8.h
+// CHECK-INST: uclamp  z23.h, z13.h, z8.h
+// CHECK-ENCODING: [0xb7,0xc5,0x48,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c5 48 44 <unknown>
+
+uclamp  z31.h, z31.h, z31.h
+// CHECK-INST: uclamp  z31.h, z31.h, z31.h
+// CHECK-ENCODING: [0xff,0xc7,0x5f,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff c7 5f 44 <unknown>
+
+// --------------------------------------------------------------------------//
+// 32-bit
+
+uclamp  z0.s, z0.s, z0.s
+// CHECK-INST: uclamp  z0.s, z0.s, z0.s
+// CHECK-ENCODING: [0x00,0xc4,0x80,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 c4 80 44 <unknown>
+
+uclamp  z21.s, z10.s, z21.s
+// CHECK-INST: uclamp  z21.s, z10.s, z21.s
+// CHECK-ENCODING: [0x55,0xc5,0x95,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 c5 95 44 <unknown>
+
+uclamp  z23.s, z13.s, z8.s
+// CHECK-INST: uclamp  z23.s, z13.s, z8.s
+// CHECK-ENCODING: [0xb7,0xc5,0x88,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c5 88 44 <unknown>
+
+uclamp  z31.s, z31.s, z31.s
+// CHECK-INST: uclamp  z31.s, z31.s, z31.s
+// CHECK-ENCODING: [0xff,0xc7,0x9f,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff c7 9f 44 <unknown>
+
+// --------------------------------------------------------------------------//
+// 64-bit
+
+uclamp  z0.d, z0.d, z0.d
+// CHECK-INST: uclamp  z0.d, z0.d, z0.d
+// CHECK-ENCODING: [0x00,0xc4,0xc0,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 00 c4 c0 44 <unknown>
+
+uclamp  z21.d, z10.d, z21.d
+// CHECK-INST: uclamp  z21.d, z10.d, z21.d
+// CHECK-ENCODING: [0x55,0xc5,0xd5,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: 55 c5 d5 44 <unknown>
+
+uclamp  z23.d, z13.d, z8.d
+// CHECK-INST: uclamp  z23.d, z13.d, z8.d
+// CHECK-ENCODING: [0xb7,0xc5,0xc8,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c5 c8 44 <unknown>
+
+uclamp  z31.d, z31.d, z31.d
+// CHECK-INST: uclamp  z31.d, z31.d, z31.d
+// CHECK-ENCODING: [0xff,0xc7,0xdf,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: ff c7 df 44 <unknown>
+
+// --------------------------------------------------------------------------//
+// Test compatibility with MOVPRFX instruction.
+
+movprfx z23, z27
+// CHECK-INST: movprfx  z23, z27
+// CHECK-ENCODING: [0x77,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 77 bf 20 04 <unknown>
+
+uclamp  z23.b, z13.b, z8.b
+// CHECK-INST: uclamp  z23.b, z13.b, z8.b
+// CHECK-ENCODING: [0xb7,0xc5,0x08,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c5 08 44 <unknown>
+
+movprfx z23, z27
+// CHECK-INST: movprfx  z23, z27
+// CHECK-ENCODING: [0x77,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 77 bf 20 04 <unknown>
+
+uclamp  z23.h, z13.h, z8.h
+// CHECK-INST: uclamp  z23.h, z13.h, z8.h
+// CHECK-ENCODING: [0xb7,0xc5,0x48,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c5 48 44 <unknown>
+
+movprfx z23, z27
+// CHECK-INST: movprfx  z23, z27
+// CHECK-ENCODING: [0x77,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 77 bf 20 04 <unknown>
+
+uclamp  z23.s, z13.s, z8.s
+// CHECK-INST: uclamp  z23.s, z13.s, z8.s
+// CHECK-ENCODING: [0xb7,0xc5,0x88,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c5 88 44 <unknown>
+
+movprfx z23, z27
+// CHECK-INST: movprfx  z23, z27
+// CHECK-ENCODING: [0x77,0xbf,0x20,0x04]
+// CHECK-ERROR: instruction requires: sve
+// CHECK-UNKNOWN: 77 bf 20 04 <unknown>
+
+uclamp  z23.d, z13.d, z8.d
+// CHECK-INST: uclamp  z23.d, z13.d, z8.d
+// CHECK-ENCODING: [0xb7,0xc5,0xc8,0x44]
+// CHECK-ERROR: instruction requires: sme
+// CHECK-UNKNOWN: b7 c5 c8 44 <unknown>