[RFC PATCH 0/5] RISC-V: Add Zcmt table-jump relaxation support
Jiawei
jiawei@iscas.ac.cn
Sat Jun 27 10:45:50 GMT 2026
This RFC series adds RISC-V Zcmt table-jump relaxation support to GNU ld.
The optimization is default-off and must be requested with `--relax-zcmt`.
The implementation follows a post-relaxation profitability model. It records
the residual `R_RISCV_CALL`, `R_RISCV_CALL_PLT`, and `R_RISCV_JAL`
opportunities that still have paired `R_RISCV_RELAX` relocations after ordinary
RISC-V relaxation. It then ranks JT and JALT candidates separately, uses a
deterministic prefix selection, accounts for the JVT payload cost, and emits no
`.riscv.jvt` section if no positive-benefit table is selected.
Runtime policy:
- when a non-empty `.riscv.jvt` is emitted, the linker defines local
`__jvt_base$` at the table base;
- programs that execute `cm.jt`/`cm.jalt` remain responsible for initializing
CSR `jvt` to `__jvt_base$` first;
- when no profitable JVT is emitted, `__jvt_base$` is not defined;
- generic startup code that unconditionally references `__jvt_base$` is not
supported unless it arranges an optional reference or is linked only when a
JVT is emitted.
ISA/profile policy:
- Zcmt relaxation is enabled only when output attributes explicitly support
`zcmt`, `zca`, and `zicsr`;
- output attributes containing `zcd` disable Zcmt relaxation because the
encodings conflict.
Scope:
- non-position-independent executable links only;
- PIC, PIE, and shared-object links are conservatively not relaxed;
- no Linux ABI claim for automatic `jvt` initialization;
Open questions:
- Is the `__jvt_base$` emission policy acceptable for v1?
- Is `R_RISCV_TABLE_JUMP` acceptable as an internal linker relocation?
- Are `.riscv.jvt` section naming, flags, and 64-byte alignment suitable?
- Should objdump present JVT entries as `jvt.jt[]`/`jvt.jalt[]`, or use a more
conservative `.word`/`.dword` presentation?
(Patch 4 is separable; if maintainers prefer, the linker relaxation support
can be reviewed independently from the objdump JVT annotation.)
- Is default-off `--relax-zcmt` the desired upstream user interface?
Contributors:
This RFC builds on earlier Zcmt table-jump relaxation work carried out
with contributions and discussions from Embecosm, SiFive and ISCAS.
Thanks to Jeremy Bennet, Kito Cheng, Mary Bennett, Nandni Jamnadas,
Simon Cook, Charlie Keaney, Hau Hsu, Jerry Zhang Jian, Sinan Lin,
Shihua Liao and Yulong Shi for the earlier work and feedback that
helped shape this series.
Since this upstream version has been substantially reworked, the commit
authorship is limited to the current patch submission, while the earlier
collaborative work is acknowledged here rather than carrying over
historical authorship trailers.
RISC-V: Add Zcmt table-jump relocation definitions
RISC-V: Add Zcmt table-jump relaxation
ld: Add RISC-V --relax-zcmt option
RISC-V: Decode Zcmt JVT entries in objdump
RISC-V: Add Zcmt table-jump linker tests
bfd/elfnn-riscv.c | 1134 ++++++++++++++++-
bfd/elfxx-riscv.c | 4 +
bfd/elfxx-riscv.h | 21 +
include/elf/riscv.h | 5 +
include/opcode/riscv.h | 9 +
ld/NEWS | 3 +
ld/emultempl/riscvelf.em | 17 +-
ld/gen-doc.texi | 2 +-
ld/ld.texi | 35 +
ld/ldlex.h | 2 +
ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp | 50 +
ld/testsuite/ld-riscv-elf/table-jump-addend.d | 18 +
ld/testsuite/ld-riscv-elf/table-jump-addend.s | 21 +
.../ld-riscv-elf/table-jump-base-collision.d | 4 +
.../ld-riscv-elf/table-jump-base-collision.s | 18 +
.../table-jump-base-local-collision.d | 4 +
.../table-jump-base-local-collision.s | 17 +
.../ld-riscv-elf/table-jump-be32-bytes.d | 10 +
.../ld-riscv-elf/table-jump-be32-text.d | 13 +
.../ld-riscv-elf/table-jump-be64-bytes.d | 10 +
.../ld-riscv-elf/table-jump-be64-text.d | 13 +
.../ld-riscv-elf/table-jump-benefit.d | 17 +
.../ld-riscv-elf/table-jump-benefit.s | 51 +
.../table-jump-default-jvt-relocs.d | 9 +
.../table-jump-default-jvt-symbol.d | 10 +
.../ld-riscv-elf/table-jump-default-jvt.d | 12 +
.../ld-riscv-elf/table-jump-default-no-jvt.d | 15 +
.../ld-riscv-elf/table-jump-dump-unknown.d | 25 +
.../ld-riscv-elf/table-jump-emit-relocs.d | 9 +
.../ld-riscv-elf/table-jump-equal-benefit.d | 18 +
.../ld-riscv-elf/table-jump-equal-benefit.s | 19 +
.../table-jump-gc-comdat-symbol.d | 9 +
.../ld-riscv-elf/table-jump-gc-comdat.d | 11 +
.../ld-riscv-elf/table-jump-gc-comdat.s | 18 +
.../ld-riscv-elf/table-jump-gc-dead-symbol.d | 9 +
.../ld-riscv-elf/table-jump-gc-dead.d | 11 +
.../ld-riscv-elf/table-jump-gc-dead.s | 18 +
ld/testsuite/ld-riscv-elf/table-jump-jalt.d | 18 +
ld/testsuite/ld-riscv-elf/table-jump-jt.d | 23 +
.../table-jump-multiple-local-sym-2.s | 12 +
.../table-jump-multiple-local-sym.d | 16 +
.../table-jump-multiple-local-sym.s | 18 +
.../table-jump-no-benefit-jvt-ref.d | 4 +
.../table-jump-no-benefit-jvt-ref.s | 16 +
.../table-jump-no-benefit-section.d | 9 +
.../table-jump-no-benefit-symbol.d | 9 +
.../ld-riscv-elf/table-jump-no-benefit.s | 12 +
.../ld-riscv-elf/table-jump-no-relax-zcmt.d | 17 +
.../ld-riscv-elf/table-jump-no-relo-1.s | 7 +
.../ld-riscv-elf/table-jump-no-relo-2.s | 12 +
.../ld-riscv-elf/table-jump-no-relo.d | 16 +
.../ld-riscv-elf/table-jump-no-zcmt.d | 16 +
.../ld-riscv-elf/table-jump-no-zcmt.s | 16 +
.../ld-riscv-elf/table-jump-norelax.d | 15 +
.../ld-riscv-elf/table-jump-norelax.s | 17 +
.../ld-riscv-elf/table-jump-overflow.d | 11 +
.../ld-riscv-elf/table-jump-overflow.s | 49 +
.../ld-riscv-elf/table-jump-pie-relocs.d | 9 +
.../ld-riscv-elf/table-jump-pie-text.d | 9 +
ld/testsuite/ld-riscv-elf/table-jump-pie.d | 9 +
ld/testsuite/ld-riscv-elf/table-jump-pie.s | 13 +
.../ld-riscv-elf/table-jump-relax-zcmt.d | 23 +
ld/testsuite/ld-riscv-elf/table-jump-rv32.d | 15 +
ld/testsuite/ld-riscv-elf/table-jump-rv32.s | 25 +
.../ld-riscv-elf/table-jump-shared-relocs.d | 9 +
.../ld-riscv-elf/table-jump-shared-symbol.d | 9 +
.../ld-riscv-elf/table-jump-shared-text.d | 9 +
ld/testsuite/ld-riscv-elf/table-jump-shared.d | 12 +
ld/testsuite/ld-riscv-elf/table-jump-shared.s | 15 +
.../ld-riscv-elf/table-jump-strip-symbol.d | 9 +
.../ld-riscv-elf/table-jump-symbol-policy.d | 8 +
.../ld-riscv-elf/table-jump-vma-lma.d | 16 +
.../ld-riscv-elf/table-jump-vma-lma.ld | 10 +
.../ld-riscv-elf/table-jump-vma-zero.d | 15 +
.../ld-riscv-elf/table-jump-vma-zero.ld | 13 +
.../ld-riscv-elf/table-jump-vma-zero.s | 14 +
.../ld-riscv-elf/table-jump-zcd-conflict.d | 9 +
.../ld-riscv-elf/table-jump-zcmt-no-zca.d | 9 +
.../ld-riscv-elf/table-jump-zcmt-no-zca.s | 24 +
.../ld-riscv-elf/table-jump-zcmt-no-zicsr.d | 9 +
.../ld-riscv-elf/table-jump-zcmt-no-zicsr.s | 24 +
ld/testsuite/ld-riscv-elf/table-jump.ld | 16 +
ld/testsuite/ld-riscv-elf/table-jump.s | 46 +
opcodes/riscv-dis.c | 164 ++-
84 files changed, 2478 insertions(+), 54 deletions(-)
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-addend.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-addend.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-base-collision.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-base-collision.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-base-local-collision.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-base-local-collision.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-be32-bytes.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-be32-text.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-be64-bytes.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-be64-text.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-benefit.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-benefit.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-default-jvt-relocs.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-default-jvt-symbol.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-default-jvt.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-default-no-jvt.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-dump-unknown.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-emit-relocs.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-equal-benefit.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-equal-benefit.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-comdat-symbol.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-comdat.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-comdat.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-dead-symbol.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-dead.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-gc-dead.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-jalt.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-jt.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym-2.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit-jvt-ref.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit-jvt-ref.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit-section.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit-symbol.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-benefit.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-relax-zcmt.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-relo-1.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-relo-2.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-relo.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-norelax.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-norelax.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-overflow.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-overflow.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-pie-relocs.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-pie-text.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-pie.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-pie.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-relax-zcmt.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-rv32.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-rv32.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared-relocs.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared-symbol.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared-text.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-strip-symbol.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-symbol-policy.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-lma.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-lma.ld
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-zero.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-zero.ld
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-vma-zero.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcd-conflict.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcmt-no-zca.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcmt-no-zca.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcmt-no-zicsr.d
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-zcmt-no-zicsr.s
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump.ld
create mode 100644 ld/testsuite/ld-riscv-elf/table-jump.s
--
2.43.0
More information about the Binutils
mailing list