OSDN Git Service

* config/i386/i386.c (ix86_eax_live_at_start_p): New.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 25 Oct 2003 19:42:39 +0000 (19:42 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 25 Oct 2003 19:42:39 +0000 (19:42 +0000)
        (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
gcc/config/i386/i386.c

index 86e6818..3b4cd09 100644 (file)
@@ -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.
index a8b2ea7..8fdf24d 100644 (file)
@@ -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)