[PATCH 3/3] RISC-V: Add ZCMT relaxation linker tests
Jerry Zhang Jian
jerry.zhangjian@sifive.com
Mon Jan 12 13:29:34 GMT 2026
From: Kito Cheng <kito.cheng@sifive.com>
Add ld tests to cover ZCMT relaxation, no-relax cases, multiple local
symbols, dump output for table jump entries, benefit-based ranking,
JVT overflow handling, RV32 cm.jt, shared library, and no-zcmt cases.
Signed-off-by: Kito Cheng <kito.cheng@sifive.com>
Co-Authored-by: Jerry Zhang Jian <jerry.zhangjian@sifive.com>
Co-Authored-by: Hau Hsu <hau.hsu@sifive.com>
Co-Authored-by: Charlie Keaney <charlie.keaney@embecosm.com>
Co-Authored-by: Mary Bennett <mary.bennett@embecosm.com>
Co-Authored-by: Nandni Jamnadas <nandni.jamnadas@embecosm.com>
Co-Authored-by: Sinan Lin <sinan.lin@linux.alibaba.com>
Co-Authored-by: Simon Cook <simon.cook@embecosm.com>
Co-Authored-by: Shihua Liao <shihua@iscas.ac.cn>
Co-Authored-by: Yulong Shi <yulong@iscas.ac.cn>
---
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 +++++++++++++
24 files changed, 496 insertions(+)
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
diff --git a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
index b0d510ac8da..cbf13d8d98b 100644
--- a/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
+++ b/ld/testsuite/ld-riscv-elf/ld-riscv-elf.exp
@@ -339,4 +339,18 @@ if [istarget "riscv*-*-*"] {
run_dump_test "tls"
run_dump_test "tlsbin"
run_dump_test "absolute-no-relative"
+
+ # Zcmt (jump table) tests
+ run_dump_test "table-jump-jalt"
+ run_dump_test "table-jump-jt"
+ run_dump_test "table-jump-dump-unknown"
+ run_dump_test "table-jump-no-relo"
+ run_dump_test "table-jump-relax-zcmt"
+ run_dump_test "table-jump-no-relax-zcmt"
+ run_dump_test "table-jump-multiple-local-sym"
+ run_dump_test "table-jump-benefit"
+ run_dump_test "table-jump-no-zcmt"
+ run_dump_test "table-jump-overflow"
+ run_dump_test "table-jump-rv32"
+ run_dump_test "table-jump-shared"
}
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-benefit.d b/ld/testsuite/ld-riscv-elf/table-jump-benefit.d
new file mode 100644
index 00000000000..012ed07d2c7
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-benefit.d
@@ -0,0 +1,18 @@
+#source: table-jump-benefit.s
+#as: -march=rv64ic_zcmt
+#ld: -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .riscv.jvt:
+0+[0-9a-f]+ <__jvt_base\$>:
+[ ]+...
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[32\]:[ ]+func_d
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[33\]:[ ]+func_c
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[34\]:[ ]+func_b
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[35\]:[ ]+func_a
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <func_d>
+#pass
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-benefit.s b/ld/testsuite/ld-riscv-elf/table-jump-benefit.s
new file mode 100644
index 00000000000..54c592ba0d7
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-benefit.s
@@ -0,0 +1,52 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ # Test benefit ranking: higher frequency functions should
+ # be prioritized for JVT entry allocation.
+ # Use reverse alphabetical order to verify sorting by benefit,
+ # not by name.
+
+ # func_d called 80 times - highest benefit
+ .rept 80
+ call func_d
+ .endr
+
+ # func_c called 50 times - medium benefit
+ .rept 50
+ call func_c
+ .endr
+
+ # func_b called 20 times - lower benefit
+ .rept 20
+ call func_b
+ .endr
+
+ # func_a called 5 times - lowest benefit
+ .rept 5
+ call func_a
+ .endr
+
+ ret
+
+ .globl func_a
+ .type func_a, %function
+func_a:
+ ret
+
+ .globl func_b
+ .type func_b, %function
+func_b:
+ ret
+
+ .globl func_c
+ .type func_c, %function
+func_c:
+ ret
+
+ .globl func_d
+ .type func_d, %function
+func_d:
+ ret
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-dump-unknown.d b/ld/testsuite/ld-riscv-elf/table-jump-dump-unknown.d
new file mode 100644
index 00000000000..b8f5b1a7729
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-dump-unknown.d
@@ -0,0 +1,24 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT=1
+#ld: -Ttable-jump.ld --strip-all --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .riscv.jvt:
+0+[0-9a-f]+ <.riscv.jvt>:
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[0]:[ ]+<unknown>
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[1]:[ ]+<unknown>
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <.text>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0
+.*:[ ]+[0-9a-f]+[ ]+ret
+.*:[ ]+[0-9a-f]+[ ]+ret
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-jalt.d b/ld/testsuite/ld-riscv-elf/table-jump-jalt.d
new file mode 100644
index 00000000000..098e65fc403
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-jalt.d
@@ -0,0 +1,18 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JALT=1
+#ld: -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .riscv.jvt:
+0+[0-9a-f]+ <__jvt_base\$>:
+[ ]+...
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[32\]:[ ]+foo_global
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[33\]:[ ]+foo_local
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+33 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+33 # [0-9a-f]+ <foo_local>
+#...
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-jt.d b/ld/testsuite/ld-riscv-elf/table-jump-jt.d
new file mode 100644
index 00000000000..0abbbb5ee5f
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-jt.d
@@ -0,0 +1,23 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT=1
+#ld: -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .riscv.jvt:
+0+[0-9a-f]+ <__jvt_base\$>:
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[0\]:[ ]+foo_global
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[1\]:[ ]+foo_local
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+#...
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym-2.s b/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym-2.s
new file mode 100644
index 00000000000..bf106b88f2d
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym-2.s
@@ -0,0 +1,12 @@
+ .section .text
+ .type bar, %function
+bar:
+ .rept 70
+ call foo_local
+ call foo_global
+ .endr
+ ret
+
+ .type foo_local, %function
+foo_local:
+ ret
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.d b/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.d
new file mode 100644
index 00000000000..07dbd3978be
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.d
@@ -0,0 +1,16 @@
+#source: table-jump-multiple-local-sym.s
+#source: table-jump-multiple-local-sym-2.s
+#as: -march=rv64ic_zcmt
+#ld: -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+
+#...
+Disassembly of section .riscv.jvt:
+0+[0-9a-f]+ <__jvt_base\$>:
+[ ]+...
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[32\]:[ ]+foo_global
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[33\]:[ ]+foo_local
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[34\]:[ ]+foo_local
+
+Disassembly of section .text:
+#...
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.s b/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.s
new file mode 100644
index 00000000000..ccc2525e2f7
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-multiple-local-sym.s
@@ -0,0 +1,18 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 70
+ call foo_global
+ call foo_local
+ .endr
+
+ .globl foo_global
+ .type foo_global, %function
+foo_global:
+ ret
+
+ .type foo_local, %function
+foo_local:
+ ret
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-no-relax-zcmt.d b/ld/testsuite/ld-riscv-elf/table-jump-no-relax-zcmt.d
new file mode 100644
index 00000000000..a551a05c97e
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-no-relax-zcmt.d
@@ -0,0 +1,17 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT_JALT=1
+#ld: -Ttable-jump.ld --no-relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <foo_global>
+#...
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-no-relo-1.s b/ld/testsuite/ld-riscv-elf/table-jump-no-relo-1.s
new file mode 100644
index 00000000000..d3e9b7ce4dd
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-no-relo-1.s
@@ -0,0 +1,7 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+L0: j L0
+ ret
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-no-relo-2.s b/ld/testsuite/ld-riscv-elf/table-jump-no-relo-2.s
new file mode 100644
index 00000000000..f68cdaf423b
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-no-relo-2.s
@@ -0,0 +1,12 @@
+ .section .text
+
+ .globl foo
+ .type foo, %function
+foo:
+ call bar
+
+
+ .globl bar
+ .type bar, %function
+bar:
+ ret
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-no-relo.d b/ld/testsuite/ld-riscv-elf/table-jump-no-relo.d
new file mode 100644
index 00000000000..9ff45cb2616
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-no-relo.d
@@ -0,0 +1,16 @@
+#source: table-jump-no-relo-1.s
+#source: table-jump-no-relo-2.s
+#as: -march=rv64ic_zcmt
+#ld: -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <_start>
+.*:[ ]+[0-9a-f]+[ ]+ret
+
+0+[0-9a-f]+ <foo>:
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <bar>
+
+0+[0-9a-f]+ <bar>:
+.*:[ ]+[0-9a-f]+[ ]+ret
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.d b/ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.d
new file mode 100644
index 00000000000..d65a6b9c47c
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.d
@@ -0,0 +1,17 @@
+#source: table-jump-no-zcmt.s
+#as: -march=rv64ic
+#ld: -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+# All calls should remain as jal (not converted to cm.jalt)
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <foo>
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <foo>
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <foo>
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <foo>
+#...
+0+[0-9a-f]+ <foo>:
+.*:[ ]+[0-9a-f]+[ ]+ret
+#pass
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.s b/ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.s
new file mode 100644
index 00000000000..630e4f5c87e
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-no-zcmt.s
@@ -0,0 +1,17 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ # This file is assembled without zcmt extension
+ # The linker should NOT generate JVT section
+ .rept 50
+ call foo
+ .endr
+ ret
+
+ .globl foo
+ .type foo, %function
+foo:
+ ret
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-overflow.d b/ld/testsuite/ld-riscv-elf/table-jump-overflow.d
new file mode 100644
index 00000000000..aa88ec93962
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-overflow.d
@@ -0,0 +1,19 @@
+#source: table-jump-overflow.s
+#as: -march=rv64ic_zcmt
+#ld: -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .riscv.jvt:
+0+[0-9a-f]+ <__jvt_base\$>:
+#...
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[32\]:[ ]+func_top
+#...
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[255\]:[ ]+func_[0-9]+
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <func_top>
+#...
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <func_overflow>
+#pass
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-overflow.s b/ld/testsuite/ld-riscv-elf/table-jump-overflow.s
new file mode 100644
index 00000000000..88aee0c669a
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-overflow.s
@@ -0,0 +1,50 @@
+ .altmacro
+ .section .text
+
+ # Test JVT overflow: cm.jalt has 224 entries (index 32-255)
+ # func_top: called 10x (highest benefit), guaranteed jvt.jalt[32]
+ # func_0 to func_222: called 2x each, fill remaining 223 JVT slots
+ # func_overflow: called 1x (lowest benefit), overflows, remains jal
+
+ .macro call2 n
+ call func_\n
+ call func_\n
+ .endm
+
+ .macro defn n
+ .type func_\n, %function
+func_\n: ret
+ .endm
+
+ .globl _start
+ .type _start, %function
+_start:
+ # func_top: highest benefit, guaranteed first JVT entry
+ .rept 10
+ call func_top
+ .endr
+
+ # 223 functions with 2 calls each (fill remaining JVT entries)
+ .set i, 0
+ .rept 223
+ call2 %i
+ .set i, i+1
+ .endr
+
+ # func_overflow: lowest benefit, will not fit in JVT
+ call func_overflow
+ ret
+
+ # Define functions
+ .type func_top, %function
+func_top: ret
+
+ .set i, 0
+ .rept 223
+ defn %i
+ .set i, i+1
+ .endr
+
+ .type func_overflow, %function
+func_overflow: ret
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-relax-zcmt.d b/ld/testsuite/ld-riscv-elf/table-jump-relax-zcmt.d
new file mode 100644
index 00000000000..1adb1b289ce
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-relax-zcmt.d
@@ -0,0 +1,23 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT_JALT=1
+#ld: -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .riscv.jvt:
+0+[0-9a-f]+ <__jvt_base\$>:
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[0\]:[ ]+foo_global
+[ ]+...
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[32\]:[ ]+foo_global
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <foo_global>
+#...
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-rv32.d b/ld/testsuite/ld-riscv-elf/table-jump-rv32.d
new file mode 100644
index 00000000000..d3db1ba4e41
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-rv32.d
@@ -0,0 +1,16 @@
+#source: table-jump-rv32.s
+#as: -march=rv32ic_zcmt
+#ld: -Ttable-jump.ld --relax-zcmt -melf32lriscv
+#objdump: -d
+#...
+Disassembly of section .riscv.jvt:
+0+[0-9a-f]+ <__jvt_base\$>:
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[0\]:[ ]+foo_global
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[1\]:[ ]+foo_local
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+#pass
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-rv32.s b/ld/testsuite/ld-riscv-elf/table-jump-rv32.s
new file mode 100644
index 00000000000..0e5c062ac55
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-rv32.s
@@ -0,0 +1,24 @@
+ .section .text
+
+ # Test RV32 ZCMT relaxation for cm.jt
+ # jal x0 (no link) -> cm.jt (index 0-31)
+ # JVT entry cost: 4 bytes (RV32), benefit = 2 per call
+ # Threshold: 3*2=6 > 4 (just profitable)
+
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 3
+ jal x0, foo_local
+ jal x0, foo_global
+ .endr
+
+ .globl foo_global
+ .type foo_global, %function
+foo_global:
+ ret
+
+ .type foo_local, %function
+foo_local:
+ ret
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-shared.d b/ld/testsuite/ld-riscv-elf/table-jump-shared.d
new file mode 100644
index 00000000000..a1e7554adf9
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-shared.d
@@ -0,0 +1,13 @@
+#source: table-jump-shared.s
+#as: -march=rv64ic_zcmt -fpic
+#ld: -shared --relax-zcmt
+#objdump: -d
+#...
+Disassembly of section .text:
+#...
+0+[0-9a-f]+ <foo>:
+# Calls should NOT be cm.jalt in shared library (should be jal to PLT)
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <bar@plt>
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <bar@plt>
+#pass
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump-shared.s b/ld/testsuite/ld-riscv-elf/table-jump-shared.s
new file mode 100644
index 00000000000..6e75a70437a
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump-shared.s
@@ -0,0 +1,16 @@
+ .section .text
+
+ .globl foo
+ .type foo, %function
+foo:
+ # Shared library: JVT relaxation should be disabled
+ .rept 50
+ call bar
+ .endr
+ ret
+
+ .globl bar
+ .type bar, %function
+bar:
+ ret
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump.ld b/ld/testsuite/ld-riscv-elf/table-jump.ld
new file mode 100644
index 00000000000..7742d653bf7
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump.ld
@@ -0,0 +1,17 @@
+ENTRY(_start)
+SECTIONS
+{
+ .got 0x1000 : {
+ *(.got)
+ }
+ .riscv.jvt : {
+ *(.riscv.jvt)
+ }
+ .data 0x2000: {
+ *(.data)
+ }
+ .text 0x3000 : {
+ *(.text)
+ }
+}
+
diff --git a/ld/testsuite/ld-riscv-elf/table-jump.s b/ld/testsuite/ld-riscv-elf/table-jump.s
new file mode 100644
index 00000000000..d4802d50021
--- /dev/null
+++ b/ld/testsuite/ld-riscv-elf/table-jump.s
@@ -0,0 +1,37 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+.ifdef TEST_CM_JT
+ .rept 5
+ jal x0, foo_local
+ jal x0, foo_global
+ .endr
+.endif
+
+.ifdef TEST_CM_JALT
+ .rept 70
+ call foo_global
+ call foo_local
+ .endr
+.endif
+
+.ifdef TEST_CM_JT_JALT
+ .rept 5
+ jal x0, foo_global
+ .endr
+ .rept 70
+ call foo_global
+ .endr
+.endif
+
+ .globl foo_global
+ .type foo_global, %function
+foo_global:
+ ret
+
+ .type foo_local, %function
+foo_local:
+ ret
+
--
2.51.0
More information about the Binutils
mailing list