;; Conversion from DFmode to SFmode.
-(define_expand "truncdfsf2"
- [(set (match_operand:SF 0 "nonimmediate_operand")
+(define_insn "truncdfsf2"
+ [(set (match_operand:SF 0 "nonimm_ssenomem_operand" "=m,f,v")
(float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand")))]
+ (match_operand:DF 1 "register_ssemem_operand" "f,f,vm")))]
"TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
{
- if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
- ;
- else if (flag_unsafe_math_optimizations)
- ;
- else
+ switch (which_alternative)
{
- rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
- emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
- DONE;
+ case 0:
+ case 1:
+ return output_387_reg_move (insn, operands);
+
+ case 2:
+ return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
+
+ default:
+ gcc_unreachable ();
}
-})
+}
+ [(set_attr "type" "fmov,fmov,ssecvt")
+ (set_attr "mode" "SF")
+ (set (attr "enabled")
+ (if_then_else
+ (match_test ("TARGET_SSE2 && TARGET_SSE_MATH"))
+ (cond [(eq_attr "alternative" "0")
+ (symbol_ref "TARGET_MIX_SSE_I387")
+ (eq_attr "alternative" "1")
+ (symbol_ref "TARGET_MIX_SSE_I387
+ && flag_unsafe_math_optimizations")
+ ]
+ (symbol_ref "true"))
+ (cond [(eq_attr "alternative" "0")
+ (symbol_ref "true")
+ (eq_attr "alternative" "1")
+ (symbol_ref "flag_unsafe_math_optimizations")
+ ]
+ (symbol_ref "false"))))])
/* For converting DF(xmm2) to SF(xmm1), use the following code instead of
cvtsd2ss:
anyway. */
(define_split
[(set (match_operand:SF 0 "sse_reg_operand")
- (float_truncate:SF
+ (float_truncate:SF
(match_operand:DF 1 "nonimmediate_operand")))]
"TARGET_USE_VECTOR_FP_CONVERTS
&& optimize_insn_for_speed_p ()
CONST0_RTX (DFmode)));
})
-;; It's more profitable to split and then extend in the same register.
+;; It's more profitable to split and then truncate in the same register.
(define_peephole2
[(set (match_operand:SF 0 "sse_reg_operand")
(float_truncate:SF
(set (match_dup 0) (float_truncate:SF (match_dup 2)))]
"operands[2] = lowpart_subreg (DFmode, operands[0], SFmode);")
-(define_expand "truncdfsf2_with_temp"
- [(parallel [(set (match_operand:SF 0)
- (float_truncate:SF (match_operand:DF 1)))
- (clobber (match_operand:SF 2))])])
-
-;; SSE alternative doesn't depend on flag_unsafe_math_optimizations,
-;; because nothing we do there is unsafe.
-(define_insn "*truncdfsf_fast_mixed"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,v")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f ,vm")))]
- "TARGET_SSE2 && TARGET_SSE_MATH"
-{
- switch (which_alternative)
- {
- case 0:
- return output_387_reg_move (insn, operands);
- case 1:
- return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
- default:
- gcc_unreachable ();
- }
-}
- [(set_attr "type" "fmov,ssecvt")
- (set_attr "prefix" "orig,maybe_vex")
- (set_attr "mode" "SF")
- (set (attr "enabled")
- (cond [(eq_attr "alternative" "0")
- (symbol_ref "TARGET_MIX_SSE_I387
- && flag_unsafe_math_optimizations")
- ]
- (symbol_ref "true")))])
-
-(define_insn "*truncdfsf_fast_i387"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f")))]
- "TARGET_80387 && flag_unsafe_math_optimizations"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf_mixed"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,v ,?f,?v,?*r")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f ,vm,f ,f ,f")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
- "TARGET_MIX_SSE_I387"
-{
- switch (which_alternative)
- {
- case 0:
- return output_387_reg_move (insn, operands);
- case 1:
- return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
-
- default:
- return "#";
- }
-}
- [(set_attr "isa" "*,sse2,*,*,*")
- (set_attr "type" "fmov,ssecvt,multi,multi,multi")
- (set_attr "unit" "*,*,i387,i387,i387")
- (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf_i387"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
- (float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
- "TARGET_80387"
-{
- switch (which_alternative)
- {
- case 0:
- return output_387_reg_move (insn, operands);
-
- default:
- return "#";
- }
-}
- [(set_attr "type" "fmov,multi,multi,multi")
- (set_attr "unit" "*,i387,i387,i387")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncdfsf2_i387_1"
- [(set (match_operand:SF 0 "memory_operand" "=m")
- (float_truncate:SF
- (match_operand:DF 1 "register_operand" "f")))]
- "TARGET_80387
- && !(TARGET_SSE2 && TARGET_SSE_MATH)
- && !TARGET_MIX_SSE_I387"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "SF")])
-
-(define_split
- [(set (match_operand:SF 0 "register_operand")
- (float_truncate:SF
- (match_operand:DF 1 "fp_register_operand")))
- (clobber (match_operand 2))]
- "reload_completed"
- [(set (match_dup 2) (match_dup 1))
- (set (match_dup 0) (match_dup 2))]
- "operands[1] = gen_rtx_REG (SFmode, REGNO (operands[1]));")
-
;; Conversion from XFmode to {SF,DF}mode
-(define_expand "truncxf<mode>2"
- [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand")))
- (clobber (match_dup 2))])]
- "TARGET_80387"
-{
- if (flag_unsafe_math_optimizations)
- {
- rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
- emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
- if (reg != operands[0])
- emit_move_insn (operands[0], reg);
- DONE;
- }
- else
- operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
-})
-
-(define_insn "*truncxfsf2_mixed"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
- (float_truncate:SF
- (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
- "TARGET_80387"
-{
- gcc_assert (!which_alternative);
- return output_387_reg_move (insn, operands);
-}
- [(set_attr "type" "fmov,multi,multi,multi")
- (set_attr "unit" "*,i387,i387,i387")
- (set_attr "mode" "SF")])
-
-(define_insn "*truncxfdf2_mixed"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?v,?*r")
- (float_truncate:DF
- (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
- (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
- "TARGET_80387"
-{
- gcc_assert (!which_alternative);
- return output_387_reg_move (insn, operands);
-}
- [(set_attr "isa" "*,*,sse2,*")
- (set_attr "type" "fmov,multi,multi,multi")
- (set_attr "unit" "*,i387,i387,i387")
- (set_attr "mode" "DF")])
-
-(define_insn "truncxf<mode>2_i387_noop"
- [(set (match_operand:MODEF 0 "register_operand" "=f")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand" "f")))]
- "TARGET_80387 && flag_unsafe_math_optimizations"
- "* return output_387_reg_move (insn, operands);"
- [(set_attr "type" "fmov")
- (set_attr "mode" "<MODE>")])
-
-(define_insn "*truncxf<mode>2_i387"
- [(set (match_operand:MODEF 0 "memory_operand" "=m")
+(define_insn "truncxf<mode>2"
+ [(set (match_operand:MODEF 0 "nonimmediate_operand" "=m,f")
(float_truncate:MODEF
- (match_operand:XF 1 "register_operand" "f")))]
+ (match_operand:XF 1 "register_operand" "f,f")))]
"TARGET_80387"
"* return output_387_reg_move (insn, operands);"
[(set_attr "type" "fmov")
- (set_attr "mode" "<MODE>")])
-
-(define_split
- [(set (match_operand:MODEF 0 "register_operand")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand")))
- (clobber (match_operand:MODEF 2 "memory_operand"))]
- "TARGET_80387 && reload_completed"
- [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
- (set (match_dup 0) (match_dup 2))])
-
-(define_split
- [(set (match_operand:MODEF 0 "memory_operand")
- (float_truncate:MODEF
- (match_operand:XF 1 "register_operand")))
- (clobber (match_operand:MODEF 2 "memory_operand"))]
- "TARGET_80387"
- [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
+ (set_attr "mode" "<MODE>")
+ (set (attr "enabled")
+ (cond [(eq_attr "alternative" "1")
+ (symbol_ref "flag_unsafe_math_optimizations")
+ ]
+ (symbol_ref "true")))])
\f
;; Signed conversion to DImode.
rtx op1 = gen_reg_rtx (XFmode);
emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[1], op1));
DONE;
})
emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
operands[1], op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
rtx op0 = gen_reg_rtx (XFmode);
emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_asinxf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_acosxf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
ix86_emit_i387_log1p (op0, operands[1]);
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
rtx op1 = gen_reg_rtx (XFmode);
emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op1));
DONE;
})
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_expxf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_exp10xf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_exp2xf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_expm1xf2 (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
emit_insn (gen_scalbxf3 (op0, op1, op2));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
rtx op1 = gen_reg_rtx (XFmode);
emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})
\f
emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
emit_insn (gen_frndintxf2_mask_pm (op0, op1));
- emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
+ emit_insn (gen_truncxf<mode>2 (operands[0], op0));
DONE;
})