[PATCH] aarch64: Support for FEAT_SVE_BFSCALE
Ezra.Sitorus@arm.com
Ezra.Sitorus@arm.com
Wed Jun 4 22:39:46 GMT 2025
From: Ezra Sitorus <ezra.sitorus@arm.com>
FEAT_SVE_BFSCALE introduces the SVE BFSCALE instruction, when the PE is not in
Streaming SVE mode. If FEAT_SME2 is implemented, FEAT_SVE_BFSCALE also
introduces SME multi-vector Z-targeting BFloat16 scaling instructions, BFSCALE
and BFMUL.
---
One thing to highlight is the name AARCH64_OPND_SME_Zmx1. I have picked
this even though it acts like a normal single Zm register just because
it uses 4 bits in [20:17], just like the Zmx2 and Zmx4 ones. The normal
Zm is [20:16] and uses 5 bits, so I thought calling it
AARCH64_OPND_SME_Zm_16 for example would not have been right as I would
naturally think it would be 5 bits too. Happy to take any feedback on
this.
Regression tested on aarch64-none-linux-gnu.
Ezra
gas/config/tc-aarch64.c | 2 +
.../gas/aarch64/sve-b16b16-sve2-bad-2.l | 4 +-
gas/testsuite/gas/aarch64/sve-bfscale-bad.d | 4 ++
gas/testsuite/gas/aarch64/sve-bfscale-bad.l | 24 ++++++++
gas/testsuite/gas/aarch64/sve-bfscale-bad.s | 25 +++++++++
.../gas/aarch64/sve-bfscale-sme2-bad.d | 4 ++
.../gas/aarch64/sve-bfscale-sme2-bad.l | 33 +++++++++++
gas/testsuite/gas/aarch64/sve-bfscale-sme2.d | 56 +++++++++++++++++++
gas/testsuite/gas/aarch64/sve-bfscale-sme2.s | 47 ++++++++++++++++
gas/testsuite/gas/aarch64/sve-bfscale.d | 18 ++++++
gas/testsuite/gas/aarch64/sve-bfscale.s | 9 +++
include/opcode/aarch64.h | 4 ++
opcodes/aarch64-opc.c | 2 +
opcodes/aarch64-tbl.h | 23 ++++++++
14 files changed, 253 insertions(+), 2 deletions(-)
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale-bad.d
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale-bad.l
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale-bad.s
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.d
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.l
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale-sme2.d
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale-sme2.s
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale.d
create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale.s
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index acb56044fb5..878065e9860 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -6823,6 +6823,7 @@ parse_operands (char *str, const aarch64_opcode *opcode)
case AARCH64_OPND_SVE_Zn:
case AARCH64_OPND_SVE_Zt:
case AARCH64_OPND_SME_Zm:
+ case AARCH64_OPND_SME_Zmx1:
reg_type = REG_TYPE_Z;
goto vector_reg;
@@ -10708,6 +10709,7 @@ static const struct aarch64_option_cpu_value_table aarch64_features[] = {
{"ite", AARCH64_FEATURE (ITE), AARCH64_NO_FEATURES},
{"d128", AARCH64_FEATURE (D128), D128_FEATURE_DEPS},
{"sve-b16b16", AARCH64_FEATURE (SVE_B16B16), AARCH64_NO_FEATURES},
+ {"sve-bfscale", AARCH64_FEATURE (SVE_BFSCALE), AARCH64_NO_FEATURES},
{"sme2p1", AARCH64_FEATURE (SME2p1), AARCH64_FEATURE (SME2)},
{"sve2p1", AARCH64_FEATURE (SVE2p1), AARCH64_FEATURE (SVE2)},
{"rcpc3", AARCH64_FEATURE (RCPC3), AARCH64_FEATURE (RCPC2)},
diff --git a/gas/testsuite/gas/aarch64/sve-b16b16-sve2-bad-2.l b/gas/testsuite/gas/aarch64/sve-b16b16-sve2-bad-2.l
index 83f00f55bd0..2ede0c95de7 100644
--- a/gas/testsuite/gas/aarch64/sve-b16b16-sve2-bad-2.l
+++ b/gas/testsuite/gas/aarch64/sve-b16b16-sve2-bad-2.l
@@ -237,8 +237,8 @@
.*: Error: operand mismatch -- `bfmul z31.b,z31.s,z31.d\[8\]'
.*: Info: did you mean this\?
.*: Info: bfmul z31.h, z31.h, z31.h\[8\]
-.*: Error: expected an SVE vector register at operand 1 -- `bfmul { ?z0.h ?},z0.h,z0.h\[1\]'
-.*: Error: expected an SVE vector register at operand 1 -- `bfmul { ?z0.h-z0.h ?},z0.h\[2\]'
+.*: Error: missing braces at operand 2 -- `bfmul { ?z0.h ?},z0.h,z0.h\[1\]'
+.*: Error: invalid range in vector register list at operand 1 -- `bfmul { ?z0.h-z0.h ?},z0.h\[2\]'
.*: Error: expected an SVE predicate register at operand 2 -- `bfmul z0.h,z0.h\[3\]'
.*: Error: operand mismatch -- `bfsub z0.b,z0.h,z0.h'
.*: Info: did you mean this\?
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale-bad.d b/gas/testsuite/gas/aarch64/sve-bfscale-bad.d
new file mode 100644
index 00000000000..297fb30ad71
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale-bad.d
@@ -0,0 +1,4 @@
+#name: Invalid SVE_BFSCALE instructions
+#as: -march=armv8-a+sve-bfscale+sme2
+#source: sve-bfscale-bad.s
+#error_output: sve-bfscale-bad.l
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale-bad.l b/gas/testsuite/gas/aarch64/sve-bfscale-bad.l
new file mode 100644
index 00000000000..52044c2e134
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale-bad.l
@@ -0,0 +1,24 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: operand 3 must be the same register as operand 1 -- `bfscale z0\.h,p0/m,z1\.h,z0\.h'
+[^ :]+:[0-9]+: Error: operand mismatch -- `bfscale z0\.h,p0/z,z0\.h,z0\.h'
+[^ :]+:[0-9]+: Info: did you mean this\?
+[^ :]+:[0-9]+: Info: bfscale z0\.h, p0/m, z0\.h, z0\.h
+[^ :]+:[0-9]+: Error: operand 2 must be the same register as operand 1 -- `bfscale { ?z0\.h-z1\.h ?},{ ?z0\.h-z2\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: expected a list of 2 or 4 registers at operand 1 -- `bfscale { ?z0\.h-z2\.h ?},{ ?z0\.h-z2\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: too many registers in vector register list at operand 1 -- `bfscale { ?z0\.h-z4\.h ?},{ ?z0\.h-z4\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: operand 2 must be the same register as operand 1 -- `bfscale { ?z0\.h-z1\.h ?},{ ?z0\.h-z2\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 2 or 4 registers at operand 1 -- `bfscale { ?z0\.h-z2\.h ?},{ ?z0\.h-z2\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: too many registers in vector register list at operand 1 -- `bfscale { ?z0\.h-z4\.h ?},{ ?z0\.h-z4\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 2 registers at operand 3 -- `bfscale { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},{ ?z0\.h-z2\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 4 registers at operand 3 -- `bfscale { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: too many registers in vector register list at operand 3 -- `bfscale { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},{ ?z0\.h-z4\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 2 registers at operand 2 -- `bfmul { ?z0\.h-z1\.h ?},{ ?z0\.h-z2\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: expected a list of 2 or 4 registers at operand 1 -- `bfmul { ?z0\.h-z2\.h ?},{ ?z0\.h-z1\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: expected a list of 4 registers at operand 2 -- `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z2\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: expected a list of 4 registers at operand 2 -- `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z1\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: expected a list of 2 registers at operand 2 -- `bfmul { ?z0\.h-z1\.h ?},{ ?z0\.h-z2\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 2 or 4 registers at operand 1 -- `bfmul { ?z0\.h-z2\.h ?},{ ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 4 registers at operand 2 -- `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z2\.h ?},{ ?z0\.h-z3\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 4 registers at operand 2 -- `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z1\.h ?},{ ?z0\.h-z3\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 2 registers at operand 3 -- `bfmul { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},{ ?z0\.h-z2\.h ?}'
+[^ :]+:[0-9]+: Error: expected a list of 4 registers at operand 3 -- `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},{ ?z0\.h-z2\.h ?}'
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale-bad.s b/gas/testsuite/gas/aarch64/sve-bfscale-bad.s
new file mode 100644
index 00000000000..b137a67b71b
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale-bad.s
@@ -0,0 +1,25 @@
+bfscale:
+ bfscale z0.h, p0/m, z1.h, z0.h
+ bfscale z0.h, p0/z, z0.h, z0.h
+ bfscale {z0.h-z1.h}, {z0.h-z2.h}, z0.h
+ bfscale {z0.h-z2.h}, {z0.h-z2.h}, z0.h
+ bfscale {z0.h-z4.h}, {z0.h-z4.h}, z0.h
+ bfscale {z0.h-z1.h}, {z0.h-z2.h}, {z0.h-z1.h}
+ bfscale {z0.h-z2.h}, {z0.h-z2.h}, {z0.h-z1.h}
+ bfscale {z0.h-z4.h}, {z0.h-z4.h}, {z0.h-z1.h}
+ bfscale {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z2.h}
+ bfscale {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z1.h}
+ bfscale {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z4.h}
+
+bfmul:
+ bfmul {z0.h-z1.h}, {z0.h-z2.h}, z0.h
+ bfmul {z0.h-z2.h}, {z0.h-z1.h}, z0.h
+ bfmul {z0.h-z3.h}, {z0.h-z2.h}, z0.h
+ bfmul {z0.h-z3.h}, {z0.h-z1.h}, z0.h
+ bfmul {z0.h-z1.h}, {z0.h-z2.h}, {z0.h-z1.h}
+ bfmul {z0.h-z2.h}, {z0.h-z1.h}, {z0.h-z1.h}
+ bfmul {z0.h-z3.h}, {z0.h-z2.h}, {z0.h-z3.h}
+ bfmul {z0.h-z3.h}, {z0.h-z1.h}, {z0.h-z3.h}
+ bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z2.h}
+ bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z2.h}
+ bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h}
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.d b/gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.d
new file mode 100644
index 00000000000..ad6d365e288
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.d
@@ -0,0 +1,4 @@
+#name: Negative SVE_BFSCALE test with missing +sme2 flag.
+#as: -march=armv8-a+sve-bfscale
+#source: sve-bfscale-sme2.s
+#error_output: sve-bfscale-sme2-bad.l
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.l b/gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.l
new file mode 100644
index 00000000000..097213f9912
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.l
@@ -0,0 +1,33 @@
+[^ :]+: Assembler messages:
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},z15\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z30\.h-z31\.h ?},{ ?z30\.h-z31\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z30\.h-z31\.h ?},{ ?z30\.h-z31\.h ?},z15\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},z15\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z28\.h-z31\.h ?},{ ?z28\.h-z31\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z28\.h-z31\.h ?},{ ?z28\.h-z31\.h ?},z15\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},{ ?z14\.h-z15\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z30\.h-z31\.h ?},{ ?z30\.h-z31\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z30\.h-z31\.h ?},{ ?z30\.h-z31\.h ?},{ ?z14\.h-z15\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},{ ?z12\.h-z15\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z28\.h-z31\.h ?},{ ?z28\.h-z31\.h ?},{ ?z0\.h-z3\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfscale { ?z28\.h-z31\.h ?},{ ?z28\.h-z31\.h ?},{ ?z12\.h-z15\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},z15\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z30\.h-z31\.h ?},{ ?z30\.h-z31\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z30\.h-z31\.h ?},{ ?z30\.h-z31\.h ?},z15\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},z15\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z28\.h-z31\.h ?},{ ?z28\.h-z31\.h ?},z0\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z28\.h-z31\.h ?},{ ?z28\.h-z31\.h ?},z15\.h'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},{ ?z14\.h-z15\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z30\.h-z31\.h ?},{ ?z30\.h-z31\.h ?},{ ?z0\.h-z1\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z30\.h-z31\.h ?},{ ?z30\.h-z31\.h ?},{ ?z14\.h-z15\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},{ ?z12\.h-z15\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z28\.h-z31\.h ?},{ ?z28\.h-z31\.h ?},{ ?z0\.h-z3\.h ?}'
+[^ :]+:[0-9]+: Error: selected processor does not support `bfmul { ?z28\.h-z31\.h ?},{ ?z28\.h-z31\.h ?},{ ?z12\.h-z15\.h ?}'
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale-sme2.d b/gas/testsuite/gas/aarch64/sve-bfscale-sme2.d
new file mode 100644
index 00000000000..2c8848f3cc2
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale-sme2.d
@@ -0,0 +1,56 @@
+#name: SVE_BFSCALE + SME2 instructions test
+#as: -march=armv8-a+sve-bfscale+sme2
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section .*:
+
+.* <bfscale_2x1>:
+.*: c120a180 bfscale {z0.h-z1.h}, {z0.h-z1.h}, z0.h
+.*: c12fa180 bfscale {z0.h-z1.h}, {z0.h-z1.h}, z15.h
+.*: c120a19e bfscale {z30.h-z31.h}, {z30.h-z31.h}, z0.h
+.*: c12fa19e bfscale {z30.h-z31.h}, {z30.h-z31.h}, z15.h
+
+.* <bfscale_4x1>:
+.*: c120a980 bfscale {z0.h-z3.h}, {z0.h-z3.h}, z0.h
+.*: c12fa980 bfscale {z0.h-z3.h}, {z0.h-z3.h}, z15.h
+.*: c120a99c bfscale {z28.h-z31.h}, {z28.h-z31.h}, z0.h
+.*: c12fa99c bfscale {z28.h-z31.h}, {z28.h-z31.h}, z15.h
+
+.* <bfscale_2x2>:
+.*: c120b180 bfscale {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h}
+.*: c12eb180 bfscale {z0.h-z1.h}, {z0.h-z1.h}, {z14.h-z15.h}
+.*: c120b19e bfscale {z30.h-z31.h}, {z30.h-z31.h}, {z0.h-z1.h}
+.*: c12eb19e bfscale {z30.h-z31.h}, {z30.h-z31.h}, {z14.h-z15.h}
+
+.* <bfscale_4x4>:
+.*: c120b980 bfscale {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h}
+.*: c12cb980 bfscale {z0.h-z3.h}, {z0.h-z3.h}, {z12.h-z15.h}
+.*: c120b99c bfscale {z28.h-z31.h}, {z28.h-z31.h}, {z0.h-z3.h}
+.*: c12cb99c bfscale {z28.h-z31.h}, {z28.h-z31.h}, {z12.h-z15.h}
+
+.* <bfmul_2x1>:
+.*: c120e800 bfmul {z0.h-z1.h}, {z0.h-z1.h}, z0.h
+.*: c13ee800 bfmul {z0.h-z1.h}, {z0.h-z1.h}, z15.h
+.*: c120ebde bfmul {z30.h-z31.h}, {z30.h-z31.h}, z0.h
+.*: c13eebde bfmul {z30.h-z31.h}, {z30.h-z31.h}, z15.h
+
+.* <bfmul_4x1>:
+.*: c121e800 bfmul {z0.h-z3.h}, {z0.h-z3.h}, z0.h
+.*: c13fe800 bfmul {z0.h-z3.h}, {z0.h-z3.h}, z15.h
+.*: c121eb9c bfmul {z28.h-z31.h}, {z28.h-z31.h}, z0.h
+.*: c13feb9c bfmul {z28.h-z31.h}, {z28.h-z31.h}, z15.h
+
+.* <bfmul_2x2>:
+.*: c120e400 bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h}
+.*: c12ee400 bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z14.h-z15.h}
+.*: c120e7de bfmul {z30.h-z31.h}, {z30.h-z31.h}, {z0.h-z1.h}
+.*: c12ee7de bfmul {z30.h-z31.h}, {z30.h-z31.h}, {z14.h-z15.h}
+
+.* <bfmul_4x4>:
+.*: c121e400 bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h}
+.*: c12de400 bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z12.h-z15.h}
+.*: c121e79c bfmul {z28.h-z31.h}, {z28.h-z31.h}, {z0.h-z3.h}
+.*: c12de79c bfmul {z28.h-z31.h}, {z28.h-z31.h}, {z12.h-z15.h}
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale-sme2.s b/gas/testsuite/gas/aarch64/sve-bfscale-sme2.s
new file mode 100644
index 00000000000..b981c20c274
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale-sme2.s
@@ -0,0 +1,47 @@
+bfscale_2x1:
+ bfscale {z0.h-z1.h}, {z0.h-z1.h}, z0.h
+ bfscale {z0.h-z1.h}, {z0.h-z1.h}, z15.h
+ bfscale {z30.h-z31.h}, {z30.h-z31.h}, z0.h
+ bfscale {z30.h-z31.h}, {z30.h-z31.h}, z15.h
+
+bfscale_4x1:
+ bfscale {z0.h-z3.h}, {z0.h-z3.h}, z0.h
+ bfscale {z0.h-z3.h}, {z0.h-z3.h}, z15.h
+ bfscale {z28.h-z31.h}, {z28.h-z31.h}, z0.h
+ bfscale {z28.h-z31.h}, {z28.h-z31.h}, z15.h
+
+bfscale_2x2:
+ bfscale {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h}
+ bfscale {z0.h-z1.h}, {z0.h-z1.h}, {z14.h-z15.h}
+ bfscale {z30.h-z31.h}, {z30.h-z31.h}, {z0.h-z1.h}
+ bfscale {z30.h-z31.h}, {z30.h-z31.h}, {z14.h-z15.h}
+
+bfscale_4x4:
+ bfscale {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h}
+ bfscale {z0.h-z3.h}, {z0.h-z3.h}, {z12.h-z15.h}
+ bfscale {z28.h-z31.h}, {z28.h-z31.h}, {z0.h-z3.h}
+ bfscale {z28.h-z31.h}, {z28.h-z31.h}, {z12.h-z15.h}
+
+bfmul_2x1:
+ bfmul {z0.h-z1.h}, {z0.h-z1.h}, z0.h
+ bfmul {z0.h-z1.h}, {z0.h-z1.h}, z15.h
+ bfmul {z30.h-z31.h}, {z30.h-z31.h}, z0.h
+ bfmul {z30.h-z31.h}, {z30.h-z31.h}, z15.h
+
+bfmul_4x1:
+ bfmul {z0.h-z3.h}, {z0.h-z3.h}, z0.h
+ bfmul {z0.h-z3.h}, {z0.h-z3.h}, z15.h
+ bfmul {z28.h-z31.h}, {z28.h-z31.h}, z0.h
+ bfmul {z28.h-z31.h}, {z28.h-z31.h}, z15.h
+
+bfmul_2x2:
+ bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z0.h-z1.h}
+ bfmul {z0.h-z1.h}, {z0.h-z1.h}, {z14.h-z15.h}
+ bfmul {z30.h-z31.h}, {z30.h-z31.h}, {z0.h-z1.h}
+ bfmul {z30.h-z31.h}, {z30.h-z31.h}, {z14.h-z15.h}
+
+bfmul_4x4:
+ bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h}
+ bfmul {z0.h-z3.h}, {z0.h-z3.h}, {z12.h-z15.h}
+ bfmul {z28.h-z31.h}, {z28.h-z31.h}, {z0.h-z3.h}
+ bfmul {z28.h-z31.h}, {z28.h-z31.h}, {z12.h-z15.h}
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale.d b/gas/testsuite/gas/aarch64/sve-bfscale.d
new file mode 100644
index 00000000000..729bd4da67e
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale.d
@@ -0,0 +1,18 @@
+#name: FEAT_SVE_BFSCALE instruction test
+#as: -march=armv8-a+sve-bfscale
+#objdump: -dr
+
+.*: file format .*
+
+
+Disassembly of section .*:
+
+.* <bfscale>:
+.*: 65098000 bfscale z0.h, p0/m, z0.h, z0.h
+.*: 650983e0 bfscale z0.h, p0/m, z0.h, z31.h
+.*: 65099c00 bfscale z0.h, p7/m, z0.h, z0.h
+.*: 65099fe0 bfscale z0.h, p7/m, z0.h, z31.h
+.*: 6509801f bfscale z31.h, p0/m, z31.h, z0.h
+.*: 650983ff bfscale z31.h, p0/m, z31.h, z31.h
+.*: 65099c1f bfscale z31.h, p7/m, z31.h, z0.h
+.*: 65099fff bfscale z31.h, p7/m, z31.h, z31.h
diff --git a/gas/testsuite/gas/aarch64/sve-bfscale.s b/gas/testsuite/gas/aarch64/sve-bfscale.s
new file mode 100644
index 00000000000..33155242a23
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sve-bfscale.s
@@ -0,0 +1,9 @@
+bfscale:
+ bfscale z0.h, p0/m, z0.h, z0.h
+ bfscale z0.h, p0/m, z0.h, z31.h
+ bfscale z0.h, p7/m, z0.h, z0.h
+ bfscale z0.h, p7/m, z0.h, z31.h
+ bfscale z31.h, p0/m, z31.h, z0.h
+ bfscale z31.h, p0/m, z31.h, z31.h
+ bfscale z31.h, p7/m, z31.h, z0.h
+ bfscale z31.h, p7/m, z31.h, z31.h
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index dfe3f05820a..0ec1ba827d6 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -264,6 +264,8 @@ enum aarch64_feature_bit {
AARCH64_FEATURE_SME_F8F16,
/* Non-widening half-precision FP16 to FP16 arithmetic for SME2. */
AARCH64_FEATURE_SME_F16F16,
+ /* FEAT_SVE_BFSCALE. */
+ AARCH64_FEATURE_SVE_BFSCALE,
/* SVE Z-targeting non-widening BFloat16 instructions. */
AARCH64_FEATURE_SVE_B16B16,
/* SME non-widening BFloat16 instructions. */
@@ -824,6 +826,7 @@ enum aarch64_opnd
AARCH64_OPND_SME_Zdnx2, /* SVE vector register list from [4:1]*2. */
AARCH64_OPND_SME_Zdnx4, /* SVE vector register list from [4:2]*4. */
AARCH64_OPND_SME_Zm, /* SVE vector register list in 4-bit Zm. */
+ AARCH64_OPND_SME_Zmx1, /* SVE vector register list from [20:17]*1. */
AARCH64_OPND_SME_Zmx2, /* SVE vector register list from [20:17]*2. */
AARCH64_OPND_SME_Zmx4, /* SVE vector register list from [20:18]*4. */
AARCH64_OPND_SME_Znx2, /* SVE vector register list from [9:6]*2. */
@@ -1101,6 +1104,7 @@ enum aarch64_insn_class
sve_size_bhs,
sve_size_bhsd,
sve_size_hsd,
+ sve_bfscale,
sve_size_hsd2,
sve_size_sd,
sve_size_bh,
diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
index 4f0c71696fa..1466bd6feae 100644
--- a/opcodes/aarch64-opc.c
+++ b/opcodes/aarch64-opc.c
@@ -1960,6 +1960,7 @@ operand_general_constraint_met_p (const aarch64_opnd_info *opnds, int idx,
break;
case AARCH64_OPND_SME_Zm:
+ case AARCH64_OPND_SME_Zmx1:
if (opnd->reg.regno > 15)
{
set_invalid_regno_error (mismatch_detail, idx, "z", 0, 15);
@@ -4327,6 +4328,7 @@ aarch64_print_operand (char *buf, size_t size, bfd_vma pc,
case AARCH64_OPND_SVE_Zn:
case AARCH64_OPND_SVE_Zt:
case AARCH64_OPND_SME_Zm:
+ case AARCH64_OPND_SME_Zmx1:
if (opnd->qualifier == AARCH64_OPND_QLF_NIL)
snprintf (buf, size, "%s", style_reg (styler, "z%d", opnd->reg.regno));
else
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 8b64eb07067..44ac7047549 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -2833,6 +2833,10 @@ static const aarch64_feature_set aarch64_feature_fp8_sve2 =
AARCH64_FEATURES (2, FP8, SVE2);
static const aarch64_feature_set aarch64_feature_fp8_sme2 =
AARCH64_FEATURES (2, FP8, SME2);
+static const aarch64_feature_set aarch64_feature_sve_bfscale =
+ AARCH64_FEATURE (SVE_BFSCALE);
+static const aarch64_feature_set aarch64_feature_sve_bfscale_sme2 =
+ AARCH64_FEATURES (2, SVE_BFSCALE, SME2);
static const aarch64_feature_set aarch64_feature_lut =
AARCH64_FEATURE (LUT);
static const aarch64_feature_set aarch64_feature_lut_sve2 =
@@ -2945,6 +2949,8 @@ static const aarch64_feature_set aarch64_feature_sve2p1_sme2p1 =
#define FP8 &aarch64_feature_fp8
#define FP8_SVE2 &aarch64_feature_fp8_sve2
#define FP8_SME2 &aarch64_feature_fp8_sme2
+#define SVE_BFSCALE &aarch64_feature_sve_bfscale
+#define SVE_BFSCALE_SME2 &aarch64_feature_sve_bfscale_sme2
#define LUT &aarch64_feature_lut
#define LUT_SVE2 &aarch64_feature_lut_sve2
#define BRBE &aarch64_feature_brbe
@@ -3095,6 +3101,10 @@ static const aarch64_feature_set aarch64_feature_sve2p1_sme2p1 =
#define SVE2BITPERM_INSN(NAME,OPCODE,MASK,CLASS,OP,OPS,QUALS,FLAGS,TIED) \
{ NAME, OPCODE, MASK, CLASS, OP, SVE2_BITPERM, OPS, QUALS, \
FLAGS | F_STRICT, 0, TIED, NULL }
+#define SVE_BFSCALE_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS,TIED) \
+ { NAME, OPCODE, MASK, CLASS, 0, SVE_BFSCALE, OPS, QUALS, FLAGS, 0, TIED, NULL }
+#define SVE_BFSCALE_SME2_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS,TIED) \
+ { NAME, OPCODE, MASK, CLASS, 0, SVE_BFSCALE_SME2, OPS, QUALS, FLAGS, 0, TIED, NULL }
#define BFLOAT16_SVE_INSN(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS) \
{ NAME, OPCODE, MASK, CLASS, 0, BFLOAT16_SVE, OPS, QUALS, FLAGS, 0, 0, NULL }
#define BFLOAT16_SVE_INSNC(NAME,OPCODE,MASK,CLASS,OPS,QUALS,FLAGS, CONSTRAINTS, TIED) \
@@ -6385,6 +6395,17 @@ const struct aarch64_opcode aarch64_opcode_table[] =
SME2_F64F64_INSN ("fmls", 0xc1d00010, 0xfff09838, sme_misc, 0, OP3 (SME_ZA_array_off3_0, SME_Znx2, SME_Zm_INDEX1), OP_SVE_DDD, F_OD (2), 0),
SME2_F64F64_INSN ("fmls", 0xc1d08010, 0xfff09878, sme_misc, 0, OP3 (SME_ZA_array_off3_0, SME_Znx4, SME_Zm_INDEX1), OP_SVE_DDD, F_OD (4), 0),
+ /* SVE_BFSCALE instructions. */
+ SVE_BFSCALE_INSN ("bfscale", 0x65098000, 0xffffe000, sve_bfscale, OP4 (SVE_Zd, SVE_Pg3, SVE_Zd, SVE_Zm_5), OP_SVE_HMHH, 0, 2),
+ SVE_BFSCALE_SME2_INSN ("bfscale", 0xc120a180, 0xfff0ffe1, sve_bfscale, OP3 (SME_Zdnx2, SME_Zdnx2, SME_Zm), OP_SVE_VVV_H, 0, 1),
+ SVE_BFSCALE_SME2_INSN ("bfscale", 0xc120a980, 0xfff0ffe3, sve_bfscale, OP3 (SME_Zdnx4, SME_Zdnx4, SME_Zm), OP_SVE_VVV_H, 0, 1),
+ SVE_BFSCALE_SME2_INSN ("bfscale", 0xc120b180, 0xffe1ffe1, sve_bfscale, OP3 (SME_Zdnx2, SME_Zdnx2, SME_Zmx2), OP_SVE_VVV_H, 0, 1),
+ SVE_BFSCALE_SME2_INSN ("bfscale", 0xc120b980, 0xffe3ffe3, sve_bfscale, OP3 (SME_Zdnx4, SME_Zdnx4, SME_Zmx4), OP_SVE_VVV_H, 0, 1),
+ SVE_BFSCALE_SME2_INSN ("bfmul", 0xc120e800, 0xffe1fc21, sve_bfscale, OP3 (SME_Zdnx2, SME_Znx2, SME_Zmx1), OP_SVE_VVV_H, 0, 0),
+ SVE_BFSCALE_SME2_INSN ("bfmul", 0xc121e800, 0xffe1fc63, sve_bfscale, OP3 (SME_Zdnx4, SME_Znx4, SME_Zmx1), OP_SVE_VVV_H, 0, 0),
+ SVE_BFSCALE_SME2_INSN ("bfmul", 0xc120e400, 0xffe1fc21, sve_bfscale, OP3 (SME_Zdnx2, SME_Znx2, SME_Zmx2), OP_SVE_VVV_H, 0, 0),
+ SVE_BFSCALE_SME2_INSN ("bfmul", 0xc121e400, 0xffe3fc63, sve_bfscale, OP3 (SME_Zdnx4, SME_Znx4, SME_Zmx4), OP_SVE_VVV_H, 0, 0),
+
/* SIMD Dot Product (optional in v8.2-A). */
DOT_INSN ("udot", 0x2e009400, 0xbf20fc00, dotproduct, OP3 (Vd, Vn, Vm), QL_V3DOT, F_SIZEQ),
DOT_INSN ("sdot", 0x0e009400, 0xbf20fc00, dotproduct, OP3 (Vd, Vn, Vm), QL_V3DOT, F_SIZEQ),
@@ -7537,6 +7558,8 @@ const struct aarch64_opcode aarch64_opcode_table[] =
F(FLD_SME_Zdn4), "a list of SVE vector registers") \
Y(SVE_REG, regno, "SME_Zm", 0, F(FLD_SME_Zm), \
"an SVE vector register") \
+ Y(SVE_REG, regno, "SME_Zmx1", 0, F(FLD_SME_Zm2), \
+ "an SVE vector register") \
Y(SVE_REGLIST, sve_aligned_reglist, "SME_Zmx2", 2 << OPD_F_OD_LSB, \
F(FLD_SME_Zm2), "a list of SVE vector registers") \
Y(SVE_REGLIST, sve_aligned_reglist, "SME_Zmx4", 4 << OPD_F_OD_LSB, \
--
2.45.2
More information about the Binutils
mailing list