return true;
}
+
+/* Check if we need to split a 64bit move. We do not need to split it if we can
+ use vadd2 or ldd/std instructions. */
+
+bool
+arc_split_move_p (rtx *operands)
+{
+ machine_mode mode = GET_MODE (operands[0]);
+
+ if (TARGET_LL64
+ && ((memory_operand (operands[0], mode)
+ && (even_register_operand (operands[1], mode)
+ || satisfies_constraint_Cm3 (operands[1])))
+ || (memory_operand (operands[1], mode)
+ && even_register_operand (operands[0], mode))))
+ return false;
+
+ if (TARGET_PLUS_QMACW
+ && even_register_operand (operands[0], mode)
+ && even_register_operand (operands[1], mode))
+ return false;
+
+ return true;
+}
+
/* operands 0..1 are the operands of a 64 bit move instruction.
split it into two moves with operands 2/3 and 4/5. */
return;
}
- if (TARGET_LL64
- && ((memory_operand (operands[0], mode)
- && (even_register_operand (operands[1], mode)
- || satisfies_constraint_Cm3 (operands[1])))
- || (memory_operand (operands[1], mode)
- && even_register_operand (operands[0], mode))))
- {
- emit_move_insn (operands[0], operands[1]);
- return;
- }
-
- if (TARGET_PLUS_QMACW
- && even_register_operand (operands[0], mode)
- && even_register_operand (operands[1], mode))
- {
- emit_move_insn (operands[0], operands[1]);
- return;
- }
-
if (TARGET_PLUS_QMACW
&& GET_CODE (operands[1]) == CONST_VECTOR)
{
"register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)
|| (satisfies_constraint_Cm3 (operands[1])
- && memory_operand (operands[0], DImode))"
- "*
-{
- switch (which_alternative)
- {
- default:
- return \"#\";
-
- case 0:
- if (TARGET_PLUS_QMACW
- && even_register_operand (operands[0], DImode)
- && even_register_operand (operands[1], DImode))
- return \"vadd2%?\\t%0,%1,0\";
- return \"#\";
-
- case 2:
- if (TARGET_LL64
- && memory_operand (operands[1], DImode)
- && even_register_operand (operands[0], DImode))
- return \"ldd%U1%V1 %0,%1%&\";
- return \"#\";
-
- case 3:
- if (TARGET_LL64
- && memory_operand (operands[0], DImode)
- && (even_register_operand (operands[1], DImode)
- || satisfies_constraint_Cm3 (operands[1])))
- return \"std%U0%V0 %1,%0\";
- return \"#\";
- }
-}"
- "&& reload_completed"
+ && memory_operand (operands[0], DImode))"
+ "@
+ vadd2\\t%0,%1,0
+ #
+ ldd%U1%V1\\t%0,%1
+ std%U0%V0\\t%1,%0"
+ "&& reload_completed && arc_split_move_p (operands)"
[(const_int 0)]
{
arc_split_move (operands);
DONE;
}
[(set_attr "type" "move,move,load,store")
- ;; ??? The ld/st values could be 4 if it's [reg,bignum].
- (set_attr "length" "8,16,*,*")])
-
+ (set_attr "length" "8,16,16,16")])
;; Floating point move insns.
(define_insn_and_split "*movdf_insn"
[(set (match_operand:DF 0 "move_dest_operand" "=D,r,r,r,r,m")
(match_operand:DF 1 "move_double_src_operand" "r,D,r,E,m,r"))]
- "register_operand (operands[0], DFmode)
- || register_operand (operands[1], DFmode)"
- "*
-{
- switch (which_alternative)
- {
- default:
- return \"#\";
-
- case 2:
- if (TARGET_PLUS_QMACW
- && even_register_operand (operands[0], DFmode)
- && even_register_operand (operands[1], DFmode))
- return \"vadd2%?\\t%0,%1,0\";
- return \"#\";
-
- case 4:
- if (TARGET_LL64
- && ((even_register_operand (operands[0], DFmode)
- && memory_operand (operands[1], DFmode))
- || (memory_operand (operands[0], DFmode)
- && even_register_operand (operands[1], DFmode))))
- return \"ldd%U1%V1 %0,%1%&\";
- return \"#\";
-
- case 5:
- if (TARGET_LL64
- && ((even_register_operand (operands[0], DFmode)
- && memory_operand (operands[1], DFmode))
- || (memory_operand (operands[0], DFmode)
- && even_register_operand (operands[1], DFmode))))
- return \"std%U0%V0 %1,%0\";
- return \"#\";
- }
-}"
- "reload_completed"
+ "(register_operand (operands[0], DFmode)
+ || register_operand (operands[1], DFmode))"
+ "@
+ #
+ #
+ vadd2\\t%0,%1,0
+ #
+ ldd%U1%V1\\t%0,%1
+ std%U0%V0\\t%1,%0"
+ "&& reload_completed && arc_split_move_p (operands)"
[(const_int 0)]
{
arc_split_move (operands);
DONE;
}
[(set_attr "type" "move,move,move,move,load,store")
- (set_attr "predicable" "no,no,no,yes,no,no")
- ;; ??? The ld/st values could be 16 if it's [reg,bignum].
(set_attr "length" "4,16,8,16,16,16")])
(define_insn_and_split "*movdf_insn_nolrsr"
(match_operand:VWH 1 "general_operand" "i,r,m,r"))]
"(register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode))"
- "*
-{
- switch (which_alternative)
- {
- default:
- return \"#\";
-
- case 1:
- if (TARGET_PLUS_QMACW
- && even_register_operand (operands[0], <MODE>mode)
- && even_register_operand (operands[1], <MODE>mode))
- return \"vadd2%?\\t%0,%1,0\";
- return \"#\";
-
- case 2:
- if (TARGET_LL64)
- return \"ldd%U1%V1\\t%0,%1\";
- return \"#\";
-
- case 3:
- if (TARGET_LL64)
- return \"std%U0%V0\\t%1,%0\";
- return \"#\";
- }
-}"
- "reload_completed"
+ "@
+ #
+ vadd2\\t%0,%1,0
+ ldd%U1%V1\\t%0,%1
+ std%U0%V0\\t%1,%0"
+ "&& reload_completed && arc_split_move_p (operands)"
[(const_int 0)]
{
arc_split_move (operands);
DONE;
}
- [(set_attr "type" "move,multi,load,store")
- (set_attr "predicable" "no,no,no,no")
- (set_attr "iscompact" "false,false,false,false")
- ])
+ [(set_attr "type" "move,move,load,store")
+ (set_attr "length" "16,8,16,16")])
(define_expand "movmisalign<mode>"
[(set (match_operand:VWH 0 "general_operand" "")