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]

[PATCH] Re: leaf functions are broken on SPARC


> On Sun, Mar 10, 2002 at 08:40:35AM -0800, Dan Nicolaescu wrote:
> > GCC CVS does not generate leaf functions anymore on SPARC
> > (sparc-sun-solaris2.7):
> > 
> > 
> > void foo (void)
> > {
> > }
> > 
> > 
> > compiles to (with -O2):
> > 
> >         .file   "p.c"
> >         .section        ".text"
> >         .align 4
> >         .global foo
> >         .type   foo,#function
> >         .proc   020
> > foo:
> >         !#PROLOGUE# 0
> >         save    %sp, -112, %sp         <=== ???
> >         !#PROLOGUE# 1
> >         ret
> >         restore
> > 
> > This is a regression from 3.0.x
> > Is this a SPARC specific problem? 

This looks like a consequence of Richard's 2002-02-04 %sfp patch.
If ELIMINABLE_REGS is defined, then the default fp->sp elimination
is not done.
Something like the following fixes this on trivial testcases I have tried
(gave the same output as gcc 3.0 with -m64 -O2; the tests had
some automatic arrays and were passing more than 6 integer arguments
around), but I need to fix some glibc 2.2.5 issues on sparc64 before I
can do a sparc64 bootstrap.
INITIAL_ELIMINATION_OFFSET might actually need to be
  do {
    (OFFSET) = 0;
    if ((TO) == STACK_POINTER_REGNUM)
      INITIAL_FRAME_POINTER_OFFSET (OFFSET);
    (OFFSET) += SPARC_STACK_BIAS;
  } while (0)
instead.

2002-03-10  Jakub Jelinek  <jakub@redhat.com>

	* config/sparc/sparc.h (ELIMINABLE_REGS): Add sfp->sp.
	(INITIAL_ELIMINATION_OFFSET): For sfp->sp use
	INITIAL_FRAME_POINTER_OFFSET.

--- gcc/config/sparc/sparc.h.jj	Tue Feb 26 10:33:19 2002
+++ gcc/config/sparc/sparc.h	Tue Feb 26 10:33:19 2002
@@ -1589,12 +1589,20 @@ extern const char leaf_reg_remap[];
 /* ??? In TARGET_FLAT mode we needn't have a hard frame pointer.  */
    
 #define ELIMINABLE_REGS \
-  {{ FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM}}
+  {{ FRAME_POINTER_REGNUM, STACK_POINTER_REGNUM}, \
+   { FRAME_POINTER_REGNUM, HARD_FRAME_POINTER_REGNUM} }
 
 #define CAN_ELIMINATE(FROM, TO) 1
 
-#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
-  ((OFFSET) = SPARC_STACK_BIAS)
+#define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET)	\
+  do {							\
+    if ((TO) == HARD_FRAME_POINTER_REGNUM)		\
+      (OFFSET) = SPARC_STACK_BIAS;			\
+    else if ((TO) == STACK_POINTER_REGNUM)		\
+      INITIAL_FRAME_POINTER_OFFSET (OFFSET);		\
+    else						\
+      abort ();						\
+  } while (0)
 
 /* Keep the stack pointer constant throughout the function.
    This is both an optimization and a necessity: longjmp


	Jakub


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