@@ -182,11 +182,60 @@ if [istarget "riscv*-*-*"] {
"-march=rv64i -mabi=lp64" {weakref64.s} \
{{objdump -d weakref64.d}} "weakref64"]]
+ # 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-addend"
+ run_dump_test "table-jump-norelax"
+ run_dump_test "table-jump-no-zcmt"
+ run_dump_test "table-jump-zcmt-no-zca"
+ run_dump_test "table-jump-zcmt-no-zicsr"
+ run_dump_test "table-jump-zcd-conflict"
+ run_dump_test "table-jump-overflow"
+ run_dump_test "table-jump-equal-benefit"
+ run_dump_test "table-jump-rv32"
+ run_dump_test "table-jump-vma-zero"
+ run_dump_test "table-jump-emit-relocs"
+ run_dump_test "table-jump-be64-bytes"
+ run_dump_test "table-jump-be64-text"
+ run_dump_test "table-jump-be32-bytes"
+ run_dump_test "table-jump-be32-text"
+ run_dump_test "table-jump-no-benefit-symbol"
+ run_dump_test "table-jump-no-benefit-section"
+ run_dump_test "table-jump-no-benefit-jvt-ref"
+ run_dump_test "table-jump-default-no-jvt"
+ run_dump_test "table-jump-default-jvt"
+ run_dump_test "table-jump-default-jvt-symbol"
+ run_dump_test "table-jump-default-jvt-relocs"
+ run_dump_test "table-jump-base-collision"
+ run_dump_test "table-jump-base-local-collision"
+ run_dump_test "table-jump-symbol-policy"
+ run_dump_test "table-jump-strip-symbol"
+ run_dump_test "table-jump-gc-dead"
+ run_dump_test "table-jump-gc-dead-symbol"
+ run_dump_test "table-jump-gc-comdat"
+ run_dump_test "table-jump-gc-comdat-symbol"
+ run_dump_test "table-jump-vma-lma"
+
# The following tests require shared library support.
if ![check_shared_lib_support] {
return
}
+ run_dump_test "table-jump-pie"
+ run_dump_test "table-jump-pie-text"
+ run_dump_test "table-jump-pie-relocs"
+ run_dump_test "table-jump-shared"
+ run_dump_test "table-jump-shared-text"
+ run_dump_test "table-jump-shared-symbol"
+ run_dump_test "table-jump-shared-relocs"
+
run_dump_test "relro-relax-lui"
run_dump_test "relro-relax-pcrel"
run_dump_test "variant_cc-now"
@@ -342,4 +391,5 @@ if [istarget "riscv*-*-*"] {
run_dump_test "tls"
run_dump_test "tlsbin"
run_dump_test "absolute-no-relative"
+
}
new file mode 100644
@@ -0,0 +1,18 @@
+#source: table-jump-addend.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\]:[ ]+target
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[33\]:[ ]+target_4
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[34\]:[ ]+target_8
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <target>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+33 # [0-9a-f]+ <target_4>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+34 # [0-9a-f]+ <target_8>
+#pass
new file mode 100644
@@ -0,0 +1,21 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 50
+ call target
+ call target + 4
+ call target + 8
+ .endr
+
+ .globl target
+ .type target, %function
+target:
+ .word 0x00000013
+ .globl target_4
+target_4:
+ .word 0x00000013
+ .globl target_8
+target_8:
+ ret
new file mode 100644
@@ -0,0 +1,4 @@
+#source: table-jump-base-collision.s
+#as: -march=rv64ic_zcmt
+#ld: -Ttable-jump.ld --relax-zcmt
+#error: .*__jvt_base\$ is reserved for Zcmt table-jump relaxation
new file mode 100644
@@ -0,0 +1,18 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 5
+ tail target
+ .endr
+ ret
+ .space 4096
+
+ .globl __jvt_base$
+__jvt_base$:
+ .word 0
+
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -0,0 +1,4 @@
+#source: table-jump-base-local-collision.s
+#as: -march=rv64ic_zcmt
+#ld: -Ttable-jump.ld --relax-zcmt
+#error: .*__jvt_base\$ is reserved for Zcmt table-jump relaxation
new file mode 100644
@@ -0,0 +1,17 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 5
+ tail target
+ .endr
+ ret
+ .space 4096
+
+__jvt_base$:
+ .word 0
+
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -0,0 +1,10 @@
+#source: table-jump-rv32.s
+#as: -march=rv32ic_zcmt -mbig-endian
+#ld: -melf32briscv -Ttable-jump.ld --relax-zcmt
+#objdump: -s -j .riscv.jvt
+
+#...
+.*: file format elf32-bigriscv
+#...
+Contents of section .riscv.jvt:
+[ ]+0+[0-9a-f]*[ ]+0000400e[ ]+0000400c.*
new file mode 100644
@@ -0,0 +1,13 @@
+#source: table-jump-rv32.s
+#as: -march=rv32ic_zcmt -mbig-endian
+#ld: -melf32briscv -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+
+#...
+.*: file format elf32-bigriscv
+#...
+Disassembly of section .text:
+#...
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_global>
+#pass
new file mode 100644
@@ -0,0 +1,10 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT=1 -mbig-endian
+#ld: -melf64briscv -Ttable-jump.ld --relax-zcmt
+#objdump: -s -j .riscv.jvt
+
+#...
+.*: file format elf64-bigriscv
+#...
+Contents of section .riscv.jvt:
+[ ]+0+[0-9a-f]*[ ]+00000000[ ]+00004016[ ]+00000000[ ]+00004014.*
new file mode 100644
@@ -0,0 +1,13 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT=1 -mbig-endian
+#ld: -melf64briscv -Ttable-jump.ld --relax-zcmt
+#objdump: -d
+
+#...
+.*: file format elf64-bigriscv
+#...
+Disassembly of section .text:
+#...
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_global>
+#pass
new file mode 100644
@@ -0,0 +1,17 @@
+#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
new file mode 100644
@@ -0,0 +1,51 @@
+ .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
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT_JALT=1
+#ld: --relax-zcmt
+#readelf: -rW
+
+#failif
+#...
+.*R_RISCV_TABLE_JUMP.*
+#pass
new file mode 100644
@@ -0,0 +1,10 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT_JALT=1
+#ld: --relax-zcmt
+#readelf: -SWs
+
+#...
+.*\.riscv\.jvt[ ]+PROGBITS[ ]+[0-9a-f]+[ ]+[0-9a-f]+[ ]+[0-9a-f]+.*
+#...
+[ ]+[0-9]+:[ ]+0+[0-9a-f]+[ ]+0[ ]+NOTYPE[ ]+LOCAL[ ]+DEFAULT[ ]+[0-9]+[ ]+__jvt_base\$
+#pass
new file mode 100644
@@ -0,0 +1,12 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JT_JALT=1
+#ld: --relax-zcmt
+#objdump: -d
+
+#...
+Disassembly of section .text:
+#...
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_global>
+#...
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <foo_global>
+#pass
new file mode 100644
@@ -0,0 +1,15 @@
+#source: table-jump-no-benefit.s
+#as: -march=rv64ic_zcmt
+#ld: --relax-zcmt
+#objdump: -d
+
+#...
+Disassembly of section .text:
+#...
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <target>
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <target>
+#...
+0+[0-9a-f]+ <target>:
+.*:[ ]+[0-9a-f]+[ ]+ret
+#pass
new file mode 100644
@@ -0,0 +1,25 @@
+#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[ ]+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]+[ ]+cm.jt[ ]+1
+#...
+.*:[ ]+[0-9a-f]+[ ]+ret
+.*:[ ]+[0-9a-f]+[ ]+ret
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JALT=1
+#ld: -Ttable-jump.ld --emit-relocs --relax-zcmt
+#readelf: -rW
+
+#failif
+#...
+.*R_RISCV_(TABLE_JUMP|DELETE|DELETE_AND_RELAX).*
+#pass
new file mode 100644
@@ -0,0 +1,18 @@
+#source: table-jump-equal-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_b
+.*:[ ]+[0-9a-f]+[ ]+jvt.jalt\[33\]:[ ]+func_a
+#...
+Disassembly of section .text:
+#...
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # [0-9a-f]+ <func_b>
+#...
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+33 # [0-9a-f]+ <func_a>
+#pass
new file mode 100644
@@ -0,0 +1,19 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 70
+ call func_b
+ call func_a
+ .endr
+
+ .globl func_a
+ .type func_a, %function
+func_a:
+ ret
+
+ .globl func_b
+ .type func_b, %function
+func_b:
+ ret
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-gc-comdat.s
+#as: -march=rv64ic_zcmt
+#ld: --gc-sections --relax-zcmt -e _start
+#readelf: -SWs
+
+#failif
+#...
+.*(__jvt_base\$|\.riscv\.jvt).*
+#pass
new file mode 100644
@@ -0,0 +1,11 @@
+#source: table-jump-gc-comdat.s
+#as: -march=rv64ic_zcmt
+#ld: --gc-sections --relax-zcmt -e _start
+#objdump: -d
+
+#...
+Disassembly of section .text:
+#...
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+ret
+#pass
new file mode 100644
@@ -0,0 +1,18 @@
+ .section .text.live, "ax"
+
+ .globl _start
+ .type _start, %function
+_start:
+ ret
+
+ .section .text.dead_group, "axG", @progbits, dead_group, comdat
+ .type dead_group_start, %function
+dead_group_start:
+ .rept 70
+ call dead_group_target
+ .endr
+ ret
+
+ .type dead_group_target, %function
+dead_group_target:
+ ret
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-gc-dead.s
+#as: -march=rv64ic_zcmt
+#ld: --gc-sections --relax-zcmt -e _start
+#readelf: -SWs
+
+#failif
+#...
+.*(__jvt_base\$|\.riscv\.jvt).*
+#pass
new file mode 100644
@@ -0,0 +1,11 @@
+#source: table-jump-gc-dead.s
+#as: -march=rv64ic_zcmt
+#ld: --gc-sections --relax-zcmt -e _start
+#objdump: -d
+
+#...
+Disassembly of section .text:
+#...
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+ret
+#pass
new file mode 100644
@@ -0,0 +1,18 @@
+ .section .text.live, "ax"
+
+ .globl _start
+ .type _start, %function
+_start:
+ ret
+
+ .section .text.dead, "ax"
+ .type dead_start, %function
+dead_start:
+ .rept 70
+ call dead_target
+ .endr
+ ret
+
+ .type dead_target, %function
+dead_target:
+ ret
new file mode 100644
@@ -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>
+#...
new file mode 100644
@@ -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_local
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[1\]:[ ]+foo_global
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_global>
+#...
new file mode 100644
@@ -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
new file mode 100644
@@ -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:
+#...
new file mode 100644
@@ -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
new file mode 100644
@@ -0,0 +1,4 @@
+#source: table-jump-no-benefit-jvt-ref.s
+#as: -march=rv64ic_zcmt
+#ld: --relax-zcmt
+#error: .*undefined reference to `__jvt_base\$'
new file mode 100644
@@ -0,0 +1,16 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ .option push
+ .option norelax
+ la a0, __jvt_base$
+ .option pop
+ tail target
+ tail target
+ .space 4096
+
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-no-benefit.s
+#as: -march=rv64ic_zcmt
+#ld: --relax-zcmt
+#readelf: -SW
+
+#failif
+#...
+.*\.riscv\.jvt.*
+#pass
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-no-benefit.s
+#as: -march=rv64ic_zcmt
+#ld: --relax-zcmt
+#readelf: -sW
+
+#failif
+#...
+.*__jvt_base\$.*
+#pass
new file mode 100644
@@ -0,0 +1,12 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ tail target
+ tail target
+ .space 4096
+
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -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>
+#...
new file mode 100644
@@ -0,0 +1,7 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+L0: j L0
+ ret
new file mode 100644
@@ -0,0 +1,12 @@
+ .section .text
+
+ .globl foo
+ .type foo, %function
+foo:
+ call bar
+
+
+ .globl bar
+ .type bar, %function
+bar:
+ ret
new file mode 100644
@@ -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
new file mode 100644
@@ -0,0 +1,16 @@
+#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
new file mode 100644
@@ -0,0 +1,16 @@
+ .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
new file mode 100644
@@ -0,0 +1,15 @@
+#source: table-jump-norelax.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]+[ ]+auipc[ ]+ra,0x1
+.*:[ ]+[0-9a-f]+[ ]+jalr[ ]+[0-9]+\(ra\) # [0-9a-f]+ <target>
+.*:[ ]+[0-9a-f]+[ ]+auipc[ ]+t[0-9],0x1
+.*:[ ]+[0-9a-f]+[ ]+jr[ ]+[0-9]+\(t[0-9]\) # [0-9a-f]+ <target>
+.*:[ ]+[0-9a-f]+[ ]+j[ ]+[0-9a-f]+ <target>
+#...
+0+[0-9a-f]+ <target>:
+.*:[ ]+[0-9a-f]+[ ]+ret
new file mode 100644
@@ -0,0 +1,17 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ .option push
+ .option norelax
+ call target
+ tail target
+ jal x0, target
+ .option pop
+
+ .space 4096
+
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -0,0 +1,11 @@
+#source: table-jump-overflow.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]+[ ]+jal[ ]+[0-9a-f]+ <func_top>
+#...
+.*:[ ]+[0-9a-f]+[ ]+jal[ ]+[0-9a-f]+ <func_overflow>
+#pass
new file mode 100644
@@ -0,0 +1,49 @@
+ .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
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-pie.s
+#as: -march=rv64ic_zcmt -fpic
+#ld: -pie --relax-zcmt
+#readelf: -rW
+
+#failif
+#...
+.*R_RISCV_(TABLE_JUMP|DELETE|DELETE_AND_RELAX).*
+#pass
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-pie.s
+#as: -march=rv64ic_zcmt -fpic
+#ld: -pie --relax-zcmt
+#objdump: -d
+
+#failif
+#...
+.*cm\.j(al)?t.*
+#pass
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-pie.s
+#as: -march=rv64ic_zcmt -fpic
+#ld: -pie --relax-zcmt
+#readelf: -SWs
+
+#failif
+#...
+.*(__jvt_base\$|\.riscv\.jvt).*
+#pass
new file mode 100644
@@ -0,0 +1,13 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 70
+ call target
+ .endr
+ ret
+
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -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>
+#...
new file mode 100644
@@ -0,0 +1,15 @@
+#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_local
+.*:[ ]+[0-9a-f]+[ ]+jvt.jt\[1\]:[ ]+foo_global
+#...
+Disassembly of section .text:
+0+[0-9a-f]+ <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # [0-9a-f]+ <foo_local>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+1 # [0-9a-f]+ <foo_global>
+#pass
new file mode 100644
@@ -0,0 +1,25 @@
+ .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
+ tail foo_local
+ tail foo_global
+ .endr
+
+ .space 4096
+
+ .globl foo_global
+ .type foo_global, %function
+foo_global:
+ ret
+
+ .type foo_local, %function
+foo_local:
+ ret
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-shared.s
+#as: -march=rv64ic_zcmt -fpic
+#ld: -shared --relax-zcmt
+#readelf: -rW
+
+#failif
+#...
+.*R_RISCV_(TABLE_JUMP|DELETE|DELETE_AND_RELAX).*
+#pass
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-shared.s
+#as: -march=rv64ic_zcmt -fpic
+#ld: -shared --relax-zcmt
+#readelf: -SWs
+
+#failif
+#...
+.*(__jvt_base\$|\.riscv\.jvt).*
+#pass
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-shared.s
+#as: -march=rv64ic_zcmt -fpic
+#ld: -shared --relax-zcmt
+#objdump: -d
+
+#failif
+#...
+.*cm\.j(al)?t.*
+#pass
new file mode 100644
@@ -0,0 +1,12 @@
+#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
new file mode 100644
@@ -0,0 +1,15 @@
+ .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
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JALT=1
+#ld: -Ttable-jump.ld --strip-all --relax-zcmt
+#readelf: -sW
+
+#failif
+#...
+.*__jvt_base\$.*
+#pass
new file mode 100644
@@ -0,0 +1,8 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JALT=1
+#ld: -Ttable-jump.ld --relax-zcmt
+#readelf: -sW
+
+#...
+[ ]+[0-9]+:[ ]+0+[0-9a-f]+[ ]+0[ ]+NOTYPE[ ]+LOCAL[ ]+DEFAULT[ ]+[0-9]+[ ]+__jvt_base\$
+#pass
new file mode 100644
@@ -0,0 +1,16 @@
+#source: table-jump.s
+#as: -march=rv64ic_zcmt --defsym TEST_CM_JALT=1
+#ld: -Ttable-jump-vma-lma.ld --relax-zcmt
+#objdump: -d
+
+#...
+Disassembly of section .riscv.jvt:
+#...
+.*:[ ]+0000000000003118[ ]+jvt.jalt\[32\]:[ ]+foo_global
+.*:[ ]+000000000000311a[ ]+jvt.jalt\[33\]:[ ]+foo_local
+#...
+Disassembly of section .text:
+#...
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+32 # 3118 <foo_global>
+.*:[ ]+[0-9a-f]+[ ]+cm.jalt[ ]+33 # 311a <foo_local>
+#pass
new file mode 100644
@@ -0,0 +1,10 @@
+ENTRY(_start)
+SECTIONS
+{
+ .riscv.jvt 0x1000 : AT(0x8000) {
+ *(.riscv.jvt)
+ }
+ .text 0x3000 : AT(0x9000) {
+ *(.text)
+ }
+}
new file mode 100644
@@ -0,0 +1,15 @@
+#source: table-jump-vma-zero.s
+#as: -march=rv64ic_zcmt
+#ld: -Ttable-jump-vma-zero.ld --relax-zcmt
+#objdump: -d -s -j .riscv.jvt -j .text
+
+#...
+Contents of section .riscv.jvt:
+[ ]+1000[ ]+00000000[ ]+00000000.*
+#...
+Disassembly of section .text:
+#...
+0+3000 <_start>:
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # 0 <target>
+.*:[ ]+[0-9a-f]+[ ]+cm.jt[ ]+0 # 0 <target>
+#pass
new file mode 100644
@@ -0,0 +1,13 @@
+ENTRY(_start)
+SECTIONS
+{
+ .text.target 0x0 : {
+ *(.text.target)
+ }
+ .riscv.jvt 0x1000 : {
+ *(.riscv.jvt)
+ }
+ .text 0x3000 : {
+ *(.text.start)
+ }
+}
new file mode 100644
@@ -0,0 +1,14 @@
+ .section .text.start, "ax"
+
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 5
+ tail target
+ .endr
+ ret
+
+ .section .text.target, "ax"
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump.s
+#as: -march=rv64imafd_zicsr_zifencei_zca_zcd_zcmt --defsym TEST_CM_JT_JALT=1
+#ld: -Ttable-jump.ld --relax-zcmt
+#readelf: -SWs
+
+#failif
+#...
+.*(__jvt_base\$|\.riscv\.jvt).*
+#pass
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-zcmt-no-zca.s
+#as: -march=rv64i -mno-arch-attr
+#ld: --relax-zcmt
+#readelf: -SWs
+
+#failif
+#...
+.*(__jvt_base\$|\.riscv\.jvt).*
+#pass
new file mode 100644
@@ -0,0 +1,24 @@
+ .section .riscv.attributes,"",@0x70000003
+ .byte 0x41
+0:
+ .4byte 1f-0b
+ .asciz "riscv"
+2:
+ .byte 1
+ .4byte 1f-2b
+ .byte 5
+ .asciz "rv64i2p1_zicsr2p0_zcmt1p0"
+1:
+
+ .section .text
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 70
+ call target
+ .endr
+ ret
+
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -0,0 +1,9 @@
+#source: table-jump-zcmt-no-zicsr.s
+#as: -march=rv64i -mno-arch-attr
+#ld: --relax-zcmt
+#readelf: -SWs
+
+#failif
+#...
+.*(__jvt_base\$|\.riscv\.jvt).*
+#pass
new file mode 100644
@@ -0,0 +1,24 @@
+ .section .riscv.attributes,"",@0x70000003
+ .byte 0x41
+0:
+ .4byte 1f-0b
+ .asciz "riscv"
+2:
+ .byte 1
+ .4byte 1f-2b
+ .byte 5
+ .asciz "rv64i2p1_zca1p0_zcmt1p0"
+1:
+
+ .section .text
+ .globl _start
+ .type _start, %function
+_start:
+ .rept 70
+ call target
+ .endr
+ ret
+
+ .type target, %function
+target:
+ ret
new file mode 100644
@@ -0,0 +1,16 @@
+ENTRY(_start)
+SECTIONS
+{
+ .got 0x1000 : {
+ *(.got)
+ }
+ .riscv.jvt : {
+ *(.riscv.jvt)
+ }
+ .data 0x2000: {
+ *(.data)
+ }
+ .text 0x3000 : {
+ *(.text)
+ }
+}
new file mode 100644
@@ -0,0 +1,46 @@
+ .section .text
+
+ .globl _start
+ .type _start, %function
+_start:
+.ifdef TEST_CM_JT
+ .rept 5
+ tail foo_local
+ tail 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
+ tail foo_global
+ .endr
+ .rept 140
+ call foo_global
+ .endr
+.endif
+
+ # Keep paired JAL candidates out of C.J range. Zcmt profiling runs
+ # after ordinary shortening, so near paired JALs should become C.J
+ # and no longer be Zcmt candidates.
+.ifdef TEST_CM_JT
+ .space 4096
+.endif
+.ifdef TEST_CM_JT_JALT
+ .space 4096
+.endif
+
+ .globl foo_global
+ .type foo_global, %function
+foo_global:
+ ret
+
+ .type foo_local, %function
+foo_local:
+ ret