[PATCH] RISC-V: Add optional register argument to tail pseudo
Kito Cheng
kito.cheng@sifive.com
Mon Sep 14 09:53:59 GMT 2026
The lpad instruction of Zicfilp is encoded using an auipc hint encoding, so
an instrumented binary still runs correctly on a CPU without Zicfilp. For
that to work, compilers must be able to emit a software guarded tail call
using t2 as the scratch register without Zicfilp appearing in the ISA
string.
Add `tail <symbol>, <rt>' for that, which expands the same way as
`jump <symbol>, <rt>'.
See more: https://github.com/riscv-non-isa/riscv-asm-manual/pull/227
---
gas/testsuite/gas/riscv/tail-fail.d | 3 +++
gas/testsuite/gas/riscv/tail-fail.l | 3 +++
gas/testsuite/gas/riscv/tail-fail.s | 3 +++
gas/testsuite/gas/riscv/tail.d | 6 ++++++
gas/testsuite/gas/riscv/tail.s | 3 +++
opcodes/riscv-opc.c | 1 +
6 files changed, 19 insertions(+)
create mode 100644 gas/testsuite/gas/riscv/tail-fail.d
create mode 100644 gas/testsuite/gas/riscv/tail-fail.l
create mode 100644 gas/testsuite/gas/riscv/tail-fail.s
diff --git a/gas/testsuite/gas/riscv/tail-fail.d b/gas/testsuite/gas/riscv/tail-fail.d
new file mode 100644
index 00000000000..8568b7b5522
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tail-fail.d
@@ -0,0 +1,3 @@
+#as: -march=rv32i
+#source: tail-fail.s
+#error_output: tail-fail.l
diff --git a/gas/testsuite/gas/riscv/tail-fail.l b/gas/testsuite/gas/riscv/tail-fail.l
new file mode 100644
index 00000000000..4b9b3d136ac
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tail-fail.l
@@ -0,0 +1,3 @@
+.*: Assembler messages:
+.*:2: Error: illegal operands `tail foo,x0'
+.*:3: Error: illegal operands `tail foo,zero'
diff --git a/gas/testsuite/gas/riscv/tail-fail.s b/gas/testsuite/gas/riscv/tail-fail.s
new file mode 100644
index 00000000000..713591ab197
--- /dev/null
+++ b/gas/testsuite/gas/riscv/tail-fail.s
@@ -0,0 +1,3 @@
+foo:
+ tail foo, x0
+ tail foo, zero
diff --git a/gas/testsuite/gas/riscv/tail.d b/gas/testsuite/gas/riscv/tail.d
index 6e5db231061..1879c06fec8 100644
--- a/gas/testsuite/gas/riscv/tail.d
+++ b/gas/testsuite/gas/riscv/tail.d
@@ -11,3 +11,9 @@ Disassembly of section .text:
[ ]+[0-9a-f]+:[ ]+00030067[ ]+jr[ ]+t1 # 0 <foo>
[ ]+[0-9a-f]+:[ ]+00000397[ ]+auipc[ ]+t2,0x0
[ ]+[0-9a-f]+:[ ]+00038067[ ]+jr[ ]+t2 # 8 <foo\+0x8>
+[ ]+[0-9a-f]+:[ ]+00000517[ ]+auipc[ ]+a0,0x0
+[ ]+[0-9a-f]+:[ ]+00050067[ ]+jr[ ]+a0 # 10 <foo\+0x10>
+[ ]+[0-9a-f]+:[ ]+00000397[ ]+auipc[ ]+t2,0x0
+[ ]+[0-9a-f]+:[ ]+00038067[ ]+jr[ ]+t2 # 18 <foo\+0x18>
+[ ]+[0-9a-f]+:[ ]+00000317[ ]+auipc[ ]+t1,0x0
+[ ]+[0-9a-f]+:[ ]+00030067[ ]+jr[ ]+t1 # 20 <foo\+0x20>
diff --git a/gas/testsuite/gas/riscv/tail.s b/gas/testsuite/gas/riscv/tail.s
index 8058244367b..7d738ebec4f 100644
--- a/gas/testsuite/gas/riscv/tail.s
+++ b/gas/testsuite/gas/riscv/tail.s
@@ -2,8 +2,11 @@ foo:
.option push
.option arch, rv32i
tail foo
+ tail foo, t2
+ tail foo, a0
.option pop
.option push
.option arch, rv32i_zicfilp
tail foo
+ tail foo, t1
.option pop
diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c
index 7ef6e157d4f..1f7d43050bf 100644
--- a/opcodes/riscv-opc.c
+++ b/opcodes/riscv-opc.c
@@ -510,6 +510,7 @@ const struct riscv_opcode riscv_opcodes[] =
{"call", 0, INSN_CLASS_I, "c", (X_RA << OP_SH_RS1)|(X_RA << OP_SH_RD), (int) M_CALL, NULL, INSN_MACRO },
{"tail", 0, INSN_CLASS_ZICFILP, "c", (X_T2 << OP_SH_RS1), (int) M_CALL, NULL, INSN_MACRO },
{"tail", 0, INSN_CLASS_I, "c", (X_T1 << OP_SH_RS1), (int) M_CALL, NULL, INSN_MACRO },
+{"tail", 0, INSN_CLASS_I, "c,s", 0, (int) M_CALL, match_rs1_nonzero, INSN_MACRO },
{"jump", 0, INSN_CLASS_I, "c,s", 0, (int) M_CALL, match_rs1_nonzero, INSN_MACRO },
{"nop", 0, INSN_CLASS_ZCA, "", MATCH_C_ADDI, 0xffff, match_opcode, INSN_ALIAS },
{"nop", 0, INSN_CLASS_I, "", MATCH_ADDI, MASK_ADDI|MASK_RD|MASK_RS1|MASK_IMM, match_opcode, INSN_ALIAS },
--
2.54.0
More information about the Binutils
mailing list