From 33ee5810003d5d7d6fb61b0af706cfac21d4ba6c Mon Sep 17 00:00:00 2001 From: Uros Bizjak Date: Tue, 10 Jun 2008 12:29:36 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 15 ++++ gcc/config/i386/i386.c | 2 +- gcc/config/i386/i386.md | 128 ++++++++++++++++++++++++++++++++++- gcc/config/i386/predicates.md | 3 + gcc/testsuite/ChangeLog | 24 ++++--- gcc/testsuite/gcc.target/i386/bt-1.c | 15 ++++ gcc/testsuite/gcc.target/i386/bt-2.c | 16 +++++ 7 files changed, 190 insertions(+), 13 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/bt-1.c create mode 100644 gcc/testsuite/gcc.target/i386/bt-2.c 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 + + 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 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 + + 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 * gcc.c-torture/execute/builtins/lib/chk.c: Only include sys/types.h @@ -47,8 +53,8 @@ 2008-06-08 Paolo Carlini - 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 @@ -127,8 +133,8 @@ 2008-06-07 Paolo Carlini - PR c++/35327 - * g++.dg/parse/crash41.C: New. + PR c++/35327 + * g++.dg/parse/crash41.C: New. 2008-06-06 Jakub Jelinek @@ -184,7 +190,7 @@ * gfortran.dg/proc_decl_2.f90: Extended. 2008-06-04 Joseph Myers - Maxim Kuvyrkov + Maxim Kuvyrkov * gcc.target/m68k/xgot-1.c: New test. @@ -240,8 +246,8 @@ 2008-06-02 Paolo Carlini - 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 @@ -304,8 +310,8 @@ 2008-05-29 Paolo Carlini - 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 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 } } } */ -- 2.7.4