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]

Re: other/7114: ICE building strcoll.op from glibc-2.2.5


This patch cures the testcase.  The !using_store_multiple code tests
whether regs are live before saving.  We need to do something similar
for using_store_multiple, in case all regs need not be saved.

	* config/rs6000/rs6000.c (rs6000_emit_prologue): Trim saved regs
	for -mmultiple case like -mno-multiple case.
	(rs6000_emit_epilogue): Likewise.

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.291.2.13
diff -u -p -r1.291.2.13 rs6000.c
--- gcc/config/rs6000/rs6000.c	23 May 2002 23:22:44 -0000	1.291.2.13
+++ gcc/config/rs6000/rs6000.c	15 Jul 2002 09:06:31 -0000
@@ -8836,30 +8836,45 @@ rs6000_emit_prologue ()
      the store-multiple instructions.  */
   if (using_store_multiple)
     {
-      rtvec p, dwarfp;
-      int i;
-      p = rtvec_alloc (32 - info->first_gp_reg_save);
-      dwarfp = rtvec_alloc (32 - info->first_gp_reg_save);
-      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
+      int n = info->first_gp_reg_save;
+
+      while (n < 32
+	     && !((regs_ever_live[n]
+		   && ! call_used_regs[n])
+		  || (n == RS6000_PIC_OFFSET_TABLE_REGNUM
+		      && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
+			  || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
+	n++;
+
+      if (n < 32)
 	{
-	  rtx addr, reg, mem;
-	  reg = gen_rtx_REG (reg_mode, info->first_gp_reg_save + i);
-	  addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
-			       GEN_INT (info->gp_save_offset 
-					+ sp_offset 
-					+ reg_size * i));
-	  mem = gen_rtx_MEM (reg_mode, addr);
-	  set_mem_alias_set (mem, rs6000_sr_alias_set);
+	  rtvec p, dwarfp;
+	  int i;
+
+	  p = rtvec_alloc (32 - n);
+	  dwarfp = rtvec_alloc (32 - n);
+	  for (i = 0; i < 32 - n; i++)
+	    {
+	      rtx addr, reg, mem;
+	      reg = gen_rtx_REG (reg_mode, n + i);
+	      addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
+				   GEN_INT (info->gp_save_offset 
+					    + sp_offset 
+					    + reg_size * i));
+	      mem = gen_rtx_MEM (reg_mode, addr);
+	      set_mem_alias_set (mem, rs6000_sr_alias_set);
 
-	  RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
+	      RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, reg);
+	    }
+	  insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
+	  rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
+				NULL_RTX, NULL_RTX);
 	}
-      insn = emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
-      rs6000_frame_related (insn, frame_ptr_rtx, info->total_size, 
-			    NULL_RTX, NULL_RTX);
     }
   else
     {
       int i;
+
       for (i = 0; i < 32 - info->first_gp_reg_save; i++)
 	if ((regs_ever_live[info->first_gp_reg_save+i] 
 	     && ! call_used_regs[info->first_gp_reg_save+i])
@@ -9226,24 +9241,38 @@ rs6000_emit_epilogue (sibcall)
      the load-multiple instructions.  */
   if (using_load_multiple)
     {
-      rtvec p;
-      p = rtvec_alloc (32 - info->first_gp_reg_save);
-      for (i = 0; i < 32 - info->first_gp_reg_save; i++)
-	{
-	  rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
-				   GEN_INT (info->gp_save_offset 
-					    + sp_offset 
-					    + reg_size * i));
-	  rtx mem = gen_rtx_MEM (reg_mode, addr);
+      int n = info->first_gp_reg_save;
 
-	  set_mem_alias_set (mem, rs6000_sr_alias_set);
+      while (n < 32
+	     && !((regs_ever_live[n]
+		   && ! call_used_regs[n])
+		  || (n == RS6000_PIC_OFFSET_TABLE_REGNUM
+		      && ((DEFAULT_ABI == ABI_V4 && flag_pic == 1)
+			  || (DEFAULT_ABI == ABI_DARWIN && flag_pic)))))
+	n++;
+
+      if (n < 32)
+	{
+	  rtvec p;
 
-	  RTVEC_ELT (p, i) = 
-	    gen_rtx_SET (VOIDmode,
-			 gen_rtx_REG (reg_mode, info->first_gp_reg_save + i),
-			 mem);
+	  p = rtvec_alloc (32 - n);
+	  for (i = 0; i < 32 - n; i++)
+	    {
+	      rtx addr = gen_rtx_PLUS (Pmode, frame_reg_rtx, 
+				       GEN_INT (info->gp_save_offset 
+						+ sp_offset 
+						+ reg_size * i));
+	      rtx mem = gen_rtx_MEM (reg_mode, addr);
+
+	      set_mem_alias_set (mem, rs6000_sr_alias_set);
+
+	      RTVEC_ELT (p, i) = 
+		gen_rtx_SET (VOIDmode,
+			     gen_rtx_REG (reg_mode, n + i),
+			     mem);
+	    }
+	  emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
 	}
-      emit_insn (gen_rtx_PARALLEL (VOIDmode, p));
     }
   else
     for (i = 0; i < 32 - info->first_gp_reg_save; i++)

-- 
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]