------- Comment #4 from dje at gcc dot gnu dot org 2006-07-17 01:43 ------- Double Complex on e500 with double GPRs fundamentally does not interact well with GCC's current design. GCC does not want to have a double placed in the same register that can contain an int if the width of the register for ints cannot span the width of the register for float.
rs6000_hard_regno_nregs() can cover the e500 double case with: if (TARGET_E500_DOUBLE && FLOAT_MODE_P (mode)) return (GET_MODE_SIZE (mode) + UNITS_PER_FP_WORD - 1) / UNITS_PER_FP_WORD; which fixes the first dubreg_offset_representable_p() assert, but subreg_offset with double nregs foir regno != int nregs for same regno intends this case for "holes", e.g., XFmode spanning three 32-bit float words but four 32-bit int words. (In this example, xmode is DCmode and ymode is DFmode.) For this special case, the function overrides the default (and correct) nregs nregs_xmode = hard_regno_nregs[xregno][xmode]; with nregs_xmode_unit_int * GET_MODE_NUNITS (xmode) which is twice the number of units. However, ymode is calculated the normal way. Hilarity ensues, e.g., gcc_assert ((mode_multiple % nregs_multiple) == 0); fails. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=24036