re PR target/36473 (Generate bit test (bt) instructions)
authorUros Bizjak <uros@gcc.gnu.org>
Tue, 10 Jun 2008 10:29:36 +0000 (12:29 +0200)
committerUros Bizjak <uros@gcc.gnu.org>
Tue, 10 Jun 2008 10:29:36 +0000 (12:29 +0200)
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

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

index de089334244fe555da250e18d9a18a3c5e79c689..bd7d2048dc020227952951ad3d03c8c3decdfbca 100644 (file)
@@ -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
index e3feb30d01b64613bf49589754fb3b168b61af57..6fd4c0266d00a705ed65683e86501d351fec5b3c 100644 (file)
@@ -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),
index 6debb18d2a0a9a5bdbd3aae1d4e909cd0c5041cd..4da50afce2853370d38f985e82cd71e00ff9f09f 100644 (file)
        (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"
        (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"
        (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.
   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")])
 \f
 ;; Store-flag instructions.
 
     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.
index 5389aa998425ebed589fb3f16549561af583202e..4f2ff6b7c9f62e342aab74945623828787e3c542 100644 (file)
 (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")
index 09740f5b4f79c384ef7e650d1ed5d6b240369fb3..1f6c771fa30b5715900a4b945a8783cd5a4e3847 100644 (file)
@@ -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>
 
 
 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>
 
        * 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.
 
 
 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>
 
 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 (file)
index 0000000..3727155
--- /dev/null
@@ -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 (file)
index 0000000..34fa829
--- /dev/null
@@ -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 } } } */