aarch64: Reject no-Xt SYS aliases when Rt != 31 in disassembly

Message ID 20260318134957.129565-1-muhammad.kamran@arm.com
State Committed
Headers
Series aarch64: Reject no-Xt SYS aliases when Rt != 31 in disassembly |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Muhammad Kamran March 18, 2026, 1:49 p.m. UTC
  From: Muhammad Kamran <Muhammad.Kamran@arm.com>

For SYS-encoding aliases that do not take Xt (for example TLBI ALLE1,
PLBI ALLE1), disassembly should not print the alias form when Rt != 31.
In that case, disassemble as the generic sys form instead.

Add a focused gas test that checks:
- Rt=31 still disassembles to aliases for no-Xt forms.
- Rt!=31 disassembles to sys ... , xN for those no-Xt forms.
- A valid Xt alias (TLBI VALE1) continues to disassemble as the alias.

opcodes/ChangeLog:

	* aarch64-dis.c (aarch64_ext_regrt_sysins): Mark present as
	whether Rt is non-default or the SYS op accepts Xt, so aliases
	that do not take Xt are rejected when Rt != 31.

gas/ChangeLog:

	* testsuite/gas/aarch64/sys-rt-alias.s: New test source for SYS
	alias disassembly with Rt=31 vs Rt!=31, plus a valid Xt-alias
	control case.
	* testsuite/gas/aarch64/sys-rt-alias.d: New expected disassembly.
---
 gas/testsuite/gas/aarch64/sys-rt-alias.d | 17 +++++++++++++++++
 gas/testsuite/gas/aarch64/sys-rt-alias.s | 13 +++++++++++++
 opcodes/aarch64-dis.c                    |  9 +++------
 3 files changed, 33 insertions(+), 6 deletions(-)
 create mode 100644 gas/testsuite/gas/aarch64/sys-rt-alias.d
 create mode 100644 gas/testsuite/gas/aarch64/sys-rt-alias.s

--
2.43.0
  

Comments

Alice Carlotti April 9, 2026, 2:37 p.m. UTC | #1
On Wed, Mar 18, 2026 at 01:49:57PM +0000, Muhammad Kamran wrote:
> From: Muhammad Kamran <Muhammad.Kamran@arm.com>
> 
> For SYS-encoding aliases that do not take Xt (for example TLBI ALLE1,
> PLBI ALLE1), disassembly should not print the alias form when Rt != 31.
> In that case, disassemble as the generic sys form instead.
> 
> Add a focused gas test that checks:
> - Rt=31 still disassembles to aliases for no-Xt forms.
> - Rt!=31 disassembles to sys ... , xN for those no-Xt forms.
> - A valid Xt alias (TLBI VALE1) continues to disassemble as the alias.
> 
> opcodes/ChangeLog:
> 
> 	* aarch64-dis.c (aarch64_ext_regrt_sysins): Mark present as
> 	whether Rt is non-default or the SYS op accepts Xt, so aliases
> 	that do not take Xt are rejected when Rt != 31.
> 
> gas/ChangeLog:
> 
> 	* testsuite/gas/aarch64/sys-rt-alias.s: New test source for SYS
> 	alias disassembly with Rt=31 vs Rt!=31, plus a valid Xt-alias
> 	control case.
> 	* testsuite/gas/aarch64/sys-rt-alias.d: New expected disassembly.

Thanks!  This looks fine now, although I'll note that the commit message seems
a little verbose, and changelogs in Binutils aren't required (but are
permitted).  I've reduced the test changelog entries to "New test.", but
otherwise I've committed this for you as is.

Alice

> ---
>  gas/testsuite/gas/aarch64/sys-rt-alias.d | 17 +++++++++++++++++
>  gas/testsuite/gas/aarch64/sys-rt-alias.s | 13 +++++++++++++
>  opcodes/aarch64-dis.c                    |  9 +++------
>  3 files changed, 33 insertions(+), 6 deletions(-)
>  create mode 100644 gas/testsuite/gas/aarch64/sys-rt-alias.d
>  create mode 100644 gas/testsuite/gas/aarch64/sys-rt-alias.s
> 
> diff --git a/gas/testsuite/gas/aarch64/sys-rt-alias.d b/gas/testsuite/gas/aarch64/sys-rt-alias.d
> new file mode 100644
> index 00000000000..96c2f6844a8
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sys-rt-alias.d
> @@ -0,0 +1,17 @@
> +#objdump: -dr
> +
> +.*:     file format .*
> +
> +Disassembly of section \.text:
> +
> +0+ <.*>:
> +.*:	d50c879f 	tlbi	alle1
> +.*:	d50c8780 	sys	#4, C8, C7, #4, x0
> +.*:	d50ca79f 	plbi	alle1
> +.*:	d50ca780 	sys	#4, C10, C7, #4, x0
> +.*:	d50c709f 	mlbi	alle1
> +.*:	d50c7080 	sys	#4, C7, C0, #4, x0
> +.*:	d508751f 	ic	iallu
> +.*:	d5087500 	sys	#0, C7, C5, #0, x0
> +.*:	d50887bf 	tlbi	vale1, xzr
> +.*:	d50887a0 	tlbi	vale1, x0
> diff --git a/gas/testsuite/gas/aarch64/sys-rt-alias.s b/gas/testsuite/gas/aarch64/sys-rt-alias.s
> new file mode 100644
> index 00000000000..2aa107fa6d9
> --- /dev/null
> +++ b/gas/testsuite/gas/aarch64/sys-rt-alias.s
> @@ -0,0 +1,13 @@
> +// sys-rt-alias.s Test file for AArch64 instructions where Rt !=31 is undefined behaviour.
> +
> +	.text
> +	sys #4, c8, c7, #4      // TLBI ALLE1 with Rt=31
> +	sys #4, c8, c7, #4, x0  // TLBI ALLE1 with Rt!=31
> +	sys #4, c10, c7, #4     // PLBI ALLE1 with Rt=31
> +	sys #4, c10, c7, #4, x0 // PLBI ALLE1 with Rt!=31
> +	sys #4, c7, c0, #4      // MLBI ALLE1 with Rt=31
> +	sys #4, c7, c0, #4, x0  // MLBI ALLE1 with Rt!=31
> +	sys #0, c7, c5, #0      // IC IALLU with Rt=31
> +	sys #0, c7, c5, #0, x0  // IC IALLU with Rt!=31
> +	sys #0, c8, c7, #5, xzr // TLBI VALE1 with Rt=31 (valid Xt form)
> +	sys #0, c8, c7, #5, x0  // TLBI VALE1 with Rt!=31 (valid Xt form)
> diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
> index f09307847e6..8544ce4b6d4 100644
> --- a/opcodes/aarch64-dis.c
> +++ b/opcodes/aarch64-dis.c
> @@ -331,12 +331,9 @@ aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
>       help the disassembler determine whether this operand is optional or
>       not.  */
> 
> -  if (aarch64_sys_ins_reg_tlbid_xt (inst->operands[0].sysins_op)
> -      && info->reg.regno != 31)
> -    info->present = true;
> -  else
> -    info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
> -
> +  info->present
> +    = (info->reg.regno != 31
> +       || aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op));
>    return true;
>  }
> 
> --
> 2.43.0
>
  

Patch

diff --git a/gas/testsuite/gas/aarch64/sys-rt-alias.d b/gas/testsuite/gas/aarch64/sys-rt-alias.d
new file mode 100644
index 00000000000..96c2f6844a8
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sys-rt-alias.d
@@ -0,0 +1,17 @@ 
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+.*:	d50c879f 	tlbi	alle1
+.*:	d50c8780 	sys	#4, C8, C7, #4, x0
+.*:	d50ca79f 	plbi	alle1
+.*:	d50ca780 	sys	#4, C10, C7, #4, x0
+.*:	d50c709f 	mlbi	alle1
+.*:	d50c7080 	sys	#4, C7, C0, #4, x0
+.*:	d508751f 	ic	iallu
+.*:	d5087500 	sys	#0, C7, C5, #0, x0
+.*:	d50887bf 	tlbi	vale1, xzr
+.*:	d50887a0 	tlbi	vale1, x0
diff --git a/gas/testsuite/gas/aarch64/sys-rt-alias.s b/gas/testsuite/gas/aarch64/sys-rt-alias.s
new file mode 100644
index 00000000000..2aa107fa6d9
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/sys-rt-alias.s
@@ -0,0 +1,13 @@ 
+// sys-rt-alias.s Test file for AArch64 instructions where Rt !=31 is undefined behaviour.
+
+	.text
+	sys #4, c8, c7, #4      // TLBI ALLE1 with Rt=31
+	sys #4, c8, c7, #4, x0  // TLBI ALLE1 with Rt!=31
+	sys #4, c10, c7, #4     // PLBI ALLE1 with Rt=31
+	sys #4, c10, c7, #4, x0 // PLBI ALLE1 with Rt!=31
+	sys #4, c7, c0, #4      // MLBI ALLE1 with Rt=31
+	sys #4, c7, c0, #4, x0  // MLBI ALLE1 with Rt!=31
+	sys #0, c7, c5, #0      // IC IALLU with Rt=31
+	sys #0, c7, c5, #0, x0  // IC IALLU with Rt!=31
+	sys #0, c8, c7, #5, xzr // TLBI VALE1 with Rt=31 (valid Xt form)
+	sys #0, c8, c7, #5, x0  // TLBI VALE1 with Rt!=31 (valid Xt form)
diff --git a/opcodes/aarch64-dis.c b/opcodes/aarch64-dis.c
index f09307847e6..8544ce4b6d4 100644
--- a/opcodes/aarch64-dis.c
+++ b/opcodes/aarch64-dis.c
@@ -331,12 +331,9 @@  aarch64_ext_regrt_sysins (const aarch64_operand *self, aarch64_opnd_info *info,
      help the disassembler determine whether this operand is optional or
      not.  */

-  if (aarch64_sys_ins_reg_tlbid_xt (inst->operands[0].sysins_op)
-      && info->reg.regno != 31)
-    info->present = true;
-  else
-    info->present = aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op);
-
+  info->present
+    = (info->reg.regno != 31
+       || aarch64_sys_ins_reg_has_xt (inst->operands[0].sysins_op));
   return true;
 }