------- Additional Comments From uweigand at gcc dot gnu dot org 2004-10-25 20:38
-------
David Edelsohn wrote: >Correction. While the reload changes fix the crash, it looks
like there still >is a bug because the resulting code does not access the correct
SUBREG. It >does not access the LSW. That would be because alter_subreg doesn't
handle paradoxical subregs on big-endian machines correctly. Something like the
following (untested) should fix that one: Index: gcc/final.c
=================================================================== RCS file:
/cvs/gcc/gcc/gcc/final.c,v retrieving revision 1.339 diff -c -p -r1.339 final.c ***
gcc/final.c 22 Oct 2004 17:05:05 -0000 1.339 --- gcc/final.c 25 Oct 2004 20:35:41
-0000 *************** alter_subreg (rtx *xp) *** 2607,2613 **** /* simplify_subreg
does not remove subreg from volatile references. We are required to. */ if
(MEM_P (y)) ! *xp = adjust_address (y, GET_MODE (x), SUBREG_BYTE (x)); else
{ rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y), --- 2607,2628
---- /* simplify_subreg does not remove subreg from volatile references. We
are required to. */ if (MEM_P (y)) ! { ! int offset = SUBREG_BYTE (x);
! ! /* For paradoxical subregs on big-endian machines, SUBREG_BYTE !
contains 0 instead of the proper offset. See simplify_subreg. */ ! if (offset
== 0 && GET_MODE_SIZE (y) < GET_MODE_SIZE (x)) ! { ! int difference
= GET_MODE_SIZE (y) - GET_MODE_SIZE (x); ! if (WORDS_BIG_ENDIAN) !
offset += (difference / UNITS_PER_WORD) * UNITS_PER_WORD; ! if
(BYTES_BIG_ENDIAN) ! offset += difference % UNITS_PER_WORD; ! } !
! *xp = adjust_address (y, GET_MODE (x), offset); ! } else {
rtx new = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=15286