aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/i386/i386.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2001-07-30 22:30:23 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2001-07-30 20:30:23 +0000
commit0ecf09f9cc1ee9c4c2daa91d2f2a844013f81cdb (patch)
treedf492d486710873b66c3b9b278a0eac02a7df6c8 /gcc/config/i386/i386.c
parent1490f39253ed06e99aec28d0c265154039fa9b2b (diff)
downloadgcc-0ecf09f9cc1ee9c4c2daa91d2f2a844013f81cdb.zip
gcc-0ecf09f9cc1ee9c4c2daa91d2f2a844013f81cdb.tar.gz
gcc-0ecf09f9cc1ee9c4c2daa91d2f2a844013f81cdb.tar.bz2
i386.c (ix86_output_main_function_alignment_hack): New function.
* i386.c (ix86_output_main_function_alignment_hack): New function. (TARGET_ASM_FUNCTION_PROLOGUE): Default to it. * flow.c (mark_dfs_back_edges): Move from loop_p ; mark back edges by EDGE_DFS_BACK flag. (dump_edge_info): Add dfs_back flag. * basic-block.h (EDGE_DFS_BACK): New constant. (mark_dfs_back_edges): Declare. * alias.c (loop_p): Remove. (mark_constant_function): Use mark_dfs_back_edges. * reg-stack.c (block_info_def): Add predecesors counter and stack_out. (reg_to_stack): Call mark_dfs_back_edges; count the predecesors. (compensate_edge): Break out from ... (convert_regs_1): ... here; do smart choosing of stack_out to copy. (convert_regs_2): Set block_done once block is really done; Do updating of the predecesors counts. * toplev.c (rest_of_compilation): Recompute block_for_insn before post-reload cfg_cleanup. * function.c (thread_prologue_epilogue_insns): Call set_block_for_new_insns when emitting prologue directly. From-SVN: r44486
Diffstat (limited to 'gcc/config/i386/i386.c')
-rw-r--r--gcc/config/i386/i386.c47
1 files changed, 47 insertions, 0 deletions
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 725a984..9017207 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -574,6 +574,7 @@ static HOST_WIDE_INT ix86_GOT_alias_set PARAMS ((void));
static void ix86_adjust_counter PARAMS ((rtx, HOST_WIDE_INT));
static rtx ix86_expand_aligntest PARAMS ((rtx, int));
static void ix86_expand_strlensi_unroll_1 PARAMS ((rtx, rtx));
+static void ix86_output_main_function_alignment_hack PARAMS ((FILE *f, int));
struct ix86_address
{
@@ -634,6 +635,10 @@ static int ix86_comp_type_attributes PARAMS ((tree, tree));
HOST_WIDE_INT));
# undef TARGET_ASM_FUNCTION_PROLOGUE
# define TARGET_ASM_FUNCTION_PROLOGUE ix86_osf_output_function_prologue
+#else
+# undef TARGET_ASM_FUNCTION_PROLOGUE
+# define TARGET_ASM_FUNCTION_PROLOGUE \
+ ix86_output_main_function_alignment_hack
#endif
#undef TARGET_ASM_OPEN_PAREN
@@ -10775,3 +10780,45 @@ ix86_memory_move_cost (mode, class, in)
* (int) GET_MODE_SIZE (mode) / 4);
}
}
+
+/* Most of current runtimes (Jul 2001) do not align stack properly when
+ entering main, so emit an wrapper to align stack before the real main
+ code is called.
+
+ This can eventually go if we manage to fix the runtimes or teach gcc
+ to dynamically align stack in main automatically.
+
+ Adding check to configure is probably not good idea, as binarry can move
+ from one shared library to older. */
+
+static void
+ix86_output_main_function_alignment_hack (file, size)
+ FILE *file;
+ int size ATTRIBUTE_UNUSED;
+{
+ rtx label;
+ char buf[256];
+ /* Check that we see main function with maximally 8 bytes of arguments.
+ if so, emit the hack to align stack for runtimes, where this constraint
+ is broken. */
+ if (strcmp (cfun->name, "main"))
+ return;
+ if (cfun->pops_args || cfun->args_size > 12)
+ return;
+ if (PREFERRED_STACK_BOUNDARY <= 2)
+ return;
+ label = gen_label_rtx ();
+ fprintf (file, "\tpushl\t%%ebp\n");
+ fprintf (file, "\tmovl\t%%esp, %%ebp\n");
+ fprintf (file, "\tandl\t$0xfffffff0, %%esp\n");
+ fprintf (file, "\tpushl\t%%ebp\n");
+ fprintf (file, "\tpushl\t16(%%ebp)\n");
+ fprintf (file, "\tpushl\t12(%%ebp)\n");
+ fprintf (file, "\tpushl\t8(%%ebp)\n");
+ fprintf (file, "\tcall\t");
+ ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (label));
+ assemble_name (file, buf);
+ fprintf (file, "\n\tleave\n");
+ fprintf (file, "\tret\n");
+ ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (label));
+}