simplify-rtx.c (simplify_unary_operation): Deal with logicals on floats.
authorJan Hubicka <jh@suse.cz>
Wed, 18 Feb 2004 20:55:29 +0000 (21:55 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 18 Feb 2004 20:55:29 +0000 (20:55 +0000)
* simplify-rtx.c (simplify_unary_operation): Deal with logicals on
floats.
(simplify_binary_operation): Deal with logicals on floats.

* i386.md (SSE fabs splitters): Emit new patterns.
(SSE cmov splitters): Likewise.
(sse_andv4sf3, sse_nandv4sf3, sse_iorv4sf3, sse_xorv4sf3
(sse_andv2df3, sse_nandv2df3, sse_iorv2df3, sse_xorv2df3): Do not use
subregs.
(sse_andsf3, sse_nandsf3, sse_xorsf3): Kill.
(sse_anddf3, sse_nanddf3, sse_xordf3): Kill.

From-SVN: r78045

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/simplify-rtx.c

index 2ea80aa..313f0ca 100644 (file)
@@ -1,3 +1,17 @@
+2004-02-18  Jan Hubicka  <jh@suse.cz>
+
+       * simplify-rtx.c (simplify_unary_operation): Deal with logicals on
+       floats.
+       (simplify_binary_operation): Deal with logicals on floats.
+
+       * i386.md (SSE fabs splitters): Emit new patterns.
+       (SSE cmov splitters): Likewise.
+       (sse_andv4sf3, sse_nandv4sf3, sse_iorv4sf3, sse_xorv4sf3
+       (sse_andv2df3, sse_nandv2df3, sse_iorv2df3, sse_xorv2df3): Do not use
+       subregs.
+       (sse_andsf3, sse_nandsf3, sse_xorsf3): Kill.
+       (sse_anddf3, sse_nanddf3, sse_xordf3): Kill.
+
 2004-02-18  Kazu Hirata  <kazu@cs.umass.edu>
 
        * config/h8300/h8300.c (expand_a_rotate): Don't generate insns
index 309ec17..7733681 100644 (file)
    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
    (clobber (reg:CC 17))]
   "reload_completed && SSE_REG_P (operands[0])"
-  [(set (subreg:TI (match_dup 0) 0)
-       (xor:TI (match_dup 1)
-               (match_dup 2)))]
+  [(set (match_dup 0)
+       (xor:V4SF (match_dup 1)
+                 (match_dup 2)))]
 {
-  operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
-  operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
+  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+  operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
   if (operands_match_p (operands[0], operands[2]))
     {
       rtx tmp;
    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
    (clobber (reg:CC 17))]
   "reload_completed && SSE_REG_P (operands[0])"
-  [(set (subreg:TI (match_dup 0) 0)
-       (xor:TI (match_dup 1)
-               (match_dup 2)))]
+  [(set (match_dup 0)
+       (xor:V2DF (match_dup 1)
+                 (match_dup 2)))]
 {
   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
-  operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
-  operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
+  operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
   /* Avoid possible reformatting on the operands.  */
   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
    (use (match_operand:V4SF 2 "nonimmediate_operand" ""))
    (clobber (reg:CC 17))]
   "reload_completed && SSE_REG_P (operands[0])"
-  [(set (subreg:TI (match_dup 0) 0)
-       (and:TI (match_dup 1)
-               (match_dup 2)))]
+  [(set (match_dup 0)
+       (and:V4SF (match_dup 1)
+                 (match_dup 2)))]
 {
-  operands[1] = simplify_gen_subreg (TImode, operands[1], SFmode, 0);
-  operands[2] = simplify_gen_subreg (TImode, operands[2], V4SFmode, 0);
+  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+  operands[1] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
   if (operands_match_p (operands[0], operands[2]))
     {
       rtx tmp;
    (use (match_operand:V2DF 2 "nonimmediate_operand" ""))
    (clobber (reg:CC 17))]
   "reload_completed && SSE_REG_P (operands[0])"
-  [(set (subreg:TI (match_dup 0) 0)
-       (and:TI (match_dup 1)
-               (match_dup 2)))]
+  [(set (match_dup 0)
+       (and:V2DF (match_dup 1)
+                 (match_dup 2)))]
 {
   operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
-  operands[1] = simplify_gen_subreg (TImode, operands[1], DFmode, 0);
-  operands[2] = simplify_gen_subreg (TImode, operands[2], V2DFmode, 0);
+  operands[1] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
   /* Avoid possible reformatting on the operands.  */
   if (TARGET_SSE_PARTIAL_REGS && !optimize_size)
     emit_insn (gen_sse2_unpcklpd (operands[0], operands[0], operands[0]));
 ;; nand  op0, op3   -  load op3 to op0 if comparison was false
 ;; or   op2, op0   -  get the nonzero one into the result.
 (define_split
-  [(set (match_operand 0 "register_operand" "")
-       (if_then_else (match_operator 1 "sse_comparison_operator"
-                       [(match_operand 4 "register_operand" "")
-                        (match_operand 5 "nonimmediate_operand" "")])
-                     (match_operand 2 "register_operand" "")
-                     (match_operand 3 "register_operand" "")))
+  [(set (match_operand:SF 0 "register_operand" "")
+       (if_then_else (match_operator:SF 1 "sse_comparison_operator"
+                       [(match_operand:SF 4 "register_operand" "")
+                        (match_operand:SF 5 "nonimmediate_operand" "")])
+                     (match_operand:SF 2 "register_operand" "")
+                     (match_operand:SF 3 "register_operand" "")))
    (clobber (match_operand 6 "" ""))
    (clobber (reg:CC 17))]
   "SSE_REG_P (operands[0]) && reload_completed"
   [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
-   (set (subreg:TI (match_dup 2) 0) (and:TI (subreg:TI (match_dup 2) 0)
-                                           (subreg:TI (match_dup 4) 0)))
-   (set (subreg:TI (match_dup 4) 0) (and:TI (not:TI (subreg:TI (match_dup 4) 0))
-                                           (subreg:TI (match_dup 3) 0)))
-   (set (subreg:TI (match_dup 0) 0) (ior:TI (subreg:TI (match_dup 6) 0)
-                                           (subreg:TI (match_dup 7) 0)))]
+   (set (match_dup 2) (and:V4SF (match_dup 2)
+                               (match_dup 8)))
+   (set (match_dup 8) (and:V4SF (not:V4SF (match_dup 8))
+                                         (match_dup 3)))
+   (set (match_dup 0) (ior:V4SF (match_dup 6)
+                               (match_dup 7)))]
+{
+  /* If op2 == op3, op3 would be clobbered before it is used.  */
+  if (operands_match_p (operands[2], operands[3]))
+    {
+      emit_move_insn (operands[0], operands[2]);
+      DONE;
+    }
+
+  PUT_MODE (operands[1], GET_MODE (operands[0]));
+  if (operands_match_p (operands[0], operands[4]))
+    operands[6] = operands[4], operands[7] = operands[2];
+  else
+    operands[6] = operands[2], operands[7] = operands[4];
+  operands[0] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+  operands[2] = simplify_gen_subreg (V4SFmode, operands[2], SFmode, 0);
+  operands[3] = simplify_gen_subreg (V4SFmode, operands[3], SFmode, 0);
+  operands[8] = simplify_gen_subreg (V4SFmode, operands[4], SFmode, 0);
+  operands[6] = simplify_gen_subreg (V4SFmode, operands[6], SFmode, 0);
+  operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
+})
+
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+       (if_then_else (match_operator:DF 1 "sse_comparison_operator"
+                       [(match_operand:DF 4 "register_operand" "")
+                        (match_operand:DF 5 "nonimmediate_operand" "")])
+                     (match_operand:DF 2 "register_operand" "")
+                     (match_operand:DF 3 "register_operand" "")))
+   (clobber (match_operand 6 "" ""))
+   (clobber (reg:CC 17))]
+  "SSE_REG_P (operands[0]) && reload_completed"
+  [(set (match_dup 4) (match_op_dup 1 [(match_dup 4) (match_dup 5)]))
+   (set (match_dup 2) (and:V2DF (match_dup 2)
+                               (match_dup 8)))
+   (set (match_dup 8) (and:V2DF (not:V2DF (match_dup 8))
+                                         (match_dup 3)))
+   (set (match_dup 0) (ior:V2DF (match_dup 6)
+                               (match_dup 7)))]
 {
   if (GET_MODE (operands[2]) == DFmode
       && TARGET_SSE_PARTIAL_REGS && !optimize_size)
     operands[6] = operands[4], operands[7] = operands[2];
   else
     operands[6] = operands[2], operands[7] = operands[4];
+  operands[0] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
+  operands[2] = simplify_gen_subreg (V2DFmode, operands[2], DFmode, 0);
+  operands[3] = simplify_gen_subreg (V2DFmode, operands[3], DFmode, 0);
+  operands[8] = simplify_gen_subreg (V2DFmode, operands[4], DFmode, 0);
+  operands[6] = simplify_gen_subreg (V2DFmode, operands[6], DFmode, 0);
+  operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
 })
 
 ;; Special case of conditional move we can handle effectively.
   "#")
 
 (define_split
-  [(set (match_operand 0 "register_operand" "")
-       (if_then_else (match_operator 1 "comparison_operator"
-                       [(match_operand 4 "nonimmediate_operand" "")
-                        (match_operand 5 "nonimmediate_operand" "")])
-                     (match_operand 2 "nonmemory_operand" "")
-                     (match_operand 3 "nonmemory_operand" "")))]
+  [(set (match_operand:SF 0 "register_operand" "")
+       (if_then_else (match_operator:SF 1 "comparison_operator"
+                       [(match_operand:SF 4 "nonimmediate_operand" "")
+                        (match_operand:SF 5 "nonimmediate_operand" "")])
+                     (match_operand:SF 2 "nonmemory_operand" "")
+                     (match_operand:SF 3 "nonmemory_operand" "")))]
+  "SSE_REG_P (operands[0]) && reload_completed
+   && (const0_operand (operands[2], GET_MODE (operands[0]))
+       || const0_operand (operands[3], GET_MODE (operands[0])))"
+  [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
+   (set (match_dup 8) (and:V4SF (match_dup 6) (match_dup 7)))]
+{
+  PUT_MODE (operands[1], GET_MODE (operands[0]));
+  if (!sse_comparison_operator (operands[1], VOIDmode)
+      || !rtx_equal_p (operands[0], operands[4]))
+    {
+      rtx tmp = operands[5];
+      operands[5] = operands[4];
+      operands[4] = tmp;
+      PUT_CODE (operands[1], swap_condition (GET_CODE (operands[1])));
+    }
+  if (!rtx_equal_p (operands[0], operands[4]))
+    abort ();
+  operands[8] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
+  if (const0_operand (operands[2], GET_MODE (operands[2])))
+    {
+      operands[7] = operands[3];
+      operands[6] = gen_rtx_NOT (V4SFmode, operands[5]);
+    }
+  else
+    {
+      operands[7] = operands[2];
+      operands[6] = operands[0];
+    }
+  operands[7] = simplify_gen_subreg (V4SFmode, operands[7], SFmode, 0);
+})
+
+(define_split
+  [(set (match_operand:DF 0 "register_operand" "")
+       (if_then_else (match_operator:DF 1 "comparison_operator"
+                       [(match_operand:DF 4 "nonimmediate_operand" "")
+                        (match_operand:DF 5 "nonimmediate_operand" "")])
+                     (match_operand:DF 2 "nonmemory_operand" "")
+                     (match_operand:DF 3 "nonmemory_operand" "")))]
   "SSE_REG_P (operands[0]) && reload_completed
    && (const0_operand (operands[2], GET_MODE (operands[0]))
        || const0_operand (operands[3], GET_MODE (operands[0])))"
   [(set (match_dup 0) (match_op_dup 1 [(match_dup 0) (match_dup 5)]))
-   (set (subreg:TI (match_dup 0) 0) (and:TI (match_dup 6)
-                                           (match_dup 7)))]
+   (set (match_dup 8) (and:V2DF (match_dup 6) (match_dup 7)))]
 {
   if (TARGET_SSE_PARTIAL_REGS && !optimize_size
       && GET_MODE (operands[2]) == DFmode)
     }
   if (!rtx_equal_p (operands[0], operands[4]))
     abort ();
-  if (const0_operand (operands[2], GET_MODE (operands[0])))
+  operands[8] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
+  if (const0_operand (operands[2], GET_MODE (operands[2])))
     {
       operands[7] = operands[3];
-      operands[6] = gen_rtx_NOT (TImode, gen_rtx_SUBREG (TImode, operands[0],
-                                                        0));
+      operands[6] = gen_rtx_NOT (V2DFmode, operands[8]);
     }
   else
     {
       operands[7] = operands[2];
-      operands[6] = gen_rtx_SUBREG (TImode, operands[0], 0);
+      operands[6] = operands[8];
     }
-  operands[7] = simplify_gen_subreg (TImode, operands[7],
-                                    GET_MODE (operands[7]), 0);
+  operands[7] = simplify_gen_subreg (V2DFmode, operands[7], DFmode, 0);
 })
 
 (define_expand "allocate_stack_worker"
 ;; of DImode subregs again!
 ;; SSE1 single precision floating point logical operation
 (define_expand "sse_andv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
-        (and:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V4SF 0 "register_operand" "")
+        (and:V4SF (match_operand:V4SF 1 "register_operand" "")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE"
   "")
 
 (define_insn "*sse_andv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
-        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "andps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "*sse_andsf3"
-  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
-        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V4SF 0 "register_operand" "=x")
+        (and:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "andps\t{%2, %0|%0, %2}"
    (set_attr "mode" "V4SF")])
 
 (define_expand "sse_nandv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
-        (and:TI (not:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0))
-               (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V4SF 0 "register_operand" "")
+        (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" ""))
+                 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE"
   "")
 
 (define_insn "*sse_nandv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
-        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE"
-  "andnps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "*sse_nandsf3"
-  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
-        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V4SF 0 "register_operand" "=x")
+        (and:V4SF (not:V4SF (match_operand:V4SF 1 "register_operand" "0"))
+                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE"
   "andnps\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog")
    (set_attr "mode" "V4SF")])
 
 (define_expand "sse_iorv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
-        (ior:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V4SF 0 "register_operand" "")
+        (ior:V4SF (match_operand:V4SF 1 "register_operand" "")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE"
   "")
 
 (define_insn "*sse_iorv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
-        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "orps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "*sse_iorsf3"
-  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
-        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V4SF 0 "register_operand" "=x")
+        (ior:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "orps\t{%2, %0|%0, %2}"
    (set_attr "mode" "V4SF")])
 
 (define_expand "sse_xorv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "") 0)
-        (xor:TI (subreg:TI (match_operand:V4SF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V4SF 2 "nonimmediate_operand" "") 0)))]
-  "TARGET_SSE
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
+  [(set (match_operand:V4SF 0 "register_operand" "")
+        (xor:V4SF (match_operand:V4SF 1 "register_operand" "")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "")))]
+  "TARGET_SSE"
   "")
 
 (define_insn "*sse_xorv4sf3"
-  [(set (subreg:TI (match_operand:V4SF 0 "register_operand" "=x") 0)
-        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "xorps\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V4SF")])
-
-(define_insn "*sse_xorsf3"
-  [(set (subreg:TI (match_operand:SF 0 "register_operand" "=x") 0)
-        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V4SF 0 "register_operand" "=x")
+        (xor:V4SF (match_operand:V4SF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V4SF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "xorps\t{%2, %0|%0, %2}"
 ;; SSE2 double precision floating point logical operation
 
 (define_expand "sse2_andv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
-        (and:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V2DF 0 "register_operand" "")
+        (and:V2DF (match_operand:V2DF 1 "register_operand" "")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE2"
   "")
 
 (define_insn "*sse2_andv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
-        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE2
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "andpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V2DF")])
-
-(define_insn "*sse2_andv2df3"
-  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
-        (and:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=x")
+        (and:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "andpd\t{%2, %0|%0, %2}"
    (set_attr "mode" "V2DF")])
 
 (define_expand "sse2_nandv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
-        (and:TI (not:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0))
-               (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V2DF 0 "register_operand" "")
+        (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" ""))
+                 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE2"
   "")
 
 (define_insn "*sse2_nandv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
-        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE2"
-  "andnpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V2DF")])
-
-(define_insn "*sse_nandti3_df"
-  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=Y") 0)
-        (and:TI (not:TI (match_operand:TI 1 "register_operand" "0"))
-               (match_operand:TI 2 "nonimmediate_operand" "Ym")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=x")
+        (and:V2DF (not:V2DF (match_operand:V2DF 1 "register_operand" "0"))
+                 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2"
   "andnpd\t{%2, %0|%0, %2}"
   [(set_attr "type" "sselog")
    (set_attr "mode" "V2DF")])
 
 (define_expand "sse2_iorv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
-        (ior:TI (subreg:TI (match_operand:V2DF 1 "register_operand" "") 0)
-               (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V2DF 0 "register_operand" "")
+        (ior:V2DF (match_operand:V2DF 1 "register_operand" "")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE2"
   "")
 
 (define_insn "*sse2_iorv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
-        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE2
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "orpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V2DF")])
-
-(define_insn "*sse2_iordf3"
-  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
-        (ior:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=x")
+        (ior:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "orpd\t{%2, %0|%0, %2}"
    (set_attr "mode" "V2DF")])
 
 (define_expand "sse2_xorv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "") 0)
-        (xor:TI (subreg:TI (match_operand:V2DF 1 "nonimmediate_operand" "") 0)
-               (subreg:TI (match_operand:V2DF 2 "nonimmediate_operand" "") 0)))]
+  [(set (match_operand:V2DF 0 "register_operand" "")
+        (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "")))]
   "TARGET_SSE2"
   "")
 
 (define_insn "*sse2_xorv2df3"
-  [(set (subreg:TI (match_operand:V2DF 0 "register_operand" "=x") 0)
-        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
-  "TARGET_SSE2
-   && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
-  "xorpd\t{%2, %0|%0, %2}"
-  [(set_attr "type" "sselog")
-   (set_attr "mode" "V2DF")])
-
-(define_insn "*sse2_xordf3"
-  [(set (subreg:TI (match_operand:DF 0 "register_operand" "=x") 0)
-        (xor:TI (match_operand:TI 1 "nonimmediate_operand" "%0")
-               (match_operand:TI 2 "nonimmediate_operand" "xm")))]
+  [(set (match_operand:V2DF 0 "register_operand" "=x")
+        (xor:V2DF (match_operand:V2DF 1 "nonimmediate_operand" "%0")
+                 (match_operand:V2DF 2 "nonimmediate_operand" "xm")))]
   "TARGET_SSE2
    && (GET_CODE (operands[1]) != MEM || GET_CODE (operands[2]) != MEM)"
   "xorpd\t{%2, %0|%0, %2}"
index 7f6b549..dda7dd4 100644 (file)
@@ -771,7 +771,16 @@ simplify_unary_operation (enum rtx_code code, enum machine_mode mode,
        case FIX:
          real_arithmetic (&d, FIX_TRUNC_EXPR, &d, NULL);
          break;
+       case NOT:
+         {
+           long tmp[4];
+           int i;
 
+           real_to_target (tmp, &d, GET_MODE (trueop));
+           for (i = 0; i < 4; i++)
+             tmp[i] = ~tmp[i];
+           real_from_target (&d, tmp, mode);
+         }
        default:
          abort ();
        }
@@ -1210,26 +1219,56 @@ simplify_binary_operation (enum rtx_code code, enum machine_mode mode,
       && GET_CODE (trueop1) == CONST_DOUBLE
       && mode == GET_MODE (op0) && mode == GET_MODE (op1))
     {
-      REAL_VALUE_TYPE f0, f1, value;
+      if (code == AND
+         || code == IOR
+         || code == XOR)
+       {
+         long tmp0[4];
+         long tmp1[4];
+         REAL_VALUE_TYPE r;
+         int i;
+
+         real_to_target (tmp0, CONST_DOUBLE_REAL_VALUE (op0),
+                         GET_MODE (op0));
+         real_to_target (tmp1, CONST_DOUBLE_REAL_VALUE (op1),
+                         GET_MODE (op1));
+         for (i = 0; i < 4; i++)
+           {
+             if (code == AND)
+               tmp0[i] &= tmp1[i];
+             else if (code == IOR)
+               tmp0[i] |= tmp1[i];
+             else if (code == XOR)
+               tmp0[i] ^= tmp1[i];
+             else
+               abort ();
+           }
+          real_from_target (&r, tmp0, mode);
+          return CONST_DOUBLE_FROM_REAL_VALUE (r, mode);
+       }
+      else
+       {
+         REAL_VALUE_TYPE f0, f1, value;
 
-      REAL_VALUE_FROM_CONST_DOUBLE (f0, trueop0);
-      REAL_VALUE_FROM_CONST_DOUBLE (f1, trueop1);
-      f0 = real_value_truncate (mode, f0);
-      f1 = real_value_truncate (mode, f1);
+         REAL_VALUE_FROM_CONST_DOUBLE (f0, trueop0);
+         REAL_VALUE_FROM_CONST_DOUBLE (f1, trueop1);
+         f0 = real_value_truncate (mode, f0);
+         f1 = real_value_truncate (mode, f1);
 
-      if (HONOR_SNANS (mode)
-         && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1)))
-       return 0;
+         if (HONOR_SNANS (mode)
+             && (REAL_VALUE_ISNAN (f0) || REAL_VALUE_ISNAN (f1)))
+           return 0;
 
-      if (code == DIV
-         && REAL_VALUES_EQUAL (f1, dconst0)
-         && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
-       return 0;
+         if (code == DIV
+             && REAL_VALUES_EQUAL (f1, dconst0)
+             && (flag_trapping_math || ! MODE_HAS_INFINITIES (mode)))
+           return 0;
 
-      REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
+         REAL_ARITHMETIC (value, rtx_to_tree_code (code), f0, f1);
 
-      value = real_value_truncate (mode, value);
-      return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
+         value = real_value_truncate (mode, value);
+         return CONST_DOUBLE_FROM_REAL_VALUE (value, mode);
+       }
     }
 
   /* We can fold some multi-word operations.  */