aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-25 19:42:39 +0000
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>2003-10-25 19:42:39 +0000
commitcb51a849da3d4f11e701cc3d3c7a7340766560b2 (patch)
treefc022b078e3cae53f25d1e6ef6fd0ef30febe47f
parent8e0612748450de96cf75719ca36b80f3c81db92b (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@72933 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/i386/i386.c38
2 files changed, 39 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 86e68186814..3b4cd09de30 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+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-10-25 Jan Hubicka <jh@suse.cz>
* cppcharset.c (one_utf8_to_utf32): Initialize 's' to silence warning.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index a8b2ea7673b..8fdf24dad46 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1705,6 +1705,22 @@ ix86_function_regparm (tree type, tree decl)
return 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),
@@ -5098,20 +5114,32 @@ ix86_expand_prologue (void)
}
else
{
- /* Only valid for Win32 */
-
- const rtx eax = gen_rtx_REG (SImode, 0);
- rtx rtx_allocate = GEN_INT(allocate);
+ /* Only valid for Win32. */
+ rtx eax = gen_rtx_REG (SImode, 0);
+ bool eax_live = ix86_eax_live_at_start_p ();
if (TARGET_64BIT)
abort ();
- insn = emit_move_insn (eax, rtx_allocate);
+ if (eax_live)
+ {
+ emit_insn (gen_push (eax));
+ allocate -= 4;
+ }
+
+ insn = emit_move_insn (eax, GEN_INT (allocate));
RTX_FRAME_RELATED_P (insn) = 1;
insn = emit_insn (gen_allocate_stack_worker (eax));
RTX_FRAME_RELATED_P (insn) = 1;
+
+ if (eax_live)
+ {
+ rtx t = plus_constant (stack_pointer_rtx, allocate);
+ emit_move_insn (eax, gen_rtx_MEM (SImode, t));
+ }
}
+
if (frame.save_regs_using_mov && !TARGET_RED_ZONE)
{
if (!frame_pointer_needed || !frame.to_allocate)