-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[LLVM][AArch64] Add assembly/disassembly for MUL/BFMUL SME instructions #113535
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
Conversation
@llvm/pr-subscribers-backend-aarch64 Author: None (CarolineConcatto) ChangesAccording to https://developer.arm.com/documentation/ddi0602 Co-authored-by: Momchil-Velikov [email protected] Patch is 32.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113535.diff 7 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 2262ad1dfd0cc9..56ffa10774047f 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -73,8 +73,13 @@ def SVEUnsupported : AArch64Unsupported {
SVE2Unsupported.F);
}
-let F = [HasSME2p1, HasSVE2p1_or_HasSME2p1, HasSVE2p1orSSVE_AES] in
-def SME2p1Unsupported : AArch64Unsupported;
+let F = [HasSME2p2] in
+def SME2p2Unsupported : AArch64Unsupported;
+
+def SME2p1Unsupported : AArch64Unsupported {
+ let F = !listconcat([HasSME2p1, HasSVE2p1_or_HasSME2p1, HasSVE2p1orSSVE_AES],
+ SME2p2Unsupported.F);
+}
def SME2Unsupported : AArch64Unsupported {
let F = !listconcat([HasSME2, HasSVE2orSME2, HasSVE2p1_or_HasSME2, HasSSVE_FP8FMA,
diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index 6044b5bb7d8151..5c20f23160ea36 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -1004,6 +1004,11 @@ let Predicates = [HasSME2p2] in {
def FTMOPA_M2ZZZI_HtoS : sme_tmopa_32b<0b11000, ZZ_h_mul_r, ZPR16, "ftmopa">;
def FTMOPA_M2ZZZI_StoS : sme_tmopa_32b<0b00000, ZZ_s_mul_r, ZPR32, "ftmopa">;
def BFTMOPA_M2ZZZI_HtoS : sme_tmopa_32b<0b10000, ZZ_h_mul_r, ZPR16, "bftmopa">;
+
+ defm FMUL_2ZZ : sme2_multi2_fmul_sm<"fmul">;
+ defm FMUL_2Z2Z : sme2_multi2_fmul_mm< "fmul">;
+ defm FMUL_4ZZ : sme2_multi4_fmul_sm<"fmul">;
+ defm FMUL_4Z4Z : sme2_multi4_fmul_mm< "fmul">;
} // [HasSME2p2]
let Predicates = [HasSME2p2, HasSMEB16B16] in {
@@ -1021,3 +1026,8 @@ let Predicates = [HasSME2p2, HasSMEF8F16], Uses = [FPMR, FPCR] in {
let Predicates = [HasSME2p2, HasSMEF16F16] in {
def FTMOPA_M2ZZZI_HtoH : sme_tmopa_16b<0b10001, ZZ_h_mul_r, ZPR16, "ftmopa">;
} // [HasSME2p2, HasSMEF16F16]
+
+let Predicates = [HasSME2, HasSVEBFSCALE] in {
+ defm BFMUL : sme2_bfmul_single<"bfmul">;
+ defm BFMUL : sme2_bfmul_multi<"bfmul">;
+} //[HasSME2, HasSVEBFSCALE]
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 08929ed5616b2c..febb956e06982c 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -5188,3 +5188,113 @@ class sme2_luti4_vector_vg4_strided<bits<2> sz, bits<2> op, string mnemonic>
let Inst{3-2} = 0b00;
let Inst{1-0} = Zd{1-0};
}
+
+class sme2_multi2_fmul_sm<bits<2> size, string mnemonic, RegisterOperand vector_ty, RegisterOperand zpr_ty>
+ : I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, zpr_ty:$Zm),
+ mnemonic, "\t$Zd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<4> Zd;
+ bits<4> Zn;
+ bits<4> Zm;
+
+ let Inst{31-24} = 0b11000001;
+ let Inst{23-22} = size;
+ let Inst{21} = 0b1;
+ let Inst{20-17} = Zm;
+ let Inst{16-10} = 0b0111010;
+ let Inst{9-6} = Zn;
+ let Inst{5} = 0b0;
+ let Inst{4-1} = Zd;
+ let Inst{0} = 0b0;
+}
+
+multiclass sme2_multi2_fmul_sm<string mnemonic> {
+ def _H : sme2_multi2_fmul_sm<0b01, mnemonic, ZZ_h_mul_r, ZPR4b16>;
+ def _S : sme2_multi2_fmul_sm<0b10, mnemonic, ZZ_s_mul_r, ZPR4b32>;
+ def _D : sme2_multi2_fmul_sm<0b11, mnemonic, ZZ_d_mul_r, ZPR4b64>;
+}
+
+class sme2_multi4_fmul_sm<bits<2> size, string mnemonic, RegisterOperand vector_ty, RegisterOperand zpr_ty>
+ : I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, zpr_ty:$Zm),
+ mnemonic, "\t$Zd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<3> Zd;
+ bits<3> Zn;
+ bits<4> Zm;
+
+ let Inst{31-24} = 0b11000001;
+ let Inst{23-22} = size;
+ let Inst{21} = 0b1;
+ let Inst{20-17} = Zm;
+ let Inst{16-10} = 0b1111010;
+ let Inst{9-7} = Zn;
+ let Inst{6-5} = 0b00;
+ let Inst{4-2} = Zd;
+ let Inst{1-0} = 0b00;
+}
+
+multiclass sme2_multi4_fmul_sm<string mnemonic> {
+ def _H : sme2_multi4_fmul_sm<0b01, mnemonic, ZZZZ_h_mul_r, ZPR4b16>;
+ def _S : sme2_multi4_fmul_sm<0b10, mnemonic, ZZZZ_s_mul_r, ZPR4b32>;
+ def _D : sme2_multi4_fmul_sm<0b11, mnemonic, ZZZZ_d_mul_r, ZPR4b64>;
+}
+
+multiclass sme2_bfmul_single<string mnemonic> {
+ def _2ZZ : sme2_multi2_fmul_sm<0b00, mnemonic, ZZ_h_mul_r, ZPR4b16>;
+ def _4ZZ : sme2_multi4_fmul_sm<0b00, mnemonic, ZZZZ_h_mul_r, ZPR4b16>;
+}
+
+class sme2_multi2_fmul_mm<bits<2> size, string mnemonic, RegisterOperand vector_ty>
+ : I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, vector_ty:$Zm),
+ mnemonic, "\t$Zd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<4> Zd;
+ bits<4> Zn;
+ bits<4> Zm;
+
+ let Inst{31-24} = 0b11000001;
+ let Inst{23-22} = size;
+ let Inst{21} = 0b1;
+ let Inst{20-17} = Zm;
+ let Inst{16-10} = 0b0111001;
+ let Inst{9-6} = Zn;
+ let Inst{5} = 0b0;
+ let Inst{4-1} = Zd;
+ let Inst{0} = 0b0;
+}
+
+multiclass sme2_multi2_fmul_mm<string mnemonic> {
+ def _H : sme2_multi2_fmul_mm<0b01, mnemonic, ZZ_h_mul_r>;
+ def _S : sme2_multi2_fmul_mm<0b10, mnemonic, ZZ_s_mul_r>;
+ def _D : sme2_multi2_fmul_mm<0b11, mnemonic, ZZ_d_mul_r>;
+}
+
+class sme2_multi4_fmul_mm<bits<2> size, string mnemonic, RegisterOperand vector_ty>
+ : I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, vector_ty:$Zm),
+ mnemonic, "\t$Zd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<3> Zd;
+ bits<3> Zn;
+ bits<3> Zm;
+
+ let Inst{31-24} = 0b11000001;
+ let Inst{23-22} = size;
+ let Inst{21} = 0b1;
+ let Inst{20-18} = Zm;
+ let Inst{17-10} = 0b01111001;
+ let Inst{9-7} = Zn;
+ let Inst{6-5} = 0b00;
+ let Inst{4-2} = Zd;
+ let Inst{1-0} = 0b00;
+}
+
+multiclass sme2_multi4_fmul_mm<string mnemonic> {
+ def _H : sme2_multi4_fmul_mm<0b01, mnemonic, ZZZZ_h_mul_r>;
+ def _S : sme2_multi4_fmul_mm<0b10, mnemonic, ZZZZ_s_mul_r>;
+ def _D : sme2_multi4_fmul_mm<0b11, mnemonic, ZZZZ_d_mul_r>;
+}
+
+multiclass sme2_bfmul_multi<string mnemonic> {
+ def _2Z2Z : sme2_multi2_fmul_mm<0b00, mnemonic, ZZ_h_mul_r>;
+ def _4Z4Z : sme2_multi4_fmul_mm<0b00, mnemonic, ZZZZ_h_mul_r>;
+}
diff --git a/llvm/test/MC/AArch64/SME2/bfmul-diagnostics.s b/llvm/test/MC/AArch64/SME2/bfmul-diagnostics.s
new file mode 100644
index 00000000000000..c28cc5cd426dda
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/bfmul-diagnostics.s
@@ -0,0 +1,111 @@
+// RUN: not llvm-mc -triple=aarch64 -mattr=+sme2,+sve-bfscale 2>&1 < %s| FileCheck %s
+
+// Multiple and single, 2 regs
+
+bfmul {z0.s-z1.s}, {z0.h-z1.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z1.h-z2.h}, {z0.h-z1.h}, z0.h
+// 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
+
+bfmul {z0.h-z2.h}, {z0.h-z1.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.s-z1.s}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z1.h-z2.h}, z0.h
+// 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
+
+bfmul {z0.h-z1.h}, {z0.h-z2.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+// Multiple and single, 4 regs
+
+bfmul {z0.s-z3.s}, {z0.h-z3.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z1.h-z4.h}, {z0.h-z3.h}, z0.h
+// 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
+
+bfmul {z0.h-z4.h}, {z0.h-z3.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+bfmul {z0.h-z3.h}, {z0.s-z3.s}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z3.h}, {z1.h-z4.h}, z0.h
+// 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
+
+bfmul {z0.h-z3.h}, {z0.h-z4.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+// Multiple, 2 regs
+
+bfmul {z0.s-z1.s}, {z0.h-z1.h}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z1.h-z2.h}, {z0.h-z1.h}, {z0.h-z1.h}
+// 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
+
+bfmul {z0.h-z2.h}, {z0.h-z1.h}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.s-z1.s}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z1.h-z2.h}, {z0.h-z1.h}
+// 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
+
+bfmul {z0.h-z1.h}, {z0.h-z2.h}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.s-z1.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z1.h-z2.h}
+// 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
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z2.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+// Multiple, 4 regs
+
+bfmul {z0.s-z3.s}, {z0.h-z3.h}, {z0.h-z3.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z1.h-z4.h}, {z0.h-z3.h}, {z0.h-z3.h}
+// 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
+
+bfmul {z0.h-z4.h}, {z0.h-z3.h}, {z0.h-z3.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+bfmul {z0.h-z3.h}, {z0.s-z3.s}, {z0.h-z3.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z3.h}, {z1.h-z4.h}, {z0.h-z3.h}
+// 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
+
+bfmul {z0.h-z3.h}, {z0.h-z4.h}, {z0.h-z3.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.s-z3.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z1.h-z4.h}
+// 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
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z4.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
diff --git a/llvm/test/MC/AArch64/SME2/bfmul.s b/llvm/test/MC/AArch64/SME2/bfmul.s
new file mode 100644
index 00000000000000..10a43848c73819
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/bfmul.s
@@ -0,0 +1,92 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+sve-bfscale < %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,+sve-bfscale < %s \
+// RUN: | llvm-objdump -d --mattr=+sme2,+sve-bfscale - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2,+sve-bfscale < %s \
+// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+sve-bfscale < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2,+sve-bfscale -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// Multiple and single, 2 regs
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, z0.h // 11000001-00100000-11101000-00000000
+// CHECK-INST: bfmul { z0.h, z1.h }, { z0.h, z1.h }, z0.h
+// CHECK-ENCODING: [0x00,0xe8,0x20,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c120e800 <unknown>
+
+bfmul {z20.h-z21.h}, {z10.h-z11.h}, z10.h // 11000001-00110100-11101001-01010100
+// CHECK-INST: bfmul { z20.h, z21.h }, { z10.h, z11.h }, z10.h
+// CHECK-ENCODING: [0x54,0xe9,0x34,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c134e954 <unknown>
+
+bfmul {z30.h-z31.h}, {z30.h-z31.h}, z15.h // 11000001-00111110-11101011-11011110
+// CHECK-INST: bfmul { z30.h, z31.h }, { z30.h, z31.h }, z15.h
+// CHECK-ENCODING: [0xde,0xeb,0x3e,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c13eebde <unknown>
+
+// Multiple and single, 4 regs
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, z0.h // 11000001-00100001-11101000-00000000
+// CHECK-INST: bfmul { z0.h - z3.h }, { z0.h - z3.h }, z0.h
+// CHECK-ENCODING: [0x00,0xe8,0x21,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c121e800 <unknown>
+
+bfmul {z20.h-z23.h}, {z8.h-z11.h}, z10.h // 11000001-00110101-11101001-00010100
+// CHECK-INST: bfmul { z20.h - z23.h }, { z8.h - z11.h }, z10.h
+// CHECK-ENCODING: [0x14,0xe9,0x35,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c135e914 <unknown>
+
+bfmul {z28.h-z31.h}, {z28.h-z31.h}, z15.h // 11000001-00111111-11101011-10011100
+// CHECK-INST: bfmul { z28.h - z31.h }, { z28.h - z31.h }, z15.h
+// CHECK-ENCODING: [0x9c,0xeb,0x3f,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c13feb9c <unknown>
+
+// Multiple, 2 regs
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h} // 11000001-00100000-11100100-00000000
+// CHECK-INST: bfmul { z0.h, z1.h }, { z0.h, z1.h }, { z0.h, z1.h }
+// CHECK-ENCODING: [0x00,0xe4,0x20,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c120e400 <unknown>
+
+bfmul {z20.h-z21.h}, {z10.h-z11.h}, {z20.h-z21.h} // 11000001-00110100-11100101-01010100
+// CHECK-INST: bfmul { z20.h, z21.h }, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x54,0xe5,0x34,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c134e554 <unknown>
+
+bfmul {z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.h} // 11000001-00111110-11100111-11011110
+// CHECK-INST: bfmul { z30.h, z31.h }, { z30.h, z31.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xde,0xe7,0x3e,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c13ee7de <unknown>
+
+// Multiple, 4 regs
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h} // 11000001-00100001-11100100-00000000
+// CHECK-INST: bfmul { z0.h - z3.h }, { z0.h - z3.h }, { z0.h - z3.h }
+// CHECK-ENCODING: [0x00,0xe4,0x21,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c121e400 <unknown>
+
+bfmul {z20.h-z23.h}, {z8.h-z11.h}, {z20.h-z23.h} // 11000001-00110101-11100101-00010100
+// CHECK-INST: bfmul { z20.h - z23.h }, { z8.h - z11.h }, { z20.h - z23.h }
+// CHECK-ENCODING: [0x14,0xe5,0x35,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c135e514 <unknown>
+
+bfmul {z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.h} // 11000001-00111101-11100111-10011100
+// CHECK-INST: bfmul { z28.h - z31.h }, { z28.h - z31.h }, { z28.h - z31.h }
+// CHECK-ENCODING: [0x9c,0xe7,0x3d,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c13de79c <unknown>
diff --git a/llvm/test/MC/AArch64/SME2/fmul-diagnostics.s b/llvm/test/MC/AArch64/SME2/fmul-diagnostics.s
new file mode 100644
index 00000000000000..2fdd3f82adc1dd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/fmul-diagnostics.s
@@ -0,0 +1,112 @@
+
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 2>&1 < %s| FileCheck %s
+
+// Multiple and single, 2 regs
+
+fmul {z0.b-z1.b}, {z0.h-z1.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z1.s-z2.s}, {z0.s-z1.s}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+fmul {z0.d-z2.d}, {z0.d-z1.d}, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.h-z1.h}, {z0.b-z1.b}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.s-z1.s}, {z1.s-z2.s}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+fmul {z0.d-z1.d}, {z0.d-z2.d}, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.h-z1.h}, {z0.h-z1.h}, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+fmul {z0.s-z1.s}, {z0.s-z1.s}, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.s..z15.s
+
+// Multiple and single, 4 regs
+
+fmul {z0.b-z3.b}, {z0.h-z3.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z1.s-z3.s}, {z0.h-z3.h}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.d-z4.d}, {z0.d-z3.d}, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+fmul {z0.h-z3.h}, {z0.b-z3.b}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.s-z3.s}, {z1.s-z3.s}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.d-z3.d}, {z0.d-z4.d}, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+fmul {z0.h-z3.h}, {z0.h-z3.h}, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+fmul {z0.s-z3.s}, {z0.s-z3.s}, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.s..z15.s
+
+// Multiple, 2 regs
+
+fmul {z0.b-z1.b}, {z0.h-z1.h}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z1.s-z2.s}, {z0.s-z1.s}, {z0.s-z1.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+fmul {z0.d-z2.d}, {z0.d-z1.d}, {z0.d-z1.d}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.h-z1.h}, {z0.b-z1.b}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.s-z1.s}, {z1.s-z2.s}, {z0.s-z1.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+fmul {z0.d-z1.d}, {z0.d-z2.d}, {z0.d-z1.d}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.b-z1.b}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.s-z1.s}, {z0.s-z1.s}, {z1.s-z2.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+...
[truncated]
|
@llvm/pr-subscribers-mc Author: None (CarolineConcatto) ChangesAccording to https://developer.arm.com/documentation/ddi0602 Co-authored-by: Momchil-Velikov [email protected] Patch is 32.76 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/113535.diff 7 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64.td b/llvm/lib/Target/AArch64/AArch64.td
index 2262ad1dfd0cc9..56ffa10774047f 100644
--- a/llvm/lib/Target/AArch64/AArch64.td
+++ b/llvm/lib/Target/AArch64/AArch64.td
@@ -73,8 +73,13 @@ def SVEUnsupported : AArch64Unsupported {
SVE2Unsupported.F);
}
-let F = [HasSME2p1, HasSVE2p1_or_HasSME2p1, HasSVE2p1orSSVE_AES] in
-def SME2p1Unsupported : AArch64Unsupported;
+let F = [HasSME2p2] in
+def SME2p2Unsupported : AArch64Unsupported;
+
+def SME2p1Unsupported : AArch64Unsupported {
+ let F = !listconcat([HasSME2p1, HasSVE2p1_or_HasSME2p1, HasSVE2p1orSSVE_AES],
+ SME2p2Unsupported.F);
+}
def SME2Unsupported : AArch64Unsupported {
let F = !listconcat([HasSME2, HasSVE2orSME2, HasSVE2p1_or_HasSME2, HasSSVE_FP8FMA,
diff --git a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
index 6044b5bb7d8151..5c20f23160ea36 100644
--- a/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
+++ b/llvm/lib/Target/AArch64/AArch64SMEInstrInfo.td
@@ -1004,6 +1004,11 @@ let Predicates = [HasSME2p2] in {
def FTMOPA_M2ZZZI_HtoS : sme_tmopa_32b<0b11000, ZZ_h_mul_r, ZPR16, "ftmopa">;
def FTMOPA_M2ZZZI_StoS : sme_tmopa_32b<0b00000, ZZ_s_mul_r, ZPR32, "ftmopa">;
def BFTMOPA_M2ZZZI_HtoS : sme_tmopa_32b<0b10000, ZZ_h_mul_r, ZPR16, "bftmopa">;
+
+ defm FMUL_2ZZ : sme2_multi2_fmul_sm<"fmul">;
+ defm FMUL_2Z2Z : sme2_multi2_fmul_mm< "fmul">;
+ defm FMUL_4ZZ : sme2_multi4_fmul_sm<"fmul">;
+ defm FMUL_4Z4Z : sme2_multi4_fmul_mm< "fmul">;
} // [HasSME2p2]
let Predicates = [HasSME2p2, HasSMEB16B16] in {
@@ -1021,3 +1026,8 @@ let Predicates = [HasSME2p2, HasSMEF8F16], Uses = [FPMR, FPCR] in {
let Predicates = [HasSME2p2, HasSMEF16F16] in {
def FTMOPA_M2ZZZI_HtoH : sme_tmopa_16b<0b10001, ZZ_h_mul_r, ZPR16, "ftmopa">;
} // [HasSME2p2, HasSMEF16F16]
+
+let Predicates = [HasSME2, HasSVEBFSCALE] in {
+ defm BFMUL : sme2_bfmul_single<"bfmul">;
+ defm BFMUL : sme2_bfmul_multi<"bfmul">;
+} //[HasSME2, HasSVEBFSCALE]
diff --git a/llvm/lib/Target/AArch64/SMEInstrFormats.td b/llvm/lib/Target/AArch64/SMEInstrFormats.td
index 08929ed5616b2c..febb956e06982c 100644
--- a/llvm/lib/Target/AArch64/SMEInstrFormats.td
+++ b/llvm/lib/Target/AArch64/SMEInstrFormats.td
@@ -5188,3 +5188,113 @@ class sme2_luti4_vector_vg4_strided<bits<2> sz, bits<2> op, string mnemonic>
let Inst{3-2} = 0b00;
let Inst{1-0} = Zd{1-0};
}
+
+class sme2_multi2_fmul_sm<bits<2> size, string mnemonic, RegisterOperand vector_ty, RegisterOperand zpr_ty>
+ : I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, zpr_ty:$Zm),
+ mnemonic, "\t$Zd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<4> Zd;
+ bits<4> Zn;
+ bits<4> Zm;
+
+ let Inst{31-24} = 0b11000001;
+ let Inst{23-22} = size;
+ let Inst{21} = 0b1;
+ let Inst{20-17} = Zm;
+ let Inst{16-10} = 0b0111010;
+ let Inst{9-6} = Zn;
+ let Inst{5} = 0b0;
+ let Inst{4-1} = Zd;
+ let Inst{0} = 0b0;
+}
+
+multiclass sme2_multi2_fmul_sm<string mnemonic> {
+ def _H : sme2_multi2_fmul_sm<0b01, mnemonic, ZZ_h_mul_r, ZPR4b16>;
+ def _S : sme2_multi2_fmul_sm<0b10, mnemonic, ZZ_s_mul_r, ZPR4b32>;
+ def _D : sme2_multi2_fmul_sm<0b11, mnemonic, ZZ_d_mul_r, ZPR4b64>;
+}
+
+class sme2_multi4_fmul_sm<bits<2> size, string mnemonic, RegisterOperand vector_ty, RegisterOperand zpr_ty>
+ : I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, zpr_ty:$Zm),
+ mnemonic, "\t$Zd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<3> Zd;
+ bits<3> Zn;
+ bits<4> Zm;
+
+ let Inst{31-24} = 0b11000001;
+ let Inst{23-22} = size;
+ let Inst{21} = 0b1;
+ let Inst{20-17} = Zm;
+ let Inst{16-10} = 0b1111010;
+ let Inst{9-7} = Zn;
+ let Inst{6-5} = 0b00;
+ let Inst{4-2} = Zd;
+ let Inst{1-0} = 0b00;
+}
+
+multiclass sme2_multi4_fmul_sm<string mnemonic> {
+ def _H : sme2_multi4_fmul_sm<0b01, mnemonic, ZZZZ_h_mul_r, ZPR4b16>;
+ def _S : sme2_multi4_fmul_sm<0b10, mnemonic, ZZZZ_s_mul_r, ZPR4b32>;
+ def _D : sme2_multi4_fmul_sm<0b11, mnemonic, ZZZZ_d_mul_r, ZPR4b64>;
+}
+
+multiclass sme2_bfmul_single<string mnemonic> {
+ def _2ZZ : sme2_multi2_fmul_sm<0b00, mnemonic, ZZ_h_mul_r, ZPR4b16>;
+ def _4ZZ : sme2_multi4_fmul_sm<0b00, mnemonic, ZZZZ_h_mul_r, ZPR4b16>;
+}
+
+class sme2_multi2_fmul_mm<bits<2> size, string mnemonic, RegisterOperand vector_ty>
+ : I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, vector_ty:$Zm),
+ mnemonic, "\t$Zd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<4> Zd;
+ bits<4> Zn;
+ bits<4> Zm;
+
+ let Inst{31-24} = 0b11000001;
+ let Inst{23-22} = size;
+ let Inst{21} = 0b1;
+ let Inst{20-17} = Zm;
+ let Inst{16-10} = 0b0111001;
+ let Inst{9-6} = Zn;
+ let Inst{5} = 0b0;
+ let Inst{4-1} = Zd;
+ let Inst{0} = 0b0;
+}
+
+multiclass sme2_multi2_fmul_mm<string mnemonic> {
+ def _H : sme2_multi2_fmul_mm<0b01, mnemonic, ZZ_h_mul_r>;
+ def _S : sme2_multi2_fmul_mm<0b10, mnemonic, ZZ_s_mul_r>;
+ def _D : sme2_multi2_fmul_mm<0b11, mnemonic, ZZ_d_mul_r>;
+}
+
+class sme2_multi4_fmul_mm<bits<2> size, string mnemonic, RegisterOperand vector_ty>
+ : I<(outs vector_ty:$Zd), (ins vector_ty:$Zn, vector_ty:$Zm),
+ mnemonic, "\t$Zd, $Zn, $Zm",
+ "", []>, Sched<[]> {
+ bits<3> Zd;
+ bits<3> Zn;
+ bits<3> Zm;
+
+ let Inst{31-24} = 0b11000001;
+ let Inst{23-22} = size;
+ let Inst{21} = 0b1;
+ let Inst{20-18} = Zm;
+ let Inst{17-10} = 0b01111001;
+ let Inst{9-7} = Zn;
+ let Inst{6-5} = 0b00;
+ let Inst{4-2} = Zd;
+ let Inst{1-0} = 0b00;
+}
+
+multiclass sme2_multi4_fmul_mm<string mnemonic> {
+ def _H : sme2_multi4_fmul_mm<0b01, mnemonic, ZZZZ_h_mul_r>;
+ def _S : sme2_multi4_fmul_mm<0b10, mnemonic, ZZZZ_s_mul_r>;
+ def _D : sme2_multi4_fmul_mm<0b11, mnemonic, ZZZZ_d_mul_r>;
+}
+
+multiclass sme2_bfmul_multi<string mnemonic> {
+ def _2Z2Z : sme2_multi2_fmul_mm<0b00, mnemonic, ZZ_h_mul_r>;
+ def _4Z4Z : sme2_multi4_fmul_mm<0b00, mnemonic, ZZZZ_h_mul_r>;
+}
diff --git a/llvm/test/MC/AArch64/SME2/bfmul-diagnostics.s b/llvm/test/MC/AArch64/SME2/bfmul-diagnostics.s
new file mode 100644
index 00000000000000..c28cc5cd426dda
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/bfmul-diagnostics.s
@@ -0,0 +1,111 @@
+// RUN: not llvm-mc -triple=aarch64 -mattr=+sme2,+sve-bfscale 2>&1 < %s| FileCheck %s
+
+// Multiple and single, 2 regs
+
+bfmul {z0.s-z1.s}, {z0.h-z1.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z1.h-z2.h}, {z0.h-z1.h}, z0.h
+// 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
+
+bfmul {z0.h-z2.h}, {z0.h-z1.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.s-z1.s}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z1.h-z2.h}, z0.h
+// 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
+
+bfmul {z0.h-z1.h}, {z0.h-z2.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+// Multiple and single, 4 regs
+
+bfmul {z0.s-z3.s}, {z0.h-z3.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z1.h-z4.h}, {z0.h-z3.h}, z0.h
+// 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
+
+bfmul {z0.h-z4.h}, {z0.h-z3.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+bfmul {z0.h-z3.h}, {z0.s-z3.s}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z3.h}, {z1.h-z4.h}, z0.h
+// 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
+
+bfmul {z0.h-z3.h}, {z0.h-z4.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, z16.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+// Multiple, 2 regs
+
+bfmul {z0.s-z1.s}, {z0.h-z1.h}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z1.h-z2.h}, {z0.h-z1.h}, {z0.h-z1.h}
+// 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
+
+bfmul {z0.h-z2.h}, {z0.h-z1.h}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.s-z1.s}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z1.h-z2.h}, {z0.h-z1.h}
+// 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
+
+bfmul {z0.h-z1.h}, {z0.h-z2.h}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.s-z1.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z1.h-z2.h}
+// 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
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z2.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+// Multiple, 4 regs
+
+bfmul {z0.s-z3.s}, {z0.h-z3.h}, {z0.h-z3.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z1.h-z4.h}, {z0.h-z3.h}, {z0.h-z3.h}
+// 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
+
+bfmul {z0.h-z4.h}, {z0.h-z3.h}, {z0.h-z3.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+bfmul {z0.h-z3.h}, {z0.s-z3.s}, {z0.h-z3.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z3.h}, {z1.h-z4.h}, {z0.h-z3.h}
+// 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
+
+bfmul {z0.h-z3.h}, {z0.h-z4.h}, {z0.h-z3.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.s-z3.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z1.h-z4.h}
+// 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
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z4.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
diff --git a/llvm/test/MC/AArch64/SME2/bfmul.s b/llvm/test/MC/AArch64/SME2/bfmul.s
new file mode 100644
index 00000000000000..10a43848c73819
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/bfmul.s
@@ -0,0 +1,92 @@
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+sve-bfscale < %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,+sve-bfscale < %s \
+// RUN: | llvm-objdump -d --mattr=+sme2,+sve-bfscale - | FileCheck %s --check-prefix=CHECK-INST
+// RUN: llvm-mc -triple=aarch64 -filetype=obj -mattr=+sme2,+sve-bfscale < %s \
+// RUN: | llvm-objdump -d --mattr=-sme2 - | FileCheck %s --check-prefix=CHECK-UNKNOWN
+// Disassemble encoding and check the re-encoding (-show-encoding) matches.
+// RUN: llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2,+sve-bfscale < %s \
+// RUN: | sed '/.text/d' | sed 's/.*encoding: //g' \
+// RUN: | llvm-mc -triple=aarch64 -mattr=+sme2,+sve-bfscale -disassemble -show-encoding \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ENCODING,CHECK-INST
+
+// Multiple and single, 2 regs
+
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, z0.h // 11000001-00100000-11101000-00000000
+// CHECK-INST: bfmul { z0.h, z1.h }, { z0.h, z1.h }, z0.h
+// CHECK-ENCODING: [0x00,0xe8,0x20,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c120e800 <unknown>
+
+bfmul {z20.h-z21.h}, {z10.h-z11.h}, z10.h // 11000001-00110100-11101001-01010100
+// CHECK-INST: bfmul { z20.h, z21.h }, { z10.h, z11.h }, z10.h
+// CHECK-ENCODING: [0x54,0xe9,0x34,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c134e954 <unknown>
+
+bfmul {z30.h-z31.h}, {z30.h-z31.h}, z15.h // 11000001-00111110-11101011-11011110
+// CHECK-INST: bfmul { z30.h, z31.h }, { z30.h, z31.h }, z15.h
+// CHECK-ENCODING: [0xde,0xeb,0x3e,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c13eebde <unknown>
+
+// Multiple and single, 4 regs
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, z0.h // 11000001-00100001-11101000-00000000
+// CHECK-INST: bfmul { z0.h - z3.h }, { z0.h - z3.h }, z0.h
+// CHECK-ENCODING: [0x00,0xe8,0x21,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c121e800 <unknown>
+
+bfmul {z20.h-z23.h}, {z8.h-z11.h}, z10.h // 11000001-00110101-11101001-00010100
+// CHECK-INST: bfmul { z20.h - z23.h }, { z8.h - z11.h }, z10.h
+// CHECK-ENCODING: [0x14,0xe9,0x35,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c135e914 <unknown>
+
+bfmul {z28.h-z31.h}, {z28.h-z31.h}, z15.h // 11000001-00111111-11101011-10011100
+// CHECK-INST: bfmul { z28.h - z31.h }, { z28.h - z31.h }, z15.h
+// CHECK-ENCODING: [0x9c,0xeb,0x3f,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c13feb9c <unknown>
+
+// Multiple, 2 regs
+bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h} // 11000001-00100000-11100100-00000000
+// CHECK-INST: bfmul { z0.h, z1.h }, { z0.h, z1.h }, { z0.h, z1.h }
+// CHECK-ENCODING: [0x00,0xe4,0x20,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c120e400 <unknown>
+
+bfmul {z20.h-z21.h}, {z10.h-z11.h}, {z20.h-z21.h} // 11000001-00110100-11100101-01010100
+// CHECK-INST: bfmul { z20.h, z21.h }, { z10.h, z11.h }, { z20.h, z21.h }
+// CHECK-ENCODING: [0x54,0xe5,0x34,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c134e554 <unknown>
+
+bfmul {z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.h} // 11000001-00111110-11100111-11011110
+// CHECK-INST: bfmul { z30.h, z31.h }, { z30.h, z31.h }, { z30.h, z31.h }
+// CHECK-ENCODING: [0xde,0xe7,0x3e,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c13ee7de <unknown>
+
+// Multiple, 4 regs
+
+bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h} // 11000001-00100001-11100100-00000000
+// CHECK-INST: bfmul { z0.h - z3.h }, { z0.h - z3.h }, { z0.h - z3.h }
+// CHECK-ENCODING: [0x00,0xe4,0x21,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c121e400 <unknown>
+
+bfmul {z20.h-z23.h}, {z8.h-z11.h}, {z20.h-z23.h} // 11000001-00110101-11100101-00010100
+// CHECK-INST: bfmul { z20.h - z23.h }, { z8.h - z11.h }, { z20.h - z23.h }
+// CHECK-ENCODING: [0x14,0xe5,0x35,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c135e514 <unknown>
+
+bfmul {z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.h} // 11000001-00111101-11100111-10011100
+// CHECK-INST: bfmul { z28.h - z31.h }, { z28.h - z31.h }, { z28.h - z31.h }
+// CHECK-ENCODING: [0x9c,0xe7,0x3d,0xc1]
+// CHECK-ERROR: instruction requires: sme2 sve-bfscale
+// CHECK-UNKNOWN: c13de79c <unknown>
diff --git a/llvm/test/MC/AArch64/SME2/fmul-diagnostics.s b/llvm/test/MC/AArch64/SME2/fmul-diagnostics.s
new file mode 100644
index 00000000000000..2fdd3f82adc1dd
--- /dev/null
+++ b/llvm/test/MC/AArch64/SME2/fmul-diagnostics.s
@@ -0,0 +1,112 @@
+
+// RUN: not llvm-mc -triple=aarch64 -show-encoding -mattr=+sme2p2 2>&1 < %s| FileCheck %s
+
+// Multiple and single, 2 regs
+
+fmul {z0.b-z1.b}, {z0.h-z1.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z1.s-z2.s}, {z0.s-z1.s}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+fmul {z0.d-z2.d}, {z0.d-z1.d}, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.h-z1.h}, {z0.b-z1.b}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.s-z1.s}, {z1.s-z2.s}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+fmul {z0.d-z1.d}, {z0.d-z2.d}, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.h-z1.h}, {z0.h-z1.h}, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+fmul {z0.s-z1.s}, {z0.s-z1.s}, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.s..z15.s
+
+// Multiple and single, 4 regs
+
+fmul {z0.b-z3.b}, {z0.h-z3.h}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z1.s-z3.s}, {z0.h-z3.h}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.d-z4.d}, {z0.d-z3.d}, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+fmul {z0.h-z3.h}, {z0.b-z3.b}, z0.h
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.s-z3.s}, {z1.s-z3.s}, z0.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.d-z3.d}, {z0.d-z4.d}, z0.d
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid number of vectors
+
+fmul {z0.h-z3.h}, {z0.h-z3.h}, z0.b
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.h..z15.h
+
+fmul {z0.s-z3.s}, {z0.s-z3.s}, z16.s
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid restricted vector register, expected z0.s..z15.s
+
+// Multiple, 2 regs
+
+fmul {z0.b-z1.b}, {z0.h-z1.h}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z1.s-z2.s}, {z0.s-z1.s}, {z0.s-z1.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+fmul {z0.d-z2.d}, {z0.d-z1.d}, {z0.d-z1.d}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.h-z1.h}, {z0.b-z1.b}, {z0.h-z1.h}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.s-z1.s}, {z1.s-z2.s}, {z0.s-z1.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+fmul {z0.d-z1.d}, {z0.d-z2.d}, {z0.d-z1.d}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.b-z1.b}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: invalid operand for instruction
+
+fmul {z0.s-z1.s}, {z0.s-z1.s}, {z1.s-z2.s}
+// CHECK: [[@LINE-1]]:{{[0-9]+}}: error: Invalid vector list, expected list with 2 consecutive SVE vectors, where the first vector is a multiple of 2 and with matching element types
+
+...
[truncated]
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just a nit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
According to https://developer.arm.com/documentation/ddi0602 Co-authored-by: Momchil-Velikov [email protected]
683e8b4
to
000bac5
Compare
…ns (llvm#113535) According to https://developer.arm.com/documentation/ddi0602 Co-authored-by: Momchil-Velikov [email protected]
According to https://developer.arm.com/documentation/ddi0602
Co-authored-by: Momchil-Velikov [email protected]