OSDN Git Service

* i386.h (PREFERRED_STACK_BOUNDARY): Define.
authorlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Mar 1999 22:47:07 +0000 (22:47 +0000)
committerlaw <law@138bc75d-0d04-0410-961f-82ee72b054a4>
Mon, 22 Mar 1999 22:47:07 +0000 (22:47 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@25909 138bc75d-0d04-0410-961f-82ee72b054a4

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

index f498514..b6d9332 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 4d279b8..a989cac 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 e1456f9..417627f 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 1295d32..621594a 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