")
(define_insn "*truncdfsf2_1"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
(float_truncate:SF
- (match_operand:DF 1 "register_operand" "f,0")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
+ (match_operand:DF 1 "register_operand" "f,f,f,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
"TARGET_80387 && !TARGET_SSE2"
"*
{
return \"fstp%z0\\t%y0\";
else
return \"fst%z0\\t%y0\";
- case 1:
- return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
+ default:
+ abort ();
}
- abort ();
}"
- [(set_attr "type" "fmov,multi")
- (set_attr "mode" "SF,SF")])
+ [(set_attr "type" "fmov,multi,multi,multi")
+ (set_attr "mode" "SF,SF,SF,SF")])
(define_insn "*truncdfsf2_1_sse"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f,Y")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=*!m,?f#rx,?r#fx,?x#rf,Y")
(float_truncate:SF
- (match_operand:DF 1 "nonimmediate_operand" "f,0,mY")))
- (clobber (match_operand:SF 2 "memory_operand" "=X,m,X"))]
+ (match_operand:DF 1 "nonimmediate_operand" "f,f,f,f,mY")))
+ (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m,X"))]
"TARGET_80387 && TARGET_SSE2"
"*
{
return \"fstp%z0\\t%y0\";
else
return \"fst%z0\\t%y0\";
- case 1:
- return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
- case 2:
- case 3:
+ case 4:
return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
+ default:
+ abort ();
}
- abort ();
}"
- [(set_attr "type" "fmov,multi,sse")
- (set_attr "mode" "SF,SF,DF")])
+ [(set_attr "type" "fmov,multi,multi,multi,sse")
+ (set_attr "mode" "SF,SF,SF,SF,DF")])
(define_insn "*truncdfsf2_2"
[(set (match_operand:SF 0 "nonimmediate_operand" "=Y,!m")
(match_operand:DF 1 "register_operand" "")))
(clobber (match_operand:SF 2 "memory_operand" ""))]
"TARGET_80387 && reload_completed
- && FP_REG_P (operands[0])"
+ && FP_REG_P (operands[1])"
[(set (match_dup 2) (float_truncate:SF (match_dup 1)))
(set (match_dup 0) (match_dup 2))]
"")
"operands[2] = assign_386_stack_local (SFmode, 0);")
(define_insn "*truncxfsf2_1"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
(float_truncate:SF
- (match_operand:XF 1 "register_operand" "f,0")))
- (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
+ (match_operand:XF 1 "register_operand" "f,f,f,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
"TARGET_80387 && !TARGET_64BIT"
"*
{
return \"fstp%z0\\t%y0\";
else
return \"fst%z0\\t%y0\";
- case 1:
- return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
+ default:
+ abort();
}
- abort ();
}"
- [(set_attr "type" "fmov,multi")
+ [(set_attr "type" "fmov,multi,multi,multi")
(set_attr "mode" "SF")])
(define_insn "*truncxfsf2_2"
"operands[2] = assign_386_stack_local (SFmode, 0);")
(define_insn "*trunctfsf2_1"
- [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f#rx,?r#fx,?x#rf")
(float_truncate:SF
- (match_operand:TF 1 "register_operand" "f,0")))
- (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
+ (match_operand:TF 1 "register_operand" "f,f,f,f")))
+ (clobber (match_operand:SF 2 "memory_operand" "=X,m,m,m"))]
"TARGET_80387"
"*
{
return \"fstp%z0\\t%y0\";
else
return \"fst%z0\\t%y0\";
- case 1:
- return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
+ default:
+ abort();
}
- abort ();
}"
- [(set_attr "type" "fmov,multi")
+ [(set_attr "type" "fmov,multi,multi,multi")
(set_attr "mode" "SF")])
(define_insn "*trunctfsf2_2"
"operands[2] = assign_386_stack_local (DFmode, 0);")
(define_insn "*truncxfdf2_1"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
(float_truncate:DF
- (match_operand:XF 1 "register_operand" "f,0")))
- (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
+ (match_operand:XF 1 "register_operand" "f,f,f,f")))
+ (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
"TARGET_80387 && !TARGET_64BIT"
"*
{
return \"fstp%z0\\t%y0\";
else
return \"fst%z0\\t%y0\";
- case 1:
- return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
+ default:
+ abort();
}
abort ();
}"
- [(set_attr "type" "fmov,multi")
+ [(set_attr "type" "fmov,multi,multi,multi")
(set_attr "mode" "DF")])
(define_insn "*truncxfdf2_2"
"operands[2] = assign_386_stack_local (DFmode, 0);")
(define_insn "*trunctfdf2_1"
- [(set (match_operand:DF 0 "nonimmediate_operand" "=m,f")
+ [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f#rY,?r#fY,?Y#rf")
(float_truncate:DF
- (match_operand:TF 1 "register_operand" "f,0")))
- (clobber (match_operand:DF 2 "memory_operand" "=m,m"))]
+ (match_operand:TF 1 "register_operand" "f,f,f,f")))
+ (clobber (match_operand:DF 2 "memory_operand" "=X,m,m,m"))]
"TARGET_80387"
"*
{
return \"fstp%z0\\t%y0\";
else
return \"fst%z0\\t%y0\";
- case 1:
- return \"fstp%z2\\t%y2\;fld%z2\\t%y2\";
+ default:
+ abort();
}
abort ();
}"
- [(set_attr "type" "fmov,multi")
+ [(set_attr "type" "fmov,multi,multi,multi")
(set_attr "mode" "DF")])
-(define_insn "*trunctfdf2_2"
+ (define_insn "*trunctfdf2_2"
[(set (match_operand:DF 0 "memory_operand" "=m")
(float_truncate:DF
(match_operand:TF 1 "register_operand" "f")))]
(clobber (match_dup 3))
(clobber (match_scratch:SI 4 ""))
(clobber (match_scratch:DF 5 ""))])]
- "TARGET_80387"
- "operands[2] = assign_386_stack_local (SImode, 0);
- operands[3] = assign_386_stack_local (DImode, 1);")
+ "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
+ "
+{
+ if (TARGET_SSE2)
+ {
+ rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
+ emit_insn (gen_fix_truncdfdi_sse (out, operands[1]));
+ if (out != operands[0])
+ emit_move_insn (operands[0], out);
+ DONE;
+ }
+ else
+ {
+ operands[2] = assign_386_stack_local (SImode, 0);
+ operands[3] = assign_386_stack_local (DImode, 1);
+ }
+}")
(define_expand "fix_truncsfdi2"
[(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
(clobber (match_dup 3))
(clobber (match_scratch:SI 4 ""))
(clobber (match_scratch:SF 5 ""))])]
- "TARGET_80387"
- "operands[2] = assign_386_stack_local (SImode, 0);
- operands[3] = assign_386_stack_local (DImode, 1);")
+ "TARGET_80387 || (TARGET_SSE && TARGET_64BIT)"
+ "
+{
+ if (TARGET_SSE2)
+ {
+ rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
+ emit_insn (gen_fix_truncsfdi_sse (out, operands[1]));
+ if (out != operands[0])
+ emit_move_insn (operands[0], out);
+ DONE;
+ }
+ else
+ {
+ operands[2] = assign_386_stack_local (SImode, 0);
+ operands[3] = assign_386_stack_local (DImode, 1);
+ }
+}")
(define_insn "*fix_truncdi_1"
[(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
(clobber (match_operand:DI 3 "memory_operand" "=m,m"))
(clobber (match_scratch:SI 4 "=&r,&r"))
(clobber (match_scratch 5 "=&f,&f"))]
- "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
+ "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && (!TARGET_SSE2 || !TARGET_64BIT
+ || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
"* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")])
(set (match_dup 0) (match_dup 3))]
"")
+;; When SSE available, it is always faster to use it!
+(define_insn "fix_truncsfdi_sse"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (fix:DI (match_operand:SF 1 "nonimmediate_operand" "xm")))]
+ "TARGET_SSE && TARGET_64BIT"
+ "cvttss2si{q}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sse")])
+
+(define_insn "fix_truncdfdi_sse"
+ [(set (match_operand:DI 0 "register_operand" "=r")
+ (fix:DI (match_operand:DF 1 "nonimmediate_operand" "Ym")))]
+ "TARGET_SSE2 && TARGET_64BIT"
+ "cvttsd2si{q}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sse")])
+
;; Signed conversion to SImode.
(define_expand "fix_truncxfsi2"
if (TARGET_SSE2)
{
rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
- emit_insn (gen_fix_truncdfsi_sse (out, operands[1]));
+ emit_insn (gen_fix_truncsfsi_sse (out, operands[1]));
if (out != operands[0])
emit_move_insn (operands[0], out);
DONE;
(define_insn "*floatsisf2_sse"
[(set (match_operand:SF 0 "register_operand" "=x")
(float:SF (match_operand:SI 1 "nonimmediate_operand" "mr")))]
- "TARGET_80387 && TARGET_SSE"
+ "TARGET_SSE"
"cvtsi2ss\\t{%1, %0|%0, %1}"
[(set_attr "type" "sse")
(set_attr "mode" "SF")
(set_attr "fp_int_src" "true")])
-(define_insn "floatdisf2"
- [(set (match_operand:SF 0 "register_operand" "=f,f")
- (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
- "TARGET_80387"
+(define_expand "floatdisf2"
+ [(set (match_operand:SF 0 "register_operand" "")
+ (float:SF (match_operand:DI 1 "nonimmediate_operand" "")))]
+ "(TARGET_SSE && TARGET_64BIT) || TARGET_80387"
+ "")
+
+(define_insn "*floatdisf2_i387"
+ [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
+ (float:SF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
+ "TARGET_80387 && (!TARGET_SSE || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
"@
fild%z1\\t%1
- #"
- [(set_attr "type" "fmov,multi")
+ #
+ cvtsi2ss{q}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "fmov,multi,sse")
+ (set_attr "mode" "SF")
+ (set_attr "fp_int_src" "true")])
+
+(define_insn "*floatdisf2_sse"
+ [(set (match_operand:SF 0 "register_operand" "=x")
+ (float:SF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
+ "TARGET_SSE && TARGET_64BIT"
+ "cvtsi2ss{q}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sse")
(set_attr "mode" "SF")
(set_attr "fp_int_src" "true")])
(set_attr "mode" "DF")
(set_attr "fp_int_src" "true")])
-(define_insn "floatdidf2"
- [(set (match_operand:DF 0 "register_operand" "=f,f")
- (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r")))]
- "TARGET_80387 && TARGET_SSE2"
+(define_expand "floatdidf2"
+ [(set (match_operand:DF 0 "register_operand" "")
+ (float:DF (match_operand:DI 1 "nonimmediate_operand" "")))]
+ "TARGET_80387 || (TARGET_SSE2 && TARGET_64BIT)"
+ "")
+
+(define_insn "*floatdidf2_i387"
+ [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
+ (float:DF (match_operand:DI 1 "nonimmediate_operand" "m,r,mr")))]
+ "TARGET_80387 && (!TARGET_SSE2 || !TARGET_64BIT || TARGET_MIX_SSE_I387)"
"@
fild%z1\\t%1
- #"
- [(set_attr "type" "fmov,multi")
+ #
+ cvtsi2sd{q}\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "fmov,multi,sse")
+ (set_attr "mode" "DF")
+ (set_attr "fp_int_src" "true")])
+
+(define_insn "*floatdidf2_sse"
+ [(set (match_operand:DF 0 "register_operand" "=Y")
+ (float:DF (match_operand:DI 1 "nonimmediate_operand" "mr")))]
+ "TARGET_SSE2"
+ "cvtsi2sd\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sse")
(set_attr "mode" "DF")
(set_attr "fp_int_src" "true")])