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 PR target/22260


This is an embarassing thinko in the new code to emit thunks without using 
delay slots if -fno-delayed-branch, for example at -O0 (retrospectively, I 
wonder whether adding this code was such a good idea), a regression present 
in the 4.x compilers.

Loading the PIC register in the thunk clobbers %o7... but also the PIC 
register itself that may have pointed to another GOT up to now.

Tested on sparc-sun-solaris2.8, applied to mainline and 4.0 branch as it's a 
serious wrong code generation bug for C++.


2005-06-30  Eric Botcazou  <ebotcazou@libertysurf.fr>

	PR target/22260
	* config/sparc/sparc.c (emit_and_preserve): Add 2nd register.
	Preserve the 2nd register too, if present.
	(sparc_output_mi_thunk) <PIC case>: Preserve the PIC register too.
	Adjust call to emit_and_preserve.

	
-- 
Eric Botcazou
Index: config/sparc/sparc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sparc/sparc.c,v
retrieving revision 1.354.8.5
diff -u -p -r1.354.8.5 sparc.c
--- config/sparc/sparc.c	10 May 2005 16:02:49 -0000	1.354.8.5
+++ config/sparc/sparc.c	30 Jun 2005 23:39:33 -0000
@@ -8895,17 +8895,26 @@ sparc_rtx_costs (rtx x, int code, int ou
     }
 }
 
-/* Emit the sequence of insns SEQ while preserving the register REG.  */
+/* Emit the sequence of insns SEQ while preserving the registers.  */
 
 static void
-emit_and_preserve (rtx seq, rtx reg)
+emit_and_preserve (rtx seq, rtx reg, rtx reg2)
 {
+  /* STACK_BOUNDARY guarantees that this is a 2-word slot.  */
   rtx slot = gen_rtx_MEM (word_mode,
 			  plus_constant (stack_pointer_rtx, SPARC_STACK_BIAS));
 
   emit_insn (gen_stack_pointer_dec (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT)));
   emit_insn (gen_rtx_SET (VOIDmode, slot, reg));
+  if (reg2)
+    emit_insn (gen_rtx_SET (VOIDmode,
+			    adjust_address (slot, word_mode, UNITS_PER_WORD),
+			    reg2));
   emit_insn (seq);
+  if (reg2)
+    emit_insn (gen_rtx_SET (VOIDmode,
+			    reg2,
+			    adjust_address (slot, word_mode, UNITS_PER_WORD)));
   emit_insn (gen_rtx_SET (VOIDmode, reg, slot));
   emit_insn (gen_stack_pointer_inc (GEN_INT (STACK_BOUNDARY/BITS_PER_UNIT)));
 }
@@ -9046,11 +9055,12 @@ sparc_output_mi_thunk (FILE *file, tree 
     {
       /* The hoops we have to jump through in order to generate a sibcall
 	 without using delay slots...  */
-      rtx spill_reg, seq, scratch = gen_rtx_REG (Pmode, 1);
+      rtx spill_reg, spill_reg2, seq, scratch = gen_rtx_REG (Pmode, 1);
 
       if (flag_pic)
         {
 	  spill_reg = gen_rtx_REG (word_mode, 15);  /* %o7 */
+	  spill_reg2 = gen_rtx_REG (word_mode, PIC_OFFSET_TABLE_REGNUM);
 	  start_sequence ();
 	  /* Delay emitting the PIC helper function because it needs to
 	     change the section and we are emitting assembly code.  */
@@ -9058,7 +9068,7 @@ sparc_output_mi_thunk (FILE *file, tree 
 	  scratch = legitimize_pic_address (funexp, Pmode, scratch);
 	  seq = get_insns ();
 	  end_sequence ();
-	  emit_and_preserve (seq, spill_reg);
+	  emit_and_preserve (seq, spill_reg, spill_reg2);
 	}
       else if (TARGET_ARCH32)
 	{
@@ -9087,7 +9097,7 @@ sparc_output_mi_thunk (FILE *file, tree 
 	      sparc_emit_set_symbolic_const64 (scratch, funexp, spill_reg);
 	      seq = get_insns ();
 	      end_sequence ();
-	      emit_and_preserve (seq, spill_reg);
+	      emit_and_preserve (seq, spill_reg, 0);
 	      break;
 
 	    default:

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