[PATCH 0/3] RISC-V: Add ZCMT table jump linker relaxation

Jerry Zhang Jian jerry.zhangjian@sifive.com
Mon Jan 12 13:29:31 GMT 2026


This patch series adds linker relaxation support for the RISC-V Zcmt
extension, which provides compressed table jump instructions (cm.jt
and cm.jalt) for code size optimization.

The Zcmt extension uses a Jump Vector Table (JVT) to store target
addresses. The linker analyzes call/jump patterns and converts
frequently-used targets to table jump instructions when beneficial:

  - cm.jt: 2-byte table jump (indices 0-31), replaces JAL with rd=x0
  - cm.jalt: 2-byte table jump and link (indices 32-255), replaces
    AUIPC+JALR or JAL with rd=ra

The optimization is controlled by --relax-zcmt (enabled by default
when Zcmt is present) and --no-relax-zcmt options.

Patch 1: Core implementation of ZCMT table jump relaxation
Patch 2: Disassembler support for printing cm.jt/cm.jalt targets
Patch 3: Linker tests for the ZCMT relaxation

Kito Cheng (3):
  RISC-V: Add ZCMT table jump relaxation
  RISC-V: Print cm.jt and cm.jalt target addresses
  RISC-V: Add ZCMT relaxation linker tests

 bfd/elfnn-riscv.c                             | 903 +++++++++++++++++-
 bfd/elfxx-riscv.h                             |  21 +
 include/elf/riscv.h                           |   5 +
 include/opcode/riscv.h                        |   9 +
 ld/emultempl/riscvelf.em                      |  17 +-
 ld/ldlex.h                                    |   4 +-
 ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp    |  14 +
 .../ld-riscv-elf/table-jump-benefit.d         |  18 +
 .../ld-riscv-elf/table-jump-benefit.s         |  52 +
 .../ld-riscv-elf/table-jump-dump-unknown.d    |  24 +
 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 +
 .../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         |  17 +
 .../ld-riscv-elf/table-jump-no-zcmt.s         |  17 +
 .../ld-riscv-elf/table-jump-overflow.d        |  19 +
 .../ld-riscv-elf/table-jump-overflow.s        |  50 +
 .../ld-riscv-elf/table-jump-relax-zcmt.d      |  23 +
 ld/testsuite/ld-riscv-elf/table-jump-rv32.d   |  16 +
 ld/testsuite/ld-riscv-elf/table-jump-rv32.s   |  24 +
 ld/testsuite/ld-riscv-elf/table-jump-shared.d |  13 +
 ld/testsuite/ld-riscv-elf/table-jump-shared.s |  16 +
 ld/testsuite/ld-riscv-elf/table-jump.ld       |  17 +
 ld/testsuite/ld-riscv-elf/table-jump.s        |  37 +
 opcodes/riscv-dis.c                           | 153 ++-
 31 files changed, 1550 insertions(+), 58 deletions(-)
 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-dump-unknown.d
 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-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-overflow.d
 create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-overflow.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.d
 create mode 100644 ld/testsuite/ld-riscv-elf/table-jump-shared.s
 create mode 100644 ld/testsuite/ld-riscv-elf/table-jump.ld
 create mode 100644 ld/testsuite/ld-riscv-elf/table-jump.s

-- 
2.51.0



More information about the Binutils mailing list