[PATCH v3] aarch64: Support for FEAT_SVE_BFSCALE

Alice Carlotti alice.carlotti@arm.com
Thu Jun 19 13:26:38 GMT 2025


On Thu, Jun 19, 2025 at 10:40:43AM +0100, Ezra.Sitorus@arm.com wrote:
> 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.
> ---
> I have addressed Alice's comments from v2:
> * SVE2_SME2 is before SVE2p1_SME in aarch64_feature_bit enum in
> aarch64-tbl.h
> * Removed SVE_BFSCALE_SVE2_SME2 in aarch64-tbl.h; SVE_BFSCALE has been
> changed to include SVE2 or SME2.
> 
> Regression tested on aarch64-none-linux-gnu.
> 
> Ezra

Thanks; I'll push this and your other approved patches shortly.

Alice

> 
>  gas/config/tc-aarch64.c                       |  4 ++
>  gas/doc/c-aarch64.texi                        |  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   | 26 ++++++++
>  gas/testsuite/gas/aarch64/sve-bfscale-bad.s   | 27 ++++++++
>  .../gas/aarch64/sve-bfscale-sme2-bad.d        |  4 ++
>  .../gas/aarch64/sve-bfscale-sme2-bad.l        | 41 ++++++++++++
>  gas/testsuite/gas/aarch64/sve-bfscale-sme2.d  | 66 +++++++++++++++++++
>  gas/testsuite/gas/aarch64/sve-bfscale-sme2.s  | 57 ++++++++++++++++
>  gas/testsuite/gas/aarch64/sve-bfscale-sve2.d  | 18 +++++
>  gas/testsuite/gas/aarch64/sve-bfscale-sve2.s  |  9 +++
>  include/opcode/aarch64.h                      |  5 ++
>  opcodes/aarch64-opc.c                         |  2 +
>  opcodes/aarch64-tbl.h                         | 23 +++++++
>  15 files changed, 290 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-sve2.d
>  create mode 100644 gas/testsuite/gas/aarch64/sve-bfscale-sve2.s
> 
> diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
> index acb56044fb5..f52fb4966d2 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_Zm_17:
>  	  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)},
> @@ -10757,6 +10759,8 @@ static const struct aarch64_virtual_dependency_table aarch64_dependencies[] = {
>  					       SVE2p1_SME2p1)},
>    {AARCH64_FEATURE (SME), AARCH64_FEATURE (SVE2p1_SME)},
>    {AARCH64_FEATURE (SME2), AARCH64_FEATURE (SVE2p1_SME2)},
> +  {AARCH64_FEATURE (SVE2), AARCH64_FEATURE (SVE2_SME2)},
> +  {AARCH64_FEATURE (SME2), AARCH64_FEATURE (SVE2_SME2)},
>    {AARCH64_FEATURE (SME2p1), AARCH64_FEATURE (SVE2p1_SME2p1)},
>  };
>  
> diff --git a/gas/doc/c-aarch64.texi b/gas/doc/c-aarch64.texi
> index 10888d1e78f..e77a9f08ba1 100644
> --- a/gas/doc/c-aarch64.texi
> +++ b/gas/doc/c-aarch64.texi
> @@ -297,6 +297,8 @@ automatically cause those extensions to be disabled.
>   @tab Enable the Scalable Vector Extension.
>  @item @code{sve-b16b16} @tab
>  @tab Enable the SVE B16B16 extension.  These instructions also require either @code{+sve2} or @code{+sme2}.
> +@item @code{sve-bfscale} @tab
> +@tab Enable the SVE BFSCALE extension. These instructions also require either @code{+sve2} or @code{+sme2}.
>  @item @code{sve2} @tab @code{sve}
>   @tab Enable SVE2.
>  @item @code{sve2-aes} @tab @code{sve2}, @code{aes}
> 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..7cddb25c1f7
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sve-bfscale-bad.l
> @@ -0,0 +1,26 @@
> +[^ :]+: 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: z0-z15 expected at operand 3 -- `bfmul { ?z0\.h-z1\.h ?},{ ?z0\.h-z1\.h ?},z16\.h'
> +[^ :]+:[0-9]+: Error: z0-z15 expected at operand 3 -- `bfmul { ?z0\.h-z3\.h ?},{ ?z0\.h-z3\.h ?},z16\.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..bcb8867aa66
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sve-bfscale-bad.s
> @@ -0,0 +1,27 @@
> +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-z1.h}, z16.h
> +	bfmul	{z0.h-z3.h}, {z0.h-z3.h}, z16.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..79ae8514744
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sve-bfscale-sme2-bad.l
> @@ -0,0 +1,41 @@
> +[^ :]+: Assembler messages:
> +[^ :]+:[0-9]+: Error: selected processor does not support `bfscale z0\.h,p0/m,z0\.h,z0\.h'
> +[^ :]+:[0-9]+: Error: selected processor does not support `bfscale z0\.h,p0/m,z0\.h,z31\.h'
> +[^ :]+:[0-9]+: Error: selected processor does not support `bfscale z0\.h,p7/m,z0\.h,z0\.h'
> +[^ :]+:[0-9]+: Error: selected processor does not support `bfscale z0\.h,p7/m,z0\.h,z31\.h'
> +[^ :]+:[0-9]+: Error: selected processor does not support `bfscale z31\.h,p0/m,z31\.h,z0\.h'
> +[^ :]+:[0-9]+: Error: selected processor does not support `bfscale z31\.h,p0/m,z31\.h,z31\.h'
> +[^ :]+:[0-9]+: Error: selected processor does not support `bfscale z31\.h,p7/m,z31\.h,z0\.h'
> +[^ :]+:[0-9]+: Error: selected processor does not support `bfscale z31\.h,p7/m,z31\.h,z31\.h'
> +[^ :]+:[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 ?},{ ?z30\.h-z31\.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 ?},{ ?z30\.h-z31\.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 ?},{ ?z28\.h-z31\.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 ?},{ ?z28\.h-z31\.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 ?},{ ?z30\.h-z31\.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 ?},{ ?z30\.h-z31\.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 ?},{ ?z28\.h-z31\.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 ?},{ ?z28\.h-z31\.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..84b76477ffd
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sve-bfscale-sme2.d
> @@ -0,0 +1,66 @@
> +#name: SVE_BFSCALE + SME2 instructions test
> +#as: -march=armv8-a+sve-bfscale+sme2
> +#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
> +
> +.* <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}
> +.*:	c13eb180 	bfscale	{z0.h-z1.h}, {z0.h-z1.h}, {z30.h-z31.h}
> +.*:	c120b19e 	bfscale	{z30.h-z31.h}, {z30.h-z31.h}, {z0.h-z1.h}
> +.*:	c13eb19e 	bfscale	{z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.h}
> +
> +.* <bfscale_4x4>:
> +.*:	c120b980 	bfscale	{z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h}
> +.*:	c13cb980 	bfscale	{z0.h-z3.h}, {z0.h-z3.h}, {z28.h-z31.h}
> +.*:	c120b99c 	bfscale	{z28.h-z31.h}, {z28.h-z31.h}, {z0.h-z3.h}
> +.*:	c13cb99c 	bfscale	{z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.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}
> +.*:	c13ee400 	bfmul	{z0.h-z1.h}, {z0.h-z1.h}, {z30.h-z31.h}
> +.*:	c120e7de 	bfmul	{z30.h-z31.h}, {z30.h-z31.h}, {z0.h-z1.h}
> +.*:	c13ee7de 	bfmul	{z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.h}
> +
> +.* <bfmul_4x4>:
> +.*:	c121e400 	bfmul	{z0.h-z3.h}, {z0.h-z3.h}, {z0.h-z3.h}
> +.*:	c13de400 	bfmul	{z0.h-z3.h}, {z0.h-z3.h}, {z28.h-z31.h}
> +.*:	c121e79c 	bfmul	{z28.h-z31.h}, {z28.h-z31.h}, {z0.h-z3.h}
> +.*:	c13de79c 	bfmul	{z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.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..46bc6c649cb
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sve-bfscale-sme2.s
> @@ -0,0 +1,57 @@
> +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
> +
> +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}, {z30.h-z31.h}
> +	bfscale	{z30.h-z31.h}, {z30.h-z31.h}, {z0.h-z1.h}
> +	bfscale	{z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.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}, {z28.h-z31.h}
> +	bfscale	{z28.h-z31.h}, {z28.h-z31.h}, {z0.h-z3.h}
> +	bfscale	{z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.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}, {z30.h-z31.h}
> +	bfmul	{z30.h-z31.h}, {z30.h-z31.h}, {z0.h-z1.h}
> +	bfmul	{z30.h-z31.h}, {z30.h-z31.h}, {z30.h-z31.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}, {z28.h-z31.h}
> +	bfmul	{z28.h-z31.h}, {z28.h-z31.h}, {z0.h-z3.h}
> +	bfmul	{z28.h-z31.h}, {z28.h-z31.h}, {z28.h-z31.h}
> diff --git a/gas/testsuite/gas/aarch64/sve-bfscale-sve2.d b/gas/testsuite/gas/aarch64/sve-bfscale-sve2.d
> new file mode 100644
> index 00000000000..874dda04fe7
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sve-bfscale-sve2.d
> @@ -0,0 +1,18 @@
> +#name: FEAT_SVE_BFSCALE instruction test
> +#as: -march=armv8-a+sve-bfscale+sve2
> +#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-sve2.s b/gas/testsuite/gas/aarch64/sve-bfscale-sve2.s
> new file mode 100644
> index 00000000000..33155242a23
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sve-bfscale-sve2.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..cc111b91617 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.  */
> @@ -281,6 +283,8 @@ enum aarch64_feature_bit {
>    AARCH64_FEATURE_FP8DOT2_SVE,
>    /* +sme-f16f16 or +sme-f8f16  */
>    AARCH64_FEATURE_SME_F16F16_F8F16,
> +  /* +sve2 or +sme2 */
> +  AARCH64_FEATURE_SVE2_SME2,
>    /* +sve2p1 or +sme */
>    AARCH64_FEATURE_SVE2p1_SME,
>    /* +sve2p1 or +sme2 */
> @@ -824,6 +828,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_Zm_17,	/* SVE vector register list in [20:17].  */
>    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.  */
> diff --git a/opcodes/aarch64-opc.c b/opcodes/aarch64-opc.c
> index 4f0c71696fa..40b150e20e3 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_Zm_17:
>  	  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_Zm_17:
>        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..6ba9ed31fcc 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_FEATURES (2, SVE_BFSCALE, SVE2_SME2);
> +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_misc, OP4 (SVE_Zd, SVE_Pg3, SVE_Zd, SVE_Zm_5), OP_SVE_HMHH, 0, 2),
> +  SVE_BFSCALE_SME2_INSN ("bfscale", 0xc120a180, 0xfff0ffe1, sme_misc, OP3 (SME_Zdnx2, SME_Zdnx2, SME_Zm), OP_SVE_VVV_H, 0, 1),
> +  SVE_BFSCALE_SME2_INSN ("bfscale", 0xc120a980, 0xfff0ffe3, sme_misc, OP3 (SME_Zdnx4, SME_Zdnx4, SME_Zm), OP_SVE_VVV_H, 0, 1),
> +  SVE_BFSCALE_SME2_INSN ("bfscale", 0xc120b180, 0xffe1ffe1, sme_misc, OP3 (SME_Zdnx2, SME_Zdnx2, SME_Zmx2), OP_SVE_VVV_H, 0, 1),
> +  SVE_BFSCALE_SME2_INSN ("bfscale", 0xc120b980, 0xffe3ffe3, sme_misc, OP3 (SME_Zdnx4, SME_Zdnx4, SME_Zmx4), OP_SVE_VVV_H, 0, 1),
> +  SVE_BFSCALE_SME2_INSN ("bfmul", 0xc120e800, 0xffe1fc21, sme_misc, OP3 (SME_Zdnx2, SME_Znx2, SME_Zm_17), OP_SVE_VVV_H, 0, 0),
> +  SVE_BFSCALE_SME2_INSN ("bfmul", 0xc121e800, 0xffe1fc63, sme_misc, OP3 (SME_Zdnx4, SME_Znx4, SME_Zm_17), OP_SVE_VVV_H, 0, 0),
> +  SVE_BFSCALE_SME2_INSN ("bfmul", 0xc120e400, 0xffe1fc21, sme_misc, OP3 (SME_Zdnx2, SME_Znx2, SME_Zmx2), OP_SVE_VVV_H, 0, 0),
> +  SVE_BFSCALE_SME2_INSN ("bfmul", 0xc121e400, 0xffe3fc63, sme_misc, 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_Zm_17", 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