+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
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;
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;
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;
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 )
/* 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. */
(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