diff options
author | Jim Wilson <wilson@gcc.gnu.org> | 2005-01-17 19:51:05 -0800 |
---|---|---|
committer | Jim Wilson <wilson@gcc.gnu.org> | 2005-01-17 19:51:05 -0800 |
commit | 696a2ca15ffb199bf85594121380dc0d7399e0c9 (patch) | |
tree | e5493efa4813b7695d995d6f889ede488ee49aa3 | |
parent | 115a33c2196266e0462e516fac5bc7ff21276d13 (diff) | |
download | gcc-696a2ca15ffb199bf85594121380dc0d7399e0c9.tar.gz |
Fix ICE with long double after float HFA.
PR target/19357
* config/ia64/ia64.md (movxf): Handle general register source. Adjust
comment to document why.
* gcc.c-torture/compile/pr19357.c: New test.
From-SVN: r93809
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/config/ia64/ia64.md | 45 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.c-torture/compile/pr19357.c | 8 |
4 files changed, 59 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6ef223abdac..ec637b52c0d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2005-01-17 James E Wilson <wilson@specifixinc.com> + + PR target/19357 + * config/ia64/ia64.md (movxf): Handle general register source. Adjust + comment to document why. + 2005-01-17 Richard Henderson <rth@redhat.com> * config/i386/sse.md (smaxv4sf3_finite, sse_vmsmaxv4sf3_finite, diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index c406a797f41..b22f49e255b 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -685,10 +685,12 @@ 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. */ + /* 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,7 +710,6 @@ 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); @@ -743,6 +744,40 @@ 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); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9f39f00e233..5a5a3b83f91 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2005-01-17 James E. Wilson <wilson@specifixinc.com> + + PR target/19357 + * gcc.c-torture/compile/pr19357.c: New test. + 2005-01-17 Ian Lance Taylor <ian@airs.com> PR c/5675 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr19357.c b/gcc/testsuite/gcc.c-torture/compile/pr19357.c new file mode 100644 index 00000000000..2dc26d78628 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr19357.c @@ -0,0 +1,8 @@ +/* This generated an ICE for an ia64-linux target. */ +struct f { + float f[8]; +}; + +long double ftest(struct f arg1, long double arg2) { + return arg2; +} |