OSDN Git Service

2010-09-21 Kai Tietz <kai.tietz@onevision.com>
authorktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Sep 2010 17:58:32 +0000 (17:58 +0000)
committerktietz <ktietz@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 21 Sep 2010 17:58:32 +0000 (17:58 +0000)
        PR target/45694
        * config/i386/i386.c (ix86_expand_prologue): Save r10 in case that
        static chain-register is used for 64-bit.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@164489 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c

index a0d6e78..07cea55 100644 (file)
@@ -1,3 +1,9 @@
+2010-09-21  Kai Tietz  <kai.tietz@onevision.com>
+
+       PR target/45694
+       * config/i386/i386.c (ix86_expand_prologue): Save r10 in case that
+       static chain-register is used for 64-bit.
+
 2010-09-21  Richard Guenther  <rguenther@suse.de>
 
        * dwarf2out.c (is_cu_die): New function.
index de1564a..4501efb 100644 (file)
@@ -9692,19 +9692,27 @@ ix86_expand_prologue (void)
     }
   else
     {
-      rtx eax = gen_rtx_REG (Pmode, AX_REG);
-      bool eax_live;
+      rtx eax = gen_rtx_REG (Pmode, AX_REG);;
+      rtx r10 = NULL;
+      bool eax_live = false;
+      bool r10_live = false;
 
-      if (cfun->machine->call_abi == MS_ABI)
-       eax_live = false;
-      else
-       eax_live = ix86_eax_live_at_start_p ();
+      if (TARGET_64BIT)
+        r10_live = (DECL_STATIC_CHAIN (current_function_decl) != 0);
+      if (!TARGET_64BIT_MS_ABI)
+        eax_live = ix86_eax_live_at_start_p ();
 
       if (eax_live)
        {
          emit_insn (gen_push (eax));
          allocate -= UNITS_PER_WORD;
        }
+      if (r10_live)
+       {
+         r10 = gen_rtx_REG (Pmode, R10_REG);
+         emit_insn (gen_push (r10));
+         allocate -= UNITS_PER_WORD;
+       }
 
       emit_move_insn (eax, GEN_INT (allocate));
 
@@ -9720,11 +9728,18 @@ ix86_expand_prologue (void)
        }
       m->fs.sp_offset += allocate;
 
-      if (eax_live)
-       {
+      if (r10_live && eax_live)
+        {
          t = choose_baseaddr (m->fs.sp_offset - allocate);
+         emit_move_insn (r10, gen_frame_mem (Pmode, t));
+         t = choose_baseaddr (m->fs.sp_offset - allocate - UNITS_PER_WORD);
          emit_move_insn (eax, gen_frame_mem (Pmode, t));
        }
+      else if (eax_live || r10_live)
+       {
+         t = choose_baseaddr (m->fs.sp_offset - allocate);
+         emit_move_insn ((eax_live ? eax : r10), gen_frame_mem (Pmode, t));
+       }
     }
   gcc_assert (m->fs.sp_offset == frame.stack_pointer_offset);