diff options
author | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-28 21:55:24 +0000 |
---|---|---|
committer | jsm28 <jsm28@138bc75d-0d04-0410-961f-82ee72b054a4> | 2005-06-28 21:55:24 +0000 |
commit | 7a979707f55fcaf9f028bba6c7a39dd169329dd3 (patch) | |
tree | caf995fd6dda6f4540bef216b200472fdbd03fbc /gcc/config/ia64/ia64.md | |
parent | 7590af71b959d645f1c0f1c9bf285fce502bfe67 (diff) | |
download | gcc-7a979707f55fcaf9f028bba6c7a39dd169329dd3.tar.gz |
* target.h (invalid_conversion, invalid_unary_op,
invalid_binary_op): New hooks.
* target-def.h (TARGET_INVALID_CONVERSION,
TARGET_INVALID_UNARY_OP, TARGET_INVALID_BINARY_OP,
TARGET_INITIALIZER): Likewise.
* hooks.h (hook_constcharptr_tree_tree_null,
hook_constcharptr_int_tree_null,
hook_constcharptr_int_tree_tree_null): New.
* hooks.c (hook_constcharptr_tree_tree_null,
hook_constcharptr_int_tree_null,
hook_constcharptr_int_tree_tree_null): Likewise.
* gcc/doc/tm.texi (TARGET_INVALID_CONVERSION,
TARGET_INVALID_UNARY_OP, TARGET_INVALID_BINARY_OP): Document.
* c-convert.c (convert): Use invalid_conversion hook.
* c-typeck.c (build_unary_op): Use invalid_unary_op hook.
(build_binary_op): Use invalid_binary_op hook.
* config/ia64/ia64-modes.def: Define RFmode.
* config/ia64/ia64-protos.h (spill_xfmode_operand): Remove.
(ia64_expand_movxf_movrf): New.
* config/ia64/ia64.md (movxf): Move code to
ia64_expand_movxf_movrf.
(movrf, movrf_internal): New.
* ia64.c (ia64_invalid_conversion, ia64_invalid_unary_op,
ia64_invalid_binary_op, TARGET_INVALID_CONVERSION,
TARGET_INVALID_UNARY_OP, TARGET_INVALID_BINARY_OP): New.
(spill_xfmode_operand): Rename to spill_xfmode_rfmode_operand.
Add mode parameter. Make static.
(ia64_expand_movxf_movrf): New, moved from ia64.md. Handle RFmode
as well as XFmode.
(ia64_function_arg, ia64_function_value, ia64_register_move_cost,
ia64_scalar_mode_supported_p): Handle RFmode as well as XFmode.
(ia64_init_builtins): Set up __fpreg as RFmode.
(ia64_mangle_fundamental_type): Mangle __fpreg as u7__fpreg.
cp:
* cvt.c (ocp_convert): Use invalid_conversion hook.
* typeck.c (build_binary_op): Use invalid_binary_op hook.
(build_unary_op): Use invalid_unary_op hook.
testsuite:
* g++.dg/ext/fpreg1.C, gcc.target/ia64/fpreg-1.c,
gcc.target/ia64/fpreg-2.c: New tests.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101391 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/ia64/ia64.md')
-rw-r--r-- | gcc/config/ia64/ia64.md | 137 |
1 files changed, 22 insertions, 115 deletions
diff --git a/gcc/config/ia64/ia64.md b/gcc/config/ia64/ia64.md index 57cd70beba5..18e6cb3ace6 100644 --- a/gcc/config/ia64/ia64.md +++ b/gcc/config/ia64/ia64.md @@ -736,121 +736,8 @@ (match_operand:XF 1 "general_operand" ""))] "" { - rtx op0 = operands[0]; - - 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))) - { - rtx out[2]; - - /* We're hoping to transform everything that deals with XFmode - quantities and GR registers early in the compiler. */ - gcc_assert (!no_new_pseudos); - - /* Struct to register can just use TImode instead. */ - if ((GET_CODE (operands[1]) == SUBREG - && GET_MODE (SUBREG_REG (operands[1])) == TImode) - || (GET_CODE (operands[1]) == REG - && GR_REGNO_P (REGNO (operands[1])))) - { - rtx op1 = operands[1]; - - if (GET_CODE (op1) == SUBREG) - op1 = SUBREG_REG (op1); - else - op1 = gen_rtx_REG (TImode, REGNO (op1)); - - emit_move_insn (gen_rtx_REG (TImode, REGNO (op0)), op1); - DONE; - } - - if (GET_CODE (operands[1]) == CONST_DOUBLE) - { - emit_move_insn (gen_rtx_REG (DImode, REGNO (op0)), - operand_subword (operands[1], 0, 0, XFmode)); - emit_move_insn (gen_rtx_REG (DImode, REGNO (op0) + 1), - operand_subword (operands[1], 1, 0, XFmode)); - DONE; - } - - /* If the quantity is in a register not known to be GR, spill it. */ - if (register_operand (operands[1], XFmode)) - operands[1] = spill_xfmode_operand (operands[1], 1); - - gcc_assert (GET_CODE (operands[1]) == MEM); - - out[WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0)); - out[!WORDS_BIG_ENDIAN] = gen_rtx_REG (DImode, REGNO (op0) + 1); - - emit_move_insn (out[0], adjust_address (operands[1], DImode, 0)); - emit_move_insn (out[1], adjust_address (operands[1], DImode, 8)); - DONE; - } - - 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. */ - gcc_assert (!no_new_pseudos); - - /* 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 - { - rtx in[2]; - - gcc_assert (GET_CODE (operands[0]) == MEM); - 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; - } - } - - if (! reload_in_progress && ! reload_completed) - { - operands[1] = spill_xfmode_operand (operands[1], 0); - - if (GET_MODE (op0) == TImode && GET_CODE (op0) == REG) - { - rtx memt, memx, in = operands[1]; - if (CONSTANT_P (in)) - in = validize_mem (force_const_mem (XFmode, in)); - if (GET_CODE (in) == MEM) - memt = adjust_address (in, TImode, 0); - else - { - memt = assign_stack_temp (TImode, 16, 0); - memx = adjust_address (memt, XFmode, 0); - emit_move_insn (memx, in); - } - emit_move_insn (op0, memt); - DONE; - } - - if (! ia64_move_ok (operands[0], operands[1])) - operands[1] = force_reg (XFmode, operands[1]); - } + if (ia64_expand_movxf_movrf (XFmode, operands)) + DONE; }) ;; ??? There's no easy way to mind volatile acquire/release semantics. @@ -865,6 +752,26 @@ stfe %0 = %F1%P0" [(set_attr "itanium_class" "fmisc,fld,stf")]) +;; Same as for movxf, but for RFmode. +(define_expand "movrf" + [(set (match_operand:RF 0 "general_operand" "") + (match_operand:RF 1 "general_operand" ""))] + "" +{ + if (ia64_expand_movxf_movrf (RFmode, operands)) + DONE; +}) + +(define_insn "*movrf_internal" + [(set (match_operand:RF 0 "destination_operand" "=f,f, m") + (match_operand:RF 1 "general_operand" "fG,m,fG"))] + "ia64_move_ok (operands[0], operands[1])" + "@ + mov %0 = %F1 + ldf.fill %0 = %1%P1 + stf.spill %0 = %F1%P0" + [(set_attr "itanium_class" "fmisc,fld,stf")]) + ;; Better code generation via insns that deal with TFmode register pairs ;; directly. Same concerns apply as for TImode. (define_expand "movtf" |