2005-01-17 James E Wilson PR target/19357 * config/ia64/ia64.md (movxf): Handle general register source. Adjust comment to document why. Index: ia64.md =================================================================== RCS file: /cvs/gcc/gcc/gcc/config/ia64/ia64.md,v retrieving revision 1.140 diff -p -p -r1.140 ia64.md *** ia64.md 3 Jan 2005 19:59:11 -0000 1.140 --- ia64.md 14 Jan 2005 21:51:39 -0000 *************** *** 685,694 **** if (GET_CODE (op0) == SUBREG) op0 = SUBREG_REG (op0); ! /* We must support XFmode loads into general registers for stdarg/vararg ! and unprototyped calls. We split them into DImode loads for convenience. ! We don't need XFmode stores from general regs, because a stdarg/vararg ! routine does a block store to memory of unnamed arguments. */ if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0))) { --- 685,696 ---- if (GET_CODE (op0) == SUBREG) op0 = SUBREG_REG (op0); ! /* We must support XFmode loads into general registers for stdarg/vararg, ! unprototyped calls, and a rare case where a long double is passed as ! an argument after a float HFA fills the FP registers. We split them into ! DImode loads for convenience. We also need to support XFmode stores ! for the last case. This case does not happen for stdarg/vararg routines, ! because we do a block store to memory of unnamed arguments. */ if (GET_CODE (op0) == REG && GR_REGNO_P (REGNO (op0))) { *************** *** 708,714 **** if (GET_CODE (op1) == SUBREG) op1 = SUBREG_REG (op1); else - /* ??? Maybe we should make a SUBREG here? */ op1 = gen_rtx_REG (TImode, REGNO (op1)); emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1); --- 710,715 ---- *************** *** 743,748 **** --- 744,783 ---- abort (); } + if (GET_CODE (operands[1]) == REG && GR_REGNO_P (REGNO (operands[1]))) + { + /* We're hoping to transform everything that deals with XFmode + quantities and GR registers early in the compiler. */ + if (no_new_pseudos) + abort (); + + /* Op0 can't be a GR_REG here, as that case is handled above. + If op0 is a register, then we spill op1, so that we now have a + MEM operand. This requires creating an XFmode subreg of a TImode reg + to force the spill. */ + if (register_operand (operands[0], XFmode)) + { + rtx op1 = gen_rtx_REG (TImode, REGNO (operands[1])); + op1 = gen_rtx_SUBREG (XFmode, op1, 0); + operands[1] = spill_xfmode_operand (op1, 0); + } + + else if (GET_CODE (operands[0]) == MEM) + { + rtx in[2]; + + in[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[1])); + in[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (operands[1]) + 1); + + emit_move_insn (adjust_address (operands[0], DImode, 0), in[0]); + emit_move_insn (adjust_address (operands[0], DImode, 8), in[1]); + DONE; + } + + else + abort (); + } + if (! reload_in_progress && ! reload_completed) { operands[1] = spill_xfmode_operand (operands[1], 0);