summaryrefslogtreecommitdiff
path: root/gcc/config/rs6000/rs6000.c
diff options
context:
space:
mode:
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>2012-12-27 17:53:17 +0000
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>2012-12-27 17:53:17 +0000
commitdc9c6abef5a100822bec23e9dbd753629d5278b3 (patch)
tree7e1f0af05f3bbeeb9a7aad33f6094003215fbca5 /gcc/config/rs6000/rs6000.c
parentd368f369d53f667f1f1783a72ff50b9cec71fb00 (diff)
downloadgcc-dc9c6abef5a100822bec23e9dbd753629d5278b3.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@194732 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r--gcc/config/rs6000/rs6000.c74
1 files changed, 47 insertions, 27 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 668566eb228..bc663eabcc0 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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