")
(define_insn_and_split "*movdi_insn"
- [(set (match_operand:DI 0 "move_dest_operand" "=w, w,r, m")
- (match_operand:DI 1 "move_double_src_operand" "c,Hi,m,cCm3"))]
+ [(set (match_operand:DI 0 "move_dest_operand" "=r, r,r, m")
+ (match_operand:DI 1 "move_double_src_operand" "r,Hi,m,rCm3"))]
"register_operand (operands[0], DImode)
|| register_operand (operands[1], DImode)
|| (satisfies_constraint_Cm3 (operands[1])
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)
return \"#\";
}
}"
- "reload_completed"
+ "&& reload_completed"
[(const_int 0)]
{
arc_split_move (operands);
"if (prepare_move_operands (operands, DFmode)) DONE;")
(define_insn_and_split "*movdf_insn"
- [(set (match_operand:DF 0 "move_dest_operand" "=D,r,c,c,r,m")
- (match_operand:DF 1 "move_double_src_operand" "r,D,c,E,m,c"))]
- "register_operand (operands[0], DFmode) || register_operand (operands[1], DFmode)"
+ [(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)
[(set_attr "length" "0")])
;; MAC and DMPY instructions
+
+; Use MAC instruction to emulate 16bit mac.
+(define_expand "maddhisi4"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "extend_operand" "")
+ (match_operand:SI 3 "register_operand" "")]
+ "TARGET_PLUS_DMPY"
+ "{
+ rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
+ rtx tmp1 = gen_reg_rtx (SImode);
+ rtx tmp2 = gen_reg_rtx (SImode);
+ rtx accl = gen_lowpart (SImode, acc_reg);
+
+ emit_move_insn (accl, operands[3]);
+ emit_insn (gen_rtx_SET (tmp1, gen_rtx_SIGN_EXTEND (SImode, operands[1])));
+ emit_insn (gen_rtx_SET (tmp2, gen_rtx_SIGN_EXTEND (SImode, operands[2])));
+ emit_insn (gen_mac (tmp1, tmp2));
+ emit_move_insn (operands[0], accl);
+ DONE;
+ }")
+
+; The same for the unsigned variant, but using MACU instruction.
+(define_expand "umaddhisi4"
+ [(match_operand:SI 0 "register_operand" "")
+ (match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "extend_operand" "")
+ (match_operand:SI 3 "register_operand" "")]
+ "TARGET_PLUS_DMPY"
+ "{
+ rtx acc_reg = gen_rtx_REG (DImode, ACC_REG_FIRST);
+ rtx tmp1 = gen_reg_rtx (SImode);
+ rtx tmp2 = gen_reg_rtx (SImode);
+ rtx accl = gen_lowpart (SImode, acc_reg);
+
+ emit_move_insn (accl, operands[3]);
+ emit_insn (gen_rtx_SET (tmp1, gen_rtx_ZERO_EXTEND (SImode, operands[1])));
+ emit_insn (gen_rtx_SET (tmp2, gen_rtx_ZERO_EXTEND (SImode, operands[2])));
+ emit_insn (gen_macu (tmp1, tmp2));
+ emit_move_insn (operands[0], accl);
+ DONE;
+ }")
+
(define_expand "maddsidi4"
[(match_operand:DI 0 "register_operand" "")
(match_operand:SI 1 "register_operand" "")
(define_insn_and_split "*mov<mode>_insn"
[(set (match_operand:VWH 0 "move_dest_operand" "=r,r,r,m")
(match_operand:VWH 1 "general_operand" "i,r,m,r"))]
- "TARGET_PLUS_QMACW
- && (register_operand (operands[0], <MODE>mode)
+ "(register_operand (operands[0], <MODE>mode)
|| register_operand (operands[1], <MODE>mode))"
"*
{
return \"#\";
case 1:
- return \"vadd2 %0, %1, 0\";
+ 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)
arc_split_move (operands);
DONE;
}
- [(set_attr "type" "move,move,load,store")
+ [(set_attr "type" "move,multi,load,store")
(set_attr "predicable" "yes,no,no,no")
(set_attr "iscompact" "false,false,false,false")
])
DONE;
})
+(define_expand "sdot_prodv4hi"
+ [(match_operand:V2SI 0 "register_operand" "")
+ (match_operand:V4HI 1 "register_operand" "")
+ (match_operand:V4HI 2 "register_operand" "")
+ (match_operand:V2SI 3 "register_operand" "")]
+ "TARGET_PLUS_MACD"
+{
+ rtx acc_reg = gen_rtx_REG (V2SImode, ACC_REG_FIRST);
+ rtx op1_low = gen_lowpart (V2HImode, operands[1]);
+ rtx op1_high = gen_highpart (V2HImode, operands[1]);
+ rtx op2_low = gen_lowpart (V2HImode, operands[2]);
+ rtx op2_high = gen_highpart (V2HImode, operands[2]);
+
+ emit_move_insn (acc_reg, operands[3]);
+ emit_insn (gen_arc_vec_smac_v2hiv2si_zero (op1_low, op2_low));
+ emit_insn (gen_arc_vec_smac_v2hiv2si (operands[0], op1_high, op2_high));
+ DONE;
+})
+
+(define_expand "udot_prodv4hi"
+ [(match_operand:V2SI 0 "register_operand" "")
+ (match_operand:V4HI 1 "register_operand" "")
+ (match_operand:V4HI 2 "register_operand" "")
+ (match_operand:V2SI 3 "register_operand" "")]
+ "TARGET_PLUS_MACD"
+{
+ rtx acc_reg = gen_rtx_REG (V2SImode, ACC_REG_FIRST);
+ rtx op1_low = gen_lowpart (V2HImode, operands[1]);
+ rtx op1_high = gen_highpart (V2HImode, operands[1]);
+ rtx op2_low = gen_lowpart (V2HImode, operands[2]);
+ rtx op2_high = gen_highpart (V2HImode, operands[2]);
+
+ emit_move_insn (acc_reg, operands[3]);
+ emit_insn (gen_arc_vec_umac_v2hiv2si_zero (op1_low, op2_low));
+ emit_insn (gen_arc_vec_umac_v2hiv2si (operands[0], op1_high, op2_high));
+ DONE;
+})
+
(define_insn "arc_vec_<V_US>mult_lo_v4hi"
[(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
(mult:V2SI (SE:V2SI (vec_select:V2HI
}
)
-(define_insn "arc_vec_<V_US>mac_hi_v4hi"
- [(set (match_operand:V2SI 0 "even_register_operand" "=r,r")
+(define_insn "arc_vec_<V_US>mac_v2hiv2si"
+ [(set (match_operand:V2SI 0 "even_register_operand" "=r,Ral,r")
(plus:V2SI
- (reg:V2SI ARCV2_ACC)
- (mult:V2SI (SE:V2SI (vec_select:V2HI
- (match_operand:V4HI 1 "even_register_operand" "0,r")
- (parallel [(const_int 2) (const_int 3)])))
- (SE:V2SI (vec_select:V2HI
- (match_operand:V4HI 2 "even_register_operand" "r,r")
- (parallel [(const_int 2) (const_int 3)]))))))
+ (mult:V2SI (SE:V2SI (match_operand:V2HI 1 "register_operand" "0, r,r"))
+ (SE:V2SI (match_operand:V2HI 2 "register_operand" "r, r,r")))
+ (reg:V2SI ARCV2_ACC)))
(set (reg:V2SI ARCV2_ACC)
(plus:V2SI
- (reg:V2SI ARCV2_ACC)
- (mult:V2SI (SE:V2SI (vec_select:V2HI (match_dup 1)
- (parallel [(const_int 2) (const_int 3)])))
- (SE:V2SI (vec_select:V2HI (match_dup 2)
- (parallel [(const_int 2) (const_int 3)]))))))
+ (mult:V2SI (SE:V2SI (match_dup 1))
+ (SE:V2SI (match_dup 2)))
+ (reg:V2SI ARCV2_ACC)))
]
"TARGET_PLUS_MACD"
- "vmac2h<V_US_suffix>%? %0, %R1, %R2"
+ "@
+ vmac2h<V_US_suffix>%?\\t%0,%1,%2
+ vmac2h<V_US_suffix>%?\\t0,%1,%2
+ vmac2h<V_US_suffix>%?\\t%0,%1,%2"
[(set_attr "length" "4")
(set_attr "type" "multi")
- (set_attr "predicable" "yes,no")
- (set_attr "cond" "canuse,nocond")])
+ (set_attr "predicable" "yes,no,no")])
+
+(define_insn "arc_vec_<V_US>mac_v2hiv2si_zero"
+ [(set (reg:V2SI ARCV2_ACC)
+ (plus:V2SI
+ (mult:V2SI (SE:V2SI (match_operand:V2HI 0 "register_operand" "r"))
+ (SE:V2SI (match_operand:V2HI 1 "register_operand" "r")))
+ (reg:V2SI ARCV2_ACC)))]
+ "TARGET_PLUS_MACD"
+ "vmac2h<V_US_suffix>%?\\t0,%0,%1"
+ [(set_attr "length" "4")
+ (set_attr "type" "multi")])
;; Builtins
(define_insn "dmach"