[v0,10/13] aarch64: add PAuth_LR instructions with no or one-register operand

Message ID 20240708123452.1883314-11-matthieu.longo@arm.com
State New
Headers
Series aarch64: add instructions for Armv9.5-A PAC enhancement |

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-arm success Test passed

Commit Message

Matthieu Longo July 8, 2024, 12:34 p.m. UTC
  This patch adds the instructions required by Armv9.5-A PAC
enhancements.
- paci<k>sppc, pacnbi<>sppc, paci<k>171615, auti<k>171615
- the register variant of auti<k>sppc -> auti<k>sppcr
- the register variant of reta<k>sppc -> reta<k>sppcr
A new register type R was also added to prevent a misuse of SP or XZR
registers with the register variant instructions.
It also adds the relevant tests for those instructions.
---
 gas/config/tc-aarch64.c                  | 12 +++++++++-
 gas/testsuite/gas/aarch64/pauth_lr-bad.d |  3 +++
 gas/testsuite/gas/aarch64/pauth_lr-bad.l | 11 +++++++++
 gas/testsuite/gas/aarch64/pauth_lr-bad.s | 12 ++++++++++
 gas/testsuite/gas/aarch64/pauth_lr.d     | 24 +++++++++++++++++++
 gas/testsuite/gas/aarch64/pauth_lr.s     | 30 ++++++++++++++++++++++++
 include/opcode/aarch64.h                 |  1 +
 opcodes/aarch64-tbl.h                    | 18 ++++++++++++++
 8 files changed, 110 insertions(+), 1 deletion(-)
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.d
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.l
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr-bad.s
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr.d
 create mode 100644 gas/testsuite/gas/aarch64/pauth_lr.s
  

Patch

diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 0887d9a0736..f69b0b0c0e2 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -306,6 +306,8 @@  struct reloc_entry
   /* Typecheck: same, plus SVE registers.  */				\
   MULTI_REG_TYPE(SVE_BASE, REG_TYPE(R_64) | REG_TYPE(SP_64)		\
 		 | REG_TYPE(Z))						\
+  /* Typecheck: x[0-30], w[0-30].  */					\
+  MULTI_REG_TYPE(R, REG_TYPE(R_32) | REG_TYPE(R_64))			\
   /* Typecheck: x[0-30], w[0-30] or [xw]zr.  */				\
   MULTI_REG_TYPE(R_ZR, REG_TYPE(R_32) | REG_TYPE(R_64)			\
 		 | REG_TYPE(ZR_32) | REG_TYPE(ZR_64))			\
@@ -6688,7 +6690,15 @@  parse_operands (char *str, const aarch64_opcode *opcode)
 	case AARCH64_OPND_PAIRREG:
 	case AARCH64_OPND_PAIRREG_OR_XZR:
 	case AARCH64_OPND_SVE_Rm:
-	  po_int_fp_reg_or_fail (REG_TYPE_R_ZR);
+	  switch (opcode->iclass)
+	  {
+	    case ic_pauth_lr:
+	      po_int_fp_reg_or_fail (REG_TYPE_R);
+	      break;
+	    default:
+	      po_int_fp_reg_or_fail (REG_TYPE_R_ZR);
+	      break;
+	  }
 
 	  /* In LS64 load/store instructions Rt register number must be even
 	     and <=22.  */
diff --git a/gas/testsuite/gas/aarch64/pauth_lr-bad.d b/gas/testsuite/gas/aarch64/pauth_lr-bad.d
new file mode 100644
index 00000000000..4ee0bfcaf35
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr-bad.d
@@ -0,0 +1,3 @@ 
+#source: pauth_lr-bad.s
+#as: -march=armv9.4-a+pauth-lr
+#error_output: pauth_lr-bad.l
\ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/pauth_lr-bad.l b/gas/testsuite/gas/aarch64/pauth_lr-bad.l
new file mode 100644
index 00000000000..d0a629f216f
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr-bad.l
@@ -0,0 +1,11 @@ 
+.*: Assembler messages:
+.*: Error: operand mismatch -- `autiasppcr w0'
+.*: Info:    did you mean this\?
+.*: Info:    	autiasppcr x0
+.*: Error: unexpected register type at operand 1 -- `autiasppcr sp'
+.*: Error: unexpected register type at operand 1 -- `autiasppcr xzr'
+.*: Error: operand mismatch -- `retaasppcr w0'
+.*: Info:    did you mean this\?
+.*: Info:    	retaasppcr x0
+.*: Error: unexpected register type at operand 1 -- `retaasppcr sp'
+.*: Error: unexpected register type at operand 1 -- `retaasppcr xzr'
\ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/pauth_lr-bad.s b/gas/testsuite/gas/aarch64/pauth_lr-bad.s
new file mode 100644
index 00000000000..98840d4c257
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr-bad.s
@@ -0,0 +1,12 @@ 
+	/* ARMv9.5 Pointer authentication instructions.  */
+	.text
+
+lr_signing:
+
+	autiasppcr w0 // 32-bit registers not allowed
+	autiasppcr sp // stack pointer register not allowed
+	autiasppcr xzr // zero register not allowed
+
+	retaasppcr w0 // 32-bit registers not allowed
+	retaasppcr sp // SP not allowed
+	retaasppcr xzr // zero register not allowed
diff --git a/gas/testsuite/gas/aarch64/pauth_lr.d b/gas/testsuite/gas/aarch64/pauth_lr.d
new file mode 100644
index 00000000000..ddd65b77fd1
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr.d
@@ -0,0 +1,24 @@ 
+#source: pauth_lr.s
+#as: -march=armv9.4-a+pauth-lr
+#objdump: -dr
+
+.*:     file .*
+
+Disassembly of section \.text:
+
+0+ <.*>:
+.*:	d50324ff 	pacm
+.*:	dac1a3fe 	paciasppc
+.*:	dac1a7fe 	pacibsppc
+.*:	dac18bfe 	pacia171615
+.*:	dac18ffe 	pacib171615
+.*:	dac183fe 	pacnbiasppc
+.*:	dac187fe 	pacnbibsppc
+.*:	dac1bbfe 	autia171615
+.*:	dac1bffe 	autib171615
+.*:	dac1901e 	autiasppcr	x0
+.*:	dac193de 	autiasppcr	x30
+.*:	dac1941e 	autibsppcr	x0
+.*:	d65f0be0 	retaasppcr	x0
+.*:	d65f0bfe 	retaasppcr	x30
+.*:	d65f0fe0 	retabsppcr	x0
\ No newline at end of file
diff --git a/gas/testsuite/gas/aarch64/pauth_lr.s b/gas/testsuite/gas/aarch64/pauth_lr.s
new file mode 100644
index 00000000000..cdedd6e4588
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/pauth_lr.s
@@ -0,0 +1,30 @@ 
+	/* ARMv9.5 Pointer authentication instructions.  */
+	.text
+
+	// only NOP-space instruction to enable ComputePAC2() with PAuth instructions.
+	pacm
+
+	// Signing of LR using SP and PC as deversifiers.
+	paciasppc
+	pacibsppc
+
+	pacia171615
+	pacib171615
+
+	// When used along feature FEAT_BTI
+	pacnbiasppc
+	pacnbibsppc
+
+	// Authenticating the PAC in the address in register LR
+	autia171615
+	autib171615
+
+	// Variant with value of PC passed by register
+	autiasppcr x0
+	autiasppcr x30
+	autibsppcr x0
+
+	// Authentication + return
+	retaasppcr x0
+	retaasppcr x30
+	retabsppcr x0
diff --git a/include/opcode/aarch64.h b/include/opcode/aarch64.h
index 2710730e72e..81c9b1f1220 100644
--- a/include/opcode/aarch64.h
+++ b/include/opcode/aarch64.h
@@ -1054,6 +1054,7 @@  enum aarch64_insn_class
   lse_atomic,
   lse128_atomic,
   movewide,
+  ic_pauth_lr,
   pcreladdr,
   ic_system,
   sme_fp_sd,
diff --git a/opcodes/aarch64-tbl.h b/opcodes/aarch64-tbl.h
index 3ba2c088be8..ef7b69e4970 100644
--- a/opcodes/aarch64-tbl.h
+++ b/opcodes/aarch64-tbl.h
@@ -1034,6 +1034,12 @@ 
   QLF4(V_16B, V_16B, V_16B, imm_0_15),	\
 }
 
+/* e.g. AUTI<k>SPPCR Xn  */
+#define QL_PAUTH_REG		\
+{				\
+  QLF1(X),			\
+}
+
 /* e.g. .  */
 #define QL_V3SAMEHS		\
 {				\
@@ -3888,6 +3894,8 @@  const struct aarch64_opcode aarch64_opcode_table[] =
   PAUTH_INSN ("retab", 0xd65f0fff, 0xffffffff, branch_reg, OP0 (), {}, 0),
   PAUTH_INSN ("eretaa", 0xd69f0bff, 0xffffffff, branch_reg, OP0 (), {}, 0),
   PAUTH_INSN ("eretab", 0xd69f0fff, 0xffffffff, branch_reg, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("retaasppcr", 0xd65f0be0, 0xffffffe0, ic_pauth_lr, OP1 (Rd), QL_PAUTH_REG, 0),
+  PAUTH_LR_INSN ("retabsppcr", 0xd65f0fe0, 0xffffffe0, ic_pauth_lr, OP1 (Rd), QL_PAUTH_REG, 0),
   /* Compare & branch (immediate).  */
   CORE_INSN ("cbz", 0x34000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
   CORE_INSN ("cbnz", 0x35000000, 0x7f000000, compbranch, 0, OP2 (Rt, ADDR_PCREL19), QL_R_PCREL, F_SF),
@@ -3939,10 +3947,20 @@  const struct aarch64_opcode aarch64_opcode_table[] =
   PAUTH_INSN ("pacib", 0xdac10400, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("pacda", 0xdac10800, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("pacdb", 0xdac10c00, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
+  PAUTH_LR_INSN ("paciasppc", 0xdac1a3fe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacibsppc", 0xdac1a7fe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacnbiasppc", 0xdac183fe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacnbibsppc", 0xdac187fe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacia171615", 0xdac18bfe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("pacib171615", 0xdac18ffe, 0xffffffff, ic_system, OP0 (), {}, 0),
   PAUTH_INSN ("autia", 0xdac11000, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("autib", 0xdac11400, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("autda", 0xdac11800, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
   PAUTH_INSN ("autdb", 0xdac11c00, 0xfffffc00, dp_1src, OP2 (Rd, Rn_SP), QL_I2SAMEX, 0),
+  PAUTH_LR_INSN ("autiasppcr", 0xdac1901e, 0xfffffc1f, ic_pauth_lr, OP1 (Rn), QL_PAUTH_REG, 0),
+  PAUTH_LR_INSN ("autibsppcr", 0xdac1941e, 0xfffffc1f, ic_pauth_lr, OP1 (Rn), QL_PAUTH_REG, 0),
+  PAUTH_LR_INSN ("autia171615", 0xdac1bbfe, 0xffffffff, ic_system, OP0 (), {}, 0),
+  PAUTH_LR_INSN ("autib171615", 0xdac1bffe, 0xffffffff, ic_system, OP0 (), {}, 0),
   PAUTH_INSN ("paciza", 0xdac123e0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),
   PAUTH_INSN ("pacizb", 0xdac127e0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),
   PAUTH_INSN ("pacdza", 0xdac12be0, 0xffffffe0, dp_1src, OP1 (Rd), QL_I1X, 0),