This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR target/16304: AIX 4.x forward reference problem


Albert Chin asked me to look at PR 16304.  The AIX 4.x assembler doesn't
like undefined or forward references in .set directives.  For example,

FAIL: gcc.c-torture/compile/20040323-1.c  -O0  (test for excess errors)
Excess errors:
Assembler:
/tmp//ccYlfLZp.s: line 70: 1252-003 The .set operand is not defined
        or is a forward reference.

The use of local aliases in thunk generation caused the build of
libstdc++ to fail compiling strstream.cc due to the generation of a
number of forward references.  This patch fixes the forward reference
problem by deferring the output of the .set directives to the end of
the translation unit.

This fix will handle normal situations where aliases don't refer to
symbols that are themselves aliases.  The patch doesn't fix the
problem regarding undefined symbols.  In that case, a .extern directive
needs to be emitted.  However, I couldn't see any way to determine
if the DECL_OF_VALUE passed in ASM_OUTPUT_DEF_FROM_DECLS is defined
or not.  Typically, it is an identifier node and we don't have a
flag to determine if the node is defined.

The enclosed patch is for the main.  There are some small changes
for 3.4 (DOT_SYMBOLS isn't used there).  On 3.4, this patch is sufficient
to provide a successful bootstrap:

  http://gcc.gnu.org/ml/gcc-testresults/2004-10/msg01501.html

On the main, some additional changes are needed which I will try to
address in other patches.  Here is the current state of the main
on AIX 4.3.3:

  http://gcc.gnu.org/ml/gcc-testresults/2004-10/msg01502.html

The 3.4 version of the patch as also been tested on AIX 5.1 and 5.2.

OK for 3.4 and main?

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2004-10-30  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	PR target/16304
	* rs6000-protos.h (rs6000_xcoff_asm_output_def): Declare.
	* rs6000.c (deferred_output_defs, n_deferred_output_defs): Declare.
	(rs6000_xcoff_asm_output_def): New function.
	(rs6000_xcoff_file_end): Output deferred output definitions.
	* rs6000.h (RS6000_OUTPUT_DOTDEF): New macro.
	(ASM_WEAKEN_DECL, ASM_OUTPUT_DEF_FROM_DECLS): Use RS6000_OUTPUT_DOTDEF.
	* xcoff.h (ASM_OUTPUT_DEF): Change to use rs6000_xcoff_asm_output_def.
	(RS6000_OUTPUT_DOTDEF): Redefine using rs6000_xcoff_asm_output_def.

Index: config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.90
diff -u -3 -p -r1.90 rs6000-protos.h
--- config/rs6000/rs6000-protos.h	7 Oct 2004 16:05:35 -0000	1.90
+++ config/rs6000/rs6000-protos.h	29 Oct 2004 01:36:52 -0000
@@ -214,6 +214,9 @@ extern void rs6000_conditional_register_
 extern void rs6000_pragma_longcall (struct cpp_reader *);
 extern void rs6000_cpu_cpp_builtins (struct cpp_reader *);
 
+#if TARGET_XCOFF
+void rs6000_xcoff_asm_output_def (const char *, const char *, const char *);
+#endif
 #if TARGET_MACHO
 char *output_call (rtx, rtx *, int, int);
 #endif
Index: config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.732
diff -u -3 -p -r1.732 rs6000.c
--- config/rs6000/rs6000.c	28 Oct 2004 22:32:41 -0000	1.732
+++ config/rs6000/rs6000.c	29 Oct 2004 01:36:53 -0000
@@ -776,6 +776,18 @@ static void rs6000_emit_vector_select (r
 const int INSN_NOT_AVAILABLE = -1;
 static enum machine_mode rs6000_eh_return_filter_mode (void);
 
+#if TARGET_XCOFF
+struct deferred_output_def GTY(())
+{
+  const char *label1;
+  const char *label2;
+  const char *prefix;
+};
+static GTY((length ("n_deferred_output_defs"))) struct deferred_output_def *
+  deferred_output_defs;
+static GTY(()) unsigned int n_deferred_output_defs = 0;
+#endif
+
 /* Hash table stuff for keeping track of TOC entries.  */
 
 struct toc_hash_struct GTY(())
@@ -17498,6 +17510,25 @@ rs6000_elf_declare_function_name (FILE *
 #endif
 
 #if TARGET_XCOFF
+void
+rs6000_xcoff_asm_output_def (const char *label1, const char *label2,
+			     const char *prefix)
+{
+  size_t size = sizeof (struct deferred_output_def);
+  unsigned int i;
+
+  i = n_deferred_output_defs++;
+  if (deferred_output_defs == 0)
+    deferred_output_defs = ggc_alloc (size);
+  else
+    deferred_output_defs = ggc_realloc (deferred_output_defs,
+					n_deferred_output_defs * size);
+
+  deferred_output_defs[i].label1 = (*targetm.strip_name_encoding) (label1);
+  deferred_output_defs[i].label2 = (*targetm.strip_name_encoding) (label2);
+  deferred_output_defs[i].prefix = prefix;
+}
+
 static void
 rs6000_xcoff_asm_globalize_label (FILE *stream, const char *name)
 {
@@ -17655,6 +17686,21 @@ rs6000_xcoff_file_start (void)
 static void
 rs6000_xcoff_file_end (void)
 {
+  struct deferred_output_def *p = deferred_output_defs;
+  unsigned int i;
+
+  for (i = 0; i < n_deferred_output_defs; i++)
+    {
+      fprintf (asm_out_file, "%s%s", SET_ASM_OP, p->prefix);
+      assemble_name (asm_out_file, p->label1);
+      fprintf (asm_out_file, ",%s", p->prefix);
+      assemble_name (asm_out_file, p->label2);
+      fputs ("\n", asm_out_file);
+      p++;
+    }
+  deferred_output_defs = 0;
+  n_deferred_output_defs = 0;
+
   text_section ();
   fputs ("_section_.text:\n", asm_out_file);
   data_section ();
Index: config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.345
diff -u -3 -p -r1.345 rs6000.h
--- config/rs6000/rs6000.h	26 Oct 2004 17:36:22 -0000	1.345
+++ config/rs6000/rs6000.h	29 Oct 2004 01:36:54 -0000
@@ -2239,6 +2239,17 @@ extern int toc_initialized;
     }									  \
 }
 
+#define RS6000_OUTPUT_DOTDEF(FILE,LABEL1,LABEL2) \
+  do									\
+    {									\
+      fputs ("\t.set\t.", (FILE));					\
+      RS6000_OUTPUT_BASENAME ((FILE), (NAME));				\
+      fputs (",.", (FILE));						\
+      RS6000_OUTPUT_BASENAME ((FILE), (VAL));				\
+      fputc ('\n', (FILE));						\
+    }									\
+  while (0)
+
 #ifdef HAVE_GAS_WEAK
 #define RS6000_WEAK 1
 #else
@@ -2266,13 +2277,7 @@ extern int toc_initialized;
 	  ASM_OUTPUT_DEF ((FILE), (NAME), (VAL));			\
 	  if ((DECL) && TREE_CODE (DECL) == FUNCTION_DECL		\
 	      && DEFAULT_ABI == ABI_AIX && DOT_SYMBOLS)			\
-	    {								\
-	      fputs ("\t.set\t.", (FILE));				\
-	      RS6000_OUTPUT_BASENAME ((FILE), (NAME));			\
-	      fputs (",.", (FILE));					\
-	      RS6000_OUTPUT_BASENAME ((FILE), (VAL));			\
-	      fputc ('\n', (FILE));					\
-	    }								\
+	    RS6000_OUTPUT_DOTDEF ((FILE), (NAME), (VAL));		\
 	}								\
     }									\
   while (0)
@@ -2303,11 +2308,7 @@ extern int toc_initialized;
 	      RS6000_OUTPUT_BASENAME (FILE, alias);			\
 	      putc ('\n', FILE);					\
 	    }								\
-	  fputs ("\t.set\t.", FILE);					\
-	  RS6000_OUTPUT_BASENAME (FILE, alias);				\
-	  fputs (",.", FILE);						\
-	  RS6000_OUTPUT_BASENAME (FILE, name);				\
-	  fputc ('\n', FILE);						\
+	  RS6000_OUTPUT_DOTDEF ((FILE), alias, name);			\
 	}								\
       ASM_OUTPUT_DEF (FILE, alias, name);				\
     }									\
Index: config/rs6000/xcoff.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/xcoff.h,v
retrieving revision 1.53
diff -u -3 -p -r1.53 xcoff.h
--- config/rs6000/xcoff.h	12 Aug 2004 13:56:54 -0000	1.53
+++ config/rs6000/xcoff.h	29 Oct 2004 01:36:54 -0000
@@ -344,13 +344,12 @@ toc_section (void)					\
 #define SET_ASM_OP "\t.set "
 
 /* This is how we tell the assembler to equate two values.  */
-#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)				\
- do {	fprintf ((FILE), "%s", SET_ASM_OP);				\
-	RS6000_OUTPUT_BASENAME (FILE, LABEL1);				\
-	fprintf (FILE, ",");						\
-	RS6000_OUTPUT_BASENAME (FILE, LABEL2);				\
-	fprintf (FILE, "\n");						\
-  } while (0)
+#define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2) \
+  rs6000_xcoff_asm_output_def (LABEL1, LABEL2, "")
+
+#undef RS6000_OUTPUT_DOTDEF
+#define RS6000_OUTPUT_DOTDEF(FILE,LABEL1,LABEL2) \
+  rs6000_xcoff_asm_output_def (LABEL1, LABEL2, ".")
 
 /* Used by rs6000_assemble_integer, among others.  */
 #define DOUBLE_INT_ASM_OP "\t.llong\t"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]