From 1d4820563901c443ef95b649963c54efbb1268a4 Mon Sep 17 00:00:00 2001 From: Richard Henderson Date: Mon, 6 Aug 2001 09:38:18 -0700 Subject: [PATCH] i386.h (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): New. * config/i386/i386.h (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): New. * function.c (expand_main_function): Implement it. * doc/tm.texi: Document it. From-SVN: r44664 --- gcc/ChangeLog | 6 ++++++ gcc/config/i386/i386.h | 7 +++++++ gcc/doc/tm.texi | 6 ++++++ gcc/function.c | 29 +++++++++++++++++++++++++++-- 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 603ee3ed494..da7df11b66d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2001-08-06 Richard Henderson + + * config/i386/i386.h (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN): New. + * function.c (expand_main_function): Implement it. + * doc/tm.texi: Document it. + 2001-08-06 Stan Shebs * doc/install.texi: Document powerpc-*-darwin* details. diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h index 408ea2bac12..e145cae3e8d 100644 --- a/gcc/config/i386/i386.h +++ b/gcc/config/i386/i386.h @@ -640,6 +640,13 @@ extern int ix86_arch; aligned; the compiler cannot rely on having this alignment. */ #define PREFERRED_STACK_BOUNDARY ix86_preferred_stack_boundary +/* As of July 2001, many runtimes to not align the stack properly when + entering main. This causes expand_main_function to forcably align + the stack, which results in aligned frames for functions called from + main, though it does nothing for the alignment of main itself. */ +#define FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN \ + (ix86_preferred_stack_boundary > STACK_BOUNDARY) + /* Allocation boundary for the code of a function. */ #define FUNCTION_BOUNDARY 16 diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index e9c747ac7e4..4bcf82748b5 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -1028,6 +1028,12 @@ for the desired alignment (measured in bits). If @code{STACK_BOUNDARY} is also defined, this macro must evaluate to a value equal to or larger than @code{STACK_BOUNDARY}. +@findex FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN +@item FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN +A C expression that evaluates true if @code{PREFERRED_STACK_BOUNDARY} is +not guaranteed by the runtime and we should emit code to align the stack +at the beginning of @code{main}. + @cindex @code{PUSH_ROUNDING}, interaction with @code{PREFERRED_STACK_BOUNDARY} If @code{PUSH_ROUNDING} is not defined, the stack will always be aligned to the specified boundary. If @code{PUSH_ROUNDING} is defined and specifies diff --git a/gcc/function.c b/gcc/function.c index 6015366c4b1..0c4d7126292 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -6315,10 +6315,35 @@ mark_varargs () void expand_main_function () { -#if !defined (HAS_INIT_SECTION) +#ifdef FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN + if (FORCE_PREFERRED_STACK_BOUNDARY_IN_MAIN) + { + int align = PREFERRED_STACK_BOUNDARY / BITS_PER_UNIT; + rtx tmp; + + /* Forcably align the stack. */ +#ifdef STACK_GROWS_DOWNWARD + tmp = expand_binop (Pmode, and_optab, stack_pointer_rtx, + GEN_INT (-align), stack_pointer_rtx, 1, OPTAB_WIDEN); +#else + tmp = expand_binop (Pmode, add_optab, stack_pointer_rtx, + GEN_INT (align - 1), NULL_RTX, 1, OPTAB_WIDEN); + tmp = expand_binop (Pmode, and_optab, tmp, GEN_INT (-align), + stack_pointer_rtx, 1, OPTAB_WIDEN); +#endif + if (tmp != stack_pointer_rtx) + emit_move_insn (stack_pointer_rtx, tmp); + + /* Enlist allocate_dynamic_stack_space to pick up the pieces. */ + tmp = force_reg (Pmode, const0_rtx); + allocate_dynamic_stack_space (tmp, NULL_RTX, BIGGEST_ALIGNMENT); + } +#endif + +#ifndef HAS_INIT_SECTION emit_library_call (gen_rtx_SYMBOL_REF (Pmode, NAME__MAIN), 0, VOIDmode, 0); -#endif /* not HAS_INIT_SECTION */ +#endif } extern struct obstack permanent_obstack;