aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <uros@gcc.gnu.org>2008-06-10 12:29:36 +0200
committerUros Bizjak <uros@gcc.gnu.org>2008-06-10 12:29:36 +0200
commit33ee5810003d5d7d6fb61b0af706cfac21d4ba6c (patch)
treeadb12f0c0cddf0e92f91c40cfd912d8549be148b
parentf1ebbb579c845765a4ca795bb82b58738f83b796 (diff)
downloadgcc-33ee5810003d5d7d6fb61b0af706cfac21d4ba6c.zip
gcc-33ee5810003d5d7d6fb61b0af706cfac21d4ba6c.tar.gz
gcc-33ee5810003d5d7d6fb61b0af706cfac21d4ba6c.tar.bz2
re PR target/36473 (Generate bit test (bt) instructions)
PR target/36473 * config/i386/i386.c (ix86_tune_features) [TUNE_USE_BT]: Add m_CORE2 and m_GENERIC. * config/i386/predicates.md (bt_comparison_operator): New predicate. * config/i386/i386.md (*btdi_rex64): New instruction pattern. (*btsi): Ditto. (*jcc_btdi_rex64): New instruction and split pattern. (*jcc_btsi): Ditto. (*jcc_btsi_1): Ditto. (*btsq): Fix Intel asm dialect operand order. (*btrq): Ditto. (*btcq): Ditto. testsuite/ChangeLog: PR target/36473 * testsuite/gcc.target/i386/bt-1.c: New test. * testsuite/gcc.target/i386/bt-2.c: Ditto. From-SVN: r136615
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/config/i386/i386.c2
-rw-r--r--gcc/config/i386/i386.md128
-rw-r--r--gcc/config/i386/predicates.md3
-rw-r--r--gcc/testsuite/ChangeLog24
-rw-r--r--gcc/testsuite/gcc.target/i386/bt-1.c15
-rw-r--r--gcc/testsuite/gcc.target/i386/bt-2.c16
7 files changed, 190 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index de08933..bd7d204 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2008-06-10 Uros Bizjak <ubizjak@gmail.com>
+
+ PR target/36473
+ * config/i386/i386.c (ix86_tune_features) [TUNE_USE_BT]:
+ Add m_CORE2 and m_GENERIC.
+ * config/i386/predicates.md (bt_comparison_operator): New predicate.
+ * config/i386/i386.md (*btdi_rex64): New instruction pattern.
+ (*btsi): Ditto.
+ (*jcc_btdi_rex64): New instruction and split pattern.
+ (*jcc_btsi): Ditto.
+ (*jcc_btsi_1): Ditto.
+ (*btsq): Fix Intel asm dialect operand order.
+ (*btrq): Ditto.
+ (*btcq): Ditto.
+
2008-06-09 Andy Hutchinson <hutchinsonandy@aim.com>
PR middle-end/36447
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index e3feb30..6fd4c02 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -1390,7 +1390,7 @@ unsigned int ix86_tune_features[X86_TUNE_LAST] = {
m_PPRO | m_AMD_MULTIPLE | m_K6_GEODE | m_PENT | m_CORE2 | m_GENERIC,
/* X86_TUNE_USE_BT */
- m_AMD_MULTIPLE,
+ m_AMD_MULTIPLE | m_CORE2 | m_GENERIC,
/* X86_TUNE_USE_INCDEC */
~(m_PENT4 | m_NOCONA | m_GENERIC),
diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md
index 6debb18..4da50af 100644
--- a/gcc/config/i386/i386.md
+++ b/gcc/config/i386/i386.md
@@ -13691,7 +13691,7 @@
(const_int 1))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
- "bts{q} %1,%0"
+ "bts{q}\t{%1, %0|%0, %1}"
[(set_attr "type" "alu1")])
(define_insn "*btrq"
@@ -13701,7 +13701,7 @@
(const_int 0))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
- "btr{q} %1,%0"
+ "btr{q}\t{%1, %0|%0, %1}"
[(set_attr "type" "alu1")])
(define_insn "*btcq"
@@ -13711,7 +13711,7 @@
(not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
(clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
- "btc{q} %1,%0"
+ "btc{q}\t{%1, %0|%0, %1}"
[(set_attr "type" "alu1")])
;; Allow Nocona to avoid these instructions if a register is available.
@@ -13812,6 +13812,30 @@
emit_insn (gen_xordi3 (operands[0], operands[0], op1));
DONE;
})
+
+(define_insn "*btdi_rex64"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (zero_extract:DI
+ (match_operand:DI 0 "register_operand" "r")
+ (const_int 1)
+ (match_operand:DI 1 "register_operand" "r"))
+ (const_int 0)))]
+ "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
+ "bt{q}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "alu1")])
+
+(define_insn "*btsi"
+ [(set (reg:CCC FLAGS_REG)
+ (compare:CCC
+ (zero_extract:SI
+ (match_operand:SI 0 "register_operand" "r")
+ (const_int 1)
+ (match_operand:SI 1 "register_operand" "r"))
+ (const_int 0)))]
+ "TARGET_USE_BT || optimize_size"
+ "bt{l}\t{%1, %0|%0, %1}"
+ [(set_attr "type" "alu1")])
;; Store-flag instructions.
@@ -14057,6 +14081,104 @@
FAIL;
})
+;; zero_extend in SImode is correct, since this is what combine pass
+;; generates from shift insn with QImode operand. Actually, the mode of
+;; operand 2 (bit offset operand) doesn't matter since bt insn takes
+;; appropriate modulo of the bit offset value.
+
+(define_insn_and_split "*jcc_btdi_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)
+ (zero_extend:SI
+ (match_operand:QI 2 "register_operand" "r")))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_64BIT && (TARGET_USE_BT || optimize_size)"
+ "#"
+ "&& 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 3))
+ (pc)))]
+{
+ operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 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"
+ [(zero_extract:SI
+ (match_operand:SI 1 "register_operand" "r")
+ (const_int 1)
+ (zero_extend:SI
+ (match_operand:QI 2 "register_operand" "r")))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_USE_BT || optimize_size"
+ "#"
+ "&& 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 3))
+ (pc)))]
+{
+ operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
+
+ 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"
+ [(and:SI
+ (lshiftrt:SI
+ (match_operand:SI 1 "register_operand" "r")
+ (match_operand:QI 2 "register_operand" "r"))
+ (const_int 1))
+ (const_int 0)])
+ (label_ref (match_operand 3 "" ""))
+ (pc)))]
+ "TARGET_USE_BT || optimize_size"
+ "#"
+ "&& 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 3))
+ (pc)))]
+{
+ operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
+
+ 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/config/i386/predicates.md b/gcc/config/i386/predicates.md
index 5389aa9..4f2ff6b 100644
--- a/gcc/config/i386/predicates.md
+++ b/gcc/config/i386/predicates.md
@@ -920,6 +920,9 @@
(define_predicate "ix86_comparison_uns_operator"
(match_code "ne,eq,geu,gtu,leu,ltu"))
+(define_predicate "bt_comparison_operator"
+ (match_code "ne,eq"))
+
;; Return 1 if OP is a valid comparison operator in valid mode.
(define_predicate "ix86_comparison_operator"
(match_operand 0 "comparison_operator")
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 09740f5..1f6c771 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+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.
+
2008-06-09 Andy Hutchinson <hutchinsonandy@aim.com>
* gcc.c-torture/execute/builtins/lib/chk.c: Only include sys/types.h
@@ -47,8 +53,8 @@
2008-06-08 Paolo Carlini <paolo.carlini@oracle.com>
- PR c++/35242
- * g++.dg/cpp0x/vt-35242.C: New.
+ PR c++/35242
+ * g++.dg/cpp0x/vt-35242.C: New.
2008-06-08 Janus Weil <janus@gcc.gnu.org>
@@ -127,8 +133,8 @@
2008-06-07 Paolo Carlini <paolo.carlini@oracle.com>
- PR c++/35327
- * g++.dg/parse/crash41.C: New.
+ PR c++/35327
+ * g++.dg/parse/crash41.C: New.
2008-06-06 Jakub Jelinek <jakub@redhat.com>
@@ -184,7 +190,7 @@
* gfortran.dg/proc_decl_2.f90: Extended.
2008-06-04 Joseph Myers <joseph@codesourcery.com>
- Maxim Kuvyrkov <maxim@codesourcery.com>
+ Maxim Kuvyrkov <maxim@codesourcery.com>
* gcc.target/m68k/xgot-1.c: New test.
@@ -240,8 +246,8 @@
2008-06-02 Paolo Carlini <paolo.carlini@oracle.com>
- PR c++/36404
- * g++.dg/template/crash79.C: New.
+ PR c++/36404
+ * g++.dg/template/crash79.C: New.
* g++.dg/other/pr28114.C: Adjust.
2008-06-02 Daniel Kraft <d@domob.eu>
@@ -304,8 +310,8 @@
2008-05-29 Paolo Carlini <paolo.carlini@oracle.com>
- PR c++/35243
- * g++.dg/cpp0x/vt-35243.C: New.
+ PR c++/35243
+ * g++.dg/cpp0x/vt-35243.C: New.
2008-05-29 H.J. Lu <hongjiu.lu@intel.com>
diff --git a/gcc/testsuite/gcc.target/i386/bt-1.c b/gcc/testsuite/gcc.target/i386/bt-1.c
new file mode 100644
index 0000000..3727155
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bt-1.c
@@ -0,0 +1,15 @@
+/* PR target/36473 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=core2" } */
+
+extern void foo (void);
+
+int test(int x, int n)
+{
+ if (x & ( 0x01 << n ))
+ foo ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler "btl\[ \t\]" } } */
diff --git a/gcc/testsuite/gcc.target/i386/bt-2.c b/gcc/testsuite/gcc.target/i386/bt-2.c
new file mode 100644
index 0000000..34fa829
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/bt-2.c
@@ -0,0 +1,16 @@
+/* PR target/36473 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mtune=core2" } */
+
+extern void foo (void);
+
+int test(long x, long n)
+{
+ if (x & ( (long)0x01 << n ))
+ foo ();
+
+ return 0;
+}
+
+/* { dg-final { scan-assembler "btl\[ \t\]" { target { ! lp64 } } } } */
+/* { dg-final { scan-assembler "btq\[ \t\]" { target lp64 } } } */