[RFC,v3,3/5] ld: Add RISC-V --relax-tbljal options

Message ID 20260925033351.103018-1-jiawei@iscas.ac.cn
State New
Headers
Series None |

Commit Message

Jiawei Sept. 25, 2026, 3:33 a.m. UTC
  Expose default-off table-jump relaxation using --relax-tbljal[=zcmt]
and --no-relax-tbljal. An omitted scheme selects Zcmt; empty or unsupported
scheme names are errors. Preserve global --no-relax control.

Document the supported non-position-independent executable links and JVT
base initialization. Retain the upstream BFD pass registration entry point.

Use the option interface requested in review, following the proposal at
https://github.com/riscv-non-isa/riscv-toolchain-conventions/pull/186.

ld/ChangeLog:

        * NEWS: Add --relax-tbljal options.
        * emultempl/riscvelf.em: Handle --relax-tbljal option.
        * gen-doc.texi: Enable RISC-V docs.
        * ld.texi: Document --relax-tbljal.
        * ldlex.h (enum option_values): Add RELAX_TBLJAL options.
---
 ld/NEWS                  |  4 ++++
 ld/emultempl/riscvelf.em | 17 ++++++++++++++-
 ld/gen-doc.texi          |  2 +-
 ld/ld.texi               | 46 ++++++++++++++++++++++++++++++++++++++++
 ld/ldlex.h               |  2 ++
 5 files changed, 69 insertions(+), 2 deletions(-)
  

Patch

diff --git a/ld/NEWS b/ld/NEWS
index dab32bf648c..eae70aab5df 100644
--- a/ld/NEWS
+++ b/ld/NEWS
@@ -18,6 +18,10 @@ 
 
 Changes in 2.47:
 
+* Add the RISC-V --relax-tbljal[=zcmt] and --no-relax-tbljal options for
+  opt-in Zcmt table-jump relaxation in non-position-independent executable
+  links.  An omitted scheme selects zcmt; unsupported schemes are errors.
+
 * Add a linker optimization level of zero.  Using "-O 0" on the linker command
   line will stop it from combining the contents of mergeable sections.  This
   can significantly speed up the link process at the cost of producing larger
diff --git a/ld/emultempl/riscvelf.em b/ld/emultempl/riscvelf.em
index c0f3421f4e3..9f6fdbf20fd 100644
--- a/ld/emultempl/riscvelf.em
+++ b/ld/emultempl/riscvelf.em
@@ -26,7 +26,8 @@  fragment <<EOF
 #include "elfxx-riscv.h"
 
 static struct riscv_elf_params params = { .relax_gp = 1,
-					  .check_uleb128 = 0};
+					  .check_uleb128 = 0,
+					  .relax_zcmt = 0};
 EOF
 
 # Define some shell vars to insert bits of code into the standard elf
@@ -36,6 +37,8 @@  PARSE_AND_LIST_LONGOPTS=${PARSE_AND_LIST_LONGOPTS}'
     { "no-relax-gp", no_argument, NULL, OPTION_NO_RELAX_GP },
     { "check-uleb128", no_argument, NULL, OPTION_CHECK_ULEB128 },
     { "no-check-uleb128", no_argument, NULL, OPTION_NO_CHECK_ULEB128 },
+    { "relax-tbljal", optional_argument, NULL, OPTION_RELAX_TBLJAL },
+    { "no-relax-tbljal", no_argument, NULL, OPTION_NO_RELAX_TBLJAL },
 '
 
 PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
@@ -43,6 +46,8 @@  PARSE_AND_LIST_OPTIONS=${PARSE_AND_LIST_OPTIONS}'
   fprintf (file, _("  --no-relax-gp               Don'\''t perform GP relaxation\n"));
   fprintf (file, _("  --check-uleb128             Check if SUB_ULEB128 has non-zero addend\n"));
   fprintf (file, _("  --no-check-uleb128          Don'\''t check if SUB_ULEB128 has non-zero addend\n"));
+  fprintf (file, _("  --relax-tbljal[=zcmt]       Enable RISC-V table-jump relaxation (scheme: zcmt)\n"));
+  fprintf (file, _("  --no-relax-tbljal           Disable RISC-V table-jump relaxation (default)\n"));
 '
 
 PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
@@ -61,6 +66,16 @@  PARSE_AND_LIST_ARGS_CASES=${PARSE_AND_LIST_ARGS_CASES}'
     case OPTION_NO_CHECK_ULEB128:
       params.check_uleb128 = 0;
       break;
+
+    case OPTION_RELAX_TBLJAL:
+      if (optarg != NULL && strcmp (optarg, "zcmt") != 0)
+	fatal (_("%P: unsupported table-jump relaxation scheme: %s\n"), optarg);
+      params.relax_zcmt = 1;
+      break;
+
+    case OPTION_NO_RELAX_TBLJAL:
+      params.relax_zcmt = 0;
+      break;
 '
 
 fragment <<EOF
diff --git a/ld/gen-doc.texi b/ld/gen-doc.texi
index 561869f485a..6f1902aa85c 100644
--- a/ld/gen-doc.texi
+++ b/ld/gen-doc.texi
@@ -21,6 +21,7 @@ 
 @set PDP11
 @set POWERPC
 @set POWERPC64
+@set RISCV
 @set Renesas
 @set S/390
 @set SPU
@@ -32,4 +33,3 @@ 
 @clear SingleFormat
 @set UsesEnvVars
 @c ------------------------------ end CONFIGURATION VARS
-
diff --git a/ld/ld.texi b/ld/ld.texi
index 90c84c8d3c1..c9b3b9f8387 100644
--- a/ld/ld.texi
+++ b/ld/ld.texi
@@ -33,6 +33,7 @@ 
 @set PDP11
 @set POWERPC
 @set POWERPC64
+@set RISCV
 @set Renesas
 @set S/390
 @set SPU
@@ -4129,6 +4130,51 @@  in the PLT entries for MIPS R6.
 @c man end
 @end ifset
 
+@ifset RISCV
+@subsection Options specific to RISC-V targets
+
+@c man begin OPTIONS
+
+@table @gcctabopt
+
+@kindex --relax-tbljal
+@item --relax-tbljal
+@itemx --relax-tbljal=@var{scheme}
+Enable RISC-V table-jump relaxation using @var{scheme}.  The only supported
+scheme is currently @samp{zcmt}; omitting the argument is equivalent to
+@samp{--relax-tbljal=zcmt}.  An explicit scheme must follow @samp{=} with
+no intervening space.  Empty or unsupported scheme names are errors.
+
+Zcmt table-jump relaxation is performed only when the input architecture
+attributes permit the Zcmt extension.  The extension requires Zca and
+Zicsr, and is not compatible with Zcd.  This relaxation is disabled by
+default and is initially supported only for non-position-independent
+executable links.  It is conservatively disabled for PIC, PIE and shared
+links.
+
+The last @samp{--relax-tbljal} or @samp{--no-relax-tbljal} option determines
+whether table-jump relaxation is requested.  Disabling relaxation with
+@samp{--no-relax} also disables table-jump relaxation, regardless of where
+the table-jump option appears.
+
+When a non-empty @code{.riscv.jvt} section is emitted, the linker defines
+a local @code{__jvt_base$} symbol at the table base.  Programs using this
+relaxation must initialize the @code{jvt} CSR to @code{__jvt_base$}
+before executing @code{cm.jt} or @code{cm.jalt}.  The symbol is not
+defined when no profitable table is emitted; generic startup code that
+unconditionally references @code{__jvt_base$} is therefore unsupported
+unless it arranges an optional reference or is linked only when a JVT is
+emitted.
+
+@kindex --no-relax-tbljal
+@item --no-relax-tbljal
+Disable RISC-V table-jump relaxation.  This is the default.
+
+@end table
+
+@c man end
+@end ifset
+
 
 @ifset PDP11
 @subsection Options specific to PDP11 targets
diff --git a/ld/ldlex.h b/ld/ldlex.h
index b4f1bffd2a7..3de9e947900 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -430,6 +430,8 @@  enum option_values
   OPTION_NO_RELAX_GP,
   OPTION_CHECK_ULEB128,
   OPTION_NO_CHECK_ULEB128,
+  OPTION_RELAX_TBLJAL,
+  OPTION_NO_RELAX_TBLJAL,
   /* Used by emultempl/rxelf.em.  */
   OPTION_NO_FLAG_MISMATCH_WARNINGS,
   OPTION_IGNORE_LMA,