rs6000.c (rs6000_deligitimze_address): Do not delegitimize TLS addresses on AIX.

* config/rs6000/rs6000.c (rs6000_deligitimze_address): Do not
        delegitimize TLS addresses on AIX.
        (rs6000_legitimize_tls_address_aix): Append TLS symbol qualifier.
        Set SYMBOL_FLAG_LOCAL on module symbol.
        (output_toc): Do not append TLS symbol qualifier here.
        * config/rs6000/rs6000.md (tls_get_addr_internal): Add GPR 4 to
        clobbers.

From-SVN: r194732
This commit is contained in:
David Edelsohn 2012-12-27 17:53:17 +00:00 committed by David Edelsohn
parent 9e1883a2da
commit 53b0dee135
3 changed files with 58 additions and 27 deletions

View File

@ -1,3 +1,13 @@
2012-12-27 David Edelsohn <dje.gcc@gmail.com>
* config/rs6000/rs6000.c (rs6000_deligitimze_address): Do not
delegitimize TLS addresses on AIX.
(rs6000_legitimize_tls_address_aix): Append TLS symbol qualifier.
Set SYMBOL_FLAG_LOCAL on module symbol.
(output_toc): Do not append TLS symbol qualifier here.
* config/rs6000/rs6000.md (tls_get_addr_internal): Add GPR 4 to
clobbers.
2012-12-27 Andreas Schwab <schwab@linux-m68k.org>
* target.def (supports_function_versions): Fix typo.

View File

@ -5826,6 +5826,15 @@ rs6000_delegitimize_address (rtx orig_x)
}
#endif
y = XVECEXP (y, 0, 0);
#ifdef HAVE_AS_TLS
/* Do not associate thread-local symbols with the original
constant pool symbol. */
if (TARGET_XCOFF
&& SYMBOL_REF_TLS_MODEL (get_pool_constant (y)) >= TLS_MODEL_REAL)
return orig_x;
#endif
if (offset != NULL_RTX)
y = gen_rtx_PLUS (Pmode, y, offset);
if (!MEM_P (orig_x))
@ -5899,10 +5908,29 @@ rs6000_got_sym (void)
static rtx
rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model)
{
rtx sym, mem, tocref, tlsreg, tmpreg, dest;
rtx sym, mem, tocref, tlsreg, tmpreg, dest, tlsaddr;
const char *name;
char *tlsname;
name = XSTR (addr, 0);
/* Append TLS CSECT qualifier, unless the symbol already is qualified
or the symbol will be in TLS private data section. */
if (name[strlen (name) - 1] != ']'
&& (TREE_PUBLIC (SYMBOL_REF_DECL (addr))
|| bss_initializer_p (SYMBOL_REF_DECL (addr))))
{
tlsname = XALLOCAVEC (char, strlen (name) + 4);
strcpy (tlsname, name);
strcat (tlsname,
bss_initializer_p (SYMBOL_REF_DECL (addr)) ? "[UL]" : "[TL]");
tlsaddr = copy_rtx (addr);
XSTR (tlsaddr, 0) = ggc_strdup (tlsname);
}
else
tlsaddr = addr;
/* Place addr into TOC constant pool. */
sym = force_const_mem (GET_MODE (addr), addr);
sym = force_const_mem (GET_MODE (tlsaddr), tlsaddr);
/* Output the TOC entry and create the MEM referencing the value. */
if (constant_pool_expr_p (XEXP (sym, 0))
@ -5919,27 +5947,28 @@ rs6000_legitimize_tls_address_aix (rtx addr, enum tls_model model)
if (model == TLS_MODEL_GLOBAL_DYNAMIC
|| model == TLS_MODEL_LOCAL_DYNAMIC)
{
rtx module = gen_reg_rtx (Pmode);
/* Create new TOC reference for @m symbol. */
const char *name = XSTR (XVECEXP (XEXP (mem, 0), 0, 0), 0);
char *name2 = XALLOCAVEC (char, strlen (name) + 1);
strcpy (name2, "*LCM");
strcat (name2, name + 3);
tocref = create_TOC_reference (gen_rtx_SYMBOL_REF (Pmode,
ggc_alloc_string (name2,
strlen (name2))),
NULL_RTX);
rtx mem2 = gen_const_mem (Pmode, tocref);
set_mem_alias_set (mem2, get_TOC_alias_set ());
name = XSTR (XVECEXP (XEXP (mem, 0), 0, 0), 0);
tlsname = XALLOCAVEC (char, strlen (name) + 1);
strcpy (tlsname, "*LCM");
strcat (tlsname, name + 3);
rtx modaddr = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tlsname));
SYMBOL_REF_FLAGS (modaddr) |= SYMBOL_FLAG_LOCAL;
tocref = create_TOC_reference (modaddr, NULL_RTX);
rtx modmem = gen_const_mem (Pmode, tocref);
set_mem_alias_set (modmem, get_TOC_alias_set ());
dest = gen_reg_rtx (Pmode);
rtx modreg = gen_reg_rtx (Pmode);
emit_insn (gen_rtx_SET (VOIDmode, modreg, modmem));
tmpreg = gen_reg_rtx (Pmode);
emit_insn (gen_rtx_SET (VOIDmode, tmpreg, mem));
emit_insn (gen_rtx_SET (VOIDmode, module, mem2));
dest = gen_reg_rtx (Pmode);
if (TARGET_32BIT)
emit_insn (gen_tls_get_addrsi (dest, module, tmpreg));
emit_insn (gen_tls_get_addrsi (dest, modreg, tmpreg));
else
emit_insn (gen_tls_get_addrdi (dest, module, tmpreg));
emit_insn (gen_tls_get_addrdi (dest, modreg, tmpreg));
return dest;
}
/* Obtain TLS pointer: 32 bit call or 64 bit GPR 13. */
@ -22320,12 +22349,6 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (base) != 0)
{
tree decl = SYMBOL_REF_DECL (base);
if (bss_initializer_p (decl))
fputs ("[UL]", file);
else
fputs ("[TL]", file);
if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC)
fputs ("@le", file);
else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_INITIAL_EXEC)
@ -22340,10 +22363,7 @@ output_toc (FILE *file, rtx x, int labelno, enum machine_mode mode)
RS6000_OUTPUT_BASENAME (file, name);
fputs ("[TC],", file);
output_addr_const (file, x);
if (TREE_PUBLIC (SYMBOL_REF_DECL (base)))
fputs ("[TL]@m", file);
else
fputs ("[UL]@m", file);
fputs ("@m", file);
}
}
#endif

View File

@ -10022,6 +10022,7 @@
[(set (reg:P 3)
(unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
(clobber (reg:P 0))
(clobber (reg:P 4))
(clobber (reg:P 5))
(clobber (reg:P 11))
(clobber (reg:CC CR0_REGNO))