SSE converison patterns
Jan Hubicka
jh@suse.cz
Mon Feb 12 14:27:00 GMT 2001
Hi
This patch adds SSE converison instructions. The truncation is always
preferable using SSE, otherwise it just adds extra alternatives, since
both units can handle these well.
Mon Feb 12 16:36:27 CET 2001 Jan Hubicka <jh@suse.cz>
* i386.md (dummy_extendsfdf2): Support SSE2
(extendsfdf2): Enable if 80387 or SSE2.
(extendsfdf2_1): Support SSE2. Disable if SSE2 is avialble
and no MIX_I387_SSE2
(extendsfdf2_1_sse_only): New pattern.
(truncdfsf2): Enable if SSE2 or 80387; Always use SSE only version
of SSE.
(truncdfsf2_1): Support SSE.
(truncdfsf2_2): Support SSE.
(truncdfsf2_2_1_sse): New pattern.
(fixtruncsfsi2): Always use SSE if available.
(fix_truncsfsi_sse): New pattern.
(fix_truncdfsi_sse): New pattern.
(floatsis?f2): Support SSE.
(floatsidf2_i387): New pattern.
(floatsidf2_sse): Likewise.
Index: i386.md
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/i386/i386.md,v
retrieving revision 1.204
diff -c -3 -p -r1.204 i386.md
*** i386.md 2001/01/29 18:31:35 1.204
--- i386.md 2001/02/12 22:18:45
***************
*** 3226,3232 ****
;; %%% Kill these when call knows how to work out a DFmode push earlier.
(define_insn "*dummy_extendsfdf2"
[(set (match_operand:DF 0 "push_operand" "=<")
! (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "f")))]
"0"
"#")
--- 3292,3298 ----
;; %%% Kill these when call knows how to work out a DFmode push earlier.
(define_insn "*dummy_extendsfdf2"
[(set (match_operand:DF 0 "push_operand" "=<")
! (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))]
"0"
"#")
***************
*** 3292,3298 ****
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
! "TARGET_80387"
"
{
if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
--- 3358,3364 ----
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "nonimmediate_operand" "")
(float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))]
! "TARGET_80387 || TARGET_SSE2"
"
{
if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM)
***************
*** 3300,3308 ****
}")
(define_insn "*extendsfdf2_1"
! [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
! (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
! "TARGET_80387
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"*
{
--- 3366,3374 ----
}")
(define_insn "*extendsfdf2_1"
! [(set (match_operand:DF 0 "nonimmediate_operand" "=f#Y,mf#Y,Y#f,Ym#f")
! (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm#Y,f#Y,mY#f,Y#f")))]
! "(TARGET_80387 || TARGET_SSE2)
&& (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
"*
{
***************
*** 3323,3335 ****
else
return \"fst%z0\\t%y0\";
default:
abort ();
}
}"
! [(set_attr "type" "fmov")
! (set_attr "mode" "SF,XF")])
(define_expand "extendsfxf2"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
--- 3389,3413 ----
else
return \"fst%z0\\t%y0\";
+ case 2:
+ case 3:
+ return \"cvtss2sd\\t{%1, %0|%0, %1}\";
default:
abort ();
}
}"
! [(set_attr "type" "fmov,fmov,sse,sse")
! (set_attr "mode" "SF,XF,DF,DF")])
!
! (define_insn "*extendsfdf2_1_sse_only"
! [(set (match_operand:DF 0 "nonimmediate_operand" "=Y,Ym")
! (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY,Y")))]
! "!TARGET_80387 && TARGET_SSE2
! && (GET_CODE (operands[0]) != MEM || GET_CODE (operands[1]) != MEM)"
! "cvtss2sd\\t{%1, %0|%0, %1}"
! [(set_attr "type" "sse")
! (set_attr "mode" "DF")])
(define_expand "extendsfxf2"
[(set (match_operand:XF 0 "nonimmediate_operand" "")
***************
*** 3514,3528 ****
(float_truncate:SF
(match_operand:DF 1 "register_operand" "")))
(clobber (match_dup 2))])]
! "TARGET_80387"
! "operands[2] = assign_386_stack_local (SFmode, 0);")
(define_insn "*truncdfsf2_1"
! [(set (match_operand:SF 0 "nonimmediate_operand" "=m,f")
(float_truncate:SF
(match_operand:DF 1 "register_operand" "f,0")))
! (clobber (match_operand:SF 2 "memory_operand" "=m,m"))]
! "TARGET_80387"
"*
{
switch (which_alternative)
--- 3592,3614 ----
(float_truncate:SF
(match_operand:DF 1 "register_operand" "")))
(clobber (match_dup 2))])]
! "TARGET_80387 || TARGET_SSE2"
! "
! if (TARGET_80387)
! operands[2] = assign_386_stack_local (SFmode, 0);
! else
! {
! emit_insn (gen_truncdfsf2_sse_only (operands[0], operands[1]));
! DONE;
! }
! ")
(define_insn "*truncdfsf2_1"
! [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f")
(float_truncate:SF
(match_operand:DF 1 "register_operand" "f,0")))
! (clobber (match_operand:SF 2 "memory_operand" "=X,m"))]
! "TARGET_80387 && !TARGET_SSE2"
"*
{
switch (which_alternative)
***************
*** 3538,3548 ****
abort ();
}"
[(set_attr "type" "fmov,multi")
! (set_attr "mode" "SF")])
(define_insn "*truncdfsf2_2"
! [(set (match_operand:SF 0 "memory_operand" "=m")
(float_truncate:SF
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_80387"
"*
--- 3624,3682 ----
abort ();
}"
[(set_attr "type" "fmov,multi")
! (set_attr "mode" "SF,SF")])
!
! (define_insn "*truncdfsf2_1_sse"
! [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,Y")
! (float_truncate:SF
! (match_operand:DF 1 "nonimmediate_operand" "f,0,mY")))
! (clobber (match_operand:SF 2 "memory_operand" "=X,m,X"))]
! "TARGET_80387 && TARGET_SSE2"
! "*
! {
! 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\";
! case 2:
! case 3:
! return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
! }
! abort ();
! }"
! [(set_attr "type" "fmov,multi,sse")
! (set_attr "mode" "SF,SF,DF")])
(define_insn "*truncdfsf2_2"
! [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y")
(float_truncate:SF
+ (match_operand:DF 1 "nonimmediate_operand" "f,mY")))]
+ "TARGET_80387 && TARGET_SSE2"
+ "*
+ {
+ 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:
+ case 2:
+ return \"cvtsd2ss\\t{%1, %0|%0, %1}\";
+ }
+ }"
+ [(set_attr "type" "fmov,sse")
+ (set_attr "mode" "SF,DF")])
+
+ (define_insn "truncdfsf2_3"
+ [(set (match_operand:SF 0 "nonimmediate_operand" "=m")
+ (float_truncate:SF
(match_operand:DF 1 "register_operand" "f")))]
"TARGET_80387"
"*
***************
*** 3555,3560 ****
--- 3689,3703 ----
[(set_attr "type" "fmov")
(set_attr "mode" "SF")])
+ (define_insn "truncdfsf2_sse_only"
+ [(set (match_operand:SF 0 "register_operand" "=Y")
+ (float_truncate:SF
+ (match_operand:DF 1 "nonimmediate_operand" "mY")))]
+ "!TARGET_80387 && TARGET_SSE2"
+ "cvtsd2ss\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sse")
+ (set_attr "mode" "DF")])
+
(define_split
[(set (match_operand:SF 0 "memory_operand" "")
(float_truncate:SF
***************
*** 3565,3575 ****
"")
(define_split
[(set (match_operand:SF 0 "register_operand" "")
(float_truncate:SF
(match_operand:DF 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))]
"")
--- 3708,3728 ----
"")
(define_split
+ [(set (match_operand:SF 0 "nonimmediate_operand" "")
+ (float_truncate:SF
+ (match_operand:DF 1 "nonimmediate_operand" "")))
+ (clobber (match_operand 2 "" ""))]
+ "TARGET_80387 && !FP_REG_P (operands[0]) && !FP_REG_P (operands[1])"
+ [(set (match_dup 0) (float_truncate:SF (match_dup 1)))]
+ "")
+
+ (define_split
[(set (match_operand:SF 0 "register_operand" "")
(float_truncate:SF
(match_operand:DF 1 "register_operand" "")))
(clobber (match_operand:SF 2 "memory_operand" ""))]
! "TARGET_80387 && reload_completed
! && FP_REG_P (operands[0])"
[(set (match_dup 2) (float_truncate:SF (match_dup 1)))
(set (match_dup 0) (match_dup 2))]
"")
***************
*** 3939,3947 ****
(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_truncsfsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
--- 4092,4111 ----
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_scratch:SI 4 ""))])]
! "TARGET_80387 || TARGET_SSE2"
! "
! {
! if (TARGET_SSE2)
! {
! emit_insn (gen_fix_truncdfsi_sse (operands[0], operands[1]));
! DONE;
! }
! else
! {
! operands[2] = assign_386_stack_local (SImode, 0);
! operands[3] = assign_386_stack_local (SImode, 1);
! }
! }")
(define_expand "fix_truncsfsi2"
[(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
***************
*** 3949,3957 ****
(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_insn "*fix_truncsi_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
--- 4113,4132 ----
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_scratch:SI 4 ""))])]
! "TARGET_80387 || TARGET_SSE"
! "
! {
! if (TARGET_SSE2)
! {
! emit_insn (gen_fix_truncsfsi_sse (operands[0], operands[1]));
! DONE;
! }
! else
! {
! operands[2] = assign_386_stack_local (SImode, 0);
! operands[3] = assign_386_stack_local (SImode, 1);
! }
! }")
(define_insn "*fix_truncsi_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=m,?r")
***************
*** 3959,3968 ****
(clobber (match_operand:SI 2 "memory_operand" "=o,o"))
(clobber (match_operand:SI 3 "memory_operand" "=m,m"))
(clobber (match_scratch:SI 4 "=&r,r"))]
! "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
"* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")])
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand 1 "register_operand" "")))
--- 4134,4159 ----
(clobber (match_operand:SI 2 "memory_operand" "=o,o"))
(clobber (match_operand:SI 3 "memory_operand" "=m,m"))
(clobber (match_scratch:SI 4 "=&r,r"))]
! "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
! && (!TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
"* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")])
+ ;; When SSE available, it is always faster to use it!
+ (define_insn "fix_truncsfsi_sse"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
+ (fix:SI (match_operand:SF 1 "register_operand" "xm")))]
+ "TARGET_SSE"
+ "cvttss2si\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sse")])
+
+ (define_insn "fix_truncdfsi_sse"
+ [(set (match_operand:SI 0 "nonimmediate_operand" "=r")
+ (fix:SI (match_operand:DF 1 "register_operand" "Ym")))]
+ "TARGET_SSE2"
+ "cvttsd2si\\t{%1, %0|%0, %1}"
+ [(set_attr "type" "sse")])
+
(define_split
[(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand 1 "register_operand" "")))
***************
*** 4005,4011 ****
(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);")
--- 4196,4202 ----
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_scratch:SI 4 ""))])]
! "TARGET_80387 && !TARGET_SSE2"
"operands[2] = assign_386_stack_local (SImode, 0);
operands[3] = assign_386_stack_local (HImode, 1);")
***************
*** 4015,4021 ****
(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);")
--- 4206,4212 ----
(clobber (match_dup 2))
(clobber (match_dup 3))
(clobber (match_scratch:SI 4 ""))])]
! "TARGET_80387 && !TARGET_SSE"
"operands[2] = assign_386_stack_local (SImode, 0);
operands[3] = assign_386_stack_local (HImode, 1);")
***************
*** 4025,4031 ****
(clobber (match_operand:SI 2 "memory_operand" "=o,o"))
(clobber (match_operand:HI 3 "memory_operand" "=m,m"))
(clobber (match_scratch:SI 4 "=&r,r"))]
! "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))"
"* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")])
--- 4216,4223 ----
(clobber (match_operand:SI 2 "memory_operand" "=o,o"))
(clobber (match_operand:HI 3 "memory_operand" "=m,m"))
(clobber (match_scratch:SI 4 "=&r,r"))]
! "TARGET_80387 && FLOAT_MODE_P (GET_MODE (operands[1]))
! && (TARGET_SSE2 || !SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
"* return output_fix_trunc (insn, operands);"
[(set_attr "type" "multi")])
***************
*** 4043,4048 ****
--- 4235,4257 ----
(set (match_dup 0) (match_dup 3))]
"")
+ ;; %%% Kill these when reload knows how to do it.
+ (define_split
+ [(set (match_operand 0 "register_operand" "")
+ (fix (match_operand 1 "register_operand" "")))]
+ "reload_completed && FLOAT_MODE_P (GET_MODE (operands[1]))
+ && FP_REG_P (operands[1])"
+ [(const_int 0)]
+ "
+ {
+ operands[2] = ix86_force_to_memory (GET_MODE (operands[0]), operands[0]);
+ operands[2] = gen_rtx_FIX (GET_MODE (operands[2]), operands[1]);
+ emit_insn (gen_rtx_SET (VOIDmode, operands[2], operands[1]));
+ emit_move_insn (operands[0], operands[2]);
+ ix86_free_from_memory (GET_MODE (operands[0]));
+ DONE;
+ }")
+
;; %% Not used yet.
(define_insn "x86_fnstcw_1"
[(set (match_operand:HI 0 "memory_operand" "=m")
***************
*** 4073,4079 ****
(define_insn "floathisf2"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
! "TARGET_80387"
"@
fild%z1\\t%1
#"
--- 4282,4288 ----
(define_insn "floathisf2"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(float:SF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
! "TARGET_80387 && !TARGET_SSE"
"@
fild%z1\\t%1
#"
***************
*** 4081,4094 ****
(set_attr "mode" "SF")
(set_attr "fp_int_src" "true")])
! (define_insn "floatsisf2"
! [(set (match_operand:SF 0 "register_operand" "=f,f")
! (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
! "TARGET_80387"
"@
fild%z1\\t%1
! #"
! [(set_attr "type" "fmov,multi")
(set_attr "mode" "SF")
(set_attr "fp_int_src" "true")])
--- 4290,4319 ----
(set_attr "mode" "SF")
(set_attr "fp_int_src" "true")])
! (define_expand "floatsisf2"
! [(set (match_operand:SF 0 "register_operand" "")
! (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
! "TARGET_SSE || TARGET_80387"
! "")
!
! (define_insn "*floatsisf2_i387"
! [(set (match_operand:SF 0 "register_operand" "=f,?f,x")
! (float:SF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
! "TARGET_80387 && (!TARGET_SSE || TARGET_MIX_SSE_I387)"
"@
fild%z1\\t%1
! #
! cvtsi2ss\\t{%1, %0|%0, %1}"
! [(set_attr "type" "fmov,multi,sse")
! (set_attr "mode" "SF")
! (set_attr "fp_int_src" "true")])
!
! (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"
! "cvtsi2ss\\t{%1, %0|%0, %1}"
! [(set_attr "type" "sse")
(set_attr "mode" "SF")
(set_attr "fp_int_src" "true")])
***************
*** 4106,4112 ****
(define_insn "floathidf2"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
! "TARGET_80387"
"@
fild%z1\\t%1
#"
--- 4331,4337 ----
(define_insn "floathidf2"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(float:DF (match_operand:HI 1 "nonimmediate_operand" "m,r")))]
! "TARGET_80387 && !TARGET_SSE2"
"@
fild%z1\\t%1
#"
***************
*** 4114,4134 ****
(set_attr "mode" "DF")
(set_attr "fp_int_src" "true")])
! (define_insn "floatsidf2"
! [(set (match_operand:DF 0 "register_operand" "=f,f")
! (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r")))]
! "TARGET_80387"
"@
fild%z1\\t%1
! #"
! [(set_attr "type" "fmov,multi")
(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"
"@
fild%z1\\t%1
#"
--- 4339,4375 ----
(set_attr "mode" "DF")
(set_attr "fp_int_src" "true")])
! (define_expand "floatsidf2"
! [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
! (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
! ""
! "")
!
! (define_insn "*floatsidf2_i387"
! [(set (match_operand:DF 0 "register_operand" "=f,?f,Y")
! (float:DF (match_operand:SI 1 "nonimmediate_operand" "m,r,mr")))]
! "TARGET_80387 && (!TARGET_SSE2 || TARGET_MIX_SSE_I387)"
"@
fild%z1\\t%1
! #
! cvtsi2sd\\t{%1, %0|%0, %1}"
! [(set_attr "type" "fmov,multi,sse")
! (set_attr "mode" "DF")
! (set_attr "fp_int_src" "true")])
!
! (define_insn "*floatsidf2_sse"
! [(set (match_operand:DF 0 "register_operand" "=Y")
! (float:DF (match_operand:SI 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")])
(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"
"@
fild%z1\\t%1
#"
More information about the Gcc-patches
mailing list