Support additional relocations: TLS_GD32_FDPIC, TLS_LDM32_FDPIC, and TLS_IE32_FDPIC.
We do not support the GNU2 TLS dialect. 2018-XX-XX Christophe Lyon <christophe.l...@st.com> Mickaël Guêné <mickael.gu...@st.com> gcc/ * config/arm/arm.c (tls_reloc): Add TLS_GD32_FDPIC, TLS_LDM32_FDPIC and TLS_IE32_FDPIC. (arm_call_tls_get_addr_fdpic): New. (legitimize_tls_address_fdpic): New. (legitimize_tls_address_not_fdpic): New. (legitimize_tls_address): Add FDPIC support. (arm_emit_tls_decoration): Likewise. Change-Id: I4ea5034ff654540c4658d0a79fb92f70550cdf4a diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index 2434602..20b8f66 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2373,9 +2373,12 @@ char arm_arch_name[] = "__ARM_ARCH_PROFILE__"; enum tls_reloc { TLS_GD32, + TLS_GD32_FDPIC, TLS_LDM32, + TLS_LDM32_FDPIC, TLS_LDO32, TLS_IE32, + TLS_IE32_FDPIC, TLS_LE32, TLS_DESCSEQ /* GNU scheme */ }; @@ -8681,6 +8684,30 @@ load_tls_operand (rtx x, rtx reg) } static rtx_insn * +arm_call_tls_get_addr_fdpic (rtx x, rtx reg, rtx *valuep, int reloc) +{ + rtx sum; + + gcc_assert (reloc != TLS_DESCSEQ); + start_sequence (); + + sum = gen_rtx_UNSPEC (Pmode, + gen_rtvec (2, x, GEN_INT (reloc)), + UNSPEC_TLS); + reg = load_tls_operand (sum, reg); + emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, 9))); + + *valuep = emit_library_call_value (get_tls_get_addr (), NULL_RTX, + LCT_PURE, /* LCT_CONST? */ + Pmode, reg, Pmode); + + rtx_insn *insns = get_insns (); + end_sequence (); + + return insns; +} + +static rtx_insn * arm_call_tls_get_addr (rtx x, rtx reg, rtx *valuep, int reloc) { rtx label, labelno, sum; @@ -8736,8 +8763,84 @@ arm_tls_descseq_addr (rtx x, rtx reg) return reg; } -rtx -legitimize_tls_address (rtx x, rtx reg) +static rtx +legitimize_tls_address_fdpic (rtx x, rtx reg) +{ + rtx dest, ret, eqv, addend, sum, tp; + rtx_insn *insns; + unsigned int model = SYMBOL_REF_TLS_MODEL (x); + + switch (model) + { + case TLS_MODEL_GLOBAL_DYNAMIC: + if (TARGET_GNU2_TLS) + { + abort (); + } + else + { + /* Original scheme. */ + insns = arm_call_tls_get_addr_fdpic (x, reg, &ret, TLS_GD32_FDPIC); + dest = gen_reg_rtx (Pmode); + emit_libcall_block (insns, dest, ret, x); + } + return dest; + break; + + case TLS_MODEL_LOCAL_DYNAMIC: + if (TARGET_GNU2_TLS) + { + abort (); + } + else + { + insns = arm_call_tls_get_addr_fdpic (x, reg, &ret, TLS_LDM32_FDPIC); + /* Attach a unique REG_EQUIV, to allow the RTL optimizers to + share the LDM result with other LD model accesses. */ + eqv = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const1_rtx), + UNSPEC_TLS); + dest = gen_reg_rtx (Pmode); + emit_libcall_block (insns, dest, ret, eqv); + + /* Load the addend. */ + addend = gen_rtx_UNSPEC (Pmode, + gen_rtvec (2, x, GEN_INT (TLS_LDO32)), + UNSPEC_TLS); + addend = force_reg (SImode, gen_rtx_CONST (SImode, addend)); + dest = gen_rtx_PLUS (Pmode, dest, addend); + } + return dest; + break; + + case TLS_MODEL_INITIAL_EXEC: + sum = gen_rtx_UNSPEC (Pmode, + gen_rtvec (2, x, GEN_INT (TLS_IE32_FDPIC)), + UNSPEC_TLS); + reg = load_tls_operand (sum, reg); + /* FIXME: optimize below? */ + emit_insn (gen_addsi3 (reg, reg, gen_rtx_REG (Pmode, 9))); + emit_insn (gen_movsi (reg, gen_rtx_MEM (Pmode, reg))); + tp = arm_load_tp (NULL_RTX); + + return gen_rtx_PLUS (Pmode, tp, reg); + break; + + case TLS_MODEL_LOCAL_EXEC: + tp = arm_load_tp (NULL_RTX); + reg = gen_rtx_UNSPEC (Pmode, + gen_rtvec (2, x, GEN_INT (TLS_LE32)), + UNSPEC_TLS); + reg = force_reg (SImode, gen_rtx_CONST (SImode, reg)); + + return gen_rtx_PLUS (Pmode, tp, reg); + + default: + abort (); + } +} + +static rtx +legitimize_tls_address_not_fdpic (rtx x, rtx reg) { rtx dest, tp, label, labelno, sum, ret, eqv, addend; rtx_insn *insns; @@ -8831,6 +8934,15 @@ legitimize_tls_address (rtx x, rtx reg) } } +rtx +legitimize_tls_address (rtx x, rtx reg) +{ + if (TARGET_FDPIC) + return legitimize_tls_address_fdpic (x, reg); + else + return legitimize_tls_address_not_fdpic (x, reg); +} + /* Try machine-dependent ways of modifying an illegitimate address to be legitimate. If we find one, return the new, valid address. */ rtx @@ -28022,15 +28134,24 @@ arm_emit_tls_decoration (FILE *fp, rtx x) case TLS_GD32: fputs ("(tlsgd)", fp); break; + case TLS_GD32_FDPIC: + fputs ("(tlsgd_fdpic)", fp); + break; case TLS_LDM32: fputs ("(tlsldm)", fp); break; + case TLS_LDM32_FDPIC: + fputs ("(tlsldm_fdpic)", fp); + break; case TLS_LDO32: fputs ("(tlsldo)", fp); break; case TLS_IE32: fputs ("(gottpoff)", fp); break; + case TLS_IE32_FDPIC: + fputs ("(gottpoff_fdpic)", fp); + break; case TLS_LE32: fputs ("(tpoff)", fp); break; -- 2.6.3