PATCH:[darwin] fix load of a misaligned double word

Alan Modra amodra@bigpond.net.au
Sat Feb 21 13:45:00 GMT 2004


On Fri, Feb 20, 2004 at 03:32:40PM +1030, Alan Modra wrote:
> To figure out whether we are using a gpr or not requires passing the
> insn to LEGITIMIZE_RELOAD_ADDRESS.  Would such a patch be acceptable?

Like so.  Patch against hammer branch, and obviously I need to update
all the other target defines of LEGITIMIZE_RELOAD_ADDRESS.  Either that
or use a special invocation for rs6000..

	* reload.c (find_reloads_address): Pass insn to
	LEGITIMIZE_RELOAD_ADDRESS.
	* config/rs6000/rs6000.c (gpr_load_or_store): New function.
	(rs6000_legitimize_reload_address): Replace unused "ind_levels" arg
	with "insn".  Don't attempt to handle loads or stores of gprs
	using non multiple of four offsets.
	* config/rs6000/rs6000-protos.h (rs6000_legitimize_reload_address):
	Update prototype.
	* config/rs6000/rs6000.h (LEGITIMIZE_RELOAD_ADDRESS): Adjust.

Bootstrap in progress.

Index: gcc/reload.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload.c,v
retrieving revision 1.197.2.13
diff -u -p -r1.197.2.13 reload.c
--- gcc/reload.c	30 Jan 2004 20:38:53 -0000	1.197.2.13
+++ gcc/reload.c	20 Feb 2004 08:15:13 -0000
@@ -4797,7 +4797,7 @@ find_reloads_address (mode, memrefloc, a
       if (memrefloc)
 	{
 	  LEGITIMIZE_RELOAD_ADDRESS (ad, GET_MODE (*memrefloc), opnum, type,
-				     ind_levels, win);
+				     ind_levels, insn, win);
 	}
       break;
     win:
Index: gcc/config/rs6000/rs6000-protos.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000-protos.h,v
retrieving revision 1.47.2.8
diff -u -p -r1.47.2.8 rs6000-protos.h
--- gcc/config/rs6000/rs6000-protos.h	6 Feb 2004 08:35:52 -0000	1.47.2.8
+++ gcc/config/rs6000/rs6000-protos.h	20 Feb 2004 08:15:15 -0000
@@ -133,7 +133,7 @@ extern void rs6000_split_multireg_move (
 extern void rs6000_emit_move PARAMS ((rtx, rtx, enum machine_mode));
 extern rtx rs6000_legitimize_address PARAMS ((rtx, rtx, enum machine_mode));
 extern rtx rs6000_legitimize_reload_address PARAMS ((rtx, enum machine_mode,
-			    int, int, int, int *));
+			    int, int, rtx, int *));
 extern int rs6000_legitimate_address PARAMS ((enum machine_mode, rtx, int));
 extern bool rs6000_mode_dependent_address PARAMS ((rtx));
 extern rtx rs6000_return_addr PARAMS ((int, rtx));
Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.397.2.30
diff -u -p -r1.397.2.30 rs6000.c
--- gcc/config/rs6000/rs6000.c	12 Feb 2004 13:25:06 -0000	1.397.2.30
+++ gcc/config/rs6000/rs6000.c	20 Feb 2004 08:15:24 -0000
@@ -3120,6 +3120,55 @@ rs6000_tls_symbol_ref_1 (x, data)
   return tls_symbolic_operand_type (*x);
 }
 
+/* Return true if PAT, which contains a memref using AD as an address,
+   is loading or storing a gpr with that particular memref.  */
+
+static bool
+gpr_load_or_store (rtx pat, rtx ad)
+{
+  if (GET_CODE (pat) == SET)
+    {
+      rtx reg, mem;
+      int regno;
+
+      if (GET_CODE (XEXP (pat, 0)) == MEM)
+	{
+	  mem = XEXP (pat, 0);
+	  reg = XEXP (pat, 1);
+	}
+      else if (GET_CODE (XEXP (pat, 1)) == MEM)
+	{
+	  mem = XEXP (pat, 1);
+	  reg = XEXP (pat, 0);
+	}
+      else
+	return false;
+
+      if (XEXP (mem, 0) != ad)
+	return false;
+
+      if (GET_CODE (reg) == REG)
+	regno = REGNO (reg);
+      else if (GET_CODE (reg) == SUBREG)
+	regno = REGNO (SUBREG_REG (reg));
+      else
+	return false;
+
+      return INT_REGNO_P (regno);
+    }
+
+  if (GET_CODE (pat) == PARALLEL)
+    {
+      int i = XVECLEN (pat, 0);
+
+      while (--i >= 0)
+	if (gpr_load_or_store (XVECEXP (pat, 0, i), ad))
+	  return true;
+    }
+
+  return false;
+}
+
 /* The convention appears to be to define this wherever it is used.
    With legitimize_reload_address now defined here, REG_MODE_OK_FOR_BASE_P
    is now used here.  */
@@ -3141,12 +3190,12 @@ rs6000_tls_symbol_ref_1 (x, data)
    The Darwin code is inside #if TARGET_MACHO because only then is
    machopic_function_base_name() defined.  */
 rtx
-rs6000_legitimize_reload_address (x, mode, opnum, type, ind_levels, win)
+rs6000_legitimize_reload_address (x, mode, opnum, type, insn, win)
     rtx x;
     enum machine_mode mode;
     int opnum;
     int type;
-    int ind_levels ATTRIBUTE_UNUSED;
+    rtx insn;
     int *win;
 {
   /* We must recognize output that we have already generated ourselves.  */
@@ -3197,8 +3246,18 @@ rs6000_legitimize_reload_address (x, mod
       HOST_WIDE_INT high
 	= (((val - low) & 0xffffffff) ^ 0x80000000) - 0x80000000;
 
-      /* Check for 32-bit overflow.  */
-      if (high + low != val)
+      /* We get here for two reasons: a) The offset is too large,
+	 or b) the offset is invalid, for example, not a multiple of
+	 4 on a DImode access.  Leave case b, and when we get 32-bit
+	 overflow, to the generic parts of reload to handle.  */
+
+      if (high + low != val
+	  || high == 0
+	  || ((low & 3) != 0
+	      && GET_MODE_SIZE (mode) >= 8
+	      && TARGET_POWERPC64
+	      && insn != 0
+	      && gpr_load_or_store (PATTERN (insn), x)))
 	{
 	  *win = 0;
 	  return x;
Index: gcc/config/rs6000/rs6000.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.h,v
retrieving revision 1.234.2.23
diff -u -p -r1.234.2.23 rs6000.h
--- gcc/config/rs6000/rs6000.h	15 Feb 2004 12:57:15 -0000	1.234.2.23
+++ gcc/config/rs6000/rs6000.h	20 Feb 2004 08:15:26 -0000
@@ -2150,12 +2150,12 @@ typedef struct rs6000_args
    Implemented on rs6000 by rs6000_legitimize_reload_address.  
    Note that (X) is evaluated twice; this is safe in current usage.  */
    
-#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,WIN)	     \
+#define LEGITIMIZE_RELOAD_ADDRESS(X,MODE,OPNUM,TYPE,IND_LEVELS,INSN,WIN)     \
 do {									     \
   int win;								     \
   (X) = rs6000_legitimize_reload_address ((X), (MODE), (OPNUM),		     \
-			(int)(TYPE), (IND_LEVELS), &win);		     \
-  if ( win )								     \
+					  (int) (TYPE), (INSN), &win);	     \
+  if (win)								     \
     goto WIN;								     \
 } while (0)
 

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre



More information about the Gcc-patches mailing list