OSDN Git Service

* i386.md (sse_setccsf, sse_setccdf): New.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 28 Feb 2001 18:07:05 +0000 (18:07 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 28 Feb 2001 18:07:05 +0000 (18:07 +0000)
(sse_cmp* patterns): Use '%D' instead of outputtting condition
flag directly.
* i386.c (sse_comparison_operator): Accept the supported unordered
comparses; be ready for fast_math.
(print_operand): Support 'D'.

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

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

index 7c91121..193ed5a 100644 (file)
@@ -1,3 +1,12 @@
+Wed Feb 28 19:05:37 CET 2001  Jan Hubicka  <jh@suse.cz>
+
+       * i386.md (sse_setccsf, sse_setccdf): New.
+       (sse_cmp* patterns): Use '%D' instead of outputtting condition
+       flag directly.
+       * i386.c (sse_comparison_operator): Accept the supported unordered
+       comparses; be ready for fast_math.
+       (print_operand): Support 'D'.
+
 Wed Feb 28 18:54:51 CET 2001  Jan Hubicka  <jh@suse.cz>
 
        * jump.c (reversed_comparison_code): Kill.
index 7dfc3c5..7ae13f9 100644 (file)
@@ -1318,7 +1318,29 @@ sse_comparison_operator (op, mode)
      enum machine_mode mode ATTRIBUTE_UNUSED;
 {
   enum rtx_code code = GET_CODE (op);
-  return code == EQ || code == LT || code == LE || code == UNORDERED;
+  switch (code)
+    {
+    /* Operations supported directly.  */
+    case EQ:
+    case LT:
+    case LE:
+    case UNORDERED:
+    case NE:
+    case UNGE:
+    case UNGT:
+    case ORDERED:
+      return 1;
+    /* These are equivalent to ones above in non-IEEE comparisons.  */
+    case UNEQ:
+    case UNLT:
+    case UNLE:
+    case LTGT:
+    case GE:
+    case GT:
+      return !TARGET_IEEE_FP;
+    default:
+      return 0;
+    }
 }
 /* Return 1 if OP is a valid comparison operator in valid mode.  */
 int
@@ -3326,7 +3348,9 @@ print_reg (x, code, file)
    k --  likewise, print the SImode name of the register.
    h --  print the QImode name for a "high" register, either ah, bh, ch or dh.
    y --  print "st(0)" instead of "st" as a register.
-   m --  print "st(n)" as an mmx register.  */
+   m --  print "st(n)" as an mmx register.
+   D -- print condition for SSE cmp instruction.
+ */
 
 void
 print_operand (file, x, code)
@@ -3460,6 +3484,47 @@ print_operand (file, x, code)
            }
          return;
 
+       case 'D':
+         /* Little bit of braindamage here.  The SSE compare instructions
+            does use completely different names for the comparisons that the
+            fp conditional moves.  */
+         switch (GET_CODE (x))
+           {
+           case EQ:
+           case UNEQ:
+             fputs ("eq", file);
+             break;
+           case LT:
+           case UNLT:
+             fputs ("lt", file);
+             break;
+           case LE:
+           case UNLE:
+             fputs ("le", file);
+             break;
+           case UNORDERED:
+             fputs ("unord", file);
+             break;
+           case NE:
+           case LTGT:
+             fputs ("neq", file);
+             break;
+           case UNGE:
+           case GE:
+             fputs ("nlt", file);
+             break;
+           case UNGT:
+           case GT:
+             fputs ("nle", file);
+             break;
+           case ORDERED:
+             fputs ("ord", file);
+             break;
+           default:
+             abort ();
+             break;
+           }
+         return;
        case 'C':
          put_condition_code (GET_CODE (x), GET_MODE (XEXP (x, 0)), 0, 0, file);
          return;
index 0e65701..38d035e 100644 (file)
   [(set_attr "type" "setcc")
    (set_attr "mode" "QI")])
 
+;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
+;; subsequent logical operations are used to imitate conditional moves.
+;; 0xffffffff is NaN, but not in normalized form, so we can't represent
+;; it directly.  Futher holding this value in pseudo register might bring
+;; problem in implicit normalization in spill code.
+;; So we don't define FLOAT_STORE_FLAG_VALUE and create these
+;; instructions after reload by splitting the conditional move patterns.
+
+(define_insn "*sse_setccsf"
+  [(set (match_operand:SF 0 "register_operand" "=x")
+       (match_operator:SF 1 "sse_comparison_operator"
+         [(match_operand:SF 2 "register_operand" "0")
+          (match_operand:SF 3 "nonimmediate_operand" "xm")]))]
+  "TARGET_SSE && reload_completed"
+  "cmp%D1ss\\t{%3, %0|%0, %3}"
+  [(set_attr "type" "sse")
+   (set_attr "mode" "SF")])
+
+(define_insn "*sse_setccdf"
+  [(set (match_operand:DF 0 "register_operand" "=Y")
+       (match_operator:DF 1 "sse_comparison_operator"
+         [(match_operand:DF 2 "register_operand" "0")
+          (match_operand:DF 3 "nonimmediate_operand" "Ym")]))]
+  "TARGET_SSE2 && reload_completed"
+  "cmp%D1sd\\t{%3, %0|%0, %3}"
+  [(set_attr "type" "sse")
+   (set_attr "mode" "DF")])
 \f
 ;; Basic conditional jump instructions.
 ;; We ignore the overflow flag for signed branch instructions.
                             [(match_operand:V4SF 1 "register_operand" "0")
                              (match_operand:V4SF 2 "nonimmediate_operand" "x")]))]
   "TARGET_SSE"
-  "*
-{
-  switch (GET_CODE (operands[3]))
-    {
-    case EQ:
-      return \"cmpeqps\\t{%2, %0|%0, %2}\";
-    case LT:
-      return \"cmpltps\\t{%2, %0|%0, %2}\";
-    case LE:
-      return \"cmpleps\\t{%2, %0|%0, %2}\";
-    case UNORDERED:
-      return \"cmpunordps\\t{%2, %0|%0, %2}\";
-    default:
-      abort ();
-    }
-}"
+  "cmp%D3ps\\t{%2, %0|%0, %2}"
   [(set_attr "type" "sse")])
 
 (define_insn "maskncmpv4sf3"
                              [(match_operand:V4SF 1 "register_operand" "0")
                               (match_operand:V4SF 2 "nonimmediate_operand" "x")])))]
   "TARGET_SSE"
-  "*
-{
-  switch (GET_CODE (operands[3]))
-    {
-    case EQ:
-      return \"cmpneqps\\t{%2, %0|%0, %2}\";
-    case LT:
-      return \"cmpnltps\\t{%2, %0|%0, %2}\";
-    case LE:
-      return \"cmpnleps\\t{%2, %0|%0, %2}\";
-    case UNORDERED:
-      return \"cmpordps\\t{%2, %0|%0, %2}\";
-    default:
-      abort ();
-    }
-}"
+  "cmpn%D3ps\\t{%2, %0|%0, %2}"
   [(set_attr "type" "sse")])
 
 (define_insn "vmmaskcmpv4sf3"
         (match_dup 1)
         (const_int 1)))]
   "TARGET_SSE"
-  "*
-{
-  switch (GET_CODE (operands[3]))
-    {
-    case EQ:
-      return \"cmpeqss\\t{%2, %0|%0, %2}\";
-    case LT:
-      return \"cmpltss\\t{%2, %0|%0, %2}\";
-    case LE:
-      return \"cmpless\\t{%2, %0|%0, %2}\";
-    case UNORDERED:
-      return \"cmpunordss\\t{%2, %0|%0, %2}\";
-    default:
-      abort ();
-    }
-}"
+  "cmp%D3ss\\t{%2, %0|%0, %2}"
   [(set_attr "type" "sse")])
 
 (define_insn "vmmaskncmpv4sf3"
         (subreg:V4SI (match_dup 1) 0)
         (const_int 1)))]
   "TARGET_SSE"
-  "*
-{
-  switch (GET_CODE (operands[3]))
-    {
-    case EQ:
-      return \"cmpneqss\\t{%2, %0|%0, %2}\";
-    case LT:
-      return \"cmpnltss\\t{%2, %0|%0, %2}\";
-    case LE:
-      return \"cmpnless\\t{%2, %0|%0, %2}\";
-    case UNORDERED:
-      return \"cmpordss\\t{%2, %0|%0, %2}\";
-    default:
-      abort ();
-    }
-}"
+  "cmp%D3ss\\t{%2, %0|%0, %2}"
   [(set_attr "type" "sse")])
 
 (define_insn "sse_comi"