aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcgf <cgf@138bc75d-0d04-0410-961f-82ee72b054a4>2003-11-20 21:04:15 +0000
committercgf <cgf@138bc75d-0d04-0410-961f-82ee72b054a4>2003-11-20 21:04:15 +0000
commitdd1b1e1d56b391ca8acfb4322d1a41959ac79c20 (patch)
treec306806677aa791fcda69a13a49d16e2b4831e2a
parentbf24d08e5ae80181764b522b39b7d315dee96a08 (diff)
backport i386.c regparm fix.cygming332
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/cygming332@73773 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog.cygwin-mingw9
-rw-r--r--gcc/config/i386/i386.c50
2 files changed, 44 insertions, 15 deletions
diff --git a/gcc/ChangeLog.cygwin-mingw b/gcc/ChangeLog.cygwin-mingw
index 853a6383464..d9a3b45483b 100644
--- a/gcc/ChangeLog.cygwin-mingw
+++ b/gcc/ChangeLog.cygwin-mingw
@@ -1,3 +1,12 @@
+2003-11-20 Christopher Faylor <cgf@redhat.com>
+
+ Backport from trunk
+ 2003-10-25 Richard Henderson <rth@redhat.com>
+
+ * config/i386/i386.c (ix86_eax_live_at_start_p): New.
+ (ix86_expand_prologue): Save and restore eax around stack probe if it's
+ live.
+
2003-07-31 Danny Smith <dannysmith@users.sourceforge.net>
Backport from trunk
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b6f635db683..d04b183711c 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1497,6 +1497,22 @@ ix86_fntype_regparm (type)
return ix86_regparm;
}
+/* Return true if EAX is live at the start of the function. Used by
+ ix86_expand_prologue to determine if we need special help before
+ calling allocate_stack_worker. */
+
+static bool
+ix86_eax_live_at_start_p (void)
+{
+ /* Cheat. Don't bother working forward from ix86_function_regparm
+ to the function type to whether an actual argument is located in
+ eax. Instead just look at cfg info, which is still close enough
+ to correct at this point. This gives false positives for broken
+ functions that might use uninitialized data that happens to be
+ allocated in eax, but who cares? */
+ return REGNO_REG_SET_P (ENTRY_BLOCK_PTR->global_live_at_end, 0);
+}
+
/* Value is the number of bytes of arguments automatically
popped when returning from a subroutine call.
FUNDECL is the declaration node of the function (as a tree),
@@ -4750,28 +4766,32 @@ ix86_expand_prologue ()
}
else
{
- /* ??? Is this only valid for Win32? */
-
- rtx arg0, sym;
+ /* Only valid for Win32. */
+ rtx eax = gen_rtx_REG (SImode, 0);
+ bool eax_live = ix86_eax_live_at_start_p ();
if (TARGET_64BIT)
- abort ();
+ abort ();
- arg0 = gen_rtx_REG (SImode, 0);
- emit_move_insn (arg0, GEN_INT (allocate));
+ if (eax_live)
+ {
+ emit_insn (gen_push (eax));
+ allocate -= 4;
+ }
- sym = gen_rtx_MEM (FUNCTION_MODE,
- gen_rtx_SYMBOL_REF (Pmode, "_alloca"));
- insn = emit_call_insn (gen_call (sym, const0_rtx, constm1_rtx));
+ insn = emit_move_insn (eax, GEN_INT (allocate));
+ RTX_FRAME_RELATED_P (insn) = 1;
- CALL_INSN_FUNCTION_USAGE (insn)
- = gen_rtx_EXPR_LIST (VOIDmode, gen_rtx_USE (VOIDmode, arg0),
- CALL_INSN_FUNCTION_USAGE (insn));
+ insn = emit_insn (gen_allocate_stack_worker (eax));
+ RTX_FRAME_RELATED_P (insn) = 1;
- /* Don't allow scheduling pass to move insns across __alloca
- call. */
- emit_insn (gen_blockage (const0_rtx));
+ if (eax_live)
+ {
+ rtx t = plus_constant (stack_pointer_rtx, allocate);
+ emit_move_insn (eax, gen_rtx_MEM (SImode, t));
+ }
}
+
if (use_mov)
{
if (!frame_pointer_needed || !frame.to_allocate)