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]

[PATCH,rs6000] fix bugs with out-of-line prologues/epilogues, take 2


This patch is a repost of:

  http://gcc.gnu.org/ml/gcc-patches/2008-10/msg01375.html

with more bugs flushed--in particular, the bootstrap problems reported:

  http://gcc.gnu.org/ml/gcc-patches/2008-11/msg00047.html

should be fixed.

Regtested on powerpc64-unknown-linux-gnu.  OK to commit?

-Nathan

2008-11-19  Nathan Froyd  <froydnj@codesourcery.com>

	* config/rs6000/rs6000.c (no_global_regs_above): Fix precedence
	problem.
	(rs6000_savres_routine_sym): Fix computation for cache selector.
	Mark the generated symbol as a function.
	(rs6000_emit_prologue): Correct use of call_used_regs.
	(rs6000_emit_epilogue): Adjust computation of restore_lr.
	Duplicate restoration of LR and execute the appropriate one
	depending on whether GPRs are being restored inline.
	* config/rs6000/rs6000.md (*save_gpregs_<mode>): Use explicit
	match for register 11.
	(*save_fpregs_<mode>): Likewise.
	(*restore_gpregs_<mode>): Likewise.
	(*return_and_restore_gpregs_<mode>): Likewise.
	(*return_and_restore_fpregs_<mode>): Likewise.
	* config/rs6000/spe.md (*save_gpregs_spe): Use explicit match for
	register 11.
	(*restore_gpregs_spe): Likewise.
	(*return_and_restore_gpregs_spe): Likewise.

Index: gcc/config/rs6000/spe.md
===================================================================
--- gcc/config/rs6000/spe.md	(revision 142005)
+++ gcc/config/rs6000/spe.md	(working copy)
@@ -3144,9 +3144,9 @@ (define_insn "*save_gpregs_spe"
   [(match_parallel 0 "any_parallel_operand"
 		   [(clobber (reg:P 65))
 		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
-		    (use (match_operand:P 2 "gpc_reg_operand" "r"))
-		    (set (match_operand:V2SI 3 "memory_operand" "=m")
-			 (match_operand:V2SI 4 "gpc_reg_operand" "r"))])]
+		    (use (reg:P 11))
+		    (set (match_operand:V2SI 2 "memory_operand" "=m")
+			 (match_operand:V2SI 3 "gpc_reg_operand" "r"))])]
   "TARGET_SPE_ABI"
   "bl %z1"
   [(set_attr "type" "branch")
@@ -3156,9 +3156,9 @@ (define_insn "*restore_gpregs_spe"
  [(match_parallel 0 "any_parallel_operand"
 		  [(clobber (reg:P 65))
 		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
-		   (use (match_operand:P 2 "gpc_reg_operand" "r"))
-		   (set (match_operand:V2SI 3 "gpc_reg_operand" "=r")
-			(match_operand:V2SI 4 "memory_operand" "m"))])]
+		   (use (reg:P 11))
+		   (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
+			(match_operand:V2SI 3 "memory_operand" "m"))])]
  "TARGET_SPE_ABI"
  "bl %z1"
  [(set_attr "type" "branch")
@@ -3169,9 +3169,9 @@ (define_insn "*return_and_restore_gpregs
 		  [(return)
 		   (clobber (reg:P 65))
 		   (use (match_operand:P 1 "symbol_ref_operand" "s"))
-		   (use (match_operand:P 2 "gpc_reg_operand" "r"))
-		   (set (match_operand:V2SI 3 "gpc_reg_operand" "=r")
-			(match_operand:V2SI 4 "memory_operand" "m"))])]
+		   (use (reg:P 11))
+		   (set (match_operand:V2SI 2 "gpc_reg_operand" "=r")
+			(match_operand:V2SI 3 "memory_operand" "m"))])]
  "TARGET_SPE_ABI"
  "b %z1"
  [(set_attr "type" "branch")
Index: gcc/config/rs6000/rs6000.c
===================================================================
--- gcc/config/rs6000/rs6000.c	(revision 142005)
+++ gcc/config/rs6000/rs6000.c	(working copy)
@@ -15842,7 +15848,8 @@ static bool
 no_global_regs_above (int first, bool gpr)
 {
   int i;
-  for (i = first; i < gpr ? 32 : 64 ; i++)
+  int last = gpr ? 32 : 64;
+  for (i = first; i < last; i++)
     if (global_regs[i])
       return false;
   return true;
@@ -15868,11 +15875,11 @@ rs6000_savres_routine_sym (rs6000_stack_
   int regno = gpr ? info->first_gp_reg_save : (info->first_fp_reg_save - 32);
   rtx sym;
   int select = ((savep ? 1 : 0) << 2
-		| (gpr
+		| (TARGET_SPE_ABI
 		   /* On the SPE, we never have any FPRs, but we do have
 		      32/64-bit versions of the routines.  */
-		   ? (TARGET_SPE_ABI && info->spe_64bit_regs_used ? 1 : 0)
-		   : 0) << 1
+		   ? (info->spe_64bit_regs_used ? 1 : 0)
+		   : (gpr ? 1 : 0)) << 1
 		| (exitp ? 1: 0));
 
   /* Don't generate bogus routine names.  */
@@ -15907,6 +15914,7 @@ rs6000_savres_routine_sym (rs6000_stack_
 
       sym = savres_routine_syms[regno-FIRST_SAVRES_REGISTER][select]
 	= gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (name));
+      SYMBOL_REF_FLAGS (sym) |= SYMBOL_FLAG_FUNCTION;
     }
 
   return sym;
@@ -16121,7 +16129,7 @@ rs6000_emit_prologue (void)
   int using_store_multiple;
   int using_static_chain_p = (cfun->static_chain_decl != NULL_TREE
                               && df_regs_ever_live_p (STATIC_CHAIN_REGNUM)
-                              && !call_used_regs[STATIC_CHAIN_REGNUM]);
+                              && call_used_regs[STATIC_CHAIN_REGNUM]);
   HOST_WIDE_INT sp_offset = 0;
 
   if (TARGET_FIX_AND_CONTINUE)
@@ -16923,8 +16931,9 @@ rs6000_emit_epilogue (int sibcall)
 				 || (cfun->calls_alloca
 				     && !frame_pointer_needed));
   restore_lr = (info->lr_save_p
-		&& restoring_GPRs_inline
-		&& restoring_FPRs_inline);
+		&& (restoring_GPRs_inline
+		    || (restoring_FPRs_inline
+			&& info->first_fp_reg_save < 64)));
 
   if (WORLD_SAVE_P (info))
     {
@@ -17196,7 +17205,7 @@ rs6000_emit_epilogue (int sibcall)
 
   /* Get the old lr if we saved it.  If we are restoring registers
      out-of-line, then the out-of-line routines can do this for us.  */
-  if (restore_lr)
+  if (restore_lr && restoring_GPRs_inline)
     {
       rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
 				      info->lr_save_offset + sp_offset);
@@ -17215,7 +17224,7 @@ rs6000_emit_epilogue (int sibcall)
     }
 
   /* Set LR here to try to overlap restores below.  */
-  if (restore_lr)
+  if (restore_lr && restoring_GPRs_inline)
     emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
 		    gen_rtx_REG (Pmode, 0));
 
@@ -17395,6 +17404,18 @@ rs6000_emit_epilogue (int sibcall)
           }
     }
 
+  if (restore_lr && !restoring_GPRs_inline)
+    {
+      rtx mem = gen_frame_mem_offset (Pmode, frame_reg_rtx,
+				      info->lr_save_offset + sp_offset);
+
+      emit_move_insn (gen_rtx_REG (Pmode, 0), mem);
+    }
+
+  if (restore_lr && !restoring_GPRs_inline)
+    emit_move_insn (gen_rtx_REG (Pmode, LR_REGNO),
+		    gen_rtx_REG (Pmode, 0));
+
   /* Restore fpr's if we need to do it without calling a function.  */
   if (restoring_FPRs_inline)
     for (i = 0; i < 64 - info->first_fp_reg_save; i++)
Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 142005)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -14604,9 +14604,9 @@ (define_insn "*save_gpregs_<mode>"
   [(match_parallel 0 "any_parallel_operand"
 		   [(clobber (reg:P 65))
 		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
-                    (use (match_operand:P 2 "gpc_reg_operand" "r"))
-		    (set (match_operand:P 3 "memory_operand" "=m")
-			 (match_operand:P 4 "gpc_reg_operand" "r"))])]
+                    (use (reg:P 11))
+		    (set (match_operand:P 2 "memory_operand" "=m")
+			 (match_operand:P 3 "gpc_reg_operand" "r"))])]
   ""
   "bl %z1"
   [(set_attr "type" "branch")
@@ -14616,9 +14616,9 @@ (define_insn "*save_fpregs_<mode>"
   [(match_parallel 0 "any_parallel_operand"
 		   [(clobber (reg:P 65))
 		    (use (match_operand:P 1 "symbol_ref_operand" "s"))
-                    (use (match_operand:P 2 "gpc_reg_operand" "r"))
-		    (set (match_operand:DF 3 "memory_operand" "=m")
-			 (match_operand:DF 4 "gpc_reg_operand" "f"))])]
+                    (use (reg:P 11))
+		    (set (match_operand:DF 2 "memory_operand" "=m")
+			 (match_operand:DF 3 "gpc_reg_operand" "f"))])]
   ""
   "bl %z1"
   [(set_attr "type" "branch")
@@ -14711,9 +14711,9 @@ (define_insn "*restore_gpregs_<mode>"
  [(match_parallel 0 "any_parallel_operand"
                   [(clobber (match_operand:P 1 "register_operand" "=l"))
                    (use (match_operand:P 2 "symbol_ref_operand" "s"))
-                   (use (match_operand:P 3 "gpc_reg_operand" "r"))
-		   (set (match_operand:P 4 "gpc_reg_operand" "=r")
-			(match_operand:P 5 "memory_operand" "m"))])]
+                   (use (reg:P 11))
+		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
+			(match_operand:P 4 "memory_operand" "m"))])]
  ""
  "bl %z2"
  [(set_attr "type" "branch")
@@ -14724,9 +14724,9 @@ (define_insn "*return_and_restore_gpregs
                   [(return)
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
-                   (use (match_operand:P 3 "gpc_reg_operand" "r"))
-		   (set (match_operand:P 4 "gpc_reg_operand" "=r")
-			(match_operand:P 5 "memory_operand" "m"))])]
+                   (use (reg:P 11))
+		   (set (match_operand:P 3 "gpc_reg_operand" "=r")
+			(match_operand:P 4 "memory_operand" "m"))])]
  ""
  "b %z2"
  [(set_attr "type" "branch")
@@ -14737,9 +14737,9 @@ (define_insn "*return_and_restore_fpregs
                   [(return)
 		   (clobber (match_operand:P 1 "register_operand" "=l"))
 		   (use (match_operand:P 2 "symbol_ref_operand" "s"))
-                   (use (match_operand:P 3 "gpc_reg_operand" "r"))
-		   (set (match_operand:DF 4 "gpc_reg_operand" "=f")
-			(match_operand:DF 5 "memory_operand" "m"))])]
+                   (use (reg:P 11))
+		   (set (match_operand:DF 3 "gpc_reg_operand" "=f")
+			(match_operand:DF 4 "memory_operand" "m"))])]
  ""
  "b %z2"
  [(set_attr "type" "branch")


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