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]

powerpc64 output_mi_thunk


This patch cures a testsuite failure on powerpc64-linux.

/src/gcc-ppc64-32/gcc/testsuite/g++.dg/opt/thunk1.C: In member function `void C::_ZThn33800_N1C3fooEv()':
/src/gcc-ppc64-32/gcc/testsuite/g++.dg/opt/thunk1.C:29: Internal compiler error in output_mi_thunk, at config/rs6000/rs6000.c:9937

We were hitting the abort because the two-insn constant case wrongly
tests num_insns_constant_wide (delta) == 1.  Probably a typo, but it's
not safe to bump the comparison up to 2, as num_insns_constant_wide
can return 2 for constants not handled by code in this function.

	* config/rs6000/rs6000.c (output_mi_thunk): Don't determine insns
	for loading delta with num_insns_constant_wide.  Calculate
	delta_low, delta_high without using a conditional.

OK mainline and branch?

Index: gcc/config/rs6000/rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.366
diff -u -p -r1.366 rs6000.c
--- gcc/config/rs6000/rs6000.c	22 Aug 2002 01:53:30 -0000	1.366
+++ gcc/config/rs6000/rs6000.c	22 Aug 2002 23:41:16 -0000
@@ -11271,23 +11271,22 @@ output_mi_thunk (file, thunk_fndecl, del
 	fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta);
     }
 
+  /* 64-bit constants.  If "int" is 32 bits, we'll never hit this abort.  */
+  else if (TARGET_64BIT && (delta < -2147483647 - 1 || delta > 2147483647))
+    abort ();
+
   /* Large constants that can be done by one addis instruction.  */
-  else if ((delta & 0xffff) == 0 && num_insns_constant_wide (delta) == 1)
+  else if ((delta & 0xffff) == 0)
     asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
 		 delta >> 16);
 
   /* 32-bit constants that can be done by an add and addis instruction.  */
-  else if (TARGET_32BIT || num_insns_constant_wide (delta) == 1)
+  else
     {
       /* Break into two pieces, propagating the sign bit from the low
 	 word to the upper word.  */
-      int delta_high = delta >> 16;
-      int delta_low  = delta & 0xffff;
-      if ((delta_low & 0x8000) != 0)
-	{
-	  delta_high++;
-	  delta_low = (delta_low ^ 0x8000) - 0x8000;	/* sign extend */
-	}
+      int delta_low  = ((delta & 0xffff) ^ 0x8000) - 0x8000;
+      int delta_high = (delta - delta_low) >> 16;
 
       asm_fprintf (file, "\t{cau|addis} %s,%s,%d\n", this_reg, this_reg,
 		   delta_high);
@@ -11297,10 +11296,6 @@ output_mi_thunk (file, thunk_fndecl, del
       else
 	fprintf (file, "\taddi %s,%s,%d\n", this_reg, this_reg, delta_low);
     }
-
-  /* 64-bit constants, fixme */
-  else
-    abort ();
 
   /* Get the prefix in front of the names.  */
   switch (DEFAULT_ABI)

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