]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commit
RISC-V: Emit R_RISCV_RELAX for the la/lga pseudo instruction
authorRui Ueyama <rui314@gmail.com>
Wed, 20 Sep 2023 08:31:26 +0000 (17:31 +0900)
committerNelson Chu <nelson@rivosinc.com>
Tue, 12 Dec 2023 09:33:31 +0000 (17:33 +0800)
commitbf69326fb74b73a4a4689d6368673de491819806
treedd2505637cd7d72e7b0a11d31412bf17909792d8
parentdff565fcca8137954d6ad571ef39f6aec5c0429c
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.
gas/config/tc-riscv.c
gas/config/tc-riscv.h
gas/testsuite/gas/riscv/la-variants.d