This is the next set of patches for native TLS support on AIX.  This
mainly adds support for BSS symbols. This should use local common and
I created a tbss section name, but I cannot figure out how to convince
the AIX assembler to match the TOC symbols reference to the lcomm
symbol.  Disassembly of XLC output shows that it uses COMMON symbols,
so I am punting to that as well.

This patch also removes the section anchor flag from native TLS
symbols if it was set.

This patch uses the logic from bss_initializer_p(). Should that
function in varasm.c be made non-static?

Bootstrapped on powerpc-ibm-aix7.1.0.0, although this still does not
pass libgomp testsuite.

Thanks, David

        * xcoffout.c (xcoff_tbss_section_name): Define.
        * xcoffout.h (xcoff_tbss_section_name): Declare.
        * config/rs6000/xcoff.h (TARGET_ENCODE_SECTION_INFO): Define.
        (ASM_OUTPUT_TLS_COMMON): Merge strings.
        * config/rs6000/rs6000.c (tls_private_dat_section): New.
        (output_toc): Only output CSECT decoration for TLS.
        Output appropriate CSECT for data or bss.
        (rs6000_xcoff_asm_init_sections) Define tls_private_data_section.
        (rs6000_xcoff_select_section): Handle TLS bss and private data.
        (rs6000_xcoff_file_start): Generate xcoff_tbss_section_name.
        (rs6000_xcoff_encode_section_info): Strip SYMBOL_FLAG_HAS_BLOCK_INFO
        from native TLS symbols.

Index: xcoffout.c
===================================================================
--- xcoffout.c  (revision 194435)
+++ xcoffout.c  (working copy)
@@ -67,6 +67,7 @@
 char *xcoff_bss_section_name;
 char *xcoff_private_data_section_name;
 char *xcoff_tls_data_section_name;
+char *xcoff_tbss_section_name;
 char *xcoff_read_only_section_name;

 /* Last source file name mentioned in a NOTE insn.  */
Index: xcoffout.h
===================================================================
--- xcoffout.h  (revision 194435)
+++ xcoffout.h  (working copy)
@@ -127,6 +127,7 @@
 extern char *xcoff_bss_section_name;
 extern char *xcoff_private_data_section_name;
 extern char *xcoff_tls_data_section_name;
+extern char *xcoff_tbss_section_name;
 extern char *xcoff_read_only_section_name;

 /* Last source file name mentioned in a NOTE insn.  */
Index: config/rs6000/xcoff.h
===================================================================
--- config/rs6000/xcoff.h       (revision 194435)
+++ config/rs6000/xcoff.h       (working copy)
@@ -98,6 +98,7 @@
 #define TARGET_ASM_FUNCTION_RODATA_SECTION default_no_function_rodata_section
 #define TARGET_STRIP_NAME_ENCODING  rs6000_xcoff_strip_name_encoding
 #define TARGET_SECTION_TYPE_FLAGS  rs6000_xcoff_section_type_flags
+#define TARGET_ENCODE_SECTION_INFO rs6000_xcoff_encode_section_info

 /* FP save and restore routines.  */
 #define        SAVE_FP_PREFIX "._savef"
@@ -308,8 +309,8 @@
 #define ASM_OUTPUT_TLS_COMMON(FILE, DECL, NAME, SIZE)  \
   do { fputs(COMMON_ASM_OP, (FILE));                   \
        RS6000_OUTPUT_BASENAME ((FILE), (NAME));                \
-       fputs("[UL]", (FILE));                                  \
-       fprintf ((FILE), ","HOST_WIDE_INT_PRINT_UNSIGNED"\n", (SIZE)); \
+       fprintf ((FILE), "[UL],"HOST_WIDE_INT_PRINT_UNSIGNED"\n", \
+       (SIZE));                                                \
   } while (0)
 #endif

Index: config/rs6000/rs6000.c
===================================================================
--- config/rs6000/rs6000.c      (revision 194435)
+++ config/rs6000/rs6000.c      (working copy)
@@ -209,6 +209,7 @@ static short cached_can_issue_more;
 static GTY(()) section *read_only_data_section;
 static GTY(()) section *private_data_section;
 static GTY(()) section *tls_data_section;
+static GTY(()) section *tls_private_data_section;
 static GTY(()) section *read_only_private_data_section;
 static GTY(()) section *sdata2_section;
 static GTY(()) section *toc_section;
@@ -22316,23 +22317,39 @@ output_toc (FILE *file, rtx x, int labelno, enum m
     output_addr_const (file, x);

 #if HAVE_AS_TLS
-  if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF)
+  if (TARGET_XCOFF && GET_CODE (base) == SYMBOL_REF
+      && SYMBOL_REF_TLS_MODEL (base) != 0)
     {
+      tree decl = SYMBOL_REF_DECL (base);
+      if (DECL_INITIAL (decl) == NULL_TREE
+                  || DECL_INITIAL (decl) == error_mark_node
+                  || (flag_zero_initialized_in_bss
+                      /* Leave constant zeroes in .rodata so they
+                         can be shared.  */
+                      && !TREE_READONLY (decl)
+                      && initializer_zerop (DECL_INITIAL (decl))))
+       fputs ("[UL]", file);
+      else
+       fputs ("[TL]", file);
+
       if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_EXEC)
-       fputs ("[TL]@le", file);
+       fputs ("@le", file);
       else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_INITIAL_EXEC)
-       fputs ("[TL]@ie", file);
+       fputs ("@ie", file);
       /* Use global-dynamic for local-dynamic.  */
       else if (SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_GLOBAL_DYNAMIC
               || SYMBOL_REF_TLS_MODEL (base) == TLS_MODEL_LOCAL_DYNAMIC)
        {
-         fputs ("[TL]\n", file);
+         putc ('\n', file);
          (*targetm.asm_out.internal_label) (file, "LCM", labelno);
          fputs ("\t.tc .", file);
          RS6000_OUTPUT_BASENAME (file, name);
          fputs ("[TC],", file);
          output_addr_const (file, x);
-         fputs ("[TL]@m", file);
+         if (TREE_PUBLIC (SYMBOL_REF_DECL (base)))
+           fputs ("[TL]@m", file);
+         else
+           fputs ("[UL]@m", file);
        }
     }
 #endif
@@ -25705,6 +25722,11 @@ rs6000_xcoff_asm_init_sections (void)
                           rs6000_xcoff_output_tls_section_asm_op,
                           &xcoff_tls_data_section_name);

+  tls_private_data_section
+    = get_unnamed_section (SECTION_TLS,
+                          rs6000_xcoff_output_tls_section_asm_op,
+                          &xcoff_private_data_section_name);
+
   read_only_private_data_section
     = get_unnamed_section (0, rs6000_xcoff_output_readonly_section_asm_op,
                           &xcoff_private_data_section_name);
@@ -25758,7 +25780,24 @@ rs6000_xcoff_select_section (tree decl, int reloc,
     {
 #if HAVE_AS_TLS
       if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
-       return tls_data_section;
+       {
+         if (TREE_PUBLIC (decl))
+           return tls_data_section;
+         else if (DECL_INITIAL (decl) == NULL_TREE
+                  || DECL_INITIAL (decl) == error_mark_node
+                  || (flag_zero_initialized_in_bss
+                      /* Leave constant zeroes in .rodata so they
+                         can be shared.  */
+                      && !TREE_READONLY (decl)
+                      && initializer_zerop (DECL_INITIAL (decl))))
+           {
+             /* Convert to COMMON to emit in BSS.  */
+             DECL_COMMON (decl) = 1;
+             return tls_comm_section;
+           }
+         else
+           return tls_private_data_section;
+       }
       else
 #endif
        if (TREE_PUBLIC (decl))
@@ -25857,10 +25896,12 @@ rs6000_xcoff_file_start (void)
                           main_input_filename, ".bss_");
   rs6000_gen_section_name (&xcoff_private_data_section_name,
                           main_input_filename, ".rw_");
+  rs6000_gen_section_name (&xcoff_read_only_section_name,
+                          main_input_filename, ".ro_");
   rs6000_gen_section_name (&xcoff_tls_data_section_name,
                           main_input_filename, ".tls_");
-  rs6000_gen_section_name (&xcoff_read_only_section_name,
-                          main_input_filename, ".ro_");
+  rs6000_gen_section_name (&xcoff_tbss_section_name,
+                          main_input_filename, ".tbss_[UL]");

   fputs ("\t.file\t", asm_out_file);
   output_quoted_string (asm_out_file, main_input_filename);
@@ -25886,6 +25927,29 @@ rs6000_xcoff_file_end (void)
         ? "\t.long _section_.text\n" : "\t.llong _section_.text\n",
         asm_out_file);
 }
+
+static void
+rs6000_xcoff_encode_section_info (tree decl, rtx rtl, int first)
+{
+  rtx symbol;
+  int flags;
+
+  default_encode_section_info (decl, rtl, first);
+
+  /* Careful not to prod global register variables.  */
+  if (!MEM_P (rtl))
+    return;
+  symbol = XEXP (rtl, 0);
+  if (GET_CODE (symbol) != SYMBOL_REF)
+    return;
+
+  flags = SYMBOL_REF_FLAGS (symbol);
+
+  if (TREE_CODE (decl) == VAR_DECL && DECL_THREAD_LOCAL_P (decl))
+    flags &= ~SYMBOL_FLAG_HAS_BLOCK_INFO;
+
+  SYMBOL_REF_FLAGS (symbol) = flags;
+}
 #endif /* TARGET_XCOFF */

 /* Compute a (partial) cost for rtx X.  Return true if the complete

Reply via email to