Skip to content

[AArch64] Add assembly/disassembly for {S,U,SU,US}TMOPA instructions #113946

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Oct 31, 2024

Conversation

momchil-velikov
Copy link
Collaborator

The new instructions are described in
https://developer.arm.com/documentation/ddi0602/2024-09/SME-Instructions

Co-Authored-By: Marian Lukac [email protected]

@llvmbot
Copy link
Member

llvmbot commented Oct 28, 2024

@llvm/pr-subscribers-backend-aarch64

Author: Momchil Velikov (momchil-velikov)

Changes

The new instructions are described in
https://developer.arm.com/documentation/ddi0602/2024-09/SME-Instructions

Co-Authored-By: Marian Lukac <[email protected]>


Patch is 28.00 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113946.diff

10 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td (+9)
  • (modified) llvm/lib/Target/AArch64/SMEInstrFormats.td (+29)
  • (added) llvm/test/MC/AArch64/SME2p2/stmopa-diagnostics.s (+86)
  • (added) llvm/test/MC/AArch64/SME2p2/stmopa.s (+49)
  • (added) llvm/test/MC/AArch64/SME2p2/sutmopa-diagnostics.s (+77)
  • (added) llvm/test/MC/AArch64/SME2p2/sutmopa.s (+31)
  • (added) llvm/test/MC/AArch64/SME2p2/ustmopa-diagnostics.s (+77)
  • (added) llvm/test/MC/AArch64/SME2p2/ustmopa.s (+31)
  • (added) llvm/test/MC/AArch64/SME2p2/utmopa-diagnostics.s (+77)
  • (added) llvm/test/MC/AArch64/SME2p2/utmopa.s (+49)
diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index b763aa15a7c3f1..5d7c911b11a84f 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -131,6 +131,15 @@ defm USMOPA_MPPZZ_D : sme_int_outer_product_i64<0b100, "usmopa", int_aarch64_sme
 defm USMOPS_MPPZZ_D : sme_int_outer_product_i64<0b101, "usmops", int_aarch64_sme_usmops_wide>;
 }
 
+let Predicates = [HasSME2p2] in {
+def STMOPA_M2ZZZI_BtoS  : sme_int_sparse_outer_product_i32<0b00100, ZZ_b_mul_r, ZPR8,  "stmopa">;
+def STMOPA_M2ZZZI_HtoS  : sme_int_sparse_outer_product_i32<0b00101, ZZ_h_mul_r, ZPR16, "stmopa">;
+def UTMOPA_M2ZZZI_BtoS  : sme_int_sparse_outer_product_i32<0b11100, ZZ_b_mul_r, ZPR8,  "utmopa">;
+def UTMOPA_M2ZZZI_HtoS  : sme_int_sparse_outer_product_i32<0b10101, ZZ_h_mul_r, ZPR16, "utmopa">;
+def SUTMOPA_M2ZZZI_BtoS : sme_int_sparse_outer_product_i32<0b01100, ZZ_b_mul_r, ZPR8, "sutmopa">;
+def USTMOPA_M2ZZZI_BtoS : sme_int_sparse_outer_product_i32<0b10100, ZZ_b_mul_r, ZPR8, "ustmopa">;
+}
+
 let Predicates = [HasSME] in {
 //===----------------------------------------------------------------------===//
 // Loads and stores
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 4cfe18eddf481c..c57f5b5f095d4f 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -433,6 +433,35 @@ multiclass sme_f16_outer_product<bits<3> opc, string mnemonic, SDPatternOperator
   def : SME_ZA_Tile_TwoPred_TwoVec_Pat<NAME, op, timm32_0_3, nxv8i1, nxv8f16>;
 }
 
+class sme_int_sparse_outer_product_i32<bits<5> opc, RegisterOperand zn_ty, RegisterOperand zm_ty, string mnemonic>
+    : I<(outs TileOp32:$ZAda),
+        (ins  TileOp32:$_ZAda, zn_ty:$Zn, zm_ty:$Zm, ZK:$Zk, VectorIndexS32b:$imm),
+        mnemonic, "\t$ZAda, $Zn, $Zm, $Zk$imm",
+        "", []>,
+      Sched<[]> {
+  bits<2> ZAda;
+  bits<4> Zn;
+  bits<5> Zm;
+  bits<3> Zk;
+  bits<2> imm;
+  let Inst{31-25} = 0b1000000;
+  let Inst{24}    = opc{4};
+  let Inst{23-22} = 0b01;
+  let Inst{21}    = opc{3};
+  let Inst{20-16} = Zm;
+  let Inst{15}    = opc{2};
+  let Inst{14}    = 0b0;
+  let Inst{13}    = opc{1};
+  let Inst{12-10} = Zk;
+  let Inst{9-6}   = Zn;
+  let Inst{5-4}   = imm;
+  let Inst{3}     = opc{0};
+  let Inst{2}     = 0b0;
+  let Inst{1-0}   = ZAda;
+
+  let Constraints = "$ZAda = $_ZAda";
+}
+
 //===----------------------------------------------------------------------===//
 // SME Add Vector to Tile
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/SME2p2/stmopa-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/stmopa-diagnostics.s
new file mode 100644
index 00000000000000..ae397b9eecd7e9
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/stmopa-diagnostics.s
@@ -0,0 +1,86 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid ZA register
+
+stmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: stmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za4.s, {z30.h-z31.h}, z31.h, z31[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: stmopa  za4.s, {z30.h-z31.h}, z31.h, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector list operand
+
+stmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// 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: stmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z29.h-z30.h}, z31.h, z31[3]
+// 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: stmopa  za3.s, {z29.h-z30.h}, z31.h, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZK register
+
+stmopa  za3.s, {z28.b-z29.b}, z31.b, z27[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: stmopa  za3.s, {z28.b-z29.b}, z31.b, z27[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z28.h-z29.h}, z31.h, z24[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: stmopa  za3.s, {z28.h-z29.h}, z31.h, z24[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z28.h-z29.h}, z31.h, z27[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: stmopa  za3.s, {z28.h-z29.h}, z31.h, z27[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate
+
+stmopa  za3.s, {z28.b-z29.b}, z31.b, z20[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: stmopa  za3.s, {z28.b-z29.b}, z31.b, z20[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z28.h-z29.h}, z31.h, z20[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: stmopa  za3.s, {z28.h-z29.h}, z31.h, z20[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZPR type suffix
+
+stmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: stmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: stmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: stmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: stmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: stmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SME2p2/stmopa.s b/llvm/test/MC/AArch64/SME2p2/stmopa.s
new file mode 100644
index 00000000000000..c641eb46108a73
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/stmopa.s
@@ -0,0 +1,49 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+stmopa  za0.s, {z0.b-z1.b}, z0.b, z20[0]  // 10000000-01000000-10000000-00000000
+// CHECK-INST: stmopa  za0.s, { z0.b, z1.b }, z0.b, z20[0]
+// CHECK-ENCODING: [0x00,0x80,0x40,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80408000 <unknown>
+
+stmopa  za3.s, {z12.b-z13.b}, z8.b, z23[3]  // 10000000-01001000-10001101-10110011
+// CHECK-INST: stmopa  za3.s, { z12.b, z13.b }, z8.b, z23[3]
+// CHECK-ENCODING: [0xb3,0x8d,0x48,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80488db3 <unknown>
+
+stmopa  za3.s, {z30.b-z31.b}, z31.b, z31[3]  // 10000000-01011111-10011111-11110011
+// CHECK-INST: stmopa  za3.s, { z30.b, z31.b }, z31.b, z31[3]
+// CHECK-ENCODING: [0xf3,0x9f,0x5f,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 805f9ff3 <unknown>
+
+stmopa  za0.s, {z0.h-z1.h}, z0.h, z20[0]  // 10000000-01000000-10000000-00001000
+// CHECK-INST: stmopa  za0.s, { z0.h, z1.h }, z0.h, z20[0]
+// CHECK-ENCODING: [0x08,0x80,0x40,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80408008 <unknown>
+
+stmopa  za3.s, {z12.h-z13.h}, z8.h, z23[3]  // 10000000-01001000-10001101-10111011
+// CHECK-INST: stmopa  za3.s, { z12.h, z13.h }, z8.h, z23[3]
+// CHECK-ENCODING: [0xbb,0x8d,0x48,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80488dbb <unknown>
+
+stmopa  za3.s, {z30.h-z31.h}, z31.h, z31[3]  // 10000000-01011111-10011111-11111011
+// CHECK-INST: stmopa  za3.s, { z30.h, z31.h }, z31.h, z31[3]
+// CHECK-ENCODING: [0xfb,0x9f,0x5f,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 805f9ffb <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/sutmopa-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/sutmopa-diagnostics.s
new file mode 100644
index 00000000000000..c400f9e63c665f
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sutmopa-diagnostics.s
@@ -0,0 +1,77 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid ZA register
+
+sutmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sutmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector list operand
+
+sutmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// 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: sutmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZK register
+
+sutmopa  za3.s, {z28.b-z29.b}, z31.b, z19[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: sutmopa  za3.s, {z28.b-z29.b}, z31.b, z19[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.s, {z28.b-z29.b}, z31.b, z24[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: sutmopa  za3.s, {z28.b-z29.b}, z31.b, z24[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.s, {z28.b-z29.b}, z31.b, z27[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: sutmopa  za3.s, {z28.b-z29.b}, z31.b, z27[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate
+
+
+sutmopa  za3.s, {z28.b-z29.b}, z31.b, z29[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: sutmopa  za3.s, {z28.b-z29.b}, z31.b, z29[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZPR type suffix
+
+sutmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: sutmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: sutmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.s, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sutmopa  za3.s, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sutmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: sutmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: sutmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SME2p2/sutmopa.s b/llvm/test/MC/AArch64/SME2p2/sutmopa.s
new file mode 100644
index 00000000000000..94a86a8a3f166c
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sutmopa.s
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+sutmopa za0.s, {z0.b-z1.b}, z0.b, z20[0]  // 10000000-01100000-10000000-00000000
+// CHECK-INST: sutmopa za0.s, { z0.b, z1.b }, z0.b, z20[0]
+// CHECK-ENCODING: [0x00,0x80,0x60,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80608000 <unknown>
+
+sutmopa za1.s, {z10.b-z11.b}, z21.b, z29[1]  // 10000000-01110101-10010101-01010001
+// CHECK-INST: sutmopa za1.s, { z10.b, z11.b }, z21.b, z29[1]
+// CHECK-ENCODING: [0x51,0x95,0x75,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80759551 <unknown>
+
+sutmopa za3.s, {z30.b-z31.b}, z31.b, z31[3]  // 10000000-01111111-10011111-11110011
+// CHECK-INST: sutmopa za3.s, { z30.b, z31.b }, z31.b, z31[3]
+// CHECK-ENCODING: [0xf3,0x9f,0x7f,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 807f9ff3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/ustmopa-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/ustmopa-diagnostics.s
new file mode 100644
index 00000000000000..5a055fb74914ac
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/ustmopa-diagnostics.s
@@ -0,0 +1,77 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid ZA register
+
+ustmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ustmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector list operand
+
+ustmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// 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: ustmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZK register
+
+ustmopa  za3.s, {z28.b-z29.b}, z31.b, z19[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: ustmopa  za3.s, {z28.b-z29.b}, z31.b, z19[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.s, {z28.b-z29.b}, z31.b, z24[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: ustmopa  za3.s, {z28.b-z29.b}, z31.b, z24[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.s, {z28.b-z29.b}, z31.b, z27[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: ustmopa  za3.s, {z28.b-z29.b}, z31.b, z27[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate
+
+
+ustmopa  za3.s, {z28.b-z29.b}, z31.b, z29[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: ustmopa  za3.s, {z28.b-z29.b}, z31.b, z29[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZPR type suffix
+
+ustmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: ustmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: ustmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.s, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ustmopa  za3.s, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ustmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: ustmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: ustmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SME2p2/ustmopa.s b/llvm/test/MC/AArch64/SME2p2/ustmopa.s
new file mode 100644
index 00000000000000..678cf1256ea9bf
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/ustmopa.s
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-I...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Oct 28, 2024

@llvm/pr-subscribers-mc

Author: Momchil Velikov (momchil-velikov)

Changes

The new instructions are described in
https://developer.arm.com/documentation/ddi0602/2024-09/SME-Instructions

Co-Authored-By: Marian Lukac <[email protected]>


Patch is 28.00 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113946.diff

10 Files Affected:

  • (modified) llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td (+9)
  • (modified) llvm/lib/Target/AArch64/SMEInstrFormats.td (+29)
  • (added) llvm/test/MC/AArch64/SME2p2/stmopa-diagnostics.s (+86)
  • (added) llvm/test/MC/AArch64/SME2p2/stmopa.s (+49)
  • (added) llvm/test/MC/AArch64/SME2p2/sutmopa-diagnostics.s (+77)
  • (added) llvm/test/MC/AArch64/SME2p2/sutmopa.s (+31)
  • (added) llvm/test/MC/AArch64/SME2p2/ustmopa-diagnostics.s (+77)
  • (added) llvm/test/MC/AArch64/SME2p2/ustmopa.s (+31)
  • (added) llvm/test/MC/AArch64/SME2p2/utmopa-diagnostics.s (+77)
  • (added) llvm/test/MC/AArch64/SME2p2/utmopa.s (+49)
diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index b763aa15a7c3f1..5d7c911b11a84f 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -131,6 +131,15 @@ defm USMOPA_MPPZZ_D : sme_int_outer_product_i64<0b100, "usmopa", int_aarch64_sme
 defm USMOPS_MPPZZ_D : sme_int_outer_product_i64<0b101, "usmops", int_aarch64_sme_usmops_wide>;
 }
 
+let Predicates = [HasSME2p2] in {
+def STMOPA_M2ZZZI_BtoS  : sme_int_sparse_outer_product_i32<0b00100, ZZ_b_mul_r, ZPR8,  "stmopa">;
+def STMOPA_M2ZZZI_HtoS  : sme_int_sparse_outer_product_i32<0b00101, ZZ_h_mul_r, ZPR16, "stmopa">;
+def UTMOPA_M2ZZZI_BtoS  : sme_int_sparse_outer_product_i32<0b11100, ZZ_b_mul_r, ZPR8,  "utmopa">;
+def UTMOPA_M2ZZZI_HtoS  : sme_int_sparse_outer_product_i32<0b10101, ZZ_h_mul_r, ZPR16, "utmopa">;
+def SUTMOPA_M2ZZZI_BtoS : sme_int_sparse_outer_product_i32<0b01100, ZZ_b_mul_r, ZPR8, "sutmopa">;
+def USTMOPA_M2ZZZI_BtoS : sme_int_sparse_outer_product_i32<0b10100, ZZ_b_mul_r, ZPR8, "ustmopa">;
+}
+
 let Predicates = [HasSME] in {
 //===----------------------------------------------------------------------===//
 // Loads and stores
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 4cfe18eddf481c..c57f5b5f095d4f 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -433,6 +433,35 @@ multiclass sme_f16_outer_product<bits<3> opc, string mnemonic, SDPatternOperator
   def : SME_ZA_Tile_TwoPred_TwoVec_Pat<NAME, op, timm32_0_3, nxv8i1, nxv8f16>;
 }
 
+class sme_int_sparse_outer_product_i32<bits<5> opc, RegisterOperand zn_ty, RegisterOperand zm_ty, string mnemonic>
+    : I<(outs TileOp32:$ZAda),
+        (ins  TileOp32:$_ZAda, zn_ty:$Zn, zm_ty:$Zm, ZK:$Zk, VectorIndexS32b:$imm),
+        mnemonic, "\t$ZAda, $Zn, $Zm, $Zk$imm",
+        "", []>,
+      Sched<[]> {
+  bits<2> ZAda;
+  bits<4> Zn;
+  bits<5> Zm;
+  bits<3> Zk;
+  bits<2> imm;
+  let Inst{31-25} = 0b1000000;
+  let Inst{24}    = opc{4};
+  let Inst{23-22} = 0b01;
+  let Inst{21}    = opc{3};
+  let Inst{20-16} = Zm;
+  let Inst{15}    = opc{2};
+  let Inst{14}    = 0b0;
+  let Inst{13}    = opc{1};
+  let Inst{12-10} = Zk;
+  let Inst{9-6}   = Zn;
+  let Inst{5-4}   = imm;
+  let Inst{3}     = opc{0};
+  let Inst{2}     = 0b0;
+  let Inst{1-0}   = ZAda;
+
+  let Constraints = "$ZAda = $_ZAda";
+}
+
 //===----------------------------------------------------------------------===//
 // SME Add Vector to Tile
 //===----------------------------------------------------------------------===//
diff --git a/llvm/test/MC/AArch64/SME2p2/stmopa-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/stmopa-diagnostics.s
new file mode 100644
index 00000000000000..ae397b9eecd7e9
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/stmopa-diagnostics.s
@@ -0,0 +1,86 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid ZA register
+
+stmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: stmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za4.s, {z30.h-z31.h}, z31.h, z31[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: stmopa  za4.s, {z30.h-z31.h}, z31.h, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector list operand
+
+stmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// 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: stmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z29.h-z30.h}, z31.h, z31[3]
+// 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: stmopa  za3.s, {z29.h-z30.h}, z31.h, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZK register
+
+stmopa  za3.s, {z28.b-z29.b}, z31.b, z27[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: stmopa  za3.s, {z28.b-z29.b}, z31.b, z27[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z28.h-z29.h}, z31.h, z24[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: stmopa  za3.s, {z28.h-z29.h}, z31.h, z24[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z28.h-z29.h}, z31.h, z27[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: stmopa  za3.s, {z28.h-z29.h}, z31.h, z27[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate
+
+stmopa  za3.s, {z28.b-z29.b}, z31.b, z20[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: stmopa  za3.s, {z28.b-z29.b}, z31.b, z20[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z28.h-z29.h}, z31.h, z20[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: stmopa  za3.s, {z28.h-z29.h}, z31.h, z20[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZPR type suffix
+
+stmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: stmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: stmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: stmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: stmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+stmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: stmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SME2p2/stmopa.s b/llvm/test/MC/AArch64/SME2p2/stmopa.s
new file mode 100644
index 00000000000000..c641eb46108a73
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/stmopa.s
@@ -0,0 +1,49 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+stmopa  za0.s, {z0.b-z1.b}, z0.b, z20[0]  // 10000000-01000000-10000000-00000000
+// CHECK-INST: stmopa  za0.s, { z0.b, z1.b }, z0.b, z20[0]
+// CHECK-ENCODING: [0x00,0x80,0x40,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80408000 <unknown>
+
+stmopa  za3.s, {z12.b-z13.b}, z8.b, z23[3]  // 10000000-01001000-10001101-10110011
+// CHECK-INST: stmopa  za3.s, { z12.b, z13.b }, z8.b, z23[3]
+// CHECK-ENCODING: [0xb3,0x8d,0x48,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80488db3 <unknown>
+
+stmopa  za3.s, {z30.b-z31.b}, z31.b, z31[3]  // 10000000-01011111-10011111-11110011
+// CHECK-INST: stmopa  za3.s, { z30.b, z31.b }, z31.b, z31[3]
+// CHECK-ENCODING: [0xf3,0x9f,0x5f,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 805f9ff3 <unknown>
+
+stmopa  za0.s, {z0.h-z1.h}, z0.h, z20[0]  // 10000000-01000000-10000000-00001000
+// CHECK-INST: stmopa  za0.s, { z0.h, z1.h }, z0.h, z20[0]
+// CHECK-ENCODING: [0x08,0x80,0x40,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80408008 <unknown>
+
+stmopa  za3.s, {z12.h-z13.h}, z8.h, z23[3]  // 10000000-01001000-10001101-10111011
+// CHECK-INST: stmopa  za3.s, { z12.h, z13.h }, z8.h, z23[3]
+// CHECK-ENCODING: [0xbb,0x8d,0x48,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80488dbb <unknown>
+
+stmopa  za3.s, {z30.h-z31.h}, z31.h, z31[3]  // 10000000-01011111-10011111-11111011
+// CHECK-INST: stmopa  za3.s, { z30.h, z31.h }, z31.h, z31[3]
+// CHECK-ENCODING: [0xfb,0x9f,0x5f,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 805f9ffb <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/sutmopa-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/sutmopa-diagnostics.s
new file mode 100644
index 00000000000000..c400f9e63c665f
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sutmopa-diagnostics.s
@@ -0,0 +1,77 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid ZA register
+
+sutmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sutmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector list operand
+
+sutmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// 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: sutmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZK register
+
+sutmopa  za3.s, {z28.b-z29.b}, z31.b, z19[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: sutmopa  za3.s, {z28.b-z29.b}, z31.b, z19[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.s, {z28.b-z29.b}, z31.b, z24[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: sutmopa  za3.s, {z28.b-z29.b}, z31.b, z24[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.s, {z28.b-z29.b}, z31.b, z27[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: sutmopa  za3.s, {z28.b-z29.b}, z31.b, z27[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate
+
+
+sutmopa  za3.s, {z28.b-z29.b}, z31.b, z29[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: sutmopa  za3.s, {z28.b-z29.b}, z31.b, z29[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZPR type suffix
+
+sutmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: sutmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: sutmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.s, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sutmopa  za3.s, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: sutmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: sutmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+sutmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: sutmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SME2p2/sutmopa.s b/llvm/test/MC/AArch64/SME2p2/sutmopa.s
new file mode 100644
index 00000000000000..94a86a8a3f166c
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/sutmopa.s
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=-sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %s \
+// RUN:        | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN:        | llvm-mc -triple=aarch64 -mattr=+sme2p2 -disassemble -show-encoding \
+// RUN:        | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+sutmopa za0.s, {z0.b-z1.b}, z0.b, z20[0]  // 10000000-01100000-10000000-00000000
+// CHECK-INST: sutmopa za0.s, { z0.b, z1.b }, z0.b, z20[0]
+// CHECK-ENCODING: [0x00,0x80,0x60,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80608000 <unknown>
+
+sutmopa za1.s, {z10.b-z11.b}, z21.b, z29[1]  // 10000000-01110101-10010101-01010001
+// CHECK-INST: sutmopa za1.s, { z10.b, z11.b }, z21.b, z29[1]
+// CHECK-ENCODING: [0x51,0x95,0x75,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 80759551 <unknown>
+
+sutmopa za3.s, {z30.b-z31.b}, z31.b, z31[3]  // 10000000-01111111-10011111-11110011
+// CHECK-INST: sutmopa za3.s, { z30.b, z31.b }, z31.b, z31[3]
+// CHECK-ENCODING: [0xf3,0x9f,0x7f,0x80]
+// CHECK-ERROR: instruction requires: sme2p2
+// CHECK-UNKNOWN: 807f9ff3 <unknown>
diff --git a/llvm/test/MC/AArch64/SME2p2/ustmopa-diagnostics.s b/llvm/test/MC/AArch64/SME2p2/ustmopa-diagnostics.s
new file mode 100644
index 00000000000000..5a055fb74914ac
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/ustmopa-diagnostics.s
@@ -0,0 +1,77 @@
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 2>&1 < %s| FileCheck %s
+
+// --------------------------------------------------------------------------//
+// Invalid ZA register
+
+ustmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ustmopa  za4.s, {z30.b-z31.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid vector list operand
+
+ustmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// 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: ustmopa  za3.s, {z29.b-z30.b}, z31.b, z31[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZK register
+
+ustmopa  za3.s, {z28.b-z29.b}, z31.b, z19[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: ustmopa  za3.s, {z28.b-z29.b}, z31.b, z19[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.s, {z28.b-z29.b}, z31.b, z24[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: ustmopa  za3.s, {z28.b-z29.b}, z31.b, z24[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.s, {z28.b-z29.b}, z31.b, z27[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid restricted vector register, expected register in z20..z23 or z28..z31
+// CHECK-NEXT: ustmopa  za3.s, {z28.b-z29.b}, z31.b, z27[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid immediate
+
+
+ustmopa  za3.s, {z28.b-z29.b}, z31.b, z29[4]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: vector lane must be an integer in range [0, 3].
+// CHECK-NEXT: ustmopa  za3.s, {z28.b-z29.b}, z31.b, z29[4]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+// --------------------------------------------------------------------------//
+// Invalid ZPR type suffix
+
+ustmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: ustmopa  za0.h, {z28.b-z29.b}, z31.b, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: ustmopa  za0.h, {z28.h-z29.h}, z31.h, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.s, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ustmopa  za3.s, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT: ustmopa  za3.s, {z28.s-z29.s}, z31.s, z20[2]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: ustmopa  za3.d, {z28.s-z29.s}, z31.s, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
+
+ustmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid matrix operand, expected za[0-3].s
+// CHECK-NEXT: ustmopa  za3.d, {z28.h-z29.h}, z31.h, z20[3]
+// CHECK-NOT: [[@LINE-1]]:{{[0-9]+}}:
\ No newline at end of file
diff --git a/llvm/test/MC/AArch64/SME2p2/ustmopa.s b/llvm/test/MC/AArch64/SME2p2/ustmopa.s
new file mode 100644
index 00000000000000..678cf1256ea9bf
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2p2/ustmopa.s
@@ -0,0 +1,31 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 < %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=+sme2p2 < %s \
+// RUN:        | llvm-objdump -d --mattr=+sme2p2 --no-print-imm-hex - | FileCheck %s --check-prefix=CHECK-I...
[truncated]

Copy link
Contributor

@jthackray jthackray left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@momchil-velikov momchil-velikov force-pushed the int-sparse-outer-product branch from 87a31d5 to 48b8e20 Compare October 29, 2024 16:15
Copy link
Contributor

@SpencerAbson SpencerAbson left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks.

@momchil-velikov momchil-velikov force-pushed the int-sparse-outer-product branch from 48b8e20 to 1ed9d5b Compare October 31, 2024 12:12
@momchil-velikov momchil-velikov merged commit b185e92 into llvm:main Oct 31, 2024
4 of 5 checks passed
smallp-o-p pushed a commit to smallp-o-p/llvm-project that referenced this pull request Nov 3, 2024
NoumanAmir657 pushed a commit to NoumanAmir657/llvm-project that referenced this pull request Nov 4, 2024
@momchil-velikov momchil-velikov deleted the int-sparse-outer-product branch November 13, 2024 09:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 mc Machine (object) code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants