Hello! Attached patch renames (obsolete) extv and extzv expanders to extv<mode> and extzv<mode>. Since the patch uses SImode for operands 2 and 3 on both, 32bit and 64bit targets, we can remove a couple of BT patterns that were used for DImode operands.
The patch also removes some modes from const_int operands and introduces constraints where needed. 2015-07-06 Uros Bizjak <ubiz...@gmail.com> * config/i386/i386.md (extv<mode>): Rename from extv. Use SWI24 modes for operands 0 and 1. Use SImode for operands 2 and 3. Copy operand 1 to a temporary if !ext_register_operand. Remove ancient extract_bit_field workaround. (*extv<mode>): Rename from *mov<mode>_extv_1. (*extvqi): Rename from *movqi_extv_q. (extzv<mode>): Rename from extzv. Use SWI248 modes for operands 0 and 1. Use SImode for operands 2 and 3. Copy operand 1 to a temporary if !ext_register_operand. Remove ancient extract_bit_field workaround. (*extzv<mode>): Rename from *mov<mode>_extzv_1. (*extzvqi): Rename from *movqi_extzv_1. (*testqi_ext_3): Remove modes from const_int_operand predicated operands. Add "n" constraint. (*btsq, *btrq, *btcq): Remove mode from const_0_to_63 predicated operand. Add "J" constraint. (*btsq, *btrq, *btcq peephole2s): Remove mode from const_0_to_63 predicated operand. (regmode): New insn attribute. (*bt<mode>): Use SImode for operand 1. Change operand 1 predicate to nonmemory_operand. Use regmode insn attribute. (*jcc_bt<mode>_1): Convert operand 2 to SImode. (*jcc_bt<mode>_mask): Remove mode from operand 3. (*jcc_btsi_1, *jcc_btsi_mask_1): Remove patterns. (tbm_bextri_<mode>): Remove modes from const_0_to_255 predicated operands. Use "N" constraint instead of "n". Tested on x86_64-linux-gnu {,-m32} and committed to mainline SVN. Uros.
Index: config/i386/i386.md =================================================================== --- config/i386/i386.md (revision 225432) +++ config/i386/i386.md (working copy) @@ -2675,7 +2675,22 @@ (set_attr "mode" "<MODE>") (set_attr "length_immediate" "0")]) -(define_insn "*mov<mode>_extv_1" +(define_expand "extv<mode>" + [(set (match_operand:SWI24 0 "register_operand") + (sign_extract:SWI24 (match_operand:SWI24 1 "register_operand") + (match_operand:SI 2 "const_int_operand") + (match_operand:SI 3 "const_int_operand")))] + "" +{ + /* Handle extractions from %ah et al. */ + if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) + FAIL; + + if (! ext_register_operand (operands[1], VOIDmode)) + operands[1] = copy_to_reg (operands[1]); +}) + +(define_insn "*extv<mode>" [(set (match_operand:SWI24 0 "register_operand" "=R") (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q") (const_int 8) @@ -2685,7 +2700,7 @@ [(set_attr "type" "imovx") (set_attr "mode" "SI")]) -(define_insn "*movqi_extv_1" +(define_insn "*extvqi" [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m") (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q") (const_int 8) @@ -2712,17 +2727,32 @@ (const_string "SI") (const_string "QI")))]) -(define_insn "*mov<mode>_extzv_1" - [(set (match_operand:SWI48 0 "register_operand" "=R") - (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q") - (const_int 8) - (const_int 8)))] +(define_expand "extzv<mode>" + [(set (match_operand:SWI248 0 "register_operand") + (zero_extract:SWI248 (match_operand:SWI248 1 "register_operand") + (match_operand:SI 2 "const_int_operand") + (match_operand:SI 3 "const_int_operand")))] "" +{ + /* Handle extractions from %ah et al. */ + if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) + FAIL; + + if (! ext_register_operand (operands[1], VOIDmode)) + operands[1] = copy_to_reg (operands[1]); +}) + +(define_insn "*extzv<mode>" + [(set (match_operand:SWI248 0 "register_operand" "=R") + (zero_extract:SWI248 (match_operand 1 "ext_register_operand" "Q") + (const_int 8) + (const_int 8)))] + "" "movz{bl|x}\t{%h1, %k0|%k0, %h1}" [(set_attr "type" "imovx") (set_attr "mode" "SI")]) -(define_insn "*movqi_extzv_2" +(define_insn "*extzvqi" [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m") (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q") @@ -2752,8 +2782,8 @@ (define_insn "mov<mode>_insv_1" [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q") - (const_int 8) - (const_int 8)) + (const_int 8) + (const_int 8)) (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))] "" { @@ -7583,8 +7613,8 @@ [(set (reg FLAGS_REG) (compare (zero_extract:SWI48 (match_operand 0 "nonimmediate_operand" "rm") - (match_operand:SWI48 1 "const_int_operand") - (match_operand:SWI48 2 "const_int_operand")) + (match_operand 1 "const_int_operand" "n") + (match_operand 2 "const_int_operand" "n")) (const_int 0)))] "ix86_match_ccmode (insn, CCNOmode) && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode) @@ -10578,40 +10608,6 @@ ;; Bit set / bit test instructions -(define_expand "extv" - [(set (match_operand:SI 0 "register_operand") - (sign_extract:SI (match_operand:SI 1 "register_operand") - (match_operand:SI 2 "const8_operand") - (match_operand:SI 3 "const8_operand")))] - "" -{ - /* Handle extractions from %ah et al. */ - if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) - FAIL; - - /* From mips.md: extract_bit_field doesn't verify that our source - matches the predicate, so check it again here. */ - if (! ext_register_operand (operands[1], VOIDmode)) - FAIL; -}) - -(define_expand "extzv" - [(set (match_operand:SI 0 "register_operand") - (zero_extract:SI (match_operand 1 "ext_register_operand") - (match_operand:SI 2 "const8_operand") - (match_operand:SI 3 "const8_operand")))] - "" -{ - /* Handle extractions from %ah et al. */ - if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8) - FAIL; - - /* From mips.md: extract_bit_field doesn't verify that our source - matches the predicate, so check it again here. */ - if (! ext_register_operand (operands[1], VOIDmode)) - FAIL; -}) - (define_expand "insv" [(set (zero_extract (match_operand 0 "register_operand") (match_operand 1 "const_int_operand") @@ -10656,7 +10652,7 @@ (define_insn "*btsq" [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") (const_int 1) - (match_operand:DI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand" "J")) (const_int 1)) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" @@ -10668,7 +10664,7 @@ (define_insn "*btrq" [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") (const_int 1) - (match_operand:DI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand" "J")) (const_int 0)) (clobber (reg:CC FLAGS_REG))] "TARGET_64BIT && (TARGET_USE_BT || reload_completed)" @@ -10680,7 +10676,7 @@ (define_insn "*btcq" [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r") (const_int 1) - (match_operand:DI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand" "J")) (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)" @@ -10696,7 +10692,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "register_operand") (const_int 1) - (match_operand:DI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (const_int 1)) (clobber (reg:CC FLAGS_REG))])] "TARGET_64BIT && !TARGET_USE_BT" @@ -10721,7 +10717,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "register_operand") (const_int 1) - (match_operand:DI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (const_int 0)) (clobber (reg:CC FLAGS_REG))])] "TARGET_64BIT && !TARGET_USE_BT" @@ -10746,7 +10742,7 @@ (parallel [(set (zero_extract:DI (match_operand:DI 0 "register_operand") (const_int 1) - (match_operand:DI 1 "const_0_to_63_operand")) + (match_operand 1 "const_0_to_63_operand")) (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1)))) (clobber (reg:CC FLAGS_REG))])] @@ -10767,6 +10763,8 @@ DONE; }) +(define_mode_attr regmode [(SI "k") (DI "q")]) + (define_insn "*bt<mode>" [(set (reg:CCC FLAGS_REG) (compare:CCC @@ -10773,10 +10771,10 @@ (zero_extract:SWI48 (match_operand:SWI48 0 "register_operand" "r") (const_int 1) - (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN")) + (match_operand:SI 1 "nonmemory_operand" "rN")) (const_int 0)))] "TARGET_USE_BT || optimize_function_for_size_p (cfun)" - "bt{<imodesuffix>}\t{%1, %0|%0, %1}" + "bt{<imodesuffix>}\t{%<regmode>1, %0|%0, %<regmode>1}" [(set_attr "type" "alu1") (set_attr "prefix_0f" "1") (set_attr "mode" "<MODE>")]) @@ -11036,11 +11034,6 @@ FAIL; }) -;; zero_extend in SImode is correct also for DImode, 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_bt<mode>" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" @@ -11047,8 +11040,7 @@ [(zero_extract:SWI48 (match_operand:SWI48 1 "register_operand" "r") (const_int 1) - (zero_extend:SI - (match_operand:QI 2 "register_operand" "r"))) + (match_operand:SI 2 "register_operand" "r")) (const_int 0)]) (label_ref (match_operand 3)) (pc))) @@ -11068,13 +11060,10 @@ (label_ref (match_dup 3)) (pc)))] { - operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0); operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) -;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode -;; zero extended to SImode. (define_insn_and_split "*jcc_bt<mode>_1" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" @@ -11081,7 +11070,8 @@ [(zero_extract:SWI48 (match_operand:SWI48 1 "register_operand" "r") (const_int 1) - (match_operand:SI 2 "register_operand" "r")) + (zero_extend:SI + (match_operand:QI 2 "register_operand" "r"))) (const_int 0)]) (label_ref (match_operand 3)) (pc))) @@ -11101,13 +11091,12 @@ (label_ref (match_dup 3)) (pc)))] { - operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0); + operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0); operands[0] = shallow_copy_rtx (operands[0]); PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); }) -;; Avoid useless masking of bit offset operand. "and" in SImode is correct -;; also for DImode, this is what combine produces. +;; Avoid useless masking of bit offset operand. (define_insn_and_split "*jcc_bt<mode>_mask" [(set (pc) (if_then_else (match_operator 0 "bt_comparison_operator" @@ -11116,7 +11105,7 @@ (const_int 1) (and:SI (match_operand:SI 2 "register_operand" "r") - (match_operand:SI 3 "const_int_operand" "n")))]) + (match_operand 3 "const_int_operand" "n")))]) (label_ref (match_operand 4)) (pc))) (clobber (reg:CC FLAGS_REG))] @@ -11137,80 +11126,10 @@ (label_ref (match_dup 4)) (pc)))] { - operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0); operands[0] = shallow_copy_rtx (operands[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))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_USE_BT || optimize_function_for_size_p (cfun)" - "#" - "&& 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); - operands[0] = shallow_copy_rtx (operands[0]); - 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))) - (clobber (reg:CC FLAGS_REG))] - "(TARGET_USE_BT || optimize_function_for_size_p (cfun)) - && (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)))] -{ - operands[0] = shallow_copy_rtx (operands[0]); - PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0]))); -}) - ;; Define combination compare-and-branch fp compare instructions to help ;; combine. @@ -12748,8 +12667,8 @@ [(set (match_operand:SWI48 0 "register_operand" "=r") (zero_extract:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm") - (match_operand:SWI48 2 "const_0_to_255_operand" "n") - (match_operand:SWI48 3 "const_0_to_255_operand" "n"))) + (match_operand 2 "const_0_to_255_operand" "N") + (match_operand 3 "const_0_to_255_operand" "N"))) (clobber (reg:CC FLAGS_REG))] "TARGET_TBM" {