diff options
author | Andrew Waterman <waterman@cs.berkeley.edu> | 2014-10-22 17:21:44 -0700 |
---|---|---|
committer | Andrew Waterman <waterman@cs.berkeley.edu> | 2014-10-22 20:18:30 -0700 |
commit | 1726740baee385b3e744e40bfe51e6debd5436ba (patch) | |
tree | be98f5bf69d1d57899b606588ec8e1651495941c /gcc | |
parent | c4276840c8e41dc39c4e0b24807d882e68d89f32 (diff) | |
download | riscv-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.h | 5 | ||||
-rw-r--r-- | gcc/gcc/config/riscv/riscv.c | 56 | ||||
-rw-r--r-- | gcc/gcc/config/riscv/riscv.md | 33 |
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. |