nightmares with biased stack pointers

Jakub Jelinek jj@sunsite.ms.mff.cuni.cz
Sun Sep 14 12:00:00 GMT 1997


> The problem is that sparc64 is the only target which has whats called
> a 'biased' stack pointer.  %sp really doesn't point to the stack, it
> points to the stack minus 2,047 bytes.  Why the weird number and why
> the bias at all?  With 64-bit, stack frames get larger, the bias
> allows you to access 2k more from the frame pointer than you otherwise
> would be able to.  Think about it, you care not whats below the stack
> pointer (when stack grows downward) but you do care a lot about whats
> on both sides of the frame pointer.  This produces more chances that
> the immediate offset in a load address can allow you to get to the
> frame pointer relative stack slot in one instruction.

The problem is in combine.c/nonzero_bits, as sparc64 has
STACK_BOUNDARY defined and the code says low bits are zero, even if they are
not.
My quick solution for now is:

--- ./config/sparc/sparc.h.jj	Sun Sep 14 19:00:23 1997
+++ ./config/sparc/sparc.h	Sun Sep 14 20:49:21 1997
@@ -607,6 +607,9 @@ extern struct sparc_cpu_select sparc_sel
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
 #define STACK_BOUNDARY (TARGET_ARCH64 ? 128 : 64)
 
+/* Is stack biased? */
+#define BIASED_STACK (TARGET_STACK_BIAS ? 1 : 0)
+
 /* ALIGN FRAMES on double word boundaries */
 
 #define SPARC_STACK_ALIGN(LOC) \
--- ./combine.c.jj	Sun Sep 14 18:59:43 1997
+++ ./combine.c	Sun Sep 14 20:47:47 1997
@@ -7217,7 +7217,12 @@ 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
+      if (x == frame_pointer_rtx
+#ifndef BIASED_STACK
+	  || x == stack_pointer_rtx
+#else
+	  || (!BIASED_STACK && x == stack_pointer_rtx)
+#endif
 	  || x == hard_frame_pointer_rtx
 	  || (REGNO (x) >= FIRST_VIRTUAL_REGISTER
 	      && REGNO (x) <= LAST_VIRTUAL_REGISTER))

but of course that's just a quick hack and not the right solution, as the
stack IS aligned, just biased. With the above patch, gcc assumes stack is
not aligned, so the code David Miller presented compiles to:

        !#PROLOGUE# 0
        save %sp,-160,%sp
        !#PROLOGUE# 1
        add %sp,-16,%sp
        add %sp,2198,%o0
        call foo,0
        and %o0,-16,%o0
        ret
        restore %g0,0,%o0

while the aim is:

        save %sp,-160,%sp
        add %sp,-16,%sp
        call foo,0
        add %sp,2191,%o0
        ret
        restore %g0,0,%o0

(or even

        save %sp,-176,%sp
        call foo,0
        add %sp,2191,%o0
        ret
        restore %g0,0,%o0

but that's another issue).

The Right Way To Do It (tm) should be for BIASED_STACK special case
additions to stack_pointer_rtx and take the bias into the account.
I'll look into that in the next few days.

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.1.64 on a sparc machine (333.41 BogoMips).
___________________________________________________________________



More information about the Gcc mailing list