OSDN Git Service

* target.h (invalid_conversion, invalid_unary_op,
[pf3gnuchains/gcc-fork.git] / gcc / config / ia64 / ia64.md
index 57cd70b..18e6cb3 100644 (file)
        (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.
    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"