public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH] RISC-V: emit R_RISCV_RELAX for the la pseudo instruction
@ 2023-09-19  7:01 Rui Ueyama
  2023-09-20  1:08 ` Nelson Chu
  0 siblings, 1 reply; 9+ messages in thread
From: Rui Ueyama @ 2023-09-19  7:01 UTC (permalink / raw)
  To: binutils; +Cc: Rui Ueyama

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
---
 bfd/bfd-in2.h                         | 1 +
 bfd/elfxx-riscv.c                     | 1 +
 gas/config/tc-riscv.c                 | 3 ++-
 gas/testsuite/gas/riscv/la-variants.d | 3 +++
 4 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 1c4f75ae244..e15641a1d00 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -5413,6 +5413,7 @@ number for the SBIC, SBIS, SBI and CBI instructions  */
   BFD_RELOC_RISCV_SUB32,
   BFD_RELOC_RISCV_SUB64,
   BFD_RELOC_RISCV_GOT_HI20,
+  BFD_RELOC_RISCV_GOT_HI20_RELAX,
   BFD_RELOC_RISCV_TLS_GOT_HI20,
   BFD_RELOC_RISCV_TLS_GD_HI20,
   BFD_RELOC_RISCV_JMP,
diff --git a/bfd/elfxx-riscv.c b/bfd/elfxx-riscv.c
index 6ed657171f0..71e63e7b789 100644
--- a/bfd/elfxx-riscv.c
+++ b/bfd/elfxx-riscv.c
@@ -913,6 +913,7 @@ static const struct elf_reloc_map riscv_reloc_map[] =
   { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
   { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
   { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
+  { BFD_RELOC_RISCV_GOT_HI20_RELAX, R_RISCV_GOT_HI20 },
   { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
   { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
   { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 3b520ad208b..303ae18436c 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2039,7 +2039,7 @@ macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
       else if ((riscv_opts.pic && mask == M_LA)
 	       || mask == M_LGA)
 	pcrel_load (rd, rd, imm_expr, LOAD_ADDRESS_INSN,
-		    BFD_RELOC_RISCV_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
+		    BFD_RELOC_RISCV_GOT_HI20_RELAX, BFD_RELOC_RISCV_PCREL_LO12_I);
       /* Local PIC symbol, or any non-PIC symbol.  */
       else
 	pcrel_load (rd, rd, imm_expr, "addi",
@@ -4244,6 +4244,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       relaxable = true;
       break;
 
+    case BFD_RELOC_RISCV_GOT_HI20_RELAX:
     case BFD_RELOC_RISCV_PCREL_HI20:
     case BFD_RELOC_RISCV_PCREL_LO12_S:
     case BFD_RELOC_RISCV_PCREL_LO12_I:
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\*
-- 
2.34.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-12-12  9:38 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-09-19  7:01 [PATCH] RISC-V: emit R_RISCV_RELAX for the la pseudo instruction Rui Ueyama
2023-09-20  1:08 ` Nelson Chu
2023-09-20  8:31   ` [PATCH v2] " Rui Ueyama
2023-09-21  0:18     ` Nelson Chu
2023-09-21  5:32       ` Rui Ueyama
2023-09-21  7:37         ` Nelson Chu
2023-12-12  6:40           ` Rui Ueyama
2023-12-12  9:38             ` Nelson Chu
2023-12-12  9:25     ` Andreas Schwab

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).