--- Comment #1 from danglin at gcc dot gnu dot org 2007-09-22 01:18 ---
Although it might be possible to fix this at an earlier point,
things go seriously wrong in emit_group_load_1. We have:
Breakpoint 7, emit_group_load_1 (tmps=0x83fffdff4a70,
dst=0x83fffdfb7540, orig_src=0x83fffdfacf30,
type=0x83fffdf9b750, ssize=16) at ../../gcc/gcc/expr.c:1779
1779 else if (CONSTANT_P (src))
(gdb) p debug_rtx (src)
(const_double 4919131751843889152 [0x] 1229782938533634594
[0x] 0 [0x0] 0 [0x0])
$7 = void
(gdb) p debug_rtx (dst)
(parallel:BLK [
(expr_list:REG_DEP_TRUE (reg:DI 66 [ result ])
(const_int 0 [0x0]))
(expr_list:REG_DEP_TRUE (reg:DI 67 [ result+8 ])
(const_int 8 [0x8]))
])
As can be seen, dst is a parallel but src is a CONST_DOUBLE. The code
as currently written assigns src to both parts of the parallel.
I believe this occurs because hppa64 doesn't support TImode.
The break above is in a modified version of expr.c which appears to
correct the problem. Here's the diff:
Index: expr.c
===
--- expr.c (revision 128642)
+++ expr.c (working copy)
@@ -1776,8 +1776,23 @@
else if (CONSTANT_P (src) GET_MODE (dst) != BLKmode
XVECLEN (dst, 0) 1)
tmps[i] = simplify_gen_subreg (mode, src, GET_MODE(dst), bytepos);
- else if (CONSTANT_P (src)
- || (REG_P (src) GET_MODE (src) == mode))
+ else if (CONSTANT_P (src))
+ {
+ if ((HOST_WIDE_INT) bytelen == ssize)
+ tmps[i] = src;
+ else
+ {
+ rtx first, second;
+
+ gcc_assert (i = 1);
+ split_double (src, first, second);
+ if (i)
+ tmps[i] = second;
+ else
+ tmps[i] = first;
+ }
+ }
+ else if (REG_P (src) GET_MODE (src) == mode)
tmps[i] = src;
else
tmps[i] = extract_bit_field (src, bytelen * BITS_PER_UNIT,
I used split_double because neither simplify_subreg or extract_bit_field
handle this.
I'm a little unhappy about splitting the double but in some cases it is
possible to load the values without forcing them to memory. In any event,
this is a rare situation.
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33436