diff options
author | Uros Bizjak <uros@gcc.gnu.org> | 2010-04-12 22:20:54 +0200 |
---|---|---|
committer | Uros Bizjak <uros@gcc.gnu.org> | 2010-04-12 22:20:54 +0200 |
commit | e0db9cc648242cbbea38cc3c559663acb501aee8 (patch) | |
tree | 9a4d5d39c4a0cf17232366e25ea5b59494809dfa | |
parent | 077c8adab1eabe459c25ca1419067a00dc2cbd6e (diff) | |
download | gcc-e0db9cc648242cbbea38cc3c559663acb501aee8.zip gcc-e0db9cc648242cbbea38cc3c559663acb501aee8.tar.gz gcc-e0db9cc648242cbbea38cc3c559663acb501aee8.tar.bz2 |
i386.md (any_rotate): New code iterator.
* config/i386/i386.md (any_rotate): New code iterator.
(rotate_insn): New code attribute.
(rotate): Ditto.
(SWIM124): New mode iterator.
(<rotate_insn>ti3): New expander.
(<rotate_insn>di3): Macroize expander from {rotl,rotr}di3 using
any_rotate code iterator.
(<rotate_insn><mode>3) Macroize expander from {rotl,rotr}{qi,hi,si}3
using any_rotate code iterator and SWIM124 mode iterator.
(ix86_rotlti3): New insn_and_split pattern.
(ix86_rotrti3): Ditto.
(ix86_rotl<dwi>3_doubleword): Macroize insn_and_split pattern from
ix86_rotl{di,ti}3 patterns.
(ix86_rotr<dwi>3_doubleword): Ditto from ix86_rotr{di,ti}3 patterns.
(*<rotate_insn><mode>3_1): Merge with *{rotl,rotr}{qi,hi,si}3_1_one_bit
and *{rotl,rotr}di3_1_one_bit_rex64. Macroize insn from
*{rotl,rotr}{qi,hi,si}3_1 and *{rotl,rotr}di3_1_rex64 using any_rotate
code iterator and SWI mode iterator.
(*<rotate_insn>si3_1_zext): Merge with *{rotl,rotr}si3_1_one_bit_zext.
Macroize insn from {rotl,rotr}si3_1_zext using any_rotate
code iterator.
(*<rotate_insn>qi3_1_slp): Merge with *{rotl,rotr}qi3_1_one_bit_slp.
Macroize insn from {rotl,rotr}qi3_1_slp using any_rotate code iterator.
(bswap rotatert splitter): Add splitter.
(bswap splitter): Macroize splitter using any_rotate code iterator.
Add insn predicate to split only for TARGET_USE_XCHGB or when
optimizing function for size.
testsuite/ChangeLog:
* gcc.target/i386/rotate-2.c: New test.
From-SVN: r158243
-rw-r--r-- | gcc/ChangeLog | 68 | ||||
-rw-r--r-- | gcc/config/i386/i386.md | 548 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/i386/rotate-2.c | 17 |
4 files changed, 219 insertions, 419 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e293d01..7c2a25d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,33 @@ +2010-04-12 Uros Bizjak <ubizjak@gmail.com> + + * config/i386/i386.md (any_rotate): New code iterator. + (rotate_insn): New code attribute. + (rotate): Ditto. + (SWIM124): New mode iterator. + (<rotate_insn>ti3): New expander. + (<rotate_insn>di3): Macroize expander from {rotl,rotr}di3 using + any_rotate code iterator. + (<rotate_insn><mode>3) Macroize expander from {rotl,rotr}{qi,hi,si}3 + using any_rotate code iterator and SWIM124 mode iterator. + (ix86_rotlti3): New insn_and_split pattern. + (ix86_rotrti3): Ditto. + (ix86_rotl<dwi>3_doubleword): Macroize insn_and_split pattern from + ix86_rotl{di,ti}3 patterns. + (ix86_rotr<dwi>3_doubleword): Ditto from ix86_rotr{di,ti}3 patterns. + (*<rotate_insn><mode>3_1): Merge with *{rotl,rotr}{qi,hi,si}3_1_one_bit + and *{rotl,rotr}di3_1_one_bit_rex64. Macroize insn from + *{rotl,rotr}{qi,hi,si}3_1 and *{rotl,rotr}di3_1_rex64 using any_rotate + code iterator and SWI mode iterator. + (*<rotate_insn>si3_1_zext): Merge with *{rotl,rotr}si3_1_one_bit_zext. + Macroize insn from {rotl,rotr}si3_1_zext using any_rotate + code iterator. + (*<rotate_insn>qi3_1_slp): Merge with *{rotl,rotr}qi3_1_one_bit_slp. + Macroize insn from {rotl,rotr}qi3_1_slp using any_rotate code iterator. + (bswap rotatert splitter): Add splitter. + (bswap splitter): Macroize splitter using any_rotate code iterator. + Add insn predicate to split only for TARGET_USE_XCHGB or when + optimizing function for size. + 2010-04-12 Steve Ellcey <sje@cup.hp.com> * config/pa/pa.c (emit_move_sequence): Remove use of @@ -95,8 +125,7 @@ * ipa.c (cgraph_postorder): Adjust postorder to guarantee single-iteration always-inline inlining. * ipa-inline.c (cgraph_mark_inline): Do not return anything. - (cgraph_decide_inlining): Do not handle always-inline - specially. + (cgraph_decide_inlining): Do not handle always-inline specially. (try_inline): Remove always-inline cycle detection special case. Do not recurse on always-inlines. (cgraph_early_inlining): Do not iterate if not optimizing. @@ -151,25 +180,20 @@ * config/i386/i386.md (any_shiftrt): New code iterator. (shiftrt_insn): New code attribute. (shiftrt): Ditto. - (<shiftrt_insn><mode>3): Macroize expander from ashr<mode>3 and - lshr<mode>3 using any_shiftrt code iterator. + (<shiftrt_insn><mode>3): Macroize expander from {ashr,lshr}<mode>3 + using any_shiftrt code iterator. (*<shiftrt_insn><mode>3_doubleword): Macroize insn_and_split from - *ashr<mode>3_doubleword and *lshr<mode>3_doubleword using - any_shiftrt code iterator. + *{ashr,lshr}<mode>3_doubleword using any_shiftrt code iterator. (*<shiftrt_insn><mode>3_doubleword peephole2): Macroize peephole2 pattern from corresponding peephole2 patterns. - (*<shiftrt_insn><mode>3_1): Macroize insn from *ashr<mode>3_1 - and *lshr<mode>3_1 using any_shiftrt code iterator. - (*<shiftrt_insn>si3_1_zext): Ditto from *ashrsi3_1_zext - and *lshrsi3_1_zext. - (*<shiftrt_insn>qi3_1_slp): Ditto from *ashrqi3_1_slp - and *lshrqi3_1_slp. - (*<shiftrt_insn><mode>3_cmp): Ditto from *ashr<mode>3_cmp - and *lshr<mode>3_cmp. - (*<shiftrt_insn><mode>3_cmp_zext): Ditto from *ashr<mode>3_cmp_zext - and *lshr<mode>3_cmp_zext. - (*<shiftrt_insn><mode>3_cconly): Ditto from *ashr<mode>3_cconly - and *lshr<mode>3_cconly. + (*<shiftrt_insn><mode>3_1): Macroize insn from *{ashr,lshr}<mode>3_1 + using any_shiftrt code iterator. + (*<shiftrt_insn>si3_1_zext): Ditto from *{ashr,lshr}si3_1_zext. + (*<shiftrt_insn>qi3_1_slp): Ditto from *{ashr,lshr}qi3_1_slp. + (*<shiftrt_insn><mode>3_cmp): Ditto from *{ashr,lshr}<mode>3_cmp. + (*<shiftrt_insn><mode>3_cmp_zext): Ditto from + *{ashr,lshr}<mode>3_cmp_zext. + (*<shiftrt_insn><mode>3_cconly): Ditto from *{ashr,lshr}<mode>3_cconly. 2010-04-11 Uros Bizjak <ubizjak@gmail.com> @@ -187,8 +211,8 @@ (*lshr<mode>3_doubleword peephole2): Macroize peephole2 pattern from corresponding peephole2 patterns. (*lshr<mode>3_1): Merge with *lshr{qi,hi,si}3_1_one_bit and - *lshrdi3_1_one_bit_rex64. Macroize insn from *lshr{qi,hi,si}3_cmp - and *lshrdi3_cmp_rex64 using SWI mode iterator. + *lshrdi3_1_one_bit_rex64. Macroize insn from *lshr{qi,hi,si}3_1 + and *lshrdi3_1_rex64 using SWI mode iterator. (*lshrsi3_1_zext): Merge with *lshrsi3_1_one_bit_zext. (*lshrqi3_1_slp): Merge with *lshrqi3_1_one_bit_slp. (*lshr<mode>3_cmp): Merge with *lshr{qi,hi,si}3_one_bit_cmp and @@ -215,8 +239,8 @@ (x86_shift<mode>_adj_3): Macroize expander from x86_shift_adj_3 and x86_64_shift_adj_3 using SWI48 mode iterator. (*ashr<mode>3_1): Merge with *ashr{qi,hi,si}3_1_one_bit and - *ashrdi3_1_one_bit_rex64. Macroize insn from *ashr{qi,hi,si}3_cmp - and *ashrdi3_cmp_rex64 using SWI mode iterator. + *ashrdi3_1_one_bit_rex64. Macroize insn from *ashr{qi,hi,si}3_1 + and *ashrdi3_1_rex64 using SWI mode iterator. (*ashrsi3_1_zext): Merge with *ashrsi3_1_one_bit_zext. (*ashrqi3_1_slp): Merge with *ashrqi3_1_one_bit_slp. (*ashr<mode>3_cmp): Merge with *ashr{qi,hi,si}3_one_bit_cmp and diff --git a/gcc/config/i386/i386.md b/gcc/config/i386/i386.md index abe09cf..411feaf 100644 --- a/gcc/config/i386/i386.md +++ b/gcc/config/i386/i386.md @@ -733,6 +733,15 @@ ;; Base name for insn mnemonic. (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")]) +;; Mapping of rotate operators +(define_code_iterator any_rotate [rotate rotatert]) + +;; Base name for define_insn +(define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")]) + +;; Base name for insn mnemonic. +(define_code_attr rotate [(rotate "rol") (rotatert "ror")]) + ;; Mapping of abs neg operators (define_code_iterator absneg [abs neg]) @@ -776,6 +785,11 @@ (HI "TARGET_HIMODE_MATH") SI (DI "TARGET_64BIT")]) +;; Math-dependant single word integer modes without DImode. +(define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH") + (HI "TARGET_HIMODE_MATH") + SI]) + ;; Math-dependant single word integer modes without QImode. (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH") SI (DI "TARGET_64BIT")]) @@ -10542,451 +10556,193 @@ ;; Rotate instructions -(define_expand "rotldi3" +(define_expand "<rotate_insn>ti3" + [(set (match_operand:TI 0 "register_operand" "") + (any_rotate:TI (match_operand:TI 1 "register_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] + "TARGET_64BIT" +{ + if (const_1_to_63_operand (operands[2], VOIDmode)) + emit_insn (gen_ix86_<rotate_insn>ti3_doubleword + (operands[0], operands[1], operands[2])); + else + FAIL; + + DONE; +}) + +(define_expand "<rotate_insn>di3" [(set (match_operand:DI 0 "shiftdi_operand" "") - (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] + (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] "" { if (TARGET_64BIT) - { - ix86_expand_binary_operator (ROTATE, DImode, operands); - DONE; - } - if (!const_1_to_31_operand (operands[2], VOIDmode)) + ix86_expand_binary_operator (<CODE>, DImode, operands); + else if (const_1_to_31_operand (operands[2], VOIDmode)) + emit_insn (gen_ix86_<rotate_insn>di3_doubleword + (operands[0], operands[1], operands[2])); + else FAIL; - emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2])); + DONE; }) -;; Implement rotation using two double-precision shift instructions -;; and a scratch register. -(define_insn_and_split "ix86_rotldi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (rotate:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "const_1_to_31_operand" "I"))) +(define_expand "<rotate_insn><mode>3" + [(set (match_operand:SWIM124 0 "nonimmediate_operand" "") + (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "") + (match_operand:QI 2 "nonmemory_operand" "")))] + "" + "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;") + +;; Implement rotation using two double-precision +;; shift instructions and a scratch register. + +(define_insn_and_split "ix86_rotl<dwi>3_doubleword" + [(set (match_operand:<DWI> 0 "register_operand" "=r") + (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0") + (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) (clobber (reg:CC FLAGS_REG)) - (clobber (match_scratch:SI 3 "=&r"))] - "!TARGET_64BIT" + (clobber (match_scratch:DWIH 3 "=&r"))] "" - "&& reload_completed" + "#" + "reload_completed" [(set (match_dup 3) (match_dup 4)) (parallel [(set (match_dup 4) - (ior:SI (ashift:SI (match_dup 4) (match_dup 2)) - (lshiftrt:SI (match_dup 5) - (minus:QI (const_int 32) (match_dup 2))))) + (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2)) + (lshiftrt:DWIH (match_dup 5) + (minus:QI (match_dup 6) (match_dup 2))))) (clobber (reg:CC FLAGS_REG))]) (parallel [(set (match_dup 5) - (ior:SI (ashift:SI (match_dup 5) (match_dup 2)) - (lshiftrt:SI (match_dup 3) - (minus:QI (const_int 32) (match_dup 2))))) + (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2)) + (lshiftrt:DWIH (match_dup 3) + (minus:QI (match_dup 6) (match_dup 2))))) (clobber (reg:CC FLAGS_REG))])] - "split_di (&operands[0], 1, &operands[4], &operands[5]);") - -(define_insn "*rotlsi3_1_one_bit_rex64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATE, DImode, operands)" - "rol{q}\t%0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "DI")]) - -(define_insn "*rotldi3_1_rex64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") - (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "e,c"))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)" - "@ - rol{q}\t{%2, %0|%0, %2} - rol{q}\t{%b2, %0|%0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "DI")]) - -(define_expand "rotlsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;") - -(define_insn "*rotlsi3_1_one_bit" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATE, SImode, operands)" - "rol{l}\t%0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "SI")]) - -(define_insn "*rotlsi3_1_one_bit_zext" - [(set (match_operand:DI 0 "register_operand" "=r") - (zero_extend:DI - (rotate:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:QI 2 "const1_operand" "")))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATE, SImode, operands)" - "rol{l}\t%k0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "SI")]) - -(define_insn "*rotlsi3_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") - (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "I,c"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ROTATE, SImode, operands)" - "@ - rol{l}\t{%2, %0|%0, %2} - rol{l}\t{%b2, %0|%0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "SI")]) - -(define_insn "*rotlsi3_1_zext" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI - (rotate:SI (match_operand:SI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "I,c")))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)" - "@ - rol{l}\t{%2, %k0|%k0, %2} - rol{l}\t{%b2, %k0|%k0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "SI")]) - -(define_expand "rotlhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "") - (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "TARGET_HIMODE_MATH" - "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;") - -(define_insn "*rotlhi3_1_one_bit" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") - (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATE, HImode, operands)" - "rol{w}\t%0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "HI")]) - -(define_insn "*rotlhi3_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") - (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "I,c"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ROTATE, HImode, operands)" - "@ - rol{w}\t{%2, %0|%0, %2} - rol{w}\t{%b2, %0|%0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "HI")]) - -(define_split - [(set (match_operand:HI 0 "register_operand" "") - (rotate:HI (match_dup 0) (const_int 8))) - (clobber (reg:CC FLAGS_REG))] - "reload_completed" - [(parallel [(set (strict_low_part (match_dup 0)) - (bswap:HI (match_dup 0))) - (clobber (reg:CC FLAGS_REG))])] - "") - -(define_expand "rotlqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "TARGET_QIMODE_MATH" - "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;") - -(define_insn "*rotlqi3_1_one_bit_slp" - [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) - (rotate:QI (match_dup 0) - (match_operand:QI 1 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))" - "rol{b}\t%0" - [(set_attr "type" "rotate1") - (set_attr "length_immediate" "0") - (set_attr "mode" "QI")]) - -(define_insn "*rotlqi3_1_one_bit" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") - (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATE, QImode, operands)" - "rol{b}\t%0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "QI")]) - -(define_insn "*rotlqi3_1_slp" - [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) - (rotate:QI (match_dup 0) - (match_operand:QI 1 "nonmemory_operand" "I,c"))) - (clobber (reg:CC FLAGS_REG))] - "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) - && !(MEM_P (operands[0]) && MEM_P (operands[1]))" - "@ - rol{b}\t{%1, %0|%0, %1} - rol{b}\t{%b1, %0|%0, %b1}" - [(set_attr "type" "rotate1") - (set_attr "mode" "QI")]) - -(define_insn "*rotlqi3_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") - (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "I,c"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ROTATE, QImode, operands)" - "@ - rol{b}\t{%2, %0|%0, %2} - rol{b}\t{%b2, %0|%0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "QI")]) - -(define_expand "rotrdi3" - [(set (match_operand:DI 0 "shiftdi_operand" "") - (rotate:DI (match_operand:DI 1 "shiftdi_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" { - if (TARGET_64BIT) - { - ix86_expand_binary_operator (ROTATERT, DImode, operands); - DONE; - } - if (!const_1_to_31_operand (operands[2], VOIDmode)) - FAIL; - emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2])); - DONE; + operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); + + split_<dwi> (&operands[0], 1, &operands[4], &operands[5]); }) -;; Implement rotation using two double-precision shift instructions -;; and a scratch register. -(define_insn_and_split "ix86_rotrdi3" - [(set (match_operand:DI 0 "register_operand" "=r") - (rotatert:DI (match_operand:DI 1 "register_operand" "0") - (match_operand:QI 2 "const_1_to_31_operand" "I"))) +(define_insn_and_split "ix86_rotr<dwi>3_doubleword" + [(set (match_operand:<DWI> 0 "register_operand" "=r") + (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0") + (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))) (clobber (reg:CC FLAGS_REG)) - (clobber (match_scratch:SI 3 "=&r"))] - "!TARGET_64BIT" + (clobber (match_scratch:DWIH 3 "=&r"))] "" - "&& reload_completed" + "#" + "reload_completed" [(set (match_dup 3) (match_dup 4)) (parallel [(set (match_dup 4) - (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2)) - (ashift:SI (match_dup 5) - (minus:QI (const_int 32) (match_dup 2))))) + (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2)) + (ashift:DWIH (match_dup 5) + (minus:QI (match_dup 6) (match_dup 2))))) (clobber (reg:CC FLAGS_REG))]) (parallel [(set (match_dup 5) - (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2)) - (ashift:SI (match_dup 3) - (minus:QI (const_int 32) (match_dup 2))))) + (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2)) + (ashift:DWIH (match_dup 3) + (minus:QI (match_dup 6) (match_dup 2))))) (clobber (reg:CC FLAGS_REG))])] - "split_di (&operands[0], 1, &operands[4], &operands[5]);") - -(define_insn "*rotrdi3_1_one_bit_rex64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm") - (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATERT, DImode, operands)" - "ror{q}\t%0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "DI")]) - -(define_insn "*rotrdi3_1_rex64" - [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm") - (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "J,c"))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)" - "@ - ror{q}\t{%2, %0|%0, %2} - ror{q}\t{%b2, %0|%0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "DI")]) +{ + operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); -(define_expand "rotrsi3" - [(set (match_operand:SI 0 "nonimmediate_operand" "") - (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "" - "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;") + split_<dwi> (&operands[0], 1, &operands[4], &operands[5]); +}) -(define_insn "*rotrsi3_1_one_bit" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") - (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" ""))) +(define_insn "*<rotate_insn><mode>3_1" + [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m") + (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "c<S>"))) (clobber (reg:CC FLAGS_REG))] - "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATERT, SImode, operands)" - "ror{l}\t%0" + "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)" +{ + if (REG_P (operands[2])) + return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}"; + else if (operands[2] == const1_rtx + && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) + return "<rotate>{<imodesuffix>}\t%0"; + else + return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}"; +} [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "SI")]) + (set (attr "length_immediate") + (if_then_else + (and (match_operand 2 "const1_operand" "") + (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") + (const_int 0))) + (const_string "0") + (const_string "*"))) + (set_attr "mode" "<MODE>")]) -(define_insn "*rotrsi3_1_one_bit_zext" +(define_insn "*<rotate_insn>si3_1_zext" [(set (match_operand:DI 0 "register_operand" "=r") (zero_extend:DI - (rotatert:SI (match_operand:SI 1 "register_operand" "0") - (match_operand:QI 2 "const1_operand" "")))) - (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATERT, SImode, operands)" - "ror{l}\t%k0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "SI")]) - -(define_insn "*rotrsi3_1" - [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm") - (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "I,c"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ROTATERT, SImode, operands)" - "@ - ror{l}\t{%2, %0|%0, %2} - ror{l}\t{%b2, %0|%0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "SI")]) - -(define_insn "*rotrsi3_1_zext" - [(set (match_operand:DI 0 "register_operand" "=r,r") - (zero_extend:DI - (rotatert:SI (match_operand:SI 1 "register_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "I,c")))) + (any_rotate:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:QI 2 "nonmemory_operand" "cI")))) (clobber (reg:CC FLAGS_REG))] - "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" - "@ - ror{l}\t{%2, %k0|%k0, %2} - ror{l}\t{%b2, %k0|%k0, %b2}" + "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)" +{ + if (REG_P (operands[2])) + return "<rotate>{l}\t{%b2, %k0|%k0, %b2}"; + else if (operands[2] == const1_rtx + && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) + return "<rotate>{l}\t%k0"; + else + return "<rotate>{l}\t{%2, %k0|%k0, %2}"; +} [(set_attr "type" "rotate") + (set (attr "length_immediate") + (if_then_else + (and (match_operand 2 "const1_operand" "") + (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") + (const_int 0))) + (const_string "0") + (const_string "*"))) (set_attr "mode" "SI")]) -(define_expand "rotrhi3" - [(set (match_operand:HI 0 "nonimmediate_operand" "") - (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "TARGET_HIMODE_MATH" - "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;") - -(define_insn "*rotrhi3_one_bit" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm") - (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATERT, HImode, operands)" - "ror{w}\t%0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "HI")]) - -(define_insn "*rotrhi3_1" - [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm") - (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "I,c"))) +(define_insn "*<rotate_insn>qi3_1_slp" + [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) + (any_rotate:QI (match_dup 0) + (match_operand:QI 1 "nonmemory_operand" "cI"))) (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ROTATERT, HImode, operands)" - "@ - ror{w}\t{%2, %0|%0, %2} - ror{w}\t{%b2, %0|%0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "HI")]) + "(optimize_function_for_size_p (cfun) + || !TARGET_PARTIAL_REG_STALL + || (operands[1] == const1_rtx + && TARGET_SHIFT1))" +{ + if (REG_P (operands[1])) + return "<rotate>{b}\t{%b1, %0|%0, %b1}"; + else if (operands[1] == const1_rtx + && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))) + return "<rotate>{b}\t%0"; + else + return "<rotate>{b}\t{%1, %0|%0, %1}"; +} + [(set_attr "type" "rotate1") + (set (attr "length_immediate") + (if_then_else + (and (match_operand 1 "const1_operand" "") + (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)") + (const_int 0))) + (const_string "0") + (const_string "*"))) + (set_attr "mode" "QI")]) (define_split [(set (match_operand:HI 0 "register_operand" "") - (rotatert:HI (match_dup 0) (const_int 8))) + (any_rotate:HI (match_dup 0) (const_int 8))) (clobber (reg:CC FLAGS_REG))] - "reload_completed" + "reload_completed + && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))" [(parallel [(set (strict_low_part (match_dup 0)) (bswap:HI (match_dup 0))) (clobber (reg:CC FLAGS_REG))])] "") - -(define_expand "rotrqi3" - [(set (match_operand:QI 0 "nonimmediate_operand" "") - (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "") - (match_operand:QI 2 "nonmemory_operand" "")))] - "TARGET_QIMODE_MATH" - "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;") - -(define_insn "*rotrqi3_1_one_bit" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm") - (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0") - (match_operand:QI 2 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) - && ix86_binary_operator_ok (ROTATERT, QImode, operands)" - "ror{b}\t%0" - [(set_attr "type" "rotate") - (set_attr "length_immediate" "0") - (set_attr "mode" "QI")]) - -(define_insn "*rotrqi3_1_one_bit_slp" - [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm")) - (rotatert:QI (match_dup 0) - (match_operand:QI 1 "const1_operand" ""))) - (clobber (reg:CC FLAGS_REG))] - "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) - && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))" - "ror{b}\t%0" - [(set_attr "type" "rotate1") - (set_attr "length_immediate" "0") - (set_attr "mode" "QI")]) - -(define_insn "*rotrqi3_1" - [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm") - (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0") - (match_operand:QI 2 "nonmemory_operand" "I,c"))) - (clobber (reg:CC FLAGS_REG))] - "ix86_binary_operator_ok (ROTATERT, QImode, operands)" - "@ - ror{b}\t{%2, %0|%0, %2} - ror{b}\t{%b2, %0|%0, %b2}" - [(set_attr "type" "rotate") - (set_attr "mode" "QI")]) - -(define_insn "*rotrqi3_1_slp" - [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm")) - (rotatert:QI (match_dup 0) - (match_operand:QI 1 "nonmemory_operand" "I,c"))) - (clobber (reg:CC FLAGS_REG))] - "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)) - && !(MEM_P (operands[0]) && MEM_P (operands[1]))" - "@ - ror{b}\t{%1, %0|%0, %1} - ror{b}\t{%b1, %0|%0, %b1}" - [(set_attr "type" "rotate1") - (set_attr "mode" "QI")]) ;; Bit set / bit test instructions diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 03bfcc0..68e4aa9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,8 +1,11 @@ +2010-04-12 Uros Bizjak <ubizjak@gmail.com> + + * gcc.target/i386/rotate-2.c: New test. + 2010-04-12 Jason Merrill <jason@redhat.com> PR c++/43641 * g++.dg/cpp0x/lambda/lambda-conv4.C: New. - * g++.dg/cpp0x/lambda/lambda-deduce2.C: New. 2010-04-12 Fabien Chene <fabien.chene@gmail.com> diff --git a/gcc/testsuite/gcc.target/i386/rotate-2.c b/gcc/testsuite/gcc.target/i386/rotate-2.c new file mode 100644 index 0000000..69a0625 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/rotate-2.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-options "-O2" } */ + +typedef unsigned int UTItype __attribute__ ((mode (TI))); + +void foo (UTItype *); + +UTItype +test (void) +{ + UTItype c = 0; + foo (&c); + c = c >> 5 | c << 123; + return c; +} +/* { dg-final { scan-assembler-times "shrdq" 2 } } */ |