[AArch32] Armv8.6a Matrix Mul Assembly Parsing Support
authorLuke Geeson <luke.geeson@arm.com>
Thu, 9 Apr 2020 20:38:37 +0000 (21:38 +0100)
committerLuke Geeson <luke.geeson@arm.com>
Fri, 24 Apr 2020 14:54:06 +0000 (15:54 +0100)
This patch upstreams support for the Armv8.6-a Matrix Multiplication
Extension. A summary of the features can be found here:

https://community.arm.com/developer/ip-products/processors/b/processors-ip-blog/posts/arm-architecture-developments-armv8-6-a

This patch includes:

- Assembly support for AArch32 and Assembly Parsing

D77872 has already added the MC representations of the instructions so that
they can be used in code gen; this patch fills in the details needed to
make assembly parsing work, and adds tests for asm and disasm

This is part of a patch series, starting with BFloat16 support and
the other components in the armv8.6a extension (in previous patches
linked in phabricator)

Based on work by:
- Luke Geeson
- Oliver Stannard
- Luke Cheeseman

Reviewers: t.p.northover, simon_tatham

Reviewed By: simon_tatham

Subscribers: simon_tatham, ostannard, kristof.beyls, hiraditya,
danielkiss, llvm-commits

Tags: #llvm

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

llvm/lib/Target/ARM/AsmParser/ARMAsmParser.cpp
llvm/test/MC/ARM/armv8.6a-matmul-error.s [new file with mode: 0644]
llvm/test/MC/ARM/armv8.6a-matmul.s [new file with mode: 0644]
llvm/test/MC/Disassembler/ARM/armv8.6a-matmul-arm.txt [new file with mode: 0644]
llvm/test/MC/Disassembler/ARM/armv8.6a-matmul-thumb.txt [new file with mode: 0644]

index c3639b3..05f870b 100644 (file)
@@ -6465,7 +6465,9 @@ void ARMAsmParser::getMnemonicAcceptInfo(StringRef Mnemonic,
       Mnemonic == "vfmat" || Mnemonic == "vfmab" ||
       Mnemonic == "vdot"  || Mnemonic == "vmmla" ||
       Mnemonic == "sb"    || Mnemonic == "ssbb"  ||
-      Mnemonic == "pssbb" ||
+      Mnemonic == "pssbb" || Mnemonic == "vsmmla" ||
+      Mnemonic == "vummla" || Mnemonic == "vusmmla" ||
+      Mnemonic == "vusdot" || Mnemonic == "vsudot" ||
       Mnemonic == "bfcsel" || Mnemonic == "wls" ||
       Mnemonic == "dls" || Mnemonic == "le" || Mnemonic == "csel" ||
       Mnemonic == "csinc" || Mnemonic == "csinv" || Mnemonic == "csneg" ||
diff --git a/llvm/test/MC/ARM/armv8.6a-matmul-error.s b/llvm/test/MC/ARM/armv8.6a-matmul-error.s
new file mode 100644 (file)
index 0000000..b8da448
--- /dev/null
@@ -0,0 +1,113 @@
+// RUN: not llvm-mc -triple armv8a   -show-encoding -mattr=+i8mm < %s 2>&1 | FileCheck %s
+// RUN: not llvm-mc -triple thumbv8a -show-encoding -mattr=+i8mm < %s 2>&1 | FileCheck %s
+
+
+// VSMMLA, VUMMLA, VUSMMLA
+
+// Data type specifier must match instruction
+
+vsmmla.u8 q0, q1, q2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT:    vsmmla.u8 q0, q1, q2
+// CHECK-NEXT: {{^      \^}}
+
+vummla.s8 q0, q1, q2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT:    vummla.s8 q0, q1, q2
+// CHECK-NEXT: {{^      \^}}
+
+vusmmla.u8 q0, q1, q2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT:    vusmmla.u8 q0, q1, q2
+// CHECK-NEXT: {{^       \^}}
+
+
+// Incorrect register type
+
+vsmmla.s8 d0, q1, q2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [q0, q15]
+// CHECK-NEXT:    vsmmla.s8 d0, q1, q2
+// CHECK-NEXT: {{^          \^}}
+
+vummla.u8 q0, d1, q2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [q0, q15]
+// CHECK-NEXT:    vummla.u8 q0, d1, q2
+// CHECK-NEXT: {{^              \^}}
+
+vusmmla.s8 q0, q1, d2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [q0, q15]
+// CHECK-NEXT:    vusmmla.s8 q0, q1, d2
+// CHECK-NEXT: {{^                   \^}}
+
+
+// VUSDOT (vector)
+
+// Data type specifier must match instruction
+
+vusdot.u8 q0, q1, q2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT:    vusdot.u8 q0, q1, q2
+// CHECK-NEXT: {{^      \^}}
+
+// Mis-matched register types
+
+vusdot.s8 q0, d1, d2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [d0, d31]
+vusdot.s8 d0, q1, d2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [d0, d31]
+vusdot.s8 d0, d1, q2
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: operand must be a register in range [d0, d31]
+
+
+// VUSDOT, VSUDOT (by scalar)
+
+// Data type specifier must match instruction
+
+vusdot.u8 d0, d1, d2[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT:    vusdot.u8 d0, d1, d2[0]
+// CHECK-NEXT: {{^      \^}}
+
+vsudot.s8 d0, d1, d2[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+// CHECK-NEXT:    vsudot.s8 d0, d1, d2[0]
+// CHECK-NEXT: {{^      \^}}
+
+// Incorrect register types
+
+vusdot.s8 q0, d1, d2[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this:
+// CHECK-NEXT: vusdot.s8 q0, d1, d2[0]
+// CHECK: [[@LINE-3]]:{{[0-9]+}}: note: operand must be a register in range [d0, d31]
+// CHECK-NEXT: vusdot.s8 q0, d1, d2[0]
+// CHECK-NEXT: {{^       \^}}
+// CHECK: [[@LINE-6]]:{{[0-9]+}}: note: operand must be a register in range [q0, q15]
+// CHECK-NEXT: vusdot.s8 q0, d1, d2[0]
+// CHECK-NEXT: {{^           \^}}
+
+vusdot.s8 d0, q1, d2[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this:
+// CHECK-NEXT: vusdot.s8 d0, q1, d2[0]
+// CHECK: [[@LINE-3]]:{{[0-9]+}}: note: operand must be a register in range [d0, d31]
+// CHECK-NEXT: vusdot.s8 d0, q1, d2[0]
+// CHECK-NEXT: {{^           \^}}
+// CHECK: [[@LINE-6]]:{{[0-9]+}}: note: operand must be a register in range [q0, q15]
+// CHECK-NEXT: vusdot.s8 d0, q1, d2[0]
+// CHECK-NEXT: {{^       \^}}
+
+vusdot.s8 q0, q1, q2[0]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid instruction, any one of the following would fix this:
+// CHECK-NEXT: vusdot.s8 q0, q1, q2[0]
+// CHECK: [[@LINE-3]]:{{[0-9]+}}: note: operand must be a register in range [d0, d15]
+// CHECK-NEXT: vusdot.s8 q0, q1, q2[0]
+// CHECK-NEXT: {{^               \^}}
+// CHECK: [[@LINE-6]]:{{[0-9]+}}: note: too many operands for instruction
+// CHECK-NEXT: vusdot.s8 q0, q1, q2[0]
+// CHECK-NEXT: {{^                 \^}}
+
+// Out of range lane index
+
+vusdot.s8 d0, d1, d2[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+vsudot.u8 q0, q1, d2[2]
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
diff --git a/llvm/test/MC/ARM/armv8.6a-matmul.s b/llvm/test/MC/ARM/armv8.6a-matmul.s
new file mode 100644 (file)
index 0000000..45ebf00
--- /dev/null
@@ -0,0 +1,49 @@
+// RUN:     llvm-mc -triple armv8a   -show-encoding -mattr=+i8mm < %s      | FileCheck %s --check-prefix=ARM
+// RUN:     llvm-mc -triple thumbv8a -show-encoding -mattr=+i8mm < %s      | FileCheck %s --check-prefix=THUMB
+// RUN: not llvm-mc -triple armv8a   -show-encoding -mattr=v8.5a < %s 2>&1 | FileCheck %s --check-prefix=NOMATMUL
+// RUN: not llvm-mc -triple thumbv8a -show-encoding -mattr=v8.5a < %s 2>&1 | FileCheck %s --check-prefix=NOMATMUL
+
+vsmmla.s8 q0, q1, q2
+// ARM: vsmmla.s8       q0, q1, q2      @ encoding: [0x44,0x0c,0x22,0xfc]
+// THUMB: vsmmla.s8       q0, q1, q2      @ encoding: [0x22,0xfc,0x44,0x0c]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
+
+vummla.u8 q0, q1, q2
+// ARM: vummla.u8       q0, q1, q2      @ encoding: [0x54,0x0c,0x22,0xfc]
+// THUMB: vummla.u8       q0, q1, q2      @ encoding: [0x22,0xfc,0x54,0x0c]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
+
+vusmmla.s8 q0, q1, q2
+// ARM: vusmmla.s8      q0, q1, q2      @ encoding: [0x44,0x0c,0xa2,0xfc]
+// THUMB: vusmmla.s8      q0, q1, q2      @ encoding: [0xa2,0xfc,0x44,0x0c]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
+
+vusdot.s8 d0, d1, d2
+// ARM: vusdot.s8       d0, d1, d2      @ encoding: [0x02,0x0d,0xa1,0xfc]
+// THUMB: vusdot.s8       d0, d1, d2      @ encoding: [0xa1,0xfc,0x02,0x0d]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
+
+vusdot.s8 q0, q1, q2
+// ARM: vusdot.s8       q0, q1, q2      @ encoding: [0x44,0x0d,0xa2,0xfc]
+// THUMB: vusdot.s8       q0, q1, q2      @ encoding: [0xa2,0xfc,0x44,0x0d]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
+
+vusdot.s8 d0, d1, d2[0]
+// ARM: vusdot.s8       d0, d1, d2[0]   @ encoding: [0x02,0x0d,0x81,0xfe]
+// THUMB: vusdot.s8       d0, d1, d2[0]   @ encoding: [0x81,0xfe,0x02,0x0d]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
+
+vsudot.u8 d0, d1, d2[1]
+// ARM: vsudot.u8       d0, d1, d2[1]   @ encoding: [0x32,0x0d,0x81,0xfe]
+// THUMB: vsudot.u8       d0, d1, d2[1]   @ encoding: [0x81,0xfe,0x32,0x0d]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
+
+vusdot.s8 q0, q1, d2[0]
+// ARM: vusdot.s8       q0, q1, d2[0]   @ encoding: [0x42,0x0d,0x82,0xfe]
+// THUMB: vusdot.s8       q0, q1, d2[0]   @ encoding: [0x82,0xfe,0x42,0x0d]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
+
+vsudot.u8 q0, q1, d2[1]
+// ARM: vsudot.u8       q0, q1, d2[1]   @ encoding: [0x72,0x0d,0x82,0xfe]
+// THUMB: vsudot.u8       q0, q1, d2[1]   @ encoding: [0x82,0xfe,0x72,0x0d]
+// NOMATMUL: [[@LINE-3]]:{{[0-9]+}}: error: instruction requires: 8-bit integer matrix multiply
diff --git a/llvm/test/MC/Disassembler/ARM/armv8.6a-matmul-arm.txt b/llvm/test/MC/Disassembler/ARM/armv8.6a-matmul-arm.txt
new file mode 100644 (file)
index 0000000..a92cfc9
--- /dev/null
@@ -0,0 +1,38 @@
+# RUN:     llvm-mc -triple=armv8 -mattr=+i8mm  -disassemble < %s      | FileCheck %s
+# RUN: not llvm-mc -triple=armv8 -mattr=+v8.4a -disassemble < %s 2>&1 | FileCheck %s --check-prefix=NOMATMUL
+
+[0x44,0x0c,0x22,0xfc]
+# CHECK: vsmmla.s8 q0, q1, q2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x54,0x0c,0x22,0xfc]
+# CHECK: vummla.u8 q0, q1, q2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x44,0x0c,0xa2,0xfc]
+# CHECK: vusmmla.s8 q0, q1, q2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x02,0x0d,0xa1,0xfc]
+# CHECK: vusdot.s8 d0, d1, d2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x44,0x0d,0xa2,0xfc]
+# CHECK: vusdot.s8 q0, q1, q2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x02,0x0d,0x81,0xfe]
+# CHECK: vusdot.s8 d0, d1, d2[0]
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x32,0x0d,0x81,0xfe]
+# CHECK: vsudot.u8 d0, d1, d2[1]
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x42,0x0d,0x82,0xfe]
+# CHECK: vusdot.s8 q0, q1, d2[0]
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x72,0x0d,0x82,0xfe]
+# CHECK: vsudot.u8 q0, q1, d2[1]
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
diff --git a/llvm/test/MC/Disassembler/ARM/armv8.6a-matmul-thumb.txt b/llvm/test/MC/Disassembler/ARM/armv8.6a-matmul-thumb.txt
new file mode 100644 (file)
index 0000000..d768e53
--- /dev/null
@@ -0,0 +1,38 @@
+# RUN:     llvm-mc -triple=thumbv8a -mattr=+i8mm  -disassemble < %s      | FileCheck %s
+# RUN: not llvm-mc -triple=thumbv8a -mattr=+v8.4a -disassemble < %s 2>&1 | FileCheck %s --check-prefix=NOMATMUL
+
+[0x22,0xfc,0x44,0x0c]
+# CHECK: vsmmla.s8 q0, q1, q2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x22,0xfc,0x54,0x0c]
+# CHECK: vummla.u8 q0, q1, q2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0xa2,0xfc,0x44,0x0c]
+# CHECK: vusmmla.s8 q0, q1, q2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0xa1,0xfc,0x02,0x0d]
+# CHECK: vusdot.s8 d0, d1, d2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0xa2,0xfc,0x44,0x0d]
+# CHECK: vusdot.s8 q0, q1, q2
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x81,0xfe,0x02,0x0d]
+# CHECK: vusdot.s8 d0, d1, d2[0]
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x81,0xfe,0x32,0x0d]
+# CHECK: vsudot.u8 d0, d1, d2[1]
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x82,0xfe,0x42,0x0d]
+# CHECK: vusdot.s8 q0, q1, d2[0]
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding
+
+[0x82,0xfe,0x72,0x0d]
+# CHECK: vsudot.u8 q0, q1, d2[1]
+# NOMATMUL: :[[@LINE-2]]:{{[0-9]+}}: warning: invalid instruction encoding