OSDN Git Service

* i386.c (output_fp_compare): Support SSE.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Feb 2001 22:32:32 +0000 (22:32 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 13 Feb 2001 22:32:32 +0000 (22:32 +0000)
(prepare_fp_compare_args): SSE comparisons always support memory.
* i386.h (TARGET_CMOVE): SSE imply cmove.
* i386.md (cmp?f2): Enable for SSE too.
(cmpfp_i*): Support SSE.
(cmpfp_i_sse): New.
(cmpfp_i_sse_only): New.
(s*, b* fp expanters): Enable for SSE too.
(fp_jcc_1_sse, fp_jcc_1_sse_only, fp_jcc_2_sse, fp_jcc_2_sse_only):
New patterns.

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

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/config/i386/i386.h
gcc/config/i386/i386.md

index 8226cb8..aadb722 100644 (file)
@@ -1,3 +1,16 @@
+Tue Feb 13 23:19:27 CET 2001  Jan Hubicka  <jh@suse.cz>
+
+       * i386.c (output_fp_compare): Support SSE.
+       (prepare_fp_compare_args): SSE comparisons always support memory.
+       * i386.h (TARGET_CMOVE): SSE imply cmove.
+       * i386.md (cmp?f2): Enable for SSE too.
+       (cmpfp_i*): Support SSE.
+       (cmpfp_i_sse): New.
+       (cmpfp_i_sse_only): New.
+       (s*, b* fp expanters): Enable for SSE too.
+       (fp_jcc_1_sse, fp_jcc_1_sse_only, fp_jcc_2_sse, fp_jcc_2_sse_only):
+       New patterns.
+
 Tue Feb 13 23:05:42 CET 2001  Jan Hubicka  <jh@suse.cz>
 
        * regclass.c (init_reg_sets_1): Silence warning.
index bb4d421..0ef4acc 100644 (file)
@@ -4036,12 +4036,26 @@ output_fp_compare (insn, operands, eflags_p, unordered_p)
   int stack_top_dies;
   rtx cmp_op0 = operands[0];
   rtx cmp_op1 = operands[1];
+  int is_sse = SSE_REG_P (operands[0]) | SSE_REG_P (operands[1]);
 
   if (eflags_p == 2)
     {
       cmp_op0 = cmp_op1;
       cmp_op1 = operands[2];
     }
+  if (is_sse)
+    {
+      if (GET_MODE (operands[0]) == SFmode)
+       if (unordered_p)
+         return "ucomiss\t{%1, %0|%0, %1}";
+       else
+         return "comiss\t{%1, %0|%0, %y}";
+      else
+       if (unordered_p)
+         return "ucomisd\t{%1, %0|%0, %1}";
+       else
+         return "comisd\t{%1, %0|%0, %y}";
+    }
 
   if (! STACK_TOP_P (cmp_op0))
     abort ();
@@ -4797,15 +4811,17 @@ ix86_prepare_fp_compare_args (code, pop0, pop1)
   enum machine_mode fpcmp_mode = ix86_fp_compare_mode (code);
   rtx op0 = *pop0, op1 = *pop1;
   enum machine_mode op_mode = GET_MODE (op0);
+  int is_sse = SSE_REG_P (op0) | SSE_REG_P (op1);
 
   /* All of the unordered compare instructions only work on registers.
      The same is true of the XFmode compare instructions.  The same is
      true of the fcomi compare instructions.  */
 
-  if (fpcmp_mode == CCFPUmode
-      || op_mode == XFmode
-      || op_mode == TFmode
-      || ix86_use_fcomi_compare (code))
+  if (!is_sse
+      && (fpcmp_mode == CCFPUmode
+         || op_mode == XFmode
+         || op_mode == TFmode
+         || ix86_use_fcomi_compare (code)))
     {
       op0 = force_reg (op_mode, op0);
       op1 = force_reg (op_mode, op1);
index 0a1d441..1dd722c 100644 (file)
@@ -194,7 +194,9 @@ extern const int x86_partial_reg_dependency, x86_memory_mismatch_stall;
 #define TARGET_UNROLL_STRLEN (x86_unroll_strlen & CPUMASK)
 #define TARGET_USE_Q_REG (x86_use_q_reg & CPUMASK)
 #define TARGET_USE_ANY_REG (x86_use_any_reg & CPUMASK)
-#define TARGET_CMOVE (x86_cmove & (1 << ix86_arch))
+/* For sane SSE instruction set generation we need fcomi instruction.  It is
+   safe to enable all CMOVE instructions.  */
+#define TARGET_CMOVE ((x86_cmove & (1 << ix86_arch)) || TARGET_SSE)
 #define TARGET_DEEP_BRANCH_PREDICTION (x86_deep_branch & CPUMASK)
 #define TARGET_DOUBLE_WITH_ADD (x86_double_with_add & CPUMASK)
 #define TARGET_USE_SAHF (x86_use_sahf & CPUMASK)
index 65a3313..d85ec4d 100644 (file)
   [(set (reg:CC 17)
        (compare:CC (match_operand:DF 0 "cmp_fp_expander_operand" "")
                    (match_operand:DF 1 "cmp_fp_expander_operand" "")))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE2"
   "
 {
   ix86_compare_op0 = operands[0];
   [(set (reg:CC 17)
        (compare:CC (match_operand:SF 0 "cmp_fp_expander_operand" "")
                    (match_operand:SF 1 "cmp_fp_expander_operand" "")))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "
 {
   ix86_compare_op0 = operands[0];
        (compare:CCFP (match_operand 0 "register_operand" "f")
                      (match_operand 1 "register_operand" "f")))]
   "TARGET_80387 && TARGET_CMOVE
+   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
    && FLOAT_MODE_P (GET_MODE (operands[0]))
    && GET_MODE (operands[0]) == GET_MODE (operands[0])"
   "* return output_fp_compare (insn, operands, 1, 0);"
    (set_attr "mode" "unknownfp")
    (set_attr "athlon_decode" "vector")])
 
+(define_insn "*cmpfp_i_sse"
+  [(set (reg:CCFP 17)
+       (compare:CCFP (match_operand 0 "register_operand" "f#x,x#f")
+                     (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
+  "TARGET_80387
+   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
+   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
+  "* return output_fp_compare (insn, operands, 1, 0);"
+  [(set_attr "type" "fcmp,sse")
+   (set_attr "mode" "unknownfp")
+   (set_attr "athlon_decode" "vector")])
+
+(define_insn "*cmpfp_i_sse_only"
+  [(set (reg:CCFP 17)
+       (compare:CCFP (match_operand 0 "register_operand" "x")
+                     (match_operand 1 "nonimmediate_operand" "xm")))]
+  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
+   && GET_MODE (operands[0]) == GET_MODE (operands[0])"
+  "* return output_fp_compare (insn, operands, 1, 0);"
+  [(set_attr "type" "sse")
+   (set_attr "mode" "unknownfp")
+   (set_attr "athlon_decode" "vector")])
+
 (define_insn "*cmpfp_iu"
   [(set (reg:CCFPU 17)
        (compare:CCFPU (match_operand 0 "register_operand" "f")
                       (match_operand 1 "register_operand" "f")))]
   "TARGET_80387 && TARGET_CMOVE
+   && !SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
    && FLOAT_MODE_P (GET_MODE (operands[0]))
    && GET_MODE (operands[0]) == GET_MODE (operands[1])"
   "* return output_fp_compare (insn, operands, 1, 1);"
   [(set_attr "type" "fcmp")
    (set_attr "mode" "unknownfp")
    (set_attr "athlon_decode" "vector")])
+
+(define_insn "*cmpfp_iu_sse"
+  [(set (reg:CCFPU 17)
+       (compare:CCFPU (match_operand 0 "register_operand" "f#x,x#f")
+                      (match_operand 1 "nonimmediate_operand" "f#x,xm#f")))]
+  "TARGET_80387
+   && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
+   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
+  "* return output_fp_compare (insn, operands, 1, 1);"
+  [(set_attr "type" "fcmp,sse")
+   (set_attr "mode" "unknownfp")
+   (set_attr "athlon_decode" "vector")])
+
+(define_insn "*cmpfp_iu_sse_only"
+  [(set (reg:CCFPU 17)
+       (compare:CCFPU (match_operand 0 "register_operand" "x")
+                      (match_operand 1 "nonimmediate_operand" "xm")))]
+  "SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
+   && GET_MODE (operands[0]) == GET_MODE (operands[1])"
+  "* return output_fp_compare (insn, operands, 1, 1);"
+  [(set_attr "type" "sse")
+   (set_attr "mode" "unknownfp")
+   (set_attr "athlon_decode" "vector")])
 \f
 ;; Move instructions.
 
 (define_expand "sunordered"
   [(set (match_operand:SI 0 "register_operand" "")
         (unordered:SI (reg:CC 17) (const_int 0)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "if (ix86_expand_setcc (UNORDERED, operands[0])) DONE; else FAIL;")
 
 (define_expand "sordered"
 (define_expand "suneq"
   [(set (match_operand:SI 0 "register_operand" "")
         (uneq:SI (reg:CC 17) (const_int 0)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "if (ix86_expand_setcc (UNEQ, operands[0])) DONE; else FAIL;")
 
 (define_expand "sunge"
   [(set (match_operand:SI 0 "register_operand" "")
         (unge:SI (reg:CC 17) (const_int 0)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "if (ix86_expand_setcc (UNGE, operands[0])) DONE; else FAIL;")
 
 (define_expand "sungt"
   [(set (match_operand:SI 0 "register_operand" "")
         (ungt:SI (reg:CC 17) (const_int 0)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "if (ix86_expand_setcc (UNGT, operands[0])) DONE; else FAIL;")
 
 (define_expand "sunle"
   [(set (match_operand:SI 0 "register_operand" "")
         (unle:SI (reg:CC 17) (const_int 0)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "if (ix86_expand_setcc (UNLE, operands[0])) DONE; else FAIL;")
 
 (define_expand "sunlt"
   [(set (match_operand:SI 0 "register_operand" "")
         (unlt:SI (reg:CC 17) (const_int 0)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "if (ix86_expand_setcc (UNLT, operands[0])) DONE; else FAIL;")
 
 (define_expand "sltgt"
   [(set (match_operand:SI 0 "register_operand" "")
         (ltgt:SI (reg:CC 17) (const_int 0)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "if (ix86_expand_setcc (LTGT, operands[0])) DONE; else FAIL;")
 
 (define_insn "*setcc_1"
        (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "ix86_expand_branch (UNORDERED, operands[0]); DONE;")
 
 (define_expand "bordered"
        (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "ix86_expand_branch (ORDERED, operands[0]); DONE;")
 
 (define_expand "buneq"
        (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "ix86_expand_branch (UNEQ, operands[0]); DONE;")
 
 (define_expand "bunge"
        (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "ix86_expand_branch (UNGE, operands[0]); DONE;")
 
 (define_expand "bungt"
        (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "ix86_expand_branch (UNGT, operands[0]); DONE;")
 
 (define_expand "bunle"
        (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "ix86_expand_branch (UNLE, operands[0]); DONE;")
 
 (define_expand "bunlt"
        (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "ix86_expand_branch (UNLT, operands[0]); DONE;")
 
 (define_expand "bltgt"
        (if_then_else (match_dup 1)
                      (label_ref (match_operand 0 "" ""))
                      (pc)))]
-  "TARGET_80387"
+  "TARGET_80387 || TARGET_SSE"
   "ix86_expand_branch (LTGT, operands[0]); DONE;")
 
 (define_insn "*jcc_1"
    (clobber (reg:CCFP 18))
    (clobber (reg:CCFP 17))]
   "TARGET_CMOVE && TARGET_80387
+   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
    && FLOAT_MODE_P (GET_MODE (operands[1]))
    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
   "#")
 
+(define_insn "*fp_jcc_1_sse"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator"
+                       [(match_operand 1 "register_operand" "f#x,x#f")
+                        (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))
+   (clobber (reg:CCFP 18))
+   (clobber (reg:CCFP 17))]
+  "TARGET_80387
+   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+  "#")
+
+(define_insn "*fp_jcc_1_sse_only"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator"
+                       [(match_operand 1 "register_operand" "x")
+                        (match_operand 2 "nonimmediate_operand" "xm")])
+         (label_ref (match_operand 3 "" ""))
+         (pc)))
+   (clobber (reg:CCFP 18))
+   (clobber (reg:CCFP 17))]
+  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+  "#")
+
 (define_insn "*fp_jcc_2"
   [(set (pc)
        (if_then_else (match_operator 0 "comparison_operator"
    (clobber (reg:CCFP 18))
    (clobber (reg:CCFP 17))]
   "TARGET_CMOVE && TARGET_80387
+   && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
    && FLOAT_MODE_P (GET_MODE (operands[1]))
    && GET_MODE (operands[1]) == GET_MODE (operands[2])"
   "#")
 
+(define_insn "*fp_jcc_2_sse"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator"
+                       [(match_operand 1 "register_operand" "f#x,x#f")
+                        (match_operand 2 "nonimmediate_operand" "f#x,xm#f")])
+         (pc)
+         (label_ref (match_operand 3 "" ""))))
+   (clobber (reg:CCFP 18))
+   (clobber (reg:CCFP 17))]
+  "TARGET_80387
+   && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+  "#")
+
+(define_insn "*fp_jcc_2_sse_only"
+  [(set (pc)
+       (if_then_else (match_operator 0 "comparison_operator"
+                       [(match_operand 1 "register_operand" "x")
+                        (match_operand 2 "nonimmediate_operand" "xm")])
+         (pc)
+         (label_ref (match_operand 3 "" ""))))
+   (clobber (reg:CCFP 18))
+   (clobber (reg:CCFP 17))]
+  "SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
+   && GET_MODE (operands[1]) == GET_MODE (operands[2])"
+  "#")
+
 (define_insn "*fp_jcc_3"
   [(set (pc)
        (if_then_else (match_operator 0 "comparison_operator"