* [WIP][PATCH] RISC-V: Add `-mgprel' option for GP-relative addressing
@ 2020-08-31 14:09 Maciej W. Rozycki
0 siblings, 0 replies; only message in thread
From: Maciej W. Rozycki @ 2020-08-31 14:09 UTC (permalink / raw)
To: gcc-patches; +Cc: Alistair Francis, Maciej W. Rozycki
Implement `-mgprel', forcing `-mexplicit-relocs' whenever the option is
active due to the lack of GAS macro support for GP-relative addressing.
gcc/
* riscv/riscv-protos.h (riscv_symbol_type): Add SYMBOL_GPREL
enumeration constant.
* config/riscv/riscv.c (riscv_classify_symbol)
(riscv_symbolic_constant_p, riscv_symbol_insns)
(riscv_split_symbol_type, riscv_split_symbol, riscv_output_move)
(riscv_print_operand_reloc, riscv_option_override): Handle
GP-relative addressing.
* config/riscv/riscv.md (unspec): Add UNSPEC_GPREL enumeration
constant.
* config/riscv/riscv.opt (mgprel): New option.
---
Hi,
This is very early stage really, just implementing basic GP-relative
relocation support, in preparation for FDPIC support discussed here:
<https://groups.google.com/a/groups.riscv.org/g/sw-dev/c/ZjYUJswknQ4>
I planned adding support to GAS macros such as LA next so that we don't
have to force explicit relocations with `-mgprel' for this option to work,
but I won't be able to continue with this effort now as I am leaving
Western Digital today, so I am posting this in case someone finds it
useful or wishes to continue the effort.
No regressions in `riscv64-linux-gnu' testing, RV32/ilp32d ABI with QEMU
in the Linux user emulation mode across all GCC frontends and libraries,
except for an odd ICE with one of the Fortran test cases and a couple
timeouts with GNAT test cases, which I put all on the version difference
between the test runs (10.0.1 20200426 vs 11.0.0 20200827).
Unfortunately I lost several hours, because 11.0.0 20200829 has regressed
enough compared to 11.0.0 20200827 for testing not to progress well enough
in 15 hours where it usually completes in ~10 hours. So I had to restart
with an older snapshot and wouldn't get reference results in time (I only
had libgo results with 11.0.0 20200827). I think my assumption as to the
nature of the regressions is right though.
A corresponding binutils change has also been posted.
Maciej
---
gcc/config/riscv/riscv-protos.h | 1 +
gcc/config/riscv/riscv.c | 32 +++++++++++++++++++++++++++++---
gcc/config/riscv/riscv.md | 1 +
gcc/config/riscv/riscv.opt | 4 ++++
4 files changed, 35 insertions(+), 3 deletions(-)
gcc-riscv-gprel.diff
Index: gcc/gcc/config/riscv/riscv-protos.h
===================================================================
--- gcc.orig/gcc/config/riscv/riscv-protos.h
+++ gcc/gcc/config/riscv/riscv-protos.h
@@ -28,6 +28,7 @@ enum riscv_symbol_type {
SYMBOL_ABSOLUTE,
SYMBOL_PCREL,
SYMBOL_GOT_DISP,
+ SYMBOL_GPREL,
SYMBOL_TLS,
SYMBOL_TLS_LE,
SYMBOL_TLS_IE,
Index: gcc/gcc/config/riscv/riscv.c
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.c
+++ gcc/gcc/config/riscv/riscv.c
@@ -559,7 +559,13 @@ riscv_classify_symbol (const_rtx x)
if (GET_CODE (x) == SYMBOL_REF && flag_pic && !riscv_symbol_binds_local_p (x))
return SYMBOL_GOT_DISP;
- return riscv_cmodel == CM_MEDLOW ? SYMBOL_ABSOLUTE : SYMBOL_PCREL;
+ if (riscv_cmodel == CM_MEDLOW)
+ return SYMBOL_ABSOLUTE;
+
+ if (LABEL_REF_P (x) || (SYMBOL_REF_P (x) && SYMBOL_REF_FUNCTION_P (x)))
+ return SYMBOL_PCREL;
+
+ return TARGET_GPREL ? SYMBOL_GPREL : SYMBOL_PCREL;
}
/* Classify the base of symbolic expression X. */
@@ -604,6 +610,7 @@ riscv_symbolic_constant_p (rtx x, enum r
case SYMBOL_ABSOLUTE:
case SYMBOL_PCREL:
case SYMBOL_TLS_LE:
+ case SYMBOL_GPREL:
/* GAS rejects offsets outside the range [-2^31, 2^31-1]. */
return sext_hwi (INTVAL (offset), 32) == INTVAL (offset);
@@ -622,6 +629,7 @@ static int riscv_symbol_insns (enum risc
case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference. */
case SYMBOL_PCREL: return 2; /* AUIPC + the reference. */
case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference. */
+ case SYMBOL_GPREL: return 3; /* LUI + ADD GP + the reference. */
case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference. */
default: gcc_unreachable ();
}
@@ -735,7 +743,9 @@ riscv_split_symbol_type (enum riscv_symb
if (!TARGET_EXPLICIT_RELOCS)
return false;
- return symbol_type == SYMBOL_ABSOLUTE || symbol_type == SYMBOL_PCREL;
+ return (symbol_type == SYMBOL_ABSOLUTE
+ || symbol_type == SYMBOL_PCREL
+ || symbol_type == SYMBOL_GPREL);
}
/* Return true if a LO_SUM can address a value of mode MODE when the
@@ -1241,6 +1251,17 @@ riscv_split_symbol (rtx temp, rtx addr,
}
break;
+ case SYMBOL_GPREL:
+ {
+ rtx high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
+ rtx gp = gen_rtx_REG (Pmode, GP_REGNUM);
+ high = riscv_force_temporary (temp, high, in_splitter);
+ rtx reg = gen_rtx_PLUS (Pmode, high, gp);
+ reg = riscv_force_temporary (temp, reg, in_splitter);
+ *low_out = gen_rtx_LO_SUM (Pmode, reg, addr);
+ }
+ break;
+
default:
gcc_unreachable ();
}
@@ -2030,6 +2051,7 @@ riscv_output_move (rtx dest, rtx src)
case SYMBOL_GOT_DISP: return "la\t%0,%1";
case SYMBOL_ABSOLUTE: return "lla\t%0,%1";
case SYMBOL_PCREL: return "lla\t%0,%1";
+ case SYMBOL_GPREL: return "la\t%0,%1";
default: gcc_unreachable ();
}
}
@@ -3290,6 +3312,10 @@ riscv_print_operand_reloc (FILE *file, r
reloc = hi_reloc ? "%tprel_hi" : "%tprel_lo";
break;
+ case SYMBOL_GPREL:
+ reloc = hi_reloc ? "%gprel_hi" : "%gprel_lo";
+ break;
+
default:
output_operand_lossage ("invalid use of '%%%c'", hi_reloc ? 'h' : 'R');
return;
@@ -4735,7 +4761,7 @@ riscv_option_override (void)
/* We get better code with explicit relocs for CM_MEDLOW, but
worse code for the others (for now). Pick the best default. */
if ((target_flags_explicit & MASK_EXPLICIT_RELOCS) == 0)
- if (riscv_cmodel == CM_MEDLOW)
+ if (riscv_cmodel == CM_MEDLOW || TARGET_GPREL)
target_flags |= MASK_EXPLICIT_RELOCS;
/* Require that the ISA supports the requested floating-point ABI. */
Index: gcc/gcc/config/riscv/riscv.md
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.md
+++ gcc/gcc/config/riscv/riscv.md
@@ -28,6 +28,7 @@
UNSPEC_ADDRESS_FIRST
UNSPEC_PCREL
UNSPEC_LOAD_GOT
+ UNSPEC_GPREL
UNSPEC_TLS
UNSPEC_TLS_LE
UNSPEC_TLS_IE
Index: gcc/gcc/config/riscv/riscv.opt
===================================================================
--- gcc.orig/gcc/config/riscv/riscv.opt
+++ gcc/gcc/config/riscv/riscv.opt
@@ -179,3 +179,7 @@ Use the given offset for addressing the
TargetVariable
long riscv_stack_protector_guard_offset = 0
+
+mgprel
+Target Report Mask(GPREL)
+Use GP-relative sequences for data accesses.
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-08-31 14:09 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-08-31 14:09 [WIP][PATCH] RISC-V: Add `-mgprel' option for GP-relative addressing Maciej W. Rozycki
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).