* i386.md (dummy_extendsfdf2): Support SSE2
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Feb 2001 13:18:08 +0000 (13:18 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Feb 2001 13:18:08 +0000 (13:18 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@39634 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.md

index 456841f..c8fec55 100644 (file)
@@ -1,3 +1,22 @@
+Tue Feb 13 14:16:34 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.
+
 Tue Feb 13 07:52:04 2001  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * configure.in: Use "have_gnat" variable, not "gnat".
index 72b242b..cf2f931 100644 (file)
 ;; %%% 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"
   "#")
 
 (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)
 }")
 
 (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)"
   "*
 {
 
       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" "")
                   (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)
   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"
   [(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
   "")
 
 (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))]
   "")
              (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" "")
              (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")
    (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" "")))
              (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);")
 
              (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);")
 
    (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")])
 
    (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")
 (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
    #"
    (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")])
 
 (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
    #"
    (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
    #"