public inbox for binutils-cvs@sourceware.org
 help / color / mirror / Atom feed
* [binutils-gdb] RISC-V: Emit R_RISCV_RELAX for the la/lga pseudo instruction
@ 2023-12-12  9:33 Nelson Chu
  0 siblings, 0 replies; only message in thread
From: Nelson Chu @ 2023-12-12  9:33 UTC (permalink / raw)
  To: bfd-cvs

https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=bf69326fb74b73a4a4689d6368673de491819806

commit bf69326fb74b73a4a4689d6368673de491819806
Author: Rui Ueyama <rui314@gmail.com>
Date:   Wed Sep 20 17:31:26 2023 +0900

    RISC-V: Emit R_RISCV_RELAX for the la/lga pseudo instruction
    
    Some psABIs define a relaxation to turn a GOT load into a PC-relative
    address materialization.  For example, the AArch64's psABI allows
    adrp+ldr to be rewritten to nop+adr to eliminate the memory load.
    This patch is part of the effort to make such optimization possible
    for RISC-V.
    
    For RISC-V, we use the la assembly pseudo instruction to load a symbol
    address from the GOT. The pseudo instruction is expanded to auipc+ld.
    If the address loaded by the instruction pair is actually a PC-relative
    link-time constant, we want the linker to rewrite the instruction pair
    with auipc+addi.
    
    We can't rewrite all existing auipc+ld pairs with auipc+addi in the
    linker because there might be code that jumps to the middle of the
    instruction pair.  That should be extremely rare, if ever exists, but
    you can at least in theory write a program in assembly that jumps to
    the ld instruction of the instruction pair.  We need a marker to
    identify that an auipc+ld can be safely relaxed (i.e. they are emitted
    for la).
    
    This patch is to annotate R_RISCV_GOT_HI20 with R_RISCV_RELAX only
    when the relocation is emitted for the la pseudo instruction.  The
    linker will use it as a signal that the instruction pair can be safely
    relaxed.
    
    Proposal to the RISC-V psABI:
    https://github.com/riscv-non-isa/riscv-elf-psabi-doc/pull/397
    
    gas/
            * config/tc-riscv.c (source_macro): New static int variable.
            The identifier of the assembler macro we are expanding, if any.
            (append_insn): Updated source_macro to tc_fix_data, to record
            which macro expands, if any.
            (macro): Record which macro expands into source_macro.  Reset
            source_macro to -1 at the end.
            (md_apply_fix): Apply R_RISCV_RELAX if pcrel_got_hi is expanded
            from macro LA/LGA.
            * config/tc-riscv.h (struct riscv_fix, TC_FIX_TYPE, TC_INIT_FIX_DATA):
            Defined to record source_macro into fixups for riscv target.
            * testsuite/gas/riscv/la-variants.d: Updated.

Diff:
---
 gas/config/tc-riscv.c                 | 15 +++++++++++++++
 gas/config/tc-riscv.h                 |  8 ++++++++
 gas/testsuite/gas/riscv/la-variants.d |  3 +++
 3 files changed, 26 insertions(+)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 10f1ac7de3c..a46a6a4ec48 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -59,6 +59,9 @@ struct riscv_cl_insn
   fixS *fixp;
 };
 
+/* The identifier of the assembler macro we are expanding, if any. */
+static int source_macro = -1;
+
 /* All RISC-V CSR belong to one of these classes.  */
 enum riscv_csr_class
 {
@@ -1749,6 +1752,7 @@ append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
 				  address_expr, false, reloc_type);
 
 	  ip->fixp->fx_tcbit = riscv_opts.relax;
+	  ip->fixp->tc_fix_data.source_macro = source_macro;
 	}
     }
 
@@ -2103,6 +2107,8 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
   int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2;
   int mask = ip->insn_mo->mask;
 
+  source_macro = mask;
+
   switch (mask)
     {
     case M_LI:
@@ -2178,6 +2184,8 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
       as_bad (_("internal: macro %s not implemented"), ip->insn_mo->name);
       break;
     }
+
+  source_macro = -1;
 }
 
 static const struct percent_op_match percent_op_utype[] =
@@ -4139,6 +4147,13 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       break;
 
     case BFD_RELOC_RISCV_GOT_HI20:
+      /* R_RISCV_GOT_HI20 and the following R_RISCV_LO12_I are relaxable
+	 only if it is created as a result of la or lga assembler macros. */
+      if (fixP->tc_fix_data.source_macro == M_LA
+	  || fixP->tc_fix_data.source_macro == M_LGA)
+	relaxable = true;
+      break;
+
     case BFD_RELOC_RISCV_ADD8:
     case BFD_RELOC_RISCV_ADD16:
     case BFD_RELOC_RISCV_ADD32:
diff --git a/gas/config/tc-riscv.h b/gas/config/tc-riscv.h
index 9d2f05a4241..ff1c719d11c 100644
--- a/gas/config/tc-riscv.h
+++ b/gas/config/tc-riscv.h
@@ -104,6 +104,14 @@ extern void riscv_md_end (void);
 #define TC_FORCE_RELOCATION_LOCAL(FIX) 1
 #define DIFF_EXPR_OK 1
 
+struct riscv_fix
+{
+  int source_macro;
+};
+
+#define TC_FIX_TYPE struct riscv_fix
+#define TC_INIT_FIX_DATA(FIX) (FIX)->tc_fix_data.source_macro = -1
+
 extern void riscv_pop_insert (void);
 #define md_pop_insert()		riscv_pop_insert ()
 
diff --git a/gas/testsuite/gas/riscv/la-variants.d b/gas/testsuite/gas/riscv/la-variants.d
index b1d316983b7..e8ac09c2af2 100644
--- a/gas/testsuite/gas/riscv/la-variants.d
+++ b/gas/testsuite/gas/riscv/la-variants.d
@@ -21,11 +21,13 @@ Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
 [ 	]+[0-9a-f]+:[ 	]+00000617[ 	]+auipc[ 	]+a2,0x0
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_GOT_HI20[ 	]+a
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
 [ 	]+[0-9a-f]+:[ 	]+(00062603|00063603)[ 	]+(lw|ld)[ 	]+a2,0\(a2\).*
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+\.L0[ ]+
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
 [ 	]+[0-9a-f]+:[ 	]+00000697[ 	]+auipc[ 	]+a3,0x0
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_GOT_HI20[ 	]+a
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
 [ 	]+[0-9a-f]+:[ 	]+(0006a683|0006b683)[ 	]+(lw|ld)[ 	]+a3,0\(a3\).*
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+\.L0[ ]+
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
@@ -37,6 +39,7 @@ Disassembly of section .text:
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
 [ 	]+[0-9a-f]+:[ 	]+00000797[ 	]+auipc[ 	]+a5,0x0
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_GOT_HI20[ 	]+a
+[ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*
 [ 	]+[0-9a-f]+:[ 	]+(0007a783|0007b783)[ 	]+(lw|ld)[ 	]+a5,0\(a5\).*
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+\.L0[ ]+
 [ 	]+[0-9a-f]+:[ 	]+R_RISCV_RELAX[ 	]+\*ABS\*

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-12-12  9:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-12  9:33 [binutils-gdb] RISC-V: Emit R_RISCV_RELAX for the la/lga pseudo instruction Nelson Chu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).