;; 2 gr_restore
;; 3 fr_spill
;; 4 fr_restore
+;; 5 recip_approx
;; 8 popcnt
;; 12 mf
;; 13 cmpxchg_acq
[(set_attr "type" "I")])
(define_insn "extendsidi2"
- [(set (match_operand:DI 0 "grfr_register_operand" "=r,*f")
- (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,*f")))]
+ [(set (match_operand:DI 0 "grfr_register_operand" "=r,?f")
+ (sign_extend:DI (match_operand:SI 1 "grfr_register_operand" "r,f")))]
""
"@
sxt4 %0 = %1
[(set_attr "type" "I,M")])
(define_insn "zero_extendsidi2"
- [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,*f")
+ [(set (match_operand:DI 0 "grfr_register_operand" "=r,r,?f")
(zero_extend:DI
- (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,*f")))]
+ (match_operand:SI 1 "grfr_nonimmediate_operand" "r,m,f")))]
""
"@
zxt4 %0 = %1
ld4%O1 %0 = %1%P1
- fsxt.r %0 = f1, %1%B0"
+ fmix.r %0 = f0, %1%B0"
[(set_attr "type" "I,M,F")])
;; Convert between floating point types of different sizes.
;; would let combine merge the thing into adjacent insns.
(define_insn_and_split "extendsfdf2"
- [(set (match_operand:DF 0 "fr_register_operand" "=f,f")
- (float_extend:DF (match_operand:SF 1 "fr_register_operand" "0,f")))]
+ [(set (match_operand:DF 0 "grfr_nonimmediate_operand" "=f,f,f,f,m,*r")
+ (float_extend:DF
+ (match_operand:SF 1 "grfr_nonimmediate_operand" "0,f,m,*r,f,f")))]
""
- "mov %0 = %1"
+ "@
+ mov %0 = %1
+ mov %0 = %1
+ ldfs %0 = %1%P1
+ setf.s %0 = %1
+ stfd %0 = %1%P0
+ getf.d %0 = %1"
"reload_completed"
[(set (match_dup 0) (float_extend:DF (match_dup 1)))]
"if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
- [(set_attr "type" "F")])
+ [(set_attr "type" "F,F,M,M,M,M")])
(define_insn_and_split "extendsftf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f,f")
- (float_extend:TF (match_operand:SF 1 "fr_register_operand" "0,f")))]
+ [(set (match_operand:TF 0 "fr_nonimmediate_operand" "=f,f,f,f,Q")
+ (float_extend:TF
+ (match_operand:SF 1 "grfr_nonimmediate_operand" "0,f,Q,*r,f")))]
""
- "mov %0 = %1"
+ "@
+ mov %0 = %1
+ mov %0 = %1
+ ldfs %0 = %1%P1
+ setf.s %0 = %1
+ stfe %0 = %1%P0"
"reload_completed"
[(set (match_dup 0) (float_extend:TF (match_dup 1)))]
"if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
- [(set_attr "type" "F")])
+ [(set_attr "type" "F,F,M,M,M")])
(define_insn_and_split "extenddftf2"
- [(set (match_operand:TF 0 "fr_register_operand" "=f,f")
- (float_extend:TF (match_operand:DF 1 "fr_register_operand" "0,f")))]
+ [(set (match_operand:TF 0 "fr_nonimmediate_operand" "=f,f,f,f,Q")
+ (float_extend:TF
+ (match_operand:DF 1 "grfr_nonimmediate_operand" "0,f,Q,*r,f")))]
""
- "mov %0 = %1"
+ "@
+ mov %0 = %1
+ mov %0 = %1
+ ldfd %0 = %1%P1
+ setf.d %0 = %1
+ stfe %0 = %1%P0"
"reload_completed"
[(set (match_dup 0) (float_extend:TF (match_dup 1)))]
"if (true_regnum (operands[0]) == true_regnum (operands[1])) DONE;"
- [(set_attr "type" "F")])
+ [(set_attr "type" "F,F,M,M,M")])
(define_insn "truncdfsf2"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
"fcvt.fx.trunc %0 = %1%B0"
[(set_attr "type" "F")])
+(define_insn "fix_trunctfdi2_alts"
+ [(set (match_operand:DI 0 "fr_register_operand" "=f")
+ (fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
+ (use (match_operand:SI 2 "const_int_operand" ""))]
+ ""
+ "fcvt.fx.trunc.s%2 %0 = %1%B0"
+ [(set_attr "type" "F")])
+
;; Convert between unsigned integer types and floating point.
(define_insn "floatunsdisf2"
""
"fcvt.fxu.trunc %0 = %1%B0"
[(set_attr "type" "F")])
+
+(define_insn "fixuns_trunctfdi2_alts"
+ [(set (match_operand:DI 0 "fr_register_operand" "=f")
+ (unsigned_fix:DI (match_operand:TF 1 "fr_register_operand" "f")))
+ (use (match_operand:SI 2 "const_int_operand" ""))]
+ ""
+ "fcvt.fxu.trunc.s%2 %0 = %1%B0"
+ [(set_attr "type" "F")])
\f
;; ::::::::::::::::::::
;; ::
"xma.l %0 = %1, %2, f0%B0"
[(set_attr "type" "F")])
-(define_insn "*maddsi3"
+(define_insn "maddsi4"
[(set (match_operand:SI 0 "fr_register_operand" "=f")
(plus:SI (mult:SI (match_operand:SI 1 "grfr_register_operand" "f")
(match_operand:SI 2 "grfr_register_operand" "f"))
operands[3] = gen_reg_rtx (CCmode);
}")
+(define_expand "divsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (div:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_INLINE_DIV"
+ "
+{
+ rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
+
+ op0_tf = gen_reg_rtx (TFmode);
+ op0_di = gen_reg_rtx (DImode);
+
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_reg (SImode, operands[1]);
+ op1_tf = gen_reg_rtx (TFmode);
+ expand_float (op1_tf, operands[1], 0);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_reg (SImode, operands[2]);
+ op2_tf = gen_reg_rtx (TFmode);
+ expand_float (op2_tf, operands[2], 0);
+
+ /* 2^-34 */
+#if 0
+ twon34 = (CONST_DOUBLE_FROM_REAL_VALUE
+ (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), TFmode));
+ twon34 = force_reg (TFmode, twon34);
+#else
+ twon34 = gen_reg_rtx (TFmode);
+ convert_move (twon34, force_const_mem (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), SFmode)), 0);
+#endif
+
+ emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
+
+ emit_insn (gen_fix_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
+ emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
+ DONE;
+}")
+
+(define_expand "modsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (mod:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_INLINE_DIV"
+ "
+{
+ rtx op2_neg, op1_di, div;
+
+ div = gen_reg_rtx (SImode);
+ emit_insn (gen_divsi3 (div, operands[1], operands[2]));
+
+ op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
+
+ /* This is a trick to get us to reuse the value that we're sure to
+ have already copied to the FP regs. */
+ op1_di = gen_reg_rtx (DImode);
+ convert_move (op1_di, operands[1], 0);
+
+ emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
+ gen_lowpart (SImode, op1_di)));
+ DONE;
+}")
+
+(define_expand "udivsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (udiv:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_INLINE_DIV"
+ "
+{
+ rtx op1_tf, op2_tf, op0_tf, op0_di, twon34;
+
+ op0_tf = gen_reg_rtx (TFmode);
+ op0_di = gen_reg_rtx (DImode);
+
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_reg (SImode, operands[1]);
+ op1_tf = gen_reg_rtx (TFmode);
+ expand_float (op1_tf, operands[1], 1);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_reg (SImode, operands[2]);
+ op2_tf = gen_reg_rtx (TFmode);
+ expand_float (op2_tf, operands[2], 1);
+
+ /* 2^-34 */
+#if 0
+ twon34 = (CONST_DOUBLE_FROM_REAL_VALUE
+ (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), TFmode));
+ twon34 = force_reg (TFmode, twon34);
+#else
+ twon34 = gen_reg_rtx (TFmode);
+ convert_move (twon34, force_const_mem (SFmode, CONST_DOUBLE_FROM_REAL_VALUE (REAL_VALUE_FROM_TARGET_SINGLE (0x2e800000), SFmode)), 0);
+#endif
+
+ emit_insn (gen_divsi3_internal (op0_tf, op1_tf, op2_tf, twon34));
+
+ emit_insn (gen_fixuns_trunctfdi2_alts (op0_di, op0_tf, const1_rtx));
+ emit_move_insn (operands[0], gen_lowpart (SImode, op0_di));
+ DONE;
+}")
+
+(define_expand "umodsi3"
+ [(set (match_operand:SI 0 "register_operand" "")
+ (umod:SI (match_operand:SI 1 "general_operand" "")
+ (match_operand:SI 2 "general_operand" "")))]
+ "TARGET_INLINE_DIV"
+ "
+{
+ rtx op2_neg, op1_di, div;
+
+ div = gen_reg_rtx (SImode);
+ emit_insn (gen_udivsi3 (div, operands[1], operands[2]));
+
+ op2_neg = expand_unop (SImode, neg_optab, operands[2], NULL_RTX, 0);
+
+ /* This is a trick to get us to reuse the value that we're sure to
+ have already copied to the FP regs. */
+ op1_di = gen_reg_rtx (DImode);
+ convert_move (op1_di, operands[1], 1);
+
+ emit_insn (gen_maddsi4 (operands[0], div, op2_neg,
+ gen_lowpart (SImode, op1_di)));
+ DONE;
+}")
+
+(define_insn_and_split "divsi3_internal"
+ [(set (match_operand:TF 0 "fr_register_operand" "=&f")
+ (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
+ (match_operand:TF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:TF 4 "=&f"))
+ (clobber (match_scratch:TF 5 "=&f"))
+ (clobber (match_scratch:CC 6 "=c"))
+ (use (match_operand:TF 3 "fr_register_operand" "f"))]
+ "TARGET_INLINE_DIV"
+ "#"
+ "&& reload_completed"
+ [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ (set (match_dup 6) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
+ (use (const_int 1))])
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 5)
+ (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (match_dup 7)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:TF (mult:TF (match_dup 5) (match_dup 4))
+ (match_dup 4)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 5)
+ (plus:TF (mult:TF (match_dup 5) (match_dup 5))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (plus:TF (mult:TF (match_dup 5) (match_dup 4))
+ (match_dup 4)))
+ (use (const_int 1))]))
+ ]
+ "operands[7] = CONST1_RTX (TFmode);"
+ [(set_attr "predicable" "no")])
\f
;; ::::::::::::::::::::
;; ::
;; ??? Maybe we should change how adds are canonicalized.
-(define_insn "*madddi3"
+(define_insn "madddi4"
[(set (match_operand:DI 0 "fr_register_operand" "=f")
(plus:DI (mult:DI (match_operand:DI 1 "grfr_register_operand" "f")
(match_operand:DI 2 "grfr_register_operand" "f"))
;; We have to use nonmemory_operand for operand 4, to ensure that the
;; validate_changes call inside eliminate_regs will always succeed. If it
-;; doesn't succeed, then this remain a madddi3 pattern, and will be reloaded
+;; doesn't succeed, then this remain a madddi4 pattern, and will be reloaded
;; incorrectly.
-(define_insn "*madddi3_elim"
+(define_insn "*madddi4_elim"
[(set (match_operand:DI 0 "register_operand" "=&r")
(plus:DI (plus:DI (mult:DI (match_operand:DI 1 "register_operand" "f")
(match_operand:DI 2 "register_operand" "f"))
"popcnt %0 = %1"
[(set_attr "type" "I")])
+(define_expand "divdi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (div:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_INLINE_DIV"
+ "
+{
+ rtx op1_tf, op2_tf, op0_tf;
+
+ op0_tf = gen_reg_rtx (TFmode);
+
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_reg (DImode, operands[1]);
+ op1_tf = gen_reg_rtx (TFmode);
+ expand_float (op1_tf, operands[1], 0);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_reg (DImode, operands[2]);
+ op2_tf = gen_reg_rtx (TFmode);
+ expand_float (op2_tf, operands[2], 0);
+
+ if (TARGET_INLINE_DIV_LAT)
+ emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
+ else
+ emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
+
+ emit_insn (gen_fix_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
+ DONE;
+}")
+
+(define_expand "moddi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (mod:SI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_INLINE_DIV"
+ "
+{
+ rtx op2_neg, div;
+
+ div = gen_reg_rtx (DImode);
+ emit_insn (gen_divdi3 (div, operands[1], operands[2]));
+
+ op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
+
+ emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
+ DONE;
+}")
+
+(define_expand "udivdi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (udiv:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_INLINE_DIV"
+ "
+{
+ rtx op1_tf, op2_tf, op0_tf;
+
+ op0_tf = gen_reg_rtx (TFmode);
+
+ if (CONSTANT_P (operands[1]))
+ operands[1] = force_reg (DImode, operands[1]);
+ op1_tf = gen_reg_rtx (TFmode);
+ expand_float (op1_tf, operands[1], 1);
+
+ if (CONSTANT_P (operands[2]))
+ operands[2] = force_reg (DImode, operands[2]);
+ op2_tf = gen_reg_rtx (TFmode);
+ expand_float (op2_tf, operands[2], 1);
+
+ if (TARGET_INLINE_DIV_LAT)
+ emit_insn (gen_divdi3_internal_lat (op0_tf, op1_tf, op2_tf));
+ else
+ emit_insn (gen_divdi3_internal_thr (op0_tf, op1_tf, op2_tf));
+
+ emit_insn (gen_fixuns_trunctfdi2_alts (operands[0], op0_tf, const1_rtx));
+ DONE;
+}")
+
+(define_expand "umoddi3"
+ [(set (match_operand:DI 0 "register_operand" "")
+ (umod:DI (match_operand:DI 1 "general_operand" "")
+ (match_operand:DI 2 "general_operand" "")))]
+ "TARGET_INLINE_DIV"
+ "
+{
+ rtx op2_neg, div;
+
+ div = gen_reg_rtx (DImode);
+ emit_insn (gen_udivdi3 (div, operands[1], operands[2]));
+
+ op2_neg = expand_unop (DImode, neg_optab, operands[2], NULL_RTX, 0);
+
+ emit_insn (gen_madddi4 (operands[0], div, op2_neg, operands[1]));
+ DONE;
+}")
+
+(define_insn_and_split "divdi3_internal_lat"
+ [(set (match_operand:TF 0 "fr_register_operand" "=&f")
+ (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
+ (match_operand:TF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:TF 3 "=&f"))
+ (clobber (match_scratch:TF 4 "=&f"))
+ (clobber (match_scratch:TF 5 "=&f"))
+ (clobber (match_scratch:CC 6 "=c"))]
+ "TARGET_INLINE_DIV_LAT"
+ "#"
+ "&& reload_completed"
+ [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ (set (match_dup 6) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
+ (use (const_int 1))])
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (match_dup 7)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4) (mult:TF (match_dup 1) (match_dup 0)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 5) (mult:TF (match_dup 3) (match_dup 3)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:TF (mult:TF (match_dup 3) (match_dup 4))
+ (match_dup 4)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (match_dup 0)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:TF (mult:TF (match_dup 5) (match_dup 4))
+ (match_dup 4)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (plus:TF (mult:TF (match_dup 5) (match_dup 0))
+ (match_dup 0)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (match_dup 1)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 6) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ ]
+ "operands[7] = CONST1_RTX (TFmode);"
+ [(set_attr "predicable" "no")])
+
+(define_insn_and_split "divdi3_internal_thr"
+ [(set (match_operand:TF 0 "fr_register_operand" "=&f")
+ (float:TF (div:SI (match_operand:TF 1 "fr_register_operand" "f")
+ (match_operand:TF 2 "fr_register_operand" "f"))))
+ (clobber (match_scratch:TF 3 "=&f"))
+ (clobber (match_scratch:TF 4 "=f"))
+ (clobber (match_scratch:CC 5 "=c"))]
+ "TARGET_INLINE_DIV_THR"
+ "#"
+ "&& reload_completed"
+ [(parallel [(set (match_dup 0) (div:TF (const_int 1) (match_dup 2)))
+ (set (match_dup 5) (unspec:CC [(match_dup 1) (match_dup 2)] 5))
+ (use (const_int 1))])
+ (cond_exec (ne (match_dup 5) (const_int 0))
+ (parallel [(set (match_dup 3)
+ (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 0)))
+ (match_dup 6)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 5) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (match_dup 0)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 5) (const_int 0))
+ (parallel [(set (match_dup 3) (mult:TF (match_dup 3) (match_dup 3)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 5) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (plus:TF (mult:TF (match_dup 3) (match_dup 0))
+ (match_dup 0)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 5) (const_int 0))
+ (parallel [(set (match_dup 3) (mult:TF (match_dup 0) (match_dup 1)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 5) (const_int 0))
+ (parallel [(set (match_dup 4)
+ (plus:TF (neg:TF (mult:TF (match_dup 2) (match_dup 3)))
+ (match_dup 1)))
+ (use (const_int 1))]))
+ (cond_exec (ne (match_dup 5) (const_int 0))
+ (parallel [(set (match_dup 0)
+ (plus:TF (mult:TF (match_dup 4) (match_dup 0))
+ (match_dup 3)))
+ (use (const_int 1))]))
+ ]
+ "operands[6] = CONST1_RTX (TFmode);"
+ [(set_attr "predicable" "no")])
\f
;; ::::::::::::::::::::
;; ::
"fmax %0 = %1, %F2%B0"
[(set_attr "type" "F")])
-(define_insn "*maddsf3"
+(define_insn "*maddsf4"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(plus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
(match_operand:SF 2 "fr_register_operand" "f"))
"fma.s %0 = %1, %2, %F3%B0"
[(set_attr "type" "F")])
-(define_insn "*msubsf3"
+(define_insn "*msubsf4"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(minus:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
(match_operand:SF 2 "fr_register_operand" "f"))
;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
-(define_insn "*nmaddsf3"
+(define_insn "*nmaddsf4"
[(set (match_operand:SF 0 "fr_register_operand" "=f")
(plus:SF (neg:SF (mult:SF (match_operand:SF 1 "fr_register_operand" "f")
(match_operand:SF 2 "fr_register_operand" "f")))
"fmax %0 = %1, %F2%B0"
[(set_attr "type" "F")])
-(define_insn "*madddf3"
+(define_insn "*madddf4"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(plus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
(match_operand:DF 2 "fr_register_operand" "f"))
"fma.d %0 = %1, %2, %F3%B0"
[(set_attr "type" "F")])
-(define_insn "*msubdf3"
+(define_insn "*msubdf4"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(minus:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
(match_operand:DF 2 "fr_register_operand" "f"))
;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
-(define_insn "*nmadddf3"
+(define_insn "*nmadddf4"
[(set (match_operand:DF 0 "fr_register_operand" "=f")
(plus:DF (neg:DF (mult:DF (match_operand:DF 1 "fr_register_operand" "f")
(match_operand:DF 2 "fr_register_operand" "f")))
"fmpy %0 = %F1, %F2%B0"
[(set_attr "type" "F")])
+(define_insn "*multf3_alts"
+ [(set (match_operand:TF 0 "fr_register_operand" "=f")
+ (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
+ (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
+ (use (match_operand:SI 3 "const_int_operand" ""))]
+ ""
+ "fmpy.s%3 %0 = %F1, %F2%B0"
+ [(set_attr "type" "F")])
+
(define_insn "abstf2"
[(set (match_operand:TF 0 "fr_register_operand" "=f")
(abs:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")))]
"fmax %0 = %F1, %F2%B0"
[(set_attr "type" "F")])
-(define_insn "*maddtf3"
+(define_insn "*maddtf4"
[(set (match_operand:TF 0 "fr_register_operand" "=f")
(plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
(match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
"fma %0 = %F1, %F2, %F3%B0"
[(set_attr "type" "F")])
-(define_insn "*msubtf3"
+(define_insn "*maddtf4_alts"
+ [(set (match_operand:TF 0 "fr_register_operand" "=f")
+ (plus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
+ (match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
+ (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
+ (use (match_operand:SI 4 "const_int_operand" ""))]
+ ""
+ "fma.s%4 %0 = %F1, %F2, %F3%B0"
+ [(set_attr "type" "F")])
+
+(define_insn "*msubtf4"
[(set (match_operand:TF 0 "fr_register_operand" "=f")
(minus:TF (mult:TF (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
(match_operand:TF 2 "tfreg_or_fp01_operand" "fG"))
;; ??? Is it possible to canonicalize this as (minus (reg) (mult))?
-(define_insn "*nmaddtf3"
+(define_insn "*nmaddtf4"
[(set (match_operand:TF 0 "fr_register_operand" "=f")
(plus:TF (neg:TF (mult:TF
(match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
""
"fnma %0 = %F1, %F2, %F3%B0"
[(set_attr "type" "F")])
+
+(define_insn "*nmaddtf4_alts"
+ [(set (match_operand:TF 0 "fr_register_operand" "=f")
+ (plus:TF (neg:TF (mult:TF
+ (match_operand:TF 1 "tfreg_or_fp01_operand" "fG")
+ (match_operand:TF 2 "tfreg_or_fp01_operand" "fG")))
+ (match_operand:TF 3 "tfreg_or_fp01_operand" "fG")))
+ (use (match_operand:SI 4 "const_int_operand" ""))]
+ ""
+ "fnma.s%4 %0 = %F1, %F2, %F3%B0"
+ [(set_attr "type" "F")])
+
+(define_insn "*recip_approx"
+ [(set (match_operand:TF 0 "fr_register_operand" "=f")
+ (div:TF (const_int 1)
+ (match_operand:TF 3 "fr_register_operand" "f")))
+ (set (match_operand:CC 1 "register_operand" "=c")
+ (unspec:CC [(match_operand:TF 2 "fr_register_operand" "f")
+ (match_dup 3)] 5))
+ (use (match_operand:SI 4 "const_int_operand" ""))]
+ ""
+ "frcpa.s%4 %0, %1 = %2, %3"
+ [(set_attr "type" "F")])
\f
;; ::::::::::::::::::::
;; ::