aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2008-06-10 18:50:23 +0000
committerUros Bizjak <ubizjak@gmail.com>2008-06-10 18:50:23 +0000
commit88ef3c63ffcf384ae60937cd4aa0f92c9138f28b (patch)
treeb5e9c0865ee8dd8c7864bd6bd254cb9564f5e0a3
parentb0a1aa02b99239532647cd9e07906e39cda4481b (diff)
* 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. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@136636 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/i386/i386.md99
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.target/i386/bt-mask-1.c16
-rw-r--r--gcc/testsuite/gcc.target/i386/bt-mask-2.c16
5 files changed, 145 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6a2080da1c4..4fcc73f30c7 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 4da50afce28..ca01494871f 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -13819,7 +13819,7 @@
(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}"
@@ -13831,7 +13831,7 @@
(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}"
@@ -14117,6 +14117,39 @@
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"
@@ -14148,6 +14181,35 @@
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"
@@ -14179,6 +14241,39 @@
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.
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1f6c771fa30..072a5cb948f 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
index 00000000000..bdcfd558a1b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bt-mask-1.c
@@ -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
index 00000000000..babfc2bcd36
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bt-mask-2.c
@@ -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\]" } } */