Random ppc changes.

Geoff Keating geoffk@cygnus.com
Fri Feb 11 16:04:00 GMT 2000


This patch does a bunch of stuff.  The branch should now bootstrap on
linux and AIX.  EABI is slightly broken because the
-fleading-underscore stuff doesn't like exception handling (I'm sure
I'd tested that, it must be those pesky gremlins again :-) ).

-- 
- Geoffrey Keating <geoffk@cygnus.com>

===File ~/patches/cygnus/rs6000-misc1.patch=================
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/Attic/ChangeLog,v
retrieving revision 1.1.2.33
diff -p -u -u -p -r1.1.2.33 ChangeLog
--- ChangeLog	2000/02/10 04:30:45	1.1.2.33
+++ ChangeLog	2000/02/12 00:00:50
@@ -1,3 +1,38 @@
+2000-02-11  Geoff Keating  <geoffk@cygnus.com>
+
+	* rs6000.c (output_function_profiler): Use .long for a 32-bit
+	quantity, fix profile1.C test failure under -fPIC.
+
+	* rs6000.c: Add 'u' to many constants to suppress warnings.
+	(constant_pool_expr_1): Make static.
+	(rs6000_emit_eh_toc_restore): Remove unused 'r2'.
+	* rs6000.h: Add 'u' to many constants to suppress warnings.
+
+	* rs6000.c (rs6000_emit_load_toc_table): Use LCTOC..1 under AIX
+	for the start of the TOC, instead of LCTOC..0.
+	* aix.h (toc_section): Use LCTOC..1 under AIX for the start
+	of the TOC.
+	* rs6000.md (load_toc_aix_si): Use LCTOC..1.
+	(load_toc_aix_di): Use LCTOC..1.
+
+	* rs6000.h (LEGITIMIZE_ADDRESS): Turn into a function.
+	* rs6000.c (rs6000_legitimize_address): New function from
+	LEGITIMIZE_ADDRESS.  Only use create_TOC_reference on
+	symbols in the constant pool that really are TOC references.
+	(print_operand_address): For ELF, write TOC offsets under
+	-fPIC as subtractions in the insn.
+	(output_toc): For ELF, define symbols in TOC as normal labels,
+	to match RTL.
+	(create_TOC_reference): Use gen_rtx_PLUS rather than gen_rtx.
+	* rs6000-protos.h (rs6000_legitimize_address): Prototype.
+	(create_TOC_reference): Prototype only when RTX_CODE is defined.
+	* rs6000.md (movsi): Only use create_TOC_reference on
+	symbols in the constant pool that really are TOC references.
+
+	* rs6000.h (MACHINE_DEPENDENT_REORG): Don't define.
+	* rs6000.c (rs6000_reorg): Delete.
+	* rs6000-protos.h (rs6000_reorg): Delete.
+
 2000-02-09  Geoff Keating  <geoffk@cygnus.com>
 
 	* rs6000.h (INCOMING_RETURN_ADDR_RTX): New macro.
Index: aix.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/Attic/aix.h,v
retrieving revision 1.1.2.8
diff -p -u -u -p -r1.1.2.8 aix.h
--- aix.h	2000/02/10 04:30:45	1.1.2.8
+++ aix.h	2000/02/12 00:00:50
@@ -169,7 +169,7 @@ toc_section ()						\
 	 in each file.  */						 \
       if (! toc_initialized)				\
 	{						\
-	  fputs ("\t.toc\nLCTOC..0:\n", asm_out_file);	\
+	  fputs ("\t.toc\nLCTOC..1:\n", asm_out_file);	\
 	  fputs ("\t.tc toc_table[TC],toc_table[RW]\n", asm_out_file); \
 	  toc_initialized = 1;				\
 	}						\
Index: rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/Attic/rs6000-protos.h,v
retrieving revision 1.1.2.3
diff -p -u -u -p -r1.1.2.3 rs6000-protos.h
--- rs6000-protos.h	2000/02/10 04:30:45	1.1.2.3
+++ rs6000-protos.h	2000/02/12 00:00:50
@@ -79,7 +79,6 @@ extern int addrs_ok_for_quad_peep PARAMS
 extern enum reg_class secondary_reload_class PARAMS ((enum reg_class,
 						      enum machine_mode, rtx));
 extern int ccr_bit PARAMS ((rtx, int));
-extern void rs6000_reorg PARAMS ((rtx));
 extern void print_operand PARAMS ((FILE *, rtx, int));
 extern void print_operand_address PARAMS ((FILE *, rtx));
 extern void output_toc PARAMS ((FILE *, rtx, int));
@@ -92,7 +91,9 @@ extern void rs6000_fatal_bad_address PAR
 extern int stmw_operation PARAMS ((rtx, enum machine_mode));
 extern int mtcrf_operation PARAMS ((rtx, enum machine_mode));
 extern int lmw_operation PARAMS ((rtx, enum machine_mode));
+extern struct rtx_def *create_TOC_reference PARAMS ((rtx));
 extern void rs6000_emit_eh_toc_restore PARAMS ((rtx));
+extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
 #endif /* RTX_CODE */
 
 #ifdef TREE_CODE
@@ -146,7 +147,6 @@ extern void toc_section PARAMS ((void));
 extern void private_data_section PARAMS ((void));
 extern int get_TOC_alias_set PARAMS ((void));
 extern int uses_TOC PARAMS ((void));
-extern struct rtx_def *create_TOC_reference PARAMS ((rtx));
 extern void rs6000_emit_prologue PARAMS ((void));
 extern void rs6000_emit_load_toc_table PARAMS ((int));
 extern void rs6000_aix_emit_builtin_unwind_init PARAMS ((void));
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.108.2.17
diff -p -u -u -p -r1.108.2.17 rs6000.c
--- rs6000.c	2000/02/10 04:30:45	1.108.2.17
+++ rs6000.c	2000/02/12 00:00:51
@@ -708,10 +708,10 @@ num_insns_constant_wide (value)
       HOST_WIDE_INT low  = value & 0xffffffff;
       HOST_WIDE_INT high = value >> 32;
 
-      if (high == 0 && (low & 0x80000000) == 0)
+      if (high == 0 && (low & 0x80000000u) == 0)
 	return 2;
 
-      else if (high == -1 && (low & 0x80000000) != 0)
+      else if (high == -1 && (low & 0x80000000u) != 0)
 	return 2;
 
       else if (! low)
@@ -772,10 +772,10 @@ num_insns_constant (op, mode)
 
       else
 	{
-	  if (high == 0 && (low & 0x80000000) == 0)
+	  if (high == 0 && (low & 0x80000000u) == 0)
 	    return num_insns_constant_wide (low);
 
-	  else if (high == -1 && (low & 0x80000000) != 0)
+	  else if (high == -1 && (low & 0x80000000u) != 0)
 	    return num_insns_constant_wide (low);
 
 	  else if (mask64_operand (op, mode))
@@ -943,7 +943,7 @@ logical_operand (op, mode)
 	      && ((INTVAL (op) & GET_MODE_MASK (mode)
 		   & (~ (HOST_WIDE_INT) 0xffff)) == 0
 		  || (INTVAL (op) & GET_MODE_MASK (mode)
-		      & (~ (HOST_WIDE_INT) 0xffff0000)) == 0)));
+		      & (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) == 0)));
 }
 
 /* Return 1 if C is a constant that is not a logical operand (as
@@ -958,7 +958,7 @@ non_logical_cint_operand (op, mode)
 	  && (INTVAL (op) & GET_MODE_MASK (mode) &
 	      (~ (HOST_WIDE_INT) 0xffff)) != 0
 	  && (INTVAL (op) & GET_MODE_MASK (mode) &
-	      (~ (HOST_WIDE_INT) 0xffff0000)) != 0);
+	      (~ (unsigned HOST_WIDE_INT) 0xffff0000u)) != 0);
 }
 
 /* Return 1 if C is a constant that can be encoded in a 32-bit mask on the
@@ -1267,8 +1267,8 @@ small_data_operand (op, mode)
   return 0;
 #endif
 }
-
-int 
+
+static int 
 constant_pool_expr_1 (op, have_sym, have_toc) 
     rtx op;
     int *have_sym;
@@ -1324,6 +1324,82 @@ toc_relative_expr_p (op)
     int have_toc = 0;
     return constant_pool_expr_1 (op, &have_sym, &have_toc) && have_toc;
 }
+
+/* Try machine-dependent ways of modifying an illegitimate address
+   to be legitimate.  If we find one, return the new, valid address.
+   This is used from only one place: `memory_address' in explow.c.
+
+   OLDX is the address as it was before break_out_memory_refs was called.
+   In some cases it is useful to look at this to decide what needs to be done.
+
+   MODE is passed so that this macro can use GO_IF_LEGITIMATE_ADDRESS.
+
+   It is always safe for this macro to do nothing.  It exists to recognize
+   opportunities to optimize the output.
+
+   On RS/6000, first check for the sum of a register with a constant
+   integer that is out of range.  If so, generate code to add the
+   constant with the low-order 16 bits masked to the register and force
+   this result into another register (this can be done with `cau').
+   Then generate an address of REG+(CONST&0xffff), allowing for the
+   possibility of bit 16 being a one.
+
+   Then check for the sum of a register and something not constant, try to
+   load the other things into a register and return the sum.  */
+rtx
+rs6000_legitimize_address (x, oldx, mode)
+     rtx x;
+     rtx oldx ATTRIBUTE_UNUSED;
+     enum machine_mode mode;
+{ 
+  if (GET_CODE (x) == PLUS 
+      && GET_CODE (XEXP (x, 0)) == REG
+      && GET_CODE (XEXP (x, 1)) == CONST_INT
+      && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) + 0x8000) >= 0x10000)
+    { 
+      HOST_WIDE_INT high_int, low_int;
+      rtx sum;
+      high_int = INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff);
+      low_int = INTVAL (XEXP (x, 1)) & 0xffff;
+      if (low_int & 0x8000)
+	high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;
+      sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (x, 0),
+					 GEN_INT (high_int)), 0);
+      return gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));
+    }
+  else if (GET_CODE (x) == PLUS 
+	   && GET_CODE (XEXP (x, 0)) == REG
+	   && GET_CODE (XEXP (x, 1)) != CONST_INT
+	   && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || mode != DFmode)
+	   && (TARGET_POWERPC64 || mode != DImode)
+	   && mode != TImode)
+    {
+      return gen_rtx_PLUS (Pmode, XEXP (x, 0),
+			   force_reg (Pmode, force_operand (XEXP (x, 1), 0)));
+    }
+  else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC && ! flag_pic
+	   && GET_CODE (x) != CONST_INT
+	   && GET_CODE (x) != CONST_DOUBLE 
+	   && CONSTANT_P (x)
+	   && (TARGET_HARD_FLOAT || mode != DFmode)
+	   && mode != DImode 
+	   && mode != TImode)
+    {
+      rtx reg = gen_reg_rtx (Pmode);
+      emit_insn (gen_elf_high (reg, (x)));
+      return gen_rtx_LO_SUM (Pmode, reg, (x));
+    }
+  else if (TARGET_TOC 
+	   && CONSTANT_POOL_EXPR_P (x)
+	   && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (x)))
+    {
+      return create_TOC_reference (x);
+    }
+  else
+    return NULL_RTX;
+}
+
+
 
 /* Initialize a variable CUM of type CUMULATIVE_ARGS
    for a call to a function whose data type is FNTYPE.
@@ -3060,28 +3136,6 @@ rs6000_got_register (value)
 
   return pic_offset_table_rtx;
 }
-
-/* Search for any occurrence of the GOT_TOC register marker that should
-   have been eliminated, but may have crept back in.
-
-   This function could completely go away now (June 1999), but we leave it 
-   in for a while until all the possible issues with the new -fpic handling 
-   are resolved. */
-
-void
-rs6000_reorg (insn)
-     rtx insn;
-{
-  if (flag_pic && (DEFAULT_ABI == ABI_V4 || DEFAULT_ABI == ABI_SOLARIS))
-    {
-      rtx got_reg = gen_rtx_REG (Pmode, 2);
-      for ( ; insn != NULL_RTX; insn = NEXT_INSN (insn))
-	if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
-	    && reg_mentioned_p (got_reg, PATTERN (insn)))
-	  fatal_insn ("GOT/TOC register marker not removed:", PATTERN (insn));
-    }
-}
-
 
 /* Define the structure for the machine field in struct function.  */
 struct machine_function
@@ -3384,15 +3438,15 @@ print_operand (file, x, code)
       /* If the high bit is set and the low bit is not, the value is zero.
 	 If the high bit is zero, the value is the first 1 bit we find from
 	 the left.  */
-      if ((val & 0x80000000) && ((val & 1) == 0))
+      if ((val & 0x80000000u) && ((val & 1) == 0))
 	{
 	  putc ('0', file);
 	  return;
 	}
-      else if ((val & 0x80000000) == 0)
+      else if ((val & 0x80000000u) == 0)
 	{
 	  for (i = 1; i < 32; i++)
-	    if ((val <<= 1) & 0x80000000)
+	    if ((val <<= 1) & 0x80000000u)
 	      break;
 	  fprintf (file, "%d", i);
 	  return;
@@ -3419,7 +3473,7 @@ print_operand (file, x, code)
       /* If the low bit is set and the high bit is not, the value is 31.
 	 If the low bit is zero, the value is the first 1 bit we find from
 	 the right.  */
-      if ((val & 1) && ((val & 0x80000000) == 0))
+      if ((val & 1) && ((val & 0x80000000u) == 0))
 	{
 	  fputs ("31", file);
 	  return;
@@ -3439,7 +3493,7 @@ print_operand (file, x, code)
       /* Otherwise, look for the first 0 bit from the left.  The result is its
 	 number minus 1. We know the high-order bit is one.  */
       for (i = 0; i < 32; i++)
-	if (((val <<= 1) & 0x80000000) == 0)
+	if (((val <<= 1) & 0x80000000u) == 0)
 	  break;
 
       fprintf (file, "%d", i);
@@ -3817,23 +3871,27 @@ print_operand_address (file, x)
       fprintf (file, "@l(%s)", reg_names[ REGNO (XEXP (x, 0)) ]);
     }
 #endif
-  else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P(x))
+  else if (LEGITIMATE_CONSTANT_POOL_ADDRESS_P (x))
     {
-      /* Find the (minus (sym) (toc)) buried in X, and temporarily
-	 turn it into (sym) for output_addr_const. */
-      rtx contains_minus = XEXP (x, 1); 
-      rtx minus;
-
-      while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
-	contains_minus = XEXP (contains_minus, 0);
+      if (TARGET_AIX)
+	{
+	  rtx contains_minus = XEXP (x, 1); 
+	  rtx minus;
+	  
+	  /* Find the (minus (sym) (toc)) buried in X, and temporarily
+	     turn it into (sym) for output_addr_const. */
+	  while (GET_CODE (XEXP (contains_minus, 0)) != MINUS)
+	    contains_minus = XEXP (contains_minus, 0);
 
-      minus = XEXP (contains_minus, 0); 
-      XEXP (contains_minus, 0) = XEXP (minus, 0);
-      
-      output_addr_const (file, XEXP (x, 1)); 	  
-      XEXP (contains_minus, 0) = minus;
+	  minus = XEXP (contains_minus, 0); 
+	  XEXP (contains_minus, 0) = XEXP (minus, 0);
+	  output_addr_const (file, XEXP (x, 1)); 	  
+	  XEXP (contains_minus, 0) = minus;
+	}
+      else
+	output_addr_const (file, XEXP (x, 1));
 
-      fprintf (file, "(%s)", reg_names[TOC_REGISTER]);
+      fprintf (file, "(%s)", reg_names[REGNO (XEXP (x, 0))]);
     }
   else
     abort ();
@@ -4362,7 +4420,7 @@ rs6000_emit_load_toc_table (fromprolog)
 	  /* This is for AIX code running in non-PIC ELF.  */
 	  char buf[30];
 	  rtx realsym;
-	  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 0);
+	  ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
 	  realsym = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
 	  
 	  emit_insn (gen_elf_high (dest, realsym));
@@ -4416,12 +4474,12 @@ rtx
 create_TOC_reference(symbol) 
     rtx symbol;
 {
-    return gen_rtx (PLUS, Pmode, 
-	    gen_rtx_REG (Pmode, TOC_REGISTER),
-	    gen_rtx_CONST (Pmode, 
-		gen_rtx_MINUS (Pmode, symbol, 
-		    gen_rtx_SYMBOL_REF (Pmode,
-			ggc_alloc_string (toc_label_name, -1)))));
+    return gen_rtx_PLUS (Pmode, 
+	     gen_rtx_REG (Pmode, TOC_REGISTER),
+	       gen_rtx_CONST (Pmode, 
+		 gen_rtx_MINUS (Pmode, symbol, 
+		   gen_rtx_SYMBOL_REF (Pmode,
+		     ggc_alloc_string (toc_label_name, -1)))));
 }
 
 #if TARGET_AIX
@@ -4499,7 +4557,7 @@ rs6000_emit_eh_toc_restore (stacksize)
   rtx tocompare = gen_reg_rtx (SImode);
   rtx opcode = gen_reg_rtx (SImode);
   rtx opcode_addr = gen_reg_rtx (Pmode);
-  rtx mem, r2;
+  rtx mem;
   rtx loop_start = gen_label_rtx ();
   rtx no_toc_restore_needed = gen_label_rtx ();
   rtx loop_exit = gen_label_rtx ();
@@ -5939,15 +5997,7 @@ output_toc (file, x, labelno)
     ASM_OUTPUT_ALIGN (file, 3);
   }
 
-  if (TARGET_ELF && TARGET_MINIMAL_TOC)
-    {
-      ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LC");
-      fprintf (file, "%d = .-", labelno);
-      ASM_OUTPUT_INTERNAL_LABEL_PREFIX (file, "LCTOC");
-      fputs ("1\n", file);
-    }
-  else
-    ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
+  ASM_OUTPUT_INTERNAL_LABEL (file, "LC", labelno);
 
   /* Handle FP constants specially.  Note that if we have a minimal
      TOC, things we put here aren't actually in the TOC, so we can allow
@@ -5967,7 +6017,7 @@ output_toc (file, x, labelno)
 	    fprintf (file, "\t.llong 0x%lx%08lx\n", k[0], k[1]);
 	  else
 	    fprintf (file, "\t.tc FD_%lx_%lx[TC],0x%lx%08lx\n",
-		     k[0], k[1], k[0] & 0xffffffff, k[1] & 0xffffffff);
+		     k[0], k[1], k[0] & 0xffffffffu, k[1] & 0xffffffffu);
 	  return;
 	}
       else
@@ -6263,7 +6313,7 @@ output_function_profiler (file, labelno)
 	  asm_fprintf (file, "\t{st|stw} %s,4(%s)\n",
 		       reg_names[0], reg_names[1]);
 	  /* Now, we need to get the address of the label.  */
-	  fputs ("\tbl 1f\n\t.word ", file);
+	  fputs ("\tbl 1f\n\t.long ", file);
 	  assemble_name (file, buf);
 	  fputs ("-.\n1:", file);
 	  asm_fprintf (file, "\tmflr %s\n", reg_names[11]);
Index: rs6000.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.64.2.15
diff -p -u -u -p -r1.64.2.15 rs6000.h
--- rs6000.h	2000/02/10 04:30:45	1.64.2.15
+++ rs6000.h	2000/02/12 00:00:51
@@ -1056,7 +1056,7 @@ enum reg_class
 
 #define CONST_OK_FOR_LETTER_P(VALUE, C)					\
    ( (C) == 'I' ? (unsigned HOST_WIDE_INT) ((VALUE) + 0x8000) < 0x10000	\
-   : (C) == 'J' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff0000)) == 0	\
+   : (C) == 'J' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff0000u)) == 0	\
    : (C) == 'K' ? ((VALUE) & (~ (HOST_WIDE_INT) 0xffff)) == 0		\
    : (C) == 'L' ? (((VALUE) & 0xffff) == 0				\
 		   && ((VALUE) >> 31 == -1 || (VALUE) >> 31 == 0))	\
@@ -1807,7 +1807,7 @@ typedef struct rs6000_args
   (TARGET_TOC								\
   && GET_CODE (X) == PLUS						\
   && GET_CODE (XEXP (X, 0)) == REG					\
-  && REGNO (XEXP (X, 0)) == TOC_REGISTER 				\
+  && (TARGET_MINIMAL_TOC || REGNO (XEXP (X, 0)) == TOC_REGISTER)	\
   && CONSTANT_POOL_EXPR_P (XEXP (X, 1)))
 
 #define LEGITIMATE_SMALL_DATA_P(MODE, X)				\
@@ -1903,48 +1903,13 @@ typedef struct rs6000_args
    Then check for the sum of a register and something not constant, try to
    load the other things into a register and return the sum.  */
 
-#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)				\
-{ if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG		\
-    && GET_CODE (XEXP (X, 1)) == CONST_INT				\
-    && (unsigned HOST_WIDE_INT) (INTVAL (XEXP (X, 1)) + 0x8000) >= 0x10000) \
-    { HOST_WIDE_INT high_int, low_int;					\
-      rtx sum;								\
-      high_int = INTVAL (XEXP (X, 1)) & (~ (HOST_WIDE_INT) 0xffff);	\
-      low_int = INTVAL (XEXP (X, 1)) & 0xffff;				\
-      if (low_int & 0x8000)						\
-	high_int += 0x10000, low_int |= ((HOST_WIDE_INT) -1) << 16;	\
-      sum = force_operand (gen_rtx_PLUS (Pmode, XEXP (X, 0),		\
-					 GEN_INT (high_int)), 0);	\
-      (X) = gen_rtx_PLUS (Pmode, sum, GEN_INT (low_int));		\
-      goto WIN;								\
-    }									\
-  else if (GET_CODE (X) == PLUS && GET_CODE (XEXP (X, 0)) == REG	\
-	   && GET_CODE (XEXP (X, 1)) != CONST_INT			\
-	   && (TARGET_HARD_FLOAT || TARGET_POWERPC64 || (MODE) != DFmode) \
-	   && (TARGET_POWERPC64 || (MODE) != DImode)			\
-	   && (MODE) != TImode)						\
-    {									\
-      (X) = gen_rtx_PLUS (Pmode, XEXP (X, 0),				\
-			  force_reg (Pmode, force_operand (XEXP (X, 1), 0))); \
-      goto WIN;								\
-    }									\
-  else if (TARGET_ELF && TARGET_32BIT && TARGET_NO_TOC			\
-	   && !flag_pic							\
-	   && GET_CODE (X) != CONST_INT					\
-	   && GET_CODE (X) != CONST_DOUBLE && CONSTANT_P (X)		\
-	   && (TARGET_HARD_FLOAT || (MODE) != DFmode)			\
-	   && (MODE) != DImode && (MODE) != TImode)			\
-    {									\
-      rtx reg = gen_reg_rtx (Pmode);					\
-      emit_insn (gen_elf_high (reg, (X)));				\
-      (X) = gen_rtx_LO_SUM (Pmode, reg, (X));				\
-      goto WIN;								\
-    }									\
-  else if (TARGET_TOC && CONSTANT_POOL_EXPR_P (X))			\
-    {									\
-      (X) = create_TOC_reference(X);					\
-      goto WIN;								\
-    }									\
+#define LEGITIMIZE_ADDRESS(X,OLDX,MODE,WIN)			\
+{  rtx result = rs6000_legitimize_address (X, OLDX, MODE);	\
+   if (result != NULL_RTX)					\
+     {								\
+       (X) = result;						\
+       goto WIN;						\
+     }								\
 }
 
 /* Try a machine-dependent way of reloading an illegitimate address
@@ -1978,7 +1943,7 @@ do {                                    
       HOST_WIDE_INT val = INTVAL (XEXP (X, 1));                         \
       HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;           \
       HOST_WIDE_INT high                                                \
-        = (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;       \
+        = (((val - low) & 0xffffffffu) ^ 0x80000000u) - 0x80000000u;       \
                                                                         \
       /* Check for 32-bit overflow.  */                                 \
       if (high + low != val)                                            \
@@ -1997,9 +1962,11 @@ do {                                    
                    OPNUM, TYPE);                                        \
       goto WIN;                                                         \
     }                                                                   \
-  else if (TARGET_TOC && CONSTANT_POOL_EXPR_P (X))			\
+  else if (TARGET_TOC 							\
+	   && CONSTANT_POOL_EXPR_P (X)					\
+	   && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (X)))	\
     {									\
-      (X) = create_TOC_reference(X);					\
+      (X) = create_TOC_reference (X);					\
       goto WIN;								\
     }									\
 } while (0)
@@ -2075,12 +2042,9 @@ do {                                    
 /* In rare cases, correct code generation requires extra machine
    dependent processing between the second jump optimization pass and
    delayed branch scheduling.  On those machines, define this macro
-   as a C statement to act on the code starting at INSN.
-
-   On the RS/6000, we use it to make sure the GOT_TOC register marker
-   that FINALIZE_PIC is supposed to remove actually got removed.  */
+   as a C statement to act on the code starting at INSN.  */
 
-#define MACHINE_DEPENDENT_REORG(INSN) rs6000_reorg (INSN)
+/* #define MACHINE_DEPENDENT_REORG(INSN) */
 
 
 /* Define this if some processing needs to be done immediately before
Index: rs6000.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.md,v
retrieving revision 1.79.2.18
diff -p -u -u -p -r1.79.2.18 rs6000.md
--- rs6000.md	2000/02/10 04:30:45	1.79.2.18
+++ rs6000.md	2000/02/12 00:00:51
@@ -5961,7 +5961,10 @@
 
       operands[1] = force_const_mem (SImode, operands[1]);
 
-      if (TARGET_TOC && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0)))
+      if (TARGET_TOC 
+	  && CONSTANT_POOL_EXPR_P (XEXP (operands[1], 0))
+	  && ASM_OUTPUT_SPECIAL_POOL_ENTRY_P (get_pool_constant (
+		XEXP (operands[1], 0))))
 	{
 	  XEXP (operands[1], 0) = create_TOC_reference (XEXP (operands[1], 0));
 	  MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set ();	
@@ -5973,15 +5976,6 @@
 	operands[1] = change_address (operands[1], SImode,
 				      XEXP (operands[1], 0));
     }
-  if (TARGET_TOC 
-     && GET_CODE (operands[1]) == MEM 
-     && GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF)
-    {
-      XEXP (operands[1], 0) = create_TOC_reference (XEXP (operands[1], 0));
-      MEM_ALIAS_SET (operands[1]) = get_TOC_alias_set ();	
-      RTX_UNCHANGING_P (operands[1]) = 1;
-    }
-
 }")
 
 (define_insn ""
@@ -7902,7 +7896,7 @@
   "*
 {
   char buf[30];
-  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 0);
+  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
   operands[2] = gen_rtx_REG (Pmode, 2);
   return \"{l|lwz} %0,%1(%2)\";
@@ -7916,7 +7910,7 @@
   "*
 {
   char buf[30];
-  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 0);
+  ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
   operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_alloc_string (buf, -1));
   operands[2] = gen_rtx_REG (Pmode, 2);
   return \"ld %0,%1(%2)\";
============================================================


More information about the Gcc-patches mailing list