i386.h (PREFERRED_STACK_BOUNDARY): Define.
authorJeff Law <law@gcc.gnu.org>
Mon, 22 Mar 1999 22:47:07 +0000 (15:47 -0700)
committerJeff Law <law@gcc.gnu.org>
Mon, 22 Mar 1999 22:47:07 +0000 (15:47 -0700)
        * i386.h (PREFERRED_STACK_BOUNDARY): Define.
        * i386.c (ix86_compute_frame_size): New function.
        (ix86_prologue, ix86_epilogue): Use it.
        * i386.h (INITIAL_ELIMINATION_OFFSET): Likewise.
        * reload1.c: Provide default for PREFERRED_STACK_BOUNDARY.

From-SVN: r25909

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/reload1.c

index f498514b6056f54231f77cf46187f9d7a8001bf0..b6d9332f3df431198318c41414d488c44d81ecd1 100644 (file)
@@ -1,3 +1,14 @@
+Mon Mar 22 23:41:49 1999  Jeffrey A Law  (law@cygnus.com)
+
+       * i386.h (PREFERRED_STACK_BOUNDARY): Define.
+
+Mon Mar 22 23:41:31 1999  John Wehle  (john@feith.com)
+
+       * i386.c (ix86_compute_frame_size): New function.
+       (ix86_prologue, ix86_epilogue): Use it.
+       * i386.h (INITIAL_ELIMINATION_OFFSET): Likewise.
+       * reload1.c: Provide default for PREFERRED_STACK_BOUNDARY.
+
 Mon Mar 22 18:06:59 1999  Jim Wilson  <wilson@cygnus.com>
 
        * mips/mips.h (TARGET_SWITCHES, TARGET_OPTIONS): Add option doc
index 4d279b892a569c6a4591067dbb3cdd313c00e121..a989cac66ecf76ff4d1bda70f0390199e2a0c55e 100644 (file)
@@ -2077,6 +2077,62 @@ load_pic_register (do_rtl)
     emit_insn (gen_blockage ());
 }
 
+/* Compute the size of local storage taking into consideration the
+   desired stack alignment which is to be maintained.  Also determine
+   the number of registers saved below the local storage.  */
+
+HOST_WIDE_INT
+ix86_compute_frame_size (size, nregs_on_stack)
+     HOST_WIDE_INT size;
+     int *nregs_on_stack;
+{
+  int limit;
+  int nregs;
+  int regno;
+  int padding;
+  int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
+                                 || current_function_uses_const_pool);
+  HOST_WIDE_INT total_size;
+
+  limit = frame_pointer_needed
+         ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
+
+  nregs = 0;
+
+  for (regno = limit - 1; regno >= 0; regno--)
+    if ((regs_ever_live[regno] && ! call_used_regs[regno])
+       || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
+      nregs++;
+
+  padding = 0;
+  total_size = size + (nregs * UNITS_PER_WORD);
+
+#ifdef PREFERRED_STACK_BOUNDARY
+  {
+    int offset;
+    int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT;
+
+    offset = 4;
+    if (frame_pointer_needed)
+      offset += UNITS_PER_WORD;
+
+    total_size += offset;
+    
+    padding = ((total_size + preferred_alignment - 1)
+              & -preferred_alignment) - total_size;
+
+    if (padding < (((offset + preferred_alignment - 1)
+                   & -preferred_alignment) - offset))
+      padding += preferred_alignment;
+  }
+#endif
+
+  if (nregs_on_stack)
+    *nregs_on_stack = nregs;
+
+  return size + padding;
+}
+
 static void
 ix86_prologue (do_rtl)
      int do_rtl;
@@ -2086,7 +2142,7 @@ ix86_prologue (do_rtl)
   rtx xops[4];
   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
                                  || current_function_uses_const_pool);
-  long tsize = get_frame_size ();
+  HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), (int *)0);
   rtx insn;
   int cfa_offset = INCOMING_FRAME_SP_OFFSET, cfa_store_offset = cfa_offset;
 
@@ -2299,28 +2355,18 @@ ix86_epilogue (do_rtl)
      int do_rtl;
 {
   register int regno;
-  register int nregs, limit;
-  int offset;
+  register int limit;
+  int nregs;
   rtx xops[3];
   int pic_reg_used = flag_pic && (current_function_uses_pic_offset_table
                                  || current_function_uses_const_pool);
   int sp_valid = !frame_pointer_needed || current_function_sp_is_unchanging;
-  long tsize = get_frame_size ();
-
-  /* Compute the number of registers to pop */
-
-  limit = (frame_pointer_needed ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM);
-
-  nregs = 0;
-
-  for (regno = limit - 1; regno >= 0; regno--)
-    if ((regs_ever_live[regno] && ! call_used_regs[regno])
-       || (regno == PIC_OFFSET_TABLE_REGNUM && pic_reg_used))
-      nregs++;
+  HOST_WIDE_INT offset;
+  HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (), &nregs);
 
   /* sp is often unreliable so we may have to go off the frame pointer. */
 
-  offset = - tsize - (nregs * UNITS_PER_WORD);
+  offset = -(tsize + nregs * UNITS_PER_WORD);
 
   xops[2] = stack_pointer_rtx;
 
@@ -2340,6 +2386,9 @@ ix86_epilogue (do_rtl)
      less work than reloading sp and popping the register.  Otherwise,
      restore sp (if necessary) and pop the registers. */
 
+  limit = frame_pointer_needed
+         ? FRAME_POINTER_REGNUM : STACK_POINTER_REGNUM;
+
   if (nregs > 1 || sp_valid)
     {
       if ( !sp_valid )
index e1456f9081cdc88c91418e20d69c0a82e3d12595..417627f2afdeaa7de9dfdc7949881223b070336b 100644 (file)
@@ -410,6 +410,10 @@ extern int ix86_arch;
 /* Boundary (in *bits*) on which stack pointer should be aligned.  */
 #define STACK_BOUNDARY 32
 
+/* We want to keep the stack aligned to 64bits when possible.  But the
+   compiler can not rely on the stack having this alignment.*/
+#define PREFERRED_STACK_BOUNDARY 64
+
 /* Allocation boundary (in *bits*) for the code of a function.
    For i486, we get better performance by aligning to a cache
    line (i.e. 16 byte) boundary.  */
@@ -1627,20 +1631,23 @@ do {                                            \
     (OFFSET) = 8;      /* Skip saved PC and previous frame pointer */  \
   else                                                                 \
     {                                                                  \
-      int regno;                                                       \
-      int offset = 0;                                                  \
+      int nregs;                                                       \
+      int offset;                                                      \
+      int preferred_alignment = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; \
+      HOST_WIDE_INT tsize = ix86_compute_frame_size (get_frame_size (),        \
+                                                    &nregs);           \
                                                                        \
-      for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)          \
-       if ((regs_ever_live[regno] && ! call_used_regs[regno])          \
-           || ((current_function_uses_pic_offset_table                 \
-                || current_function_uses_const_pool)                   \
-               && flag_pic && regno == PIC_OFFSET_TABLE_REGNUM))       \
-         offset += 4;                                                  \
+      (OFFSET) = (tsize + nregs * UNITS_PER_WORD);                     \
                                                                        \
-      (OFFSET) = offset + get_frame_size ();                           \
+      offset = 4;                                                      \
+      if (frame_pointer_needed)                                                \
+       offset += UNITS_PER_WORD;                                       \
                                                                        \
-      if ((FROM) == ARG_POINTER_REGNUM && (TO) == STACK_POINTER_REGNUM)        \
-       (OFFSET) += 4;  /* Skip saved PC */                             \
+      if ((FROM) == ARG_POINTER_REGNUM)                                        \
+       (OFFSET) += offset;                                             \
+      else                                                             \
+       (OFFSET) -= ((offset + preferred_alignment - 1)                 \
+                    & -preferred_alignment) - offset;                  \
     }                                                                  \
 }
 \f
index 1295d322ee5ab77e2ae4f799f1ffe1d89362c281..621594af60744cbc825c7595c25afa89b894fe8a 100644 (file)
@@ -39,6 +39,10 @@ Boston, MA 02111-1307, USA.  */
 #include "real.h"
 #include "toplev.h"
 
+#if !defined PREFERRED_STACK_BOUNDARY && defined STACK_BOUNDARY
+#define PREFERRED_STACK_BOUNDARY STACK_BOUNDARY
+#endif
+
 /* This file contains the reload pass of the compiler, which is
    run after register allocation has been done.  It checks that
    each insn is valid (operands required to be in registers really