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]

Re: Fix powerpc-linux gcc.dg/20020103-1.c


On Mon, Nov 08, 2004 at 10:01:33PM +1030, Alan Modra wrote:
> This fixes 20020103-1.c with a minimal change.

The same for gcc-3.4.  Requires backport of another mainline fix.

	* config/rs6000/rs6000.c (rs6000_cannot_force_const_mem): New function.
	(TARGET_CANNOT_FORCE_CONST_MEM): Update.
	(rs6000_emit_move): Simplify code handling small data.  Handle
	got_operand earlier, before reload_in_progress tests.
	* config/rs6000/rs6000-protos.h (rs6000_cannot_force_const_mem):
	Declare.
	2003-11-27  Richard Sandiford  <rsandifo@redhat.com>
	* reload.c (CONST_POOL_OK_P): New macro.
	(find_reloads): Use it to decide whether a constant can be forced
	into memory.

diff -urp -xCVS -x'*~' -x'.#*' gcc-3.4-virgin/gcc/config/rs6000/rs6000-protos.h gcc-3.4-got/gcc/config/rs6000/rs6000-protos.h
--- gcc-3.4-virgin/gcc/config/rs6000/rs6000-protos.h	2004-08-03 11:57:50.000000000 +0930
+++ gcc-3.4-got/gcc/config/rs6000/rs6000-protos.h	2004-11-10 10:46:50.055723987 +1030
@@ -199,6 +199,7 @@ extern int rs6000_register_move_cost (en
 					      enum reg_class, enum reg_class);
 extern int rs6000_memory_move_cost (enum machine_mode, enum reg_class, int);
 extern bool rs6000_tls_referenced_p (rtx);
+extern bool rs6000_cannot_force_const_mem (rtx);
 extern int rs6000_tls_symbol_ref (rtx, enum machine_mode);
 extern void rs6000_output_dwarf_dtprel (FILE*, int, rtx);
 
diff -urp -xCVS -x'*~' -x'.#*' gcc-3.4-virgin/gcc/config/rs6000/rs6000.c gcc-3.4-got/gcc/config/rs6000/rs6000.c
--- gcc-3.4-virgin/gcc/config/rs6000/rs6000.c	2004-10-23 19:26:49.000000000 +0930
+++ gcc-3.4-got/gcc/config/rs6000/rs6000.c	2004-11-10 10:46:50.087718942 +1030
@@ -548,7 +548,7 @@ static const char alt_reg_names[][8] =
 #define TARGET_HAVE_TLS HAVE_AS_TLS
 
 #undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_tls_referenced_p
+#define TARGET_CANNOT_FORCE_CONST_MEM rs6000_cannot_force_const_mem
 
 #undef TARGET_ASM_FUNCTION_PROLOGUE
 #define TARGET_ASM_FUNCTION_PROLOGUE rs6000_output_function_prologue
@@ -3142,6 +3142,21 @@ rs6000_tls_referenced_p (rtx x)
   return for_each_rtx (&x, &rs6000_tls_symbol_ref_1, 0);
 }
 
+/* Return 1 if X is a V4 got reference or if it contains a thread-local
+   symbol.  */
+
+bool
+rs6000_cannot_force_const_mem (rtx x)
+{
+  if (DEFAULT_ABI == ABI_V4
+      && flag_pic == 1
+      && GET_MODE (x) == SImode
+      && got_operand (x, GET_MODE (x)))
+    return true;
+
+  return rs6000_tls_referenced_p (x);
+}
+
 /* Return 1 if *X is a thread-local symbol.  This is the same as
    rs6000_tls_symbol_ref except for the type of the unused argument.  */
 
@@ -3630,6 +3645,16 @@ rs6000_emit_move (rtx dest, rtx source, 
 	operands[1] = rs6000_legitimize_tls_address (operands[1], model);
     }
 
+  /* Recognize V4 got references.  */
+  if (DEFAULT_ABI == ABI_V4
+      && flag_pic == 1
+      && mode == SImode
+      && got_operand (operands[1], mode))
+    {
+      emit_insn (gen_movsi_got (operands[0], operands[1]));
+      return;
+    }
+
   /* Handle the case where reload calls us with an invalid address.  */
   if (reload_in_progress && mode == Pmode
       && (! general_operand (operands[1], mode)
@@ -3693,27 +3718,15 @@ rs6000_emit_move (rtx dest, rtx source, 
       break;
       
     case SImode:
-    case DImode:
       /* Use default pattern for address of ELF small data */
-      if (TARGET_ELF
-	  && mode == Pmode
-	  && DEFAULT_ABI == ABI_V4
+      if (DEFAULT_ABI == ABI_V4
 	  && (GET_CODE (operands[1]) == SYMBOL_REF 
 	      || GET_CODE (operands[1]) == CONST)
 	  && small_data_operand (operands[1], mode))
-	{
-	  emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
-	  return;
-	}
-
-      if (DEFAULT_ABI == ABI_V4
-	  && mode == Pmode && mode == SImode
-	  && flag_pic == 1 && got_operand (operands[1], mode))
-	{
-	  emit_insn (gen_movsi_got (operands[0], operands[1]));
-	  return;
-	}
+	goto emit_set;
+      /* Fall thru */
 
+    case DImode:
       if ((TARGET_ELF || DEFAULT_ABI == ABI_DARWIN)
 	  && TARGET_NO_TOC
 	  && ! flag_pic
diff -urp -xCVS -x'*~' -x'.#*' gcc-3.4-virgin/gcc/reload.c gcc-3.4-got/gcc/reload.c
--- gcc-3.4-virgin/gcc/reload.c	2004-09-15 09:17:28.000000000 +0930
+++ gcc-3.4-got/gcc/reload.c	2004-11-10 10:46:50.093717996 +1030
@@ -105,6 +105,13 @@ a register with any other reload.  */
 #include "function.h"
 #include "toplev.h"
 #include "params.h"
+#include "target.h"
+
+/* True if X is a constant that can be forced into the constant pool.  */
+#define CONST_POOL_OK_P(X)			\
+  (CONSTANT_P (X)				\
+   && GET_CODE (X) != HIGH			\
+   && !targetm.cannot_force_const_mem (X))
 
 #ifndef REGNO_MODE_OK_FOR_BASE_P
 #define REGNO_MODE_OK_FOR_BASE_P(REGNO, MODE) REGNO_OK_FOR_BASE_P (REGNO)
@@ -3129,9 +3136,7 @@ find_reloads (rtx insn, int replace, int
 			&& REGNO (operand) >= FIRST_PSEUDO_REGISTER
 			&& reg_renumber[REGNO (operand)] < 0))
 		  win = 1;
-		if (CONSTANT_P (operand)
-		    /* force_const_mem does not accept HIGH.  */
-		    && GET_CODE (operand) != HIGH)
+		if (CONST_POOL_OK_P (operand))
 		  badop = 0;
 		constmemok = 1;
 		break;
@@ -3193,8 +3198,7 @@ find_reloads (rtx insn, int replace, int
 			     && offsettable_memref_p (reg_equiv_mem[REGNO (operand)]))
 			    || (reg_equiv_address[REGNO (operand)] != 0))))
 		  win = 1;
-		/* force_const_mem does not accept HIGH.  */
-		if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
+		if (CONST_POOL_OK_P (operand)
 		    || GET_CODE (operand) == MEM)
 		  badop = 0;
 		constmemok = 1;
@@ -3314,7 +3318,7 @@ find_reloads (rtx insn, int replace, int
 			/* If we didn't already win, we can reload
 			   constants via force_const_mem, and other
 			   MEMs by reloading the address like for 'o'.  */
-			if ((CONSTANT_P (operand) && GET_CODE (operand) != HIGH)
+			if (CONST_POOL_OK_P (operand)
 			    || GET_CODE (operand) == MEM)
 			  badop = 0;
 			constmemok = 1;
@@ -3390,9 +3394,7 @@ find_reloads (rtx insn, int replace, int
 		 an early reload pass.  Note that the test here is
 		 precisely the same as in the code below that calls
 		 force_const_mem.  */
-	      if (CONSTANT_P (operand)
-		  /* force_const_mem does not accept HIGH.  */
-		  && GET_CODE (operand) != HIGH
+	      if (CONST_POOL_OK_P (operand)
 		  && ((PREFERRED_RELOAD_CLASS (operand,
 					       (enum reg_class) this_alternative[i])
 		       == NO_REGS)
@@ -3772,9 +3774,7 @@ find_reloads (rtx insn, int replace, int
      into registers are here changed into memory references.  */
   for (i = 0; i < noperands; i++)
     if (! goal_alternative_win[i]
-	&& CONSTANT_P (recog_data.operand[i])
-	/* force_const_mem does not accept HIGH.  */
-	&& GET_CODE (recog_data.operand[i]) != HIGH
+	&& CONST_POOL_OK_P (recog_data.operand[i])
 	&& ((PREFERRED_RELOAD_CLASS (recog_data.operand[i],
 				     (enum reg_class) goal_alternative[i])
 	     == NO_REGS)

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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