aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndrew Waterman <waterman@cs.berkeley.edu>2014-10-22 17:21:44 -0700
committerAndrew Waterman <waterman@cs.berkeley.edu>2014-10-22 20:18:30 -0700
commit1726740baee385b3e744e40bfe51e6debd5436ba (patch)
treebe98f5bf69d1d57899b606588ec8e1651495941c /gcc
parentc4276840c8e41dc39c4e0b24807d882e68d89f32 (diff)
downloadriscv-gnu-toolchain-1726740baee385b3e744e40bfe51e6debd5436ba.zip
riscv-gnu-toolchain-1726740baee385b3e744e40bfe51e6debd5436ba.tar.gz
riscv-gnu-toolchain-1726740baee385b3e744e40bfe51e6debd5436ba.tar.bz2
binutils, glibc, gcc: support TLS copy relocations
This allows the local-exec model to be used for any non-PIC TLS reference, even if it cannot be proven at compile time that the access binds locally. It essentially obviates the need for IE -> LE relaxations.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/gcc/config/riscv/riscv-protos.h5
-rw-r--r--gcc/gcc/config/riscv/riscv.c56
-rw-r--r--gcc/gcc/config/riscv/riscv.md33
3 files changed, 15 insertions, 79 deletions
diff --git a/gcc/gcc/config/riscv/riscv-protos.h b/gcc/gcc/config/riscv/riscv-protos.h
index 429da71..5120cb1 100644
--- a/gcc/gcc/config/riscv/riscv-protos.h
+++ b/gcc/gcc/config/riscv/riscv-protos.h
@@ -26,10 +26,9 @@ enum mips_symbol_type {
SYMBOL_ABSOLUTE,
SYMBOL_GOT_DISP,
SYMBOL_TLS,
- SYMBOL_TLS_LE,
- SYMBOL_TLS_IE
+ SYMBOL_TLS_LE
};
-#define NUM_SYMBOL_TYPES (SYMBOL_TLS_IE + 1)
+#define NUM_SYMBOL_TYPES (SYMBOL_TLS_LE + 1)
extern bool mips_symbolic_constant_p (rtx, enum mips_symbol_type *);
extern int riscv_regno_mode_ok_for_base_p (int, enum machine_mode, bool);
diff --git a/gcc/gcc/config/riscv/riscv.c b/gcc/gcc/config/riscv/riscv.c
index 8492b38..f108c42 100644
--- a/gcc/gcc/config/riscv/riscv.c
+++ b/gcc/gcc/config/riscv/riscv.c
@@ -586,11 +586,10 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
switch (*symbol_type)
{
case SYMBOL_ABSOLUTE:
+ case SYMBOL_TLS_LE:
return (int32_t) INTVAL (offset) == INTVAL (offset);
case SYMBOL_TLS:
- case SYMBOL_TLS_LE:
- case SYMBOL_TLS_IE:
case SYMBOL_GOT_DISP:
return false;
}
@@ -606,7 +605,6 @@ static int riscv_symbol_insns (enum mips_symbol_type type)
case SYMBOL_TLS: return 0; /* Depends on the TLS model. */
case SYMBOL_ABSOLUTE: return 2; /* LUI + the reference itself */
case SYMBOL_TLS_LE: return 3; /* LUI + ADD TP + the reference itself */
- case SYMBOL_TLS_IE: return 4; /* LUI + LD + ADD TP + the reference itself */
case SYMBOL_GOT_DISP: return 3; /* AUIPC + LD GOT + the reference itself */
default: gcc_unreachable();
}
@@ -1065,22 +1063,6 @@ static rtx riscv_got_load_tls_ie(rtx dest, rtx sym)
return (Pmode == DImode ? gen_got_load_tls_iedi(dest, sym) : gen_got_load_tls_iesi(dest, sym));
}
-static rtx riscv_got_load_tls_ie_hi(rtx dest, rtx sym)
-{
- return (Pmode == DImode ? gen_got_load_tls_ie_hidi(dest, sym) : gen_got_load_tls_ie_hisi(dest, sym));
-}
-
-static rtx riscv_got_load_tls_ie_lo(rtx dest, rtx base, rtx sym)
-{
- return (Pmode == DImode ? gen_got_load_tls_ie_lodi(dest, base, sym) : gen_got_load_tls_ie_losi(dest, base, sym));
-}
-
-static rtx riscv_tls_add_tp_ie(rtx dest, rtx base, rtx sym)
-{
- rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
- return (Pmode == DImode ? gen_tls_add_tp_iedi(dest, base, tp, sym) : gen_tls_add_tp_iesi(dest, base, tp, sym));
-}
-
static rtx riscv_tls_add_tp_le(rtx dest, rtx base, rtx sym)
{
rtx tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
@@ -1191,8 +1173,13 @@ static rtx
mips_legitimize_tls_address (rtx loc)
{
rtx dest, insn, v0, tp, tmp1;
+ enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
- switch (SYMBOL_REF_TLS_MODEL (loc))
+ /* Since we support TLS copy relocs, non-PIC TLS accesses may all use LE. */
+ if (!flag_pic)
+ model = TLS_MODEL_LOCAL_EXEC;
+
+ switch (model)
{
case TLS_MODEL_LOCAL_DYNAMIC:
/* Rely on section anchors for the optimization that LDM TLS
@@ -1205,27 +1192,12 @@ mips_legitimize_tls_address (rtx loc)
break;
case TLS_MODEL_INITIAL_EXEC:
- if (flag_pic)
- {
- /* la.tls.ie; tp-relative add */
- tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
- tmp1 = gen_reg_rtx (Pmode);
- emit_insn (riscv_got_load_tls_ie (tmp1, loc));
- dest = gen_reg_rtx (Pmode);
- emit_insn (gen_add3_insn (dest, tmp1, tp));
- }
- else
- {
- /* lui %tls_ie_hi; ld %tls_le_lo; tp-relative add */
- tmp1 = gen_reg_rtx (Pmode);
- emit_insn (riscv_got_load_tls_ie_hi (tmp1, loc));
- dest = gen_reg_rtx (Pmode);
- emit_insn (riscv_got_load_tls_ie_lo (dest, tmp1, loc));
- tmp1 = gen_reg_rtx (Pmode);
- emit_insn (riscv_tls_add_tp_ie (tmp1, dest, loc));
- dest = gen_rtx_LO_SUM (Pmode, tmp1,
- mips_unspec_address (loc, SYMBOL_TLS_IE));
- }
+ /* la.tls.ie; tp-relative add */
+ tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
+ tmp1 = gen_reg_rtx (Pmode);
+ emit_insn (riscv_got_load_tls_ie (tmp1, loc));
+ dest = gen_reg_rtx (Pmode);
+ emit_insn (gen_add3_insn (dest, tmp1, tp));
break;
case TLS_MODEL_LOCAL_EXEC:
@@ -2904,8 +2876,6 @@ mips_init_relocs (void)
riscv_hi_relocs[SYMBOL_TLS_LE] = "%tprel_hi(";
riscv_lo_relocs[SYMBOL_TLS_LE] = "%tprel_lo(";
-
- riscv_lo_relocs[SYMBOL_TLS_IE] = "%tls_ie_off(";
}
}
diff --git a/gcc/gcc/config/riscv/riscv.md b/gcc/gcc/config/riscv/riscv.md
index 0e3d507..f28269e 100644
--- a/gcc/gcc/config/riscv/riscv.md
+++ b/gcc/gcc/config/riscv/riscv.md
@@ -35,11 +35,8 @@
;; Symbolic accesses.
UNSPEC_LOAD_GOT
UNSPEC_TLS_LE_ADD
- UNSPEC_TLS_IE_ADD
UNSPEC_TLS_GD
UNSPEC_TLS_IE
- UNSPEC_TLS_IE_HI
- UNSPEC_TLS_IE_LO
;; Blockage and synchronisation.
UNSPEC_BLOCKAGE
@@ -1450,17 +1447,6 @@
[(set_attr "type" "arith")
(set_attr "mode" "<MODE>")])
-(define_insn "tls_add_tp_ie<mode>"
- [(set (match_operand:P 0 "register_operand" "=r")
- (unspec:P [(match_operand:P 1 "register_operand" "r")
- (match_operand:P 2 "register_operand" "r")
- (match_operand:P 3 "symbolic_operand" "")]
- UNSPEC_TLS_IE_ADD))]
- "!flag_pic"
- "add\t%0,%1,%2,%%tls_ie_add(%3)"
- [(set_attr "type" "arith")
- (set_attr "mode" "<MODE>")])
-
(define_insn "got_load_tls_gd<mode>"
[(set (match_operand:P 0 "register_operand" "=r")
(unspec:P [(match_operand:P 1 "symbolic_operand" "")]
@@ -1479,25 +1465,6 @@
[(set_attr "got" "load")
(set_attr "mode" "<MODE>")])
-(define_insn "got_load_tls_ie_hi<mode>"
- [(set (match_operand:P 0 "register_operand" "=r")
- (unspec:P [(match_operand:P 1 "symbolic_operand" "")]
- UNSPEC_TLS_IE_HI))]
- "!flag_pic"
- "lui\t%0,%%tls_ie_hi(%1)"
- [(set_attr "type" "arith")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "got_load_tls_ie_lo<mode>"
- [(set (match_operand:P 0 "register_operand" "=r")
- (unspec:P [(match_operand:P 1 "register_operand" "r")
- (match_operand:P 2 "symbolic_operand" "")]
- UNSPEC_TLS_IE_LO))]
- "!flag_pic"
- "<load>\t%0,%%tls_ie_lo(%2)(%1)"
- [(set_attr "type" "load")
- (set_attr "mode" "<MODE>")])
-
;; Instructions for adding the low 16 bits of an address to a register.
;; Operand 2 is the address: mips_print_operand works out which relocation
;; should be applied.