From dc9c6abef5a100822bec23e9dbd753629d5278b3 Mon Sep 17 00:00:00 2001 From: dje Date: Thu, 27 Dec 2012 17:53:17 +0000 Subject: [PATCH] * 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 --- gcc/ChangeLog | 10 ++++++ gcc/config/rs6000/rs6000.c | 74 ++++++++++++++++++++++++++++----------------- gcc/config/rs6000/rs6000.md | 1 + 3 files changed, 58 insertions(+), 27 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 575e03a54f4..7feee1c7bcc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2012-12-27 David Edelsohn + + * 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 * target.def (supports_function_versions): Fix typo. 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 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 03ad9280386..0fa3d88c15b 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -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)) -- 2.11.4.GIT