(define_function_unit "fpu" 1 0
(and (eq_attr "cpu" "pentium")
(and (eq_attr "type" "fmov")
- (ior (and (eq_attr "memory" "store")
- (match_operand:XF 0 "memory_operand" ""))
- (and (eq_attr "memory" "load")
- (match_operand:XF 1 "memory_operand" "")))))
+ (and (eq_attr "memory" "load,store")
+ (eq_attr "mode" "XF"))))
3 3)
(define_function_unit "pent_np" 1 0
(and (eq_attr "cpu" "pentium")
(and (eq_attr "type" "fmov")
- (ior (and (eq_attr "memory" "store")
- (match_operand:XF 0 "memory_operand" ""))
- (and (eq_attr "memory" "load")
- (match_operand:XF 1 "memory_operand" "")))))
+ (and (eq_attr "memory" "load,store")
+ (eq_attr "mode" "XF"))))
3 3)
(define_function_unit "fpu" 1 0
(match_operand 1 "memory_operand" ""))
(const_string "vector")
(and (eq_attr "type" "fmov")
- (ior (match_operand:XF 0 "memory_operand" "")
- (match_operand:XF 1 "memory_operand" "")))
+ (and (eq_attr "memory" "load,store")
+ (eq_attr "mode" "XF")))
(const_string "vector")]
(const_string "direct")))
(define_function_unit "athlon_fp" 3 0
(and (eq_attr "cpu" "athlon")
(and (eq_attr "type" "fmov")
- (match_operand:XF 1 "memory_operand" "")))
+ (and (eq_attr "memory" "load")
+ (eq_attr "mode" "XF"))))
10 1)
(define_function_unit "athlon_fp" 3 0
DONE;
}")
+(define_expand "cmptf"
+ [(set (reg:CC 17)
+ (compare:CC (match_operand:TF 0 "cmp_fp_expander_operand" "")
+ (match_operand:TF 1 "cmp_fp_expander_operand" "")))]
+ "TARGET_80387"
+ "
+{
+ ix86_compare_op0 = operands[0];
+ ix86_compare_op1 = operands[1];
+ DONE;
+}")
+
(define_expand "cmpdf"
[(set (reg:CC 17)
(compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
[(set_attr "type" "fcmp")
(set_attr "mode" "XF")])
+(define_insn "*cmpfp_2_tf"
+ [(set (reg:CCFP 18)
+ (compare:CCFP
+ (match_operand:TF 0 "register_operand" "f")
+ (match_operand:TF 1 "register_operand" "f")))]
+ "TARGET_80387"
+ "* return output_fp_compare (insn, operands, 0, 0);"
+ [(set_attr "type" "fcmp")
+ (set_attr "mode" "XF")])
+
(define_insn "*cmpfp_2_xf_1"
[(set (match_operand:HI 0 "register_operand" "=a")
(unspec:HI
[(set_attr "type" "multi")
(set_attr "mode" "XF")])
+(define_insn "*cmpfp_2_tf_1"
+ [(set (match_operand:HI 0 "register_operand" "=a")
+ (unspec:HI
+ [(compare:CCFP
+ (match_operand:TF 1 "register_operand" "f")
+ (match_operand:TF 2 "register_operand" "f"))] 9))]
+ "TARGET_80387"
+ "* return output_fp_compare (insn, operands, 2, 0);"
+ [(set_attr "type" "multi")
+ (set_attr "mode" "XF")])
+
(define_insn "*cmpfp_2u"
[(set (reg:CCFPU 18)
(compare:CCFPU
""
"ix86_expand_move (XFmode, operands); DONE;")
+(define_expand "movtf"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (match_operand:TF 1 "general_operand" ""))]
+ ""
+ "ix86_expand_move (TFmode, operands); DONE;")
+
;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
;; Size of pushdf using integer insturctions is 3+3*memory operand size
;; Pushing using integer instructions is longer except for constants
[(set_attr "type" "multi")
(set_attr "mode" "XF,SI,SI")])
+(define_insn "*pushtf_nointeger"
+ [(set (match_operand:TF 0 "push_operand" "=<,<,<")
+ (match_operand:TF 1 "general_no_elim_operand" "f,Fo,*r"))]
+ "optimize_size"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ /* %%% We loose REG_DEAD notes for controling pops if we split late. */
+ operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
+ operands[2] = stack_pointer_rtx;
+ operands[3] = GEN_INT (16);
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
+ else
+ return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
+
+ case 1:
+ case 2:
+ return \"#\";
+
+ default:
+ abort ();
+ }
+}"
+ [(set_attr "type" "multi")
+ (set_attr "mode" "XF,SI,SI")])
+
(define_insn "*pushxf_integer"
[(set (match_operand:XF 0 "push_operand" "=<,<")
(match_operand:XF 1 "general_no_elim_operand" "f#r,rFo#f"))]
[(set_attr "type" "multi")
(set_attr "mode" "XF,SI")])
+(define_insn "*pushtf_integer"
+ [(set (match_operand:TF 0 "push_operand" "=<,<")
+ (match_operand:TF 1 "general_no_elim_operand" "f#r,rFo#f"))]
+ "!optimize_size"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ /* %%% We loose REG_DEAD notes for controling pops if we split late. */
+ operands[0] = gen_rtx_MEM (XFmode, stack_pointer_rtx);
+ operands[2] = stack_pointer_rtx;
+ operands[3] = GEN_INT (16);
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"sub{l}\\t{%3, %2|%2, %3}\;fstp%z0\\t%y0\";
+ else
+ return \"sub{l}\\t{%3, %2|%2, %3}\;fst%z0\\t%y0\";
+
+ case 1:
+ return \"#\";
+
+ default:
+ abort ();
+ }
+}"
+ [(set_attr "type" "multi")
+ (set_attr "mode" "XF,SI")])
+
(define_split
- [(set (match_operand:XF 0 "push_operand" "")
- (match_operand:XF 1 "general_operand" ""))]
+ [(set (match_operand 0 "push_operand" "")
+ (match_operand 1 "general_operand" ""))]
"reload_completed
+ && (GET_MODE (operands[0]) == XFmode
+ || GET_MODE (operands[0]) == TFmode
+ || GET_MODE (operands[0]) == DFmode)
&& (!REG_P (operands[1]) || !FP_REGNO_P (REGNO (operands[1])))"
[(const_int 0)]
"if (!ix86_split_long_move (operands)) abort (); DONE;")
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
(set (mem:XF (reg:SI 7)) (match_dup 1))])
+(define_split
+ [(set (match_operand:TF 0 "push_operand" "")
+ (match_operand:TF 1 "register_operand" ""))]
+ "FP_REGNO_P (REGNO (operands[1]))"
+ [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
+ (set (mem:TF (reg:SI 7)) (match_dup 1))])
+
;; Do not use integer registers when optimizing for size
(define_insn "*movxf_nointeger"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
[(set_attr "type" "fmov,fmov,fmov,multi,multi")
(set_attr "mode" "XF,XF,XF,SI,SI")])
+(define_insn "*movtf_nointeger"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m,f,*r,o")
+ (match_operand:TF 1 "general_operand" "fm,f,G,*roF,F*r"))]
+ "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
+ && optimize_size
+ && (reload_in_progress || reload_completed
+ || GET_CODE (operands[1]) != CONST_DOUBLE
+ || memory_operand (operands[0], TFmode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (REG_P (operands[1])
+ && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp\\t%y0\";
+ else if (STACK_TOP_P (operands[0]))
+ return \"fld%z1\\t%y1\";
+ else
+ return \"fst\\t%y0\";
+
+ case 1:
+ /* There is no non-popping store to memory for XFmode. So if
+ we need one, follow the store with a load. */
+ if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
+ else
+ return \"fstp%z0\\t%y0\";
+
+ case 2:
+ switch (standard_80387_constant_p (operands[1]))
+ {
+ case 1:
+ return \"fldz\";
+ case 2:
+ return \"fld1\";
+ }
+ break;
+
+ case 3: case 4:
+ return \"#\";
+ }
+ abort();
+}"
+ [(set_attr "type" "fmov,fmov,fmov,multi,multi")
+ (set_attr "mode" "XF,XF,XF,SI,SI")])
+
(define_insn "*movxf_integer"
[(set (match_operand:XF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
(match_operand:XF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
[(set_attr "type" "fmov,fmov,fmov,multi,multi")
(set_attr "mode" "XF,XF,XF,SI,SI")])
+(define_insn "*movtf_integer"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,m,f#r,r#f,o")
+ (match_operand:TF 1 "general_operand" "fm#r,f#r,G,roF#f,Fr#f"))]
+ "(GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
+ && !optimize_size
+ && (reload_in_progress || reload_completed
+ || GET_CODE (operands[1]) != CONST_DOUBLE
+ || memory_operand (operands[0], TFmode))"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (REG_P (operands[1])
+ && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp\\t%y0\";
+ else if (STACK_TOP_P (operands[0]))
+ return \"fld%z1\\t%y1\";
+ else
+ return \"fst\\t%y0\";
+
+ case 1:
+ /* There is no non-popping store to memory for XFmode. So if
+ we need one, follow the store with a load. */
+ if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp%z0\\t%y0\;fld%z0\\t%y0\";
+ else
+ return \"fstp%z0\\t%y0\";
+
+ case 2:
+ switch (standard_80387_constant_p (operands[1]))
+ {
+ case 1:
+ return \"fldz\";
+ case 2:
+ return \"fld1\";
+ }
+ break;
+
+ case 3: case 4:
+ return \"#\";
+ }
+ abort();
+}"
+ [(set_attr "type" "fmov,fmov,fmov,multi,multi")
+ (set_attr "mode" "XF,XF,XF,SI,SI")])
+
(define_split
- [(set (match_operand:XF 0 "nonimmediate_operand" "")
- (match_operand:XF 1 "general_operand" ""))]
+ [(set (match_operand 0 "nonimmediate_operand" "")
+ (match_operand 1 "general_operand" ""))]
"reload_completed
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)
+ && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
&& ! (FP_REG_P (operands[0]) ||
(GET_CODE (operands[0]) == SUBREG
&& FP_REG_P (SUBREG_REG (operands[0]))))
"if (ix86_split_long_move (operands)) DONE;")
(define_split
- [(set (match_operand:XF 0 "register_operand" "")
- (match_operand:XF 1 "memory_operand" ""))]
+ [(set (match_operand 0 "register_operand" "")
+ (match_operand 1 "memory_operand" ""))]
"reload_completed
&& GET_CODE (operands[1]) == MEM
+ && (GET_MODE (operands[0]) == XFmode || GET_MODE (operands[0]) == TFmode)
&& GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF
&& CONSTANT_POOL_ADDRESS_P (XEXP (operands[1], 0))
&& standard_80387_constant_p (get_pool_constant (XEXP (operands[1], 0)))"
}"
[(set_attr "type" "fxch")
(set_attr "mode" "XF")])
+
+(define_insn "swaptf"
+ [(set (match_operand:TF 0 "register_operand" "+f")
+ (match_operand:TF 1 "register_operand" "+f"))
+ (set (match_dup 1)
+ (match_dup 0))]
+ ""
+ "*
+{
+ if (STACK_TOP_P (operands[0]))
+ return \"fxch\\t%1\";
+ else
+ return \"fxch\\t%0\";
+}"
+ [(set_attr "type" "fxch")
+ (set_attr "mode" "XF")])
\f
;; Zero extension instructions
(float_extend:XF (match_operand:SF 1 "register_operand" "")))]
"FP_REGNO_P (REGNO (operands[1]))"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
- (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
+ (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
+
+(define_insn "*dummy_extendsftf2"
+ [(set (match_operand:TF 0 "push_operand" "=<")
+ (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "f")))]
+ "0"
+ "#")
+
+(define_split
+ [(set (match_operand:TF 0 "push_operand" "")
+ (float_extend:TF (match_operand:SF 1 "register_operand" "")))]
+ "FP_REGNO_P (REGNO (operands[1]))"
+ [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
+ (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
(define_insn "*dummy_extenddfxf2"
[(set (match_operand:XF 0 "push_operand" "=<")
(float_extend:XF (match_operand:DF 1 "register_operand" "")))]
"FP_REGNO_P (REGNO (operands[1]))"
[(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -12)))
- (set (mem:DF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
+ (set (mem:XF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
+
+(define_insn "*dummy_extenddftf2"
+ [(set (match_operand:TF 0 "push_operand" "=<")
+ (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "f")))]
+ "0"
+ "#")
+
+(define_split
+ [(set (match_operand:TF 0 "push_operand" "")
+ (float_extend:TF (match_operand:DF 1 "register_operand" "")))]
+ "FP_REGNO_P (REGNO (operands[1]))"
+ [(set (reg:SI 7) (plus:SI (reg:SI 7) (const_int -16)))
+ (set (mem:TF (reg:SI 7)) (float_extend:XF (match_dup 1)))])
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
[(set_attr "type" "fmov")
(set_attr "mode" "SF,XF")])
+(define_expand "extendsftf2"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "")))]
+ "TARGET_80387"
+ "
+{
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+ operands[1] = force_reg (SFmode, operands[1]);
+}")
+
+(define_insn "*extendsftf2_1"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
+ (float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
+ "TARGET_80387
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (REG_P (operands[1])
+ && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp\\t%y0\";
+ else if (STACK_TOP_P (operands[0]))
+ return \"fld%z1\\t%y1\";
+ else
+ return \"fst\\t%y0\";
+
+ case 1:
+ /* There is no non-popping store to memory for XFmode. So if
+ we need one, follow the store with a load. */
+ if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
+ else
+ return \"fstp%z0\\t%y0\";
+
+ default:
+ abort ();
+ }
+}"
+ [(set_attr "type" "fmov")
+ (set_attr "mode" "SF,XF")])
+
(define_expand "extenddfxf2"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
(float_extend:XF (match_operand:DF 1 "nonimmediate_operand" "")))]
[(set_attr "type" "fmov")
(set_attr "mode" "DF,XF")])
+(define_expand "extenddftf2"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "")))]
+ "TARGET_80387"
+ "
+{
+ if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
+ operands[1] = force_reg (DFmode, operands[1]);
+}")
+
+(define_insn "*extenddftf2_1"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=f,m")
+ (float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,f")))]
+ "TARGET_80387
+ && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (REG_P (operands[1])
+ && find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp\\t%y0\";
+ else if (STACK_TOP_P (operands[0]))
+ return \"fld%z1\\t%y1\";
+ else
+ return \"fst\\t%y0\";
+
+ case 1:
+ /* There is no non-popping store to memory for XFmode. So if
+ we need one, follow the store with a load. */
+ if (! find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp%z0\\t%y0\\n\\tfld%z0\\t%y0\";
+ else
+ return \"fstp%z0\\t%y0\";
+
+ default:
+ abort ();
+ }
+}"
+ [(set_attr "type" "fmov")
+ (set_attr "mode" "DF,XF")])
+
;; %%% This seems bad bad news.
;; This cannot output into an f-reg because there is no way to be sure
;; of truncating in that case. Otherwise this is just like a simple move
(set (match_dup 0) (match_dup 2))]
"")
+(define_expand "trunctfsf2"
+ [(parallel [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ (float_truncate:SF
+ (match_operand:TF 1 "register_operand" "")))
+ (clobber (match_dup 2))])]
+ "TARGET_80387"
+ "operands[2] = assign_386_stack_local (SFmode, 0);")
+
+(define_insn "*trunctfsf2_1"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
+ (float_truncate:SF
+ (match_operand:TF 1 "register_operand" "f,0")))
+ (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
+ "TARGET_80387"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp%z0\\t%y0\";
+ else
+ return \"fst%z0\\t%y0\";
+ case 1:
+ return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
+ }
+ abort ();
+}"
+ [(set_attr "type" "fmov,multi")
+ (set_attr "mode" "SF")])
+
+(define_insn "*truncxfsf2_2"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
+ (float_truncate:SF
+ (match_operand:TF 1 "register_operand" "f")))]
+ "TARGET_80387"
+ "*
+{
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp%z0\\t%y0\";
+ else
+ return \"fst%z0\\t%y0\";
+}"
+ [(set_attr "type" "fmov")
+ (set_attr "mode" "SF")])
+
+(define_split
+ [(set (match_operand:SF 0 "memory_operand" "")
+ (float_truncate:SF
+ (match_operand:TF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387"
+ [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
+ "")
+
+(define_split
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float_truncate:SF
+ (match_operand:TF 1 "register_operand" "")))
+ (clobber (match_operand:SF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2) (float_truncate:SF (match_dup 1)))
+ (set (match_dup 0) (match_dup 2))]
+ "")
+
+
(define_expand "truncxfdf2"
[(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
(float_truncate:DF
(set (match_dup 0) (match_dup 2))]
"")
+(define_expand "trunctfdf2"
+ [(parallel [(set (match_operand:DF 0 "nonimmediate_operand" "")
+ (float_truncate:DF
+ (match_operand:TF 1 "register_operand" "")))
+ (clobber (match_dup 2))])]
+ "TARGET_80387"
+ "operands[2] = assign_386_stack_local (DFmode, 0);")
+
+(define_insn "*trunctfdf2_1"
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
+ (float_truncate:DF
+ (match_operand:TF 1 "register_operand" "f,0")))
+ (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
+ "TARGET_80387"
+ "*
+{
+ switch (which_alternative)
+ {
+ case 0:
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp%z0\\t%y0\";
+ else
+ return \"fst%z0\\t%y0\";
+ case 1:
+ return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
+ }
+ abort ();
+}"
+ [(set_attr "type" "fmov,multi")
+ (set_attr "mode" "DF")])
+
+(define_insn "*truncxfdf2_2"
+ [(set (match_operand:DF 0 "memory_operand" "=m")
+ (float_truncate:DF
+ (match_operand:TF 1 "register_operand" "f")))]
+ "TARGET_80387"
+ "*
+{
+ if (find_regno_note (insn, REG_DEAD, REGNO (operands[1])))
+ return \"fstp%z0\\t%y0\";
+ else
+ return \"fst%z0\\t%y0\";
+}"
+ [(set_attr "type" "fmov")
+ (set_attr "mode" "DF")])
+
+(define_split
+ [(set (match_operand:DF 0 "memory_operand" "")
+ (float_truncate:DF
+ (match_operand:TF 1 "register_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))]
+ "TARGET_80387"
+ [(set (match_dup 0) (float_truncate:DF (match_dup 1)))]
+ "")
+
+(define_split
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float_truncate:DF
+ (match_operand:TF 1 "register_operand" "")))
+ (clobber (match_operand:DF 2 "memory_operand" ""))]
+ "TARGET_80387 && reload_completed"
+ [(set (match_dup 2) (float_truncate:DF (match_dup 1)))
+ (set (match_dup 0) (match_dup 2))]
+ "")
+
\f
;; %%% Break up all these bad boys.
;; Signed conversion to DImode.
-(define_expand "fix_truncxfdi2"
+(define_expand "fix_truncxfdi2"
+ [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
+ (fix:DI (match_operand:XF 1 "register_operand" "")))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_scratch:SI 4 ""))
+ (clobber (match_scratch:XF 5 ""))])]
+ "TARGET_80387"
+ "operands[2] = assign_386_stack_local (SImode, 0);
+ operands[3] = assign_386_stack_local (DImode, 1);")
+
+(define_expand "fix_trunctfdi2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
- (fix:DI (match_operand:XF 1 "register_operand" "")))
+ (fix:DI (match_operand:TF 1 "register_operand" "")))
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_scratch:SI 4 ""))
- (clobber (match_scratch:XF 5 ""))])]
+ (clobber (match_scratch:TF 5 ""))])]
"TARGET_80387"
"operands[2] = assign_386_stack_local (SImode, 0);
operands[3] = assign_386_stack_local (DImode, 1);")
"operands[2] = assign_386_stack_local (SImode, 0);
operands[3] = assign_386_stack_local (SImode, 1);")
+(define_expand "fix_trunctfsi2"
+ [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
+ (fix:SI (match_operand:TF 1 "register_operand" "")))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_scratch:SI 4 ""))])]
+ "TARGET_80387"
+ "operands[2] = assign_386_stack_local (SImode, 0);
+ operands[3] = assign_386_stack_local (SImode, 1);")
+
(define_expand "fix_truncdfsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
(fix:SI (match_operand:DF 1 "register_operand" "")))
"operands[2] = assign_386_stack_local (SImode, 0);
operands[3] = assign_386_stack_local (HImode, 1);")
+(define_expand "fix_trunctfhi2"
+ [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
+ (fix:HI (match_operand:TF 1 "register_operand" "")))
+ (clobber (match_dup 2))
+ (clobber (match_dup 3))
+ (clobber (match_scratch:SI 4 ""))])]
+ "TARGET_80387"
+ "operands[2] = assign_386_stack_local (SImode, 0);
+ operands[3] = assign_386_stack_local (HImode, 1);")
+
(define_expand "fix_truncdfhi2"
[(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
(fix:HI (match_operand:DF 1 "register_operand" "")))
(set_attr "mode" "XF")
(set_attr "fp_int_src" "true")])
+(define_insn "floathitf2"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (float:TF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
+ "TARGET_80387"
+ "@
+ fild%z1\\t%1
+ #"
+ [(set_attr "type" "fmov,multi")
+ (set_attr "mode" "XF")
+ (set_attr "fp_int_src" "true")])
+
(define_insn "floatsixf2"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(float:XF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
(set_attr "mode" "XF")
(set_attr "fp_int_src" "true")])
+(define_insn "floatsitf2"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (float:TF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
+ "TARGET_80387"
+ "@
+ fild%z1\\t%1
+ #"
+ [(set_attr "type" "fmov,multi")
+ (set_attr "mode" "XF")
+ (set_attr "fp_int_src" "true")])
+
(define_insn "floatdixf2"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(float:XF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
(set_attr "mode" "XF")
(set_attr "fp_int_src" "true")])
+(define_insn "floatditf2"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (float:TF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
+ "TARGET_80387"
+ "@
+ fild%z1\\t%1
+ #"
+ [(set_attr "type" "fmov,multi")
+ (set_attr "mode" "XF")
+ (set_attr "fp_int_src" "true")])
+
;; %%% Kill these when reload knows how to do it.
(define_split
[(set (match_operand 0 "register_operand" "")
"TARGET_80387"
"")
+(define_expand "addtf3"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (plus:TF (match_operand:TF 1 "register_operand" "")
+ (match_operand:TF 2 "register_operand" "")))]
+ "TARGET_80387"
+ "")
+
(define_expand "adddf3"
[(set (match_operand:DF 0 "register_operand" "")
(plus:DF (match_operand:DF 1 "register_operand" "")
"TARGET_80387"
"")
+(define_expand "subtf3"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (minus:TF (match_operand:TF 1 "register_operand" "")
+ (match_operand:TF 2 "register_operand" "")))]
+ "TARGET_80387"
+ "")
+
(define_expand "subdf3"
[(set (match_operand:DF 0 "register_operand" "")
(minus:DF (match_operand:DF 1 "register_operand" "")
"TARGET_80387"
"")
+(define_expand "multf3"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (mult:TF (match_operand:TF 1 "register_operand" "")
+ (match_operand:TF 2 "register_operand" "")))]
+ "TARGET_80387"
+ "")
+
(define_expand "muldf3"
[(set (match_operand:DF 0 "register_operand" "")
(mult:DF (match_operand:DF 1 "register_operand" "")
"TARGET_80387"
"")
+(define_expand "divtf3"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (div:TF (match_operand:TF 1 "register_operand" "")
+ (match_operand:TF 2 "register_operand" "")))]
+ "TARGET_80387"
+ "")
+
(define_expand "divdf3"
[(set (match_operand:DF 0 "register_operand" "")
(div:DF (match_operand:DF 1 "register_operand" "")
"TARGET_80387"
"ix86_expand_unary_operator (NEG, XFmode, operands); DONE;")
+(define_expand "negtf2"
+ [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
+ (clobber (reg:CC 17))])]
+ "TARGET_80387"
+ "ix86_expand_unary_operator (NEG, TFmode, operands); DONE;")
+
;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
;; because of secondary memory needed to reload from class FLOAT_INT_REGS
;; to itself.
"operands[1] = GEN_INT (0x8000);
operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
+;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
+;; because of secondary memory needed to reload from class FLOAT_INT_REGS
+;; to itself.
+(define_insn "*negtf2_if"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
+ (neg:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
+ (clobber (reg:CC 17))]
+ "TARGET_80387 && ix86_unary_operator_ok (NEG, TFmode, operands)"
+ "#")
+
+(define_split
+ [(set (match_operand:TF 0 "register_operand" "")
+ (neg:TF (match_operand:TF 1 "register_operand" "")))
+ (clobber (reg:CC 17))]
+ "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
+ [(set (match_dup 0)
+ (neg:TF (match_dup 1)))]
+ "")
+
+(define_split
+ [(set (match_operand:TF 0 "register_operand" "")
+ (neg:TF (match_operand:TF 1 "register_operand" "")))
+ (clobber (reg:CC 17))]
+ "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
+ [(parallel [(set (match_dup 0) (xor:SI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 17))])]
+ "operands[1] = GEN_INT (0x8000);
+ operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
+
;; Conditionize these after reload. If they matches before reload, we
;; lose the clobber and ability to use integer instructions.
[(set_attr "type" "fsgn")
(set_attr "mode" "XF")
(set_attr "ppro_uops" "few")])
+
+(define_insn "*negtf2_1"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (neg:TF (match_operand:TF 1 "register_operand" "0")))]
+ "TARGET_80387 && reload_completed"
+ "fchs"
+ [(set_attr "type" "fsgn")
+ (set_attr "mode" "XF")
+ (set_attr "ppro_uops" "few")])
+
+(define_insn "*negextenddftf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (neg:TF (float_extend:TF
+ (match_operand:DF 1 "register_operand" "0"))))]
+ "TARGET_80387"
+ "fchs"
+ [(set_attr "type" "fsgn")
+ (set_attr "mode" "XF")
+ (set_attr "ppro_uops" "few")])
+
+(define_insn "*negextendsftf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (neg:TF (float_extend:TF
+ (match_operand:SF 1 "register_operand" "0"))))]
+ "TARGET_80387"
+ "fchs"
+ [(set_attr "type" "fsgn")
+ (set_attr "mode" "XF")
+ (set_attr "ppro_uops" "few")])
\f
;; Absolute value instructions
"TARGET_80387"
"ix86_expand_unary_operator (ABS, XFmode, operands); DONE;")
+(define_expand "abstf2"
+ [(parallel [(set (match_operand:TF 0 "nonimmediate_operand" "")
+ (neg:TF (match_operand:TF 1 "nonimmediate_operand" "")))
+ (clobber (reg:CC 17))])]
+ "TARGET_80387"
+ "ix86_expand_unary_operator (ABS, TFmode, operands); DONE;")
+
;; Keep 'f' and 'r' in separate alternatives to avoid reload problems
;; because of secondary memory needed to reload from class FLOAT_INT_REGS
;; to itself.
"operands[1] = GEN_INT (~0x8000);
operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
+(define_insn "*abstf2_if"
+ [(set (match_operand:TF 0 "nonimmediate_operand" "=f#r,rm#f")
+ (abs:TF (match_operand:TF 1 "nonimmediate_operand" "0,0")))
+ (clobber (reg:CC 17))]
+ "TARGET_80387 && ix86_unary_operator_ok (ABS, TFmode, operands)"
+ "#")
+
+(define_split
+ [(set (match_operand:TF 0 "register_operand" "")
+ (abs:TF (match_operand:TF 1 "register_operand" "")))
+ (clobber (reg:CC 17))]
+ "TARGET_80387 && FP_REGNO_P (REGNO (operands[0])) && reload_completed"
+ [(set (match_dup 0)
+ (abs:TF (match_dup 1)))]
+ "")
+
+(define_split
+ [(set (match_operand:TF 0 "register_operand" "")
+ (abs:TF (match_operand:TF 1 "register_operand" "")))
+ (clobber (reg:CC 17))]
+ "TARGET_80387 && reload_completed && !FP_REGNO_P (REGNO (operands[0]))"
+ [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 1)))
+ (clobber (reg:CC 17))])]
+ "operands[1] = GEN_INT (~0x8000);
+ operands[0] = gen_rtx_REG (SImode, true_regnum (operands[0]) + 2);")
+
(define_insn "*abssf2_1"
[(set (match_operand:SF 0 "register_operand" "=f")
(abs:SF (match_operand:SF 1 "register_operand" "0")))]
"fabs"
[(set_attr "type" "fsgn")
(set_attr "mode" "XF")])
+
+(define_insn "*abstf2_1"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (abs:TF (match_operand:TF 1 "register_operand" "0")))]
+ "TARGET_80387 && reload_completed"
+ "fabs"
+ [(set_attr "type" "fsgn")
+ (set_attr "mode" "DF")])
+
+(define_insn "*absextenddftf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (abs:TF (float_extend:TF
+ (match_operand:DF 1 "register_operand" "0"))))]
+ "TARGET_80387"
+ "fabs"
+ [(set_attr "type" "fsgn")
+ (set_attr "mode" "XF")])
+
+(define_insn "*absextendsftf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (abs:TF (float_extend:TF
+ (match_operand:SF 1 "register_operand" "0"))))]
+ "TARGET_80387"
+ "fabs"
+ [(set_attr "type" "fsgn")
+ (set_attr "mode" "XF")])
\f
;; One complement instructions
(const_string "fop")))
(set_attr "mode" "XF")])
+(define_insn "*fop_tf_comm"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (match_operator:TF 3 "binary_fp_operator"
+ [(match_operand:TF 1 "register_operand" "%0")
+ (match_operand:TF 2 "register_operand" "f")]))]
+ "TARGET_80387 && GET_RTX_CLASS (GET_CODE (operands[3])) == 'c'"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (if_then_else (match_operand:TF 3 "mult_operator" "")
+ (const_string "fmul")
+ (const_string "fop")))
+ (set_attr "mode" "XF")])
+
(define_insn "*fop_sf_1"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(match_operator:SF 3 "binary_fp_operator"
(const_string "fop")))
(set_attr "mode" "XF")])
+(define_insn "*fop_tf_1"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (match_operator:TF 3 "binary_fp_operator"
+ [(match_operand:TF 1 "register_operand" "0,f")
+ (match_operand:TF 2 "register_operand" "f,0")]))]
+ "TARGET_80387
+ && GET_RTX_CLASS (GET_CODE (operands[3])) != 'c'"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:TF 3 "mult_operator" "")
+ (const_string "fmul")
+ (match_operand:TF 3 "div_operator" "")
+ (const_string "fdiv")
+ ]
+ (const_string "fop")))
+ (set_attr "mode" "XF")])
+
(define_insn "*fop_xf_2"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
(set_attr "mode" "SI")
(set_attr "ppro_uops" "many")])
+(define_insn "*fop_tf_2"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (match_operator:TF 3 "binary_fp_operator"
+ [(float:TF (match_operand:SI 1 "nonimmediate_operand" "m,?r"))
+ (match_operand:TF 2 "register_operand" "0,0")]))]
+ "TARGET_80387 && TARGET_USE_FIOP"
+ "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:TF 3 "mult_operator" "")
+ (const_string "fmul")
+ (match_operand:TF 3 "div_operator" "")
+ (const_string "fdiv")
+ ]
+ (const_string "fop")))
+ (set_attr "fp_int_src" "true")
+ (set_attr "mode" "SI")
+ (set_attr "ppro_uops" "many")])
+
(define_insn "*fop_xf_3"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
(set_attr "mode" "SI")
(set_attr "ppro_uops" "many")])
+(define_insn "*fop_tf_3"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (match_operator:TF 3 "binary_fp_operator"
+ [(match_operand:TF 1 "register_operand" "0,0")
+ (float:TF (match_operand:SI 2 "nonimmediate_operand" "m,?r"))]))]
+ "TARGET_80387 && TARGET_USE_FIOP"
+ "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:TF 3 "mult_operator" "")
+ (const_string "fmul")
+ (match_operand:TF 3 "div_operator" "")
+ (const_string "fdiv")
+ ]
+ (const_string "fop")))
+ (set_attr "fp_int_src" "true")
+ (set_attr "mode" "SI")
+ (set_attr "ppro_uops" "many")])
+
(define_insn "*fop_xf_4"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
(const_string "fop")))
(set_attr "mode" "SF")])
+(define_insn "*fop_tf_4"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (match_operator:TF 3 "binary_fp_operator"
+ [(float_extend:TF (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
+ (match_operand:TF 2 "register_operand" "0,f")]))]
+ "TARGET_80387"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:TF 3 "mult_operator" "")
+ (const_string "fmul")
+ (match_operand:TF 3 "div_operator" "")
+ (const_string "fdiv")
+ ]
+ (const_string "fop")))
+ (set_attr "mode" "SF")])
+
(define_insn "*fop_xf_5"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
(const_string "fop")))
(set_attr "mode" "SF")])
+(define_insn "*fop_tf_5"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (match_operator:TF 3 "binary_fp_operator"
+ [(match_operand:TF 1 "register_operand" "0,f")
+ (float_extend:TF
+ (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
+ "TARGET_80387"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:TF 3 "mult_operator" "")
+ (const_string "fmul")
+ (match_operand:TF 3 "div_operator" "")
+ (const_string "fdiv")
+ ]
+ (const_string "fop")))
+ (set_attr "mode" "SF")])
+
(define_insn "*fop_xf_6"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
(const_string "fop")))
(set_attr "mode" "DF")])
+(define_insn "*fop_tf_6"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (match_operator:TF 3 "binary_fp_operator"
+ [(float_extend:TF (match_operand:DF 1 "nonimmediate_operand" "fm,0"))
+ (match_operand:TF 2 "register_operand" "0,f")]))]
+ "TARGET_80387"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:TF 3 "mult_operator" "")
+ (const_string "fmul")
+ (match_operand:TF 3 "div_operator" "")
+ (const_string "fdiv")
+ ]
+ (const_string "fop")))
+ (set_attr "mode" "DF")])
+
(define_insn "*fop_xf_7"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(match_operator:XF 3 "binary_fp_operator"
(const_string "fop")))
(set_attr "mode" "DF")])
+(define_insn "*fop_tf_7"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (match_operator:TF 3 "binary_fp_operator"
+ [(match_operand:TF 1 "register_operand" "0,f")
+ (float_extend:TF
+ (match_operand:DF 2 "nonimmediate_operand" "fm,0"))]))]
+ "TARGET_80387"
+ "* return output_387_binary_op (insn, operands);"
+ [(set (attr "type")
+ (cond [(match_operand:TF 3 "mult_operator" "")
+ (const_string "fmul")
+ (match_operand:TF 3 "div_operator" "")
+ (const_string "fdiv")
+ ]
+ (const_string "fop")))
+ (set_attr "mode" "DF")])
+
(define_split
[(set (match_operand 0 "register_operand" "")
(match_operator 3 "binary_fp_operator"
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")])
+(define_insn "sqrttf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (sqrt:TF (match_operand:TF 1 "register_operand" "0")))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387
+ && (TARGET_IEEE_FP || flag_fast_math) "
+ "fsqrt"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")
+ (set_attr "athlon_decode" "direct")])
+
(define_insn "*sqrtextenddfxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(sqrt:XF (float_extend:XF
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")])
+(define_insn "*sqrtextenddftf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (sqrt:TF (float_extend:TF
+ (match_operand:DF 1 "register_operand" "0"))))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
+ "fsqrt"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")
+ (set_attr "athlon_decode" "direct")])
+
(define_insn "*sqrtextendsfxf2"
[(set (match_operand:XF 0 "register_operand" "=f")
(sqrt:XF (float_extend:XF
(set_attr "mode" "XF")
(set_attr "athlon_decode" "direct")])
+(define_insn "*sqrtextendsftf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (sqrt:TF (float_extend:TF
+ (match_operand:SF 1 "register_operand" "0"))))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387"
+ "fsqrt"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")
+ (set_attr "athlon_decode" "direct")])
+
(define_insn "sindf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 1))]
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
+(define_insn "sintf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 1))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
+ "fsin"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
+
(define_insn "cosdf2"
[(set (match_operand:DF 0 "register_operand" "=f")
(unspec:DF [(match_operand:DF 1 "register_operand" "0")] 2))]
"fcos"
[(set_attr "type" "fpspc")
(set_attr "mode" "XF")])
+
+(define_insn "costf2"
+ [(set (match_operand:TF 0 "register_operand" "=f")
+ (unspec:TF [(match_operand:TF 1 "register_operand" "0")] 2))]
+ "! TARGET_NO_FANCY_MATH_387 && TARGET_80387 && flag_fast_math"
+ "fcos"
+ [(set_attr "type" "fpspc")
+ (set_attr "mode" "XF")])
\f
;; Block operation instructions
"TARGET_CMOVE"
"if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
+(define_expand "movtfcc"
+ [(set (match_operand:TF 0 "register_operand" "")
+ (if_then_else:TF (match_operand 1 "comparison_operator" "")
+ (match_operand:TF 2 "register_operand" "")
+ (match_operand:TF 3 "register_operand" "")))]
+ "TARGET_CMOVE"
+ "if (! ix86_expand_fp_movcc (operands)) FAIL; DONE;")
+
(define_insn "*movxfcc_1"
[(set (match_operand:XF 0 "register_operand" "=f,f")
(if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
fcmov%f1\\t{%3, %0|%0, %3}"
[(set_attr "type" "fcmov")
(set_attr "mode" "XF")])
+
+(define_insn "*movtfcc_1"
+ [(set (match_operand:TF 0 "register_operand" "=f,f")
+ (if_then_else:TF (match_operator 1 "fcmov_comparison_operator"
+ [(reg 17) (const_int 0)])
+ (match_operand:TF 2 "register_operand" "f,0")
+ (match_operand:TF 3 "register_operand" "0,f")))]
+ "TARGET_CMOVE"
+ "@
+ fcmov%F1\\t{%2, %0|%0, %2}
+ fcmov%f1\\t{%3, %0|%0, %3}"
+ [(set_attr "type" "fcmov")
+ (set_attr "mode" "XF")])
\f
;; Misc patterns (?)