i386.md (*btdi_rex64): Change operand 1 predicate to nonmemory_operand.
authorUros Bizjak <ubizjak@gmail.com>
Tue, 10 Jun 2008 18:50:23 +0000 (20:50 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 10 Jun 2008 18:50:23 +0000 (20:50 +0200)
* config/i386/i386.md (*btdi_rex64): Change operand 1 predicate to
nonmemory_operand. Add "N" operand constraint.
(*btsi): Ditto.
(*jcc_btdi_mask_rex64): New instruction and split pattern.
(*jcc_btsi_mask): Ditto.
(*jcc_btsi_mask_1): Ditto.

testsuite/ChangeLog:

* gcc.target/i386/bt-mask-1.c: New test.
* gcc.target/i386/bt-mask-2.c: Ditto.

From-SVN: r136636

gcc/ChangeLog
gcc/config/i386/i386.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/i386/bt-mask-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/i386/bt-mask-2.c [new file with mode: 0644]

index 6a2080da1c4d8ec7aa66e4203b69d76843684b50..4fcc73f30c7e7df1193f0cd8680cf0c4ff08fd44 100644 (file)
@@ -1,3 +1,12 @@
+2008-06-10  Uros Bizjak  <ubizjak@gmail.com>
+
+       * config/i386/i386.md (*btdi_rex64): Change operand 1 predicate to
+       nonmemory_operand. Add "N" operand constraint.
+       (*btsi): Ditto.
+       (*jcc_btdi_mask_rex64): New instruction and split pattern.
+       (*jcc_btsi_mask): Ditto.
+       (*jcc_btsi_mask_1): Ditto.
+
 2008-06-10  Joseph Myers  <joseph@codesourcery.com>
 
        * config/rs6000/rs6000.c (build_opaque_vector_type): Set
index 4da50afce2853370d38f985e82cd71e00ff9f09f..ca01494871f22450e3ca5f5dc5e8417dfc6a352e 100644 (file)
          (zero_extract:DI
            (match_operand:DI 0 "register_operand" "r")
            (const_int 1)
-           (match_operand:DI 1 "register_operand" "r"))
+           (match_operand:DI 1 "nonmemory_operand" "rN"))
          (const_int 0)))]
   "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
   "bt{q}\t{%1, %0|%0, %1}"
          (zero_extract:SI
            (match_operand:SI 0 "register_operand" "r")
            (const_int 1)
-           (match_operand:SI 1 "register_operand" "r"))
+           (match_operand:SI 1 "nonmemory_operand" "rN"))
          (const_int 0)))]
   "TARGET_USE_BT || optimize_size"
   "bt{l}\t{%1, %0|%0, %1}"
   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
 })
 
+;; avoid useless masking of bit offset operand
+(define_insn_and_split "*jcc_btdi_mask_rex64"
+  [(set (pc)
+       (if_then_else (match_operator 0 "bt_comparison_operator"
+                       [(zero_extract:DI
+                          (match_operand:DI 1 "register_operand" "r")
+                          (const_int 1)
+                          (and:SI
+                            (match_operand:SI 2 "register_operand" "r")
+                            (match_operand:SI 3 "const_int_operand" "n")))])
+                     (label_ref (match_operand 4 "" ""))
+                     (pc)))]
+  "TARGET_64BIT && (TARGET_USE_BT || optimize_size)
+   && (INTVAL (operands[3]) & 0x3f) == 0x3f"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+       (compare:CCC
+         (zero_extract:DI
+           (match_dup 1)
+           (const_int 1)
+           (match_dup 2))
+         (const_int 0)))
+   (set (pc)
+       (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
+                     (label_ref (match_dup 4))
+                     (pc)))]
+{
+  operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
+
+  PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
+})
+
 (define_insn_and_split "*jcc_btsi"
   [(set (pc)
        (if_then_else (match_operator 0 "bt_comparison_operator"
   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
 })
 
+;; avoid useless masking of bit offset operand
+(define_insn_and_split "*jcc_btsi_mask"
+  [(set (pc)
+       (if_then_else (match_operator 0 "bt_comparison_operator"
+                       [(zero_extract:SI
+                          (match_operand:SI 1 "register_operand" "r")
+                          (const_int 1)
+                          (and:SI
+                            (match_operand:SI 2 "register_operand" "r")
+                            (match_operand:SI 3 "const_int_operand" "n")))])
+                     (label_ref (match_operand 4 "" ""))
+                     (pc)))]
+  "(TARGET_USE_BT || optimize_size)
+   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+       (compare:CCC
+         (zero_extract:SI
+           (match_dup 1)
+           (const_int 1)
+           (match_dup 2))
+         (const_int 0)))
+   (set (pc)
+       (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
+                     (label_ref (match_dup 4))
+                     (pc)))]
+  "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
+
 (define_insn_and_split "*jcc_btsi_1"
   [(set (pc)
        (if_then_else (match_operator 0 "bt_comparison_operator"
   PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
 })
 
+;; avoid useless masking of bit offset operand
+(define_insn_and_split "*jcc_btsi_mask_1"
+  [(set (pc)
+       (if_then_else
+         (match_operator 0 "bt_comparison_operator"
+           [(and:SI
+              (lshiftrt:SI
+                (match_operand:SI 1 "register_operand" "r")
+                (subreg:QI
+                  (and:SI
+                    (match_operand:SI 2 "register_operand" "r")
+                    (match_operand:SI 3 "const_int_operand" "n")) 0))
+              (const_int 1))
+            (const_int 0)])
+         (label_ref (match_operand 4 "" ""))
+         (pc)))]
+  "(TARGET_USE_BT || optimize_size)
+   && (INTVAL (operands[3]) & 0x1f) == 0x1f"
+  "#"
+  "&& 1"
+  [(set (reg:CCC FLAGS_REG)
+       (compare:CCC
+         (zero_extract:SI
+           (match_dup 1)
+           (const_int 1)
+           (match_dup 2))
+         (const_int 0)))
+   (set (pc)
+       (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
+                     (label_ref (match_dup 4))
+                     (pc)))]
+  "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
+
 ;; Define combination compare-and-branch fp compare instructions to use
 ;; during early optimization.  Splitting the operation apart early makes
 ;; for bad code when we want to reverse the operation.
index 1f6c771fa30b5715900a4b945a8783cd5a4e3847..072a5cb948f955451d287a4fa4a2cd485903e0f3 100644 (file)
@@ -1,8 +1,13 @@
+2008-06-10  Uros Bizjak  <ubizjak@gmail.com>
+
+       * gcc.target/i386/bt-mask-1.c: New test.
+       * gcc.target/i386/bt-mask-2.c: Ditto.
+
 2008-06-10  Uros Bizjak  <ubizjak@gmail.com>
 
        PR target/36473
-       * testsuite/gcc.target/i386/bt-1.c: New test.
-       * testsuite/gcc.target/i386/bt-2.c: Ditto.
+       * gcc.target/i386/bt-1.c: New test.
+       * gcc.target/i386/bt-2.c: Ditto.
 
 2008-06-09  Andy Hutchinson  <hutchinsonandy@aim.com>
 
diff --git a/gcc/testsuite/gcc.target/i386/bt-mask-1.c b/gcc/testsuite/gcc.target/i386/bt-mask-1.c
new file mode 100644 (file)
index 0000000..bdcfd55
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=core2" } */
+
+void foo (void);
+
+int test (int x, int n)
+{
+  n &= 0x1f;
+
+  if (x & (0x01 << n))
+    foo ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "and\[lq\]\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/bt-mask-2.c b/gcc/testsuite/gcc.target/i386/bt-mask-2.c
new file mode 100644 (file)
index 0000000..babfc2b
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=core2" } */
+
+void foo (void);
+
+int test (long x, long n)
+{
+  n &= 0x3f;
+
+  if (x & ((long)0x01 << n))
+    foo ();
+
+  return 0;
+}
+
+/* { dg-final { scan-assembler-not "and\[lq\]\[ \t\]" } } */