diff options
author | dje <dje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-27 17:53:17 +0000 |
---|---|---|
committer | dje <dje@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-12-27 17:53:17 +0000 |
commit | dc9c6abef5a100822bec23e9dbd753629d5278b3 (patch) | |
tree | 7e1f0af05f3bbeeb9a7aad33f6094003215fbca5 /gcc/config/rs6000/rs6000.c | |
parent | d368f369d53f667f1f1783a72ff50b9cec71fb00 (diff) | |
download | gcc-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.c | 74 |
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 |