i386.md (truncdfsf2_*): Add i387->int/sse reg alternatives...
authorJan Hubicka <jh@suse.cz>
Mon, 9 Apr 2001 13:10:22 +0000 (15:10 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 9 Apr 2001 13:10:22 +0000 (13:10 +0000)
* i386.md (truncdfsf2_*): Add i387->int/sse reg alternatives;
Do not require source to match destination anymore;
Add abort to the nontrivial cases that should be handled by split.
(fix_trunc?fdi): Add SSE case for x86_64.
(floatdi?f): Likewise.
(floatdi?f_sse): New.
(fix_trunc?fdi_sse): New.

From-SVN: r41203

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

index 62bfa47..7d3a024 100644 (file)
@@ -1,3 +1,13 @@
+Mon Apr  9 15:09:13 CEST 2001  Jan Hubicka  <jh@suse.cz>
+
+       * i386.md (truncdfsf2_*): Add i387->int/sse reg alternatives;
+       Do not require source to match destination anymore;
+       Add abort to the nontrivial cases that should be handled by split.
+       (fix_trunc?fdi): Add SSE case for x86_64.
+       (floatdi?f): Likewise.
+       (floatdi?f_sse): New.
+       (fix_trunc?fdi_sse): New.
+
 2001-04-09  Richard Sandiford   <rsandifo@redhat.com>
 
        * dwarfout.c (DEBUG_ARANGES_BEGIN_LABEL): New label.
index dd10423..fb43781 100644 (file)
 ")
 
 (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")])