Index: rs6000.c
===================================================================
--- rs6000.c    (revision 194725)
+++ rs6000.c    (working copy)
@@ -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
   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 m
   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 m
          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
Index: rs6000.md
===================================================================
--- rs6000.md   (revision 194725)
+++ rs6000.md   (working copy)
@@ -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))
