This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Fix powerpc zapping static chain


The following testcase compiled with powerpc-linux-gcc -fpic shows r11,
the static chain pointer, being zapped inside function bar.

extern int x;
int foo (void)
{
  int y;
  int bar (void) { return x + y; }
  return bar ();
}

This patch fixes the problem, and marks the instructions used to save
and restore LR as possibly dead.  See PR 8659 for why they might be
dead with new-ra.

	* config/rs6000/rs6000.c (rs6000_emit_prologue): Use r12 for
	save_LR_around_toc_setup, and mark insns as maybe_dead.  Simplify
	cr_save_rtx test.

Bootstrapped, regtested powerpc-linux.  OK mainline?  3.3 too?

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.445
diff -u -p -r1.445 rs6000.c
--- gcc/config/rs6000/rs6000.c	19 Mar 2003 03:23:44 -0000	1.445
+++ gcc/config/rs6000/rs6000.c	24 Mar 2003 10:31:28 -0000
@@ -10451,7 +10451,7 @@ rs6000_emit_prologue ()
   rtx sp_reg_rtx = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM);
   rtx frame_ptr_rtx = gen_rtx_REG (Pmode, 12);
   rtx frame_reg_rtx = sp_reg_rtx;
-  rtx cr_save_rtx = NULL;
+  rtx cr_save_rtx = NULL_RTX;
   rtx insn;
   int saving_FPRs_inline;
   int using_store_multiple;
@@ -10738,7 +10738,7 @@ rs6000_emit_prologue ()
 
       /* If r12 was used to hold the original sp, copy cr into r0 now
 	 that it's free.  */
-      if (REGNO (frame_reg_rtx) == 12)
+      if (cr_save_rtx == NULL_RTX)
 	{
 	  cr_save_rtx = gen_rtx_REG (SImode, 0);
 	  emit_insn (gen_movesi_from_cr (cr_save_rtx));
@@ -10774,7 +10774,7 @@ rs6000_emit_prologue ()
 	  && regs_ever_live[RS6000_PIC_OFFSET_TABLE_REGNUM]))
   {
     /* If emit_load_toc_table will use the link register, we need to save
-       it.  We use R11 for this purpose because emit_load_toc_table
+       it.  We use R12 for this purpose because emit_load_toc_table
        can use register 0.  This allows us to use a plain 'blr' to return
        from the procedure more often.  */
     int save_LR_around_toc_setup = (TARGET_ELF
@@ -10783,14 +10783,14 @@ rs6000_emit_prologue ()
 				    && ! info->lr_save_p
 				    && EXIT_BLOCK_PTR->pred != NULL);
     if (save_LR_around_toc_setup)
-      emit_move_insn (gen_rtx_REG (Pmode, 11), 
-		      gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM));
-    
-    rs6000_emit_load_toc_table (TRUE);
-
-    if (save_LR_around_toc_setup)
-      emit_move_insn (gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM), 
-		      gen_rtx_REG (Pmode, 11));
+      {
+	rtx lr = gen_rtx_REG (Pmode, LINK_REGISTER_REGNUM);
+	rs6000_maybe_dead (emit_move_insn (frame_ptr_rtx, lr));
+	rs6000_emit_load_toc_table (TRUE);
+	rs6000_maybe_dead (emit_move_insn (lr, frame_ptr_rtx));
+      }
+    else
+      rs6000_emit_load_toc_table (TRUE);
   }
 
 #if TARGET_MACHO

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]