diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 456841fba3b..c8fec55a11f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +Tue Feb 13 14:16:34 CET 2001 Jan Hubicka + + * 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. + Tue Feb 13 07:52:04 2001 Richard Kenner * configure.in: Use "have_gnat" variable, not "gnat". diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index 72b242b8c68..cf2f931b000 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -3244,7 +3244,7 @@ ;; %%% 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")))] + (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY")))] "0" "#") @@ -3310,7 +3310,7 @@ (define_expand "extendsfdf2" [(set (match_operand:DF 0 "nonimmediate_operand" "") (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "")))] - "TARGET_80387" + "TARGET_80387 || TARGET_SSE2" " { if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) @@ -3318,9 +3318,9 @@ }") (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 + [(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)" "* { @@ -3341,13 +3341,25 @@ else return \"fst%z0\\t%y0\"; + case 2: + case 3: + return \"cvtss2sd\\t{%1, %0|%0, %1}\"; default: abort (); } }" - [(set_attr "type" "fmov") - (set_attr "mode" "SF,XF")]) + [(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 "register_operand" "=Y") + (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "mY")))] + "!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" "") @@ -3532,15 +3544,23 @@ (float_truncate:SF (match_operand:DF 1 "register_operand" ""))) (clobber (match_dup 2))])] - "TARGET_80387" - "operands[2] = assign_386_stack_local (SFmode, 0);") + "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") + [(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" + (clobber (match_operand:SF 2 "memory_operand" "=X,m"))] + "TARGET_80387 && !TARGET_SSE2" "* { switch (which_alternative) @@ -3556,10 +3576,58 @@ abort (); }" [(set_attr "type" "fmov,multi") - (set_attr "mode" "SF")]) + (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 "memory_operand" "=m") + [(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" @@ -3573,6 +3641,15 @@ [(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 @@ -3582,12 +3659,22 @@ [(set (match_dup 0) (float_truncate:SF (match_dup 1)))] "") +(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" + "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))] "") @@ -3957,9 +4044,20 @@ (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);") + "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" "") @@ -3967,9 +4065,20 @@ (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);") + "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") @@ -3977,10 +4086,26 @@ (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_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 "register_operand" "=r") + (fix:SI (match_operand:SF 1 "nonimmediate_operand" "xm")))] + "TARGET_SSE" + "cvttss2si\\t{%1, %0|%0, %1}" + [(set_attr "type" "sse")]) + +(define_insn "fix_truncdfsi_sse" + [(set (match_operand:SI 0 "register_operand" "=r") + (fix:SI (match_operand:DF 1 "nonimmediate_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" ""))) @@ -4023,7 +4148,7 @@ (clobber (match_dup 2)) (clobber (match_dup 3)) (clobber (match_scratch:SI 4 ""))])] - "TARGET_80387" + "TARGET_80387 && !TARGET_SSE2" "operands[2] = assign_386_stack_local (SImode, 0); operands[3] = assign_386_stack_local (HImode, 1);") @@ -4033,7 +4158,7 @@ (clobber (match_dup 2)) (clobber (match_dup 3)) (clobber (match_scratch:SI 4 ""))])] - "TARGET_80387" + "TARGET_80387 && !TARGET_SSE" "operands[2] = assign_386_stack_local (SImode, 0); operands[3] = assign_386_stack_local (HImode, 1);") @@ -4043,7 +4168,8 @@ (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_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")]) @@ -4061,6 +4187,23 @@ (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") @@ -4091,7 +4234,7 @@ (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_80387 && !TARGET_SSE" "@ fild%z1\\t%1 #" @@ -4099,14 +4242,30 @@ (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" +(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 - #" - [(set_attr "type" "fmov,multi") + # + 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")]) @@ -4124,7 +4283,7 @@ (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_80387 && !TARGET_SSE2" "@ fild%z1\\t%1 #" @@ -4132,21 +4291,37 @@ (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" +(define_expand "floatsidf2" + [(set (match_operand:DF 0 "register_operand" "") + (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))] + "" + "") + +(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 - #" - [(set_attr "type" "fmov,multi") + # + 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_80387 && TARGET_SSE2" "@ fild%z1\\t%1 #"