This is the mail archive of the gcc@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]

Re: nightmares with biased stack pointers


> 
>   In message <199709140245.WAA13369@jenolan.rutgers.edu>you write:
>   >    Interesting problem; what would happen if you declared the stack
>   >    was unaligned, and made sure in the backend prologue/epilogue
>   >    routines (and parameter passing) to make sure that you always made
>   >    frames that were multiples of the old alignment?
>   > 
>   > I'm not sure that I follow.
> Set STACK_BOUNDARY to 8 bits, which effectively describes what you know
> about the alignment of "sp" -- ie nothing.
> 
> This is likely to have some undesirable effects; namely parameters might
> not be put in the right spots in memory and frames created in prologues
> might not keep the stack aligned properly, so you'd have to go back
> and play with the macros & code which control this stuff.

I took another approach and modified combine.c to have some knowledge about
biased stacks. This now compiles all the stuff correctly plus optimizes most
of the cases. Please tell me if you see this as an "unclean" solution.

--- ./config/sparc/sparc.h.jj	Sun Sep 14 19:00:23 1997
+++ ./config/sparc/sparc.h	Sun Sep 14 22:43:02 1997
@@ -915,6 +915,9 @@ extern int sparc_mode_class[];
 /* The stack bias (amount by which the hardware register is offset by).  */
 #define SPARC_STACK_BIAS (TARGET_STACK_BIAS ? 2047 : 0)
 
+/* Is stack biased? */
+#define STACK_BIAS SPARC_STACK_BIAS
+
 /* Base register for access to local variables of the function.  */
 #define FRAME_POINTER_REGNUM 30
 
--- ./combine.c.jj	Sun Sep 14 18:59:43 1997
+++ ./combine.c	Mon Sep 15 11:58:47 1997
@@ -6146,12 +6146,30 @@ force_to_mode (x, mode, mask, reg, just_
 	  smask |= (HOST_WIDE_INT) -1 << width;
 
 	if (GET_CODE (XEXP (x, 1)) == CONST_INT
-	    && exact_log2 (- smask) >= 0
-	    && (nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0
-	    && (INTVAL (XEXP (x, 1)) & ~ mask) != 0)
-	  return force_to_mode (plus_constant (XEXP (x, 0),
-					       INTVAL (XEXP (x, 1)) & mask),
-				mode, mask, reg, next_select);
+	    && exact_log2 (- smask) >= 0)
+	  {
+#ifdef STACK_BIAS
+	    if (STACK_BIAS
+	        && (XEXP (x, 0) == stack_pointer_rtx
+	            || XEXP (x, 0) == frame_pointer_rtx))
+	      {
+                int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
+                unsigned HOST_WIDE_INT sp_mask = GET_MODE_MASK(mode);
+          
+		sp_mask &= ~ (sp_alignment - 1);
+		if ((sp_mask & ~ mask) == 0
+		    && ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & ~ mask) != 0)
+		  return force_to_mode (plus_constant (XEXP (x, 0),
+		  				       ((INTVAL (XEXP (x, 1)) - STACK_BIAS) & mask) + STACK_BIAS),
+		 			mode, mask, reg, next_select);
+              }
+#endif
+	    if ((nonzero_bits (XEXP (x, 0), mode) & ~ mask) == 0
+	        && (INTVAL (XEXP (x, 1)) & ~ mask) != 0)
+	      return force_to_mode (plus_constant (XEXP (x, 0),
+					           INTVAL (XEXP (x, 1)) & mask),
+				    mode, mask, reg, next_select);
+	  }
       }
 
       /* ... fall through ...  */
@@ -7217,10 +7235,15 @@ nonzero_bits (x, mode)
 	 In particular, in the Irix6 n64 ABI, the stack has 128 bit
 	 alignment but the argument pointer has only 64 bit alignment.  */
 
-      if (x == stack_pointer_rtx || x == frame_pointer_rtx
-	  || x == hard_frame_pointer_rtx
-	  || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
-	      && REGNO (x) <= LAST_VIRTUAL_REGISTER))
+      if ((x == frame_pointer_rtx
+	   || x == stack_pointer_rtx
+	   || x == hard_frame_pointer_rtx
+	   || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
+	       && REGNO (x) <= LAST_VIRTUAL_REGISTER))
+#ifdef STACK_BIAS
+	  && !STACK_BIAS
+#endif	      
+	      )
 	{
 	  int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
 
@@ -7401,6 +7424,22 @@ nonzero_bits (x, mode)
 	switch (code)
 	  {
 	  case PLUS:
+#ifdef STACK_BIAS
+	    if (STACK_BIAS
+	        && (XEXP (x, 0) == stack_pointer_rtx
+	            || XEXP (x, 0) == frame_pointer_rtx)
+	        && GET_CODE (XEXP (x, 1)) == CONST_INT)
+	      {
+		int sp_alignment = STACK_BOUNDARY / BITS_PER_UNIT;
+
+	        nz0 = (GET_MODE_MASK (mode) & ~ (sp_alignment - 1));
+	        nz1 = INTVAL(XEXP (x, 1)) - STACK_BIAS;
+	        width0 = floor_log2 (nz0) + 1;
+	        width1 = floor_log2 (nz1) + 1;
+	        low0 = floor_log2 (nz0 & -nz0);
+	        low1 = floor_log2 (nz1 & -nz1);
+	      }
+#endif	  
 	    result_width = MAX (width0, width1) + 1;
 	    result_low = MIN (low0, low1);
 	    break;

Cheers,
    Jakub
___________________________________________________________________
Jakub Jelinek | jj@sunsite.mff.cuni.cz | http://sunsite.mff.cuni.cz
Administrator of SunSITE Czech Republic, MFF, Charles University
___________________________________________________________________
Ultralinux - first 64bit OS to take full power of the UltraSparc
Linux version 2.0.30 on a sparc machine (291.64 BogoMips).
___________________________________________________________________


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