From 47f29cbf1c3718ec49a2356a69c856fc2d10a9bf Mon Sep 17 00:00:00 2001 From: rth Date: Sat, 25 Oct 2003 19:42:39 +0000 Subject: [PATCH] * 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: svn+ssh://gcc.gnu.org/svn/gcc/trunk@72933 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 6 ++++++ gcc/config/i386/i386.c | 38 +++++++++++++++++++++++++++++++++----- 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86e6818..3b4cd09 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2003-10-25 Richard Henderson + + * 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 * 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 a8b2ea7..8fdf24d 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) -- 2.7.4