This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
powerpc64 output_mi_thunk
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: gcc-patches at gcc dot gnu dot org
- Cc: David Edelsohn <dje at watson dot ibm dot com>, Geoff Keating <geoffk at redhat dot com>
- Date: Fri, 23 Aug 2002 09:36:43 +0930
- Subject: 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