Commit e0db9cc6 by Uros Bizjak

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
parent 077c8ada
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> 2010-04-12 Steve Ellcey <sje@cup.hp.com>
* config/pa/pa.c (emit_move_sequence): Remove use of * config/pa/pa.c (emit_move_sequence): Remove use of
...@@ -95,8 +125,7 @@ ...@@ -95,8 +125,7 @@
* ipa.c (cgraph_postorder): Adjust postorder to guarantee * ipa.c (cgraph_postorder): Adjust postorder to guarantee
single-iteration always-inline inlining. single-iteration always-inline inlining.
* ipa-inline.c (cgraph_mark_inline): Do not return anything. * ipa-inline.c (cgraph_mark_inline): Do not return anything.
(cgraph_decide_inlining): Do not handle always-inline (cgraph_decide_inlining): Do not handle always-inline specially.
specially.
(try_inline): Remove always-inline cycle detection special case. (try_inline): Remove always-inline cycle detection special case.
Do not recurse on always-inlines. Do not recurse on always-inlines.
(cgraph_early_inlining): Do not iterate if not optimizing. (cgraph_early_inlining): Do not iterate if not optimizing.
...@@ -151,25 +180,20 @@ ...@@ -151,25 +180,20 @@
* config/i386/i386.md (any_shiftrt): New code iterator. * config/i386/i386.md (any_shiftrt): New code iterator.
(shiftrt_insn): New code attribute. (shiftrt_insn): New code attribute.
(shiftrt): Ditto. (shiftrt): Ditto.
(<shiftrt_insn><mode>3): Macroize expander from ashr<mode>3 and (<shiftrt_insn><mode>3): Macroize expander from {ashr,lshr}<mode>3
lshr<mode>3 using any_shiftrt code iterator. using any_shiftrt code iterator.
(*<shiftrt_insn><mode>3_doubleword): Macroize insn_and_split from (*<shiftrt_insn><mode>3_doubleword): Macroize insn_and_split from
*ashr<mode>3_doubleword and *lshr<mode>3_doubleword using *{ashr,lshr}<mode>3_doubleword using any_shiftrt code iterator.
any_shiftrt code iterator.
(*<shiftrt_insn><mode>3_doubleword peephole2): Macroize peephole2 (*<shiftrt_insn><mode>3_doubleword peephole2): Macroize peephole2
pattern from corresponding peephole2 patterns. pattern from corresponding peephole2 patterns.
(*<shiftrt_insn><mode>3_1): Macroize insn from *ashr<mode>3_1 (*<shiftrt_insn><mode>3_1): Macroize insn from *{ashr,lshr}<mode>3_1
and *lshr<mode>3_1 using any_shiftrt code iterator. using any_shiftrt code iterator.
(*<shiftrt_insn>si3_1_zext): Ditto from *ashrsi3_1_zext (*<shiftrt_insn>si3_1_zext): Ditto from *{ashr,lshr}si3_1_zext.
and *lshrsi3_1_zext. (*<shiftrt_insn>qi3_1_slp): Ditto from *{ashr,lshr}qi3_1_slp.
(*<shiftrt_insn>qi3_1_slp): Ditto from *ashrqi3_1_slp (*<shiftrt_insn><mode>3_cmp): Ditto from *{ashr,lshr}<mode>3_cmp.
and *lshrqi3_1_slp. (*<shiftrt_insn><mode>3_cmp_zext): Ditto from
(*<shiftrt_insn><mode>3_cmp): Ditto from *ashr<mode>3_cmp *{ashr,lshr}<mode>3_cmp_zext.
and *lshr<mode>3_cmp. (*<shiftrt_insn><mode>3_cconly): Ditto from *{ashr,lshr}<mode>3_cconly.
(*<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.
2010-04-11 Uros Bizjak <ubizjak@gmail.com> 2010-04-11 Uros Bizjak <ubizjak@gmail.com>
...@@ -187,8 +211,8 @@ ...@@ -187,8 +211,8 @@
(*lshr<mode>3_doubleword peephole2): Macroize peephole2 pattern (*lshr<mode>3_doubleword peephole2): Macroize peephole2 pattern
from corresponding peephole2 patterns. from corresponding peephole2 patterns.
(*lshr<mode>3_1): Merge with *lshr{qi,hi,si}3_1_one_bit and (*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 *lshrdi3_1_one_bit_rex64. Macroize insn from *lshr{qi,hi,si}3_1
and *lshrdi3_cmp_rex64 using SWI mode iterator. and *lshrdi3_1_rex64 using SWI mode iterator.
(*lshrsi3_1_zext): Merge with *lshrsi3_1_one_bit_zext. (*lshrsi3_1_zext): Merge with *lshrsi3_1_one_bit_zext.
(*lshrqi3_1_slp): Merge with *lshrqi3_1_one_bit_slp. (*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 (*lshr<mode>3_cmp): Merge with *lshr{qi,hi,si}3_one_bit_cmp and
...@@ -215,8 +239,8 @@ ...@@ -215,8 +239,8 @@
(x86_shift<mode>_adj_3): Macroize expander from x86_shift_adj_3 (x86_shift<mode>_adj_3): Macroize expander from x86_shift_adj_3
and x86_64_shift_adj_3 using SWI48 mode iterator. 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 (*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 *ashrdi3_1_one_bit_rex64. Macroize insn from *ashr{qi,hi,si}3_1
and *ashrdi3_cmp_rex64 using SWI mode iterator. and *ashrdi3_1_rex64 using SWI mode iterator.
(*ashrsi3_1_zext): Merge with *ashrsi3_1_one_bit_zext. (*ashrsi3_1_zext): Merge with *ashrsi3_1_one_bit_zext.
(*ashrqi3_1_slp): Merge with *ashrqi3_1_one_bit_slp. (*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 (*ashr<mode>3_cmp): Merge with *ashr{qi,hi,si}3_one_bit_cmp and
......
...@@ -733,6 +733,15 @@ ...@@ -733,6 +733,15 @@
;; Base name for insn mnemonic. ;; Base name for insn mnemonic.
(define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")]) (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 ;; Mapping of abs neg operators
(define_code_iterator absneg [abs neg]) (define_code_iterator absneg [abs neg])
...@@ -776,6 +785,11 @@ ...@@ -776,6 +785,11 @@
(HI "TARGET_HIMODE_MATH") (HI "TARGET_HIMODE_MATH")
SI (DI "TARGET_64BIT")]) 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. ;; Math-dependant single word integer modes without QImode.
(define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH") (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
SI (DI "TARGET_64BIT")]) SI (DI "TARGET_64BIT")])
...@@ -10542,451 +10556,193 @@ ...@@ -10542,451 +10556,193 @@
;; Rotate instructions ;; 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" "") [(set (match_operand:DI 0 "shiftdi_operand" "")
(rotate:DI (match_operand:DI 1 "shiftdi_operand" "") (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))] (match_operand:QI 2 "nonmemory_operand" "")))]
"" ""
{ {
if (TARGET_64BIT) if (TARGET_64BIT)
{ ix86_expand_binary_operator (<CODE>, DImode, operands);
ix86_expand_binary_operator (ROTATE, DImode, operands); else if (const_1_to_31_operand (operands[2], VOIDmode))
DONE; emit_insn (gen_ix86_<rotate_insn>di3_doubleword
} (operands[0], operands[1], operands[2]));
if (!const_1_to_31_operand (operands[2], VOIDmode)) else
FAIL; FAIL;
emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
DONE; DONE;
}) })
;; Implement rotation using two double-precision shift instructions (define_expand "<rotate_insn><mode>3"
;; and a scratch register. [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
(define_insn_and_split "ix86_rotldi3" (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
[(set (match_operand:DI 0 "register_operand" "=r") (match_operand:QI 2 "nonmemory_operand" "")))]
(rotate:DI (match_operand:DI 1 "register_operand" "0") ""
(match_operand:QI 2 "const_1_to_31_operand" "I"))) "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 (reg:CC FLAGS_REG))
(clobber (match_scratch:SI 3 "=&r"))] (clobber (match_scratch:DWIH 3 "=&r"))]
"!TARGET_64BIT"
"" ""
"&& reload_completed" "#"
"reload_completed"
[(set (match_dup 3) (match_dup 4)) [(set (match_dup 3) (match_dup 4))
(parallel (parallel
[(set (match_dup 4) [(set (match_dup 4)
(ior:SI (ashift:SI (match_dup 4) (match_dup 2)) (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
(lshiftrt:SI (match_dup 5) (lshiftrt:DWIH (match_dup 5)
(minus:QI (const_int 32) (match_dup 2))))) (minus:QI (match_dup 6) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))]) (clobber (reg:CC FLAGS_REG))])
(parallel (parallel
[(set (match_dup 5) [(set (match_dup 5)
(ior:SI (ashift:SI (match_dup 5) (match_dup 2)) (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
(lshiftrt:SI (match_dup 3) (lshiftrt:DWIH (match_dup 3)
(minus:QI (const_int 32) (match_dup 2))))) (minus:QI (match_dup 6) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))])] (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) operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
{
ix86_expand_binary_operator (ROTATERT, DImode, operands); split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
DONE;
}
if (!const_1_to_31_operand (operands[2], VOIDmode))
FAIL;
emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
DONE;
}) })
;; Implement rotation using two double-precision shift instructions (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
;; and a scratch register. [(set (match_operand:<DWI> 0 "register_operand" "=r")
(define_insn_and_split "ix86_rotrdi3" (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
[(set (match_operand:DI 0 "register_operand" "=r") (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
(rotatert:DI (match_operand:DI 1 "register_operand" "0")
(match_operand:QI 2 "const_1_to_31_operand" "I")))
(clobber (reg:CC FLAGS_REG)) (clobber (reg:CC FLAGS_REG))
(clobber (match_scratch:SI 3 "=&r"))] (clobber (match_scratch:DWIH 3 "=&r"))]
"!TARGET_64BIT"
"" ""
"&& reload_completed" "#"
"reload_completed"
[(set (match_dup 3) (match_dup 4)) [(set (match_dup 3) (match_dup 4))
(parallel (parallel
[(set (match_dup 4) [(set (match_dup 4)
(ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2)) (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
(ashift:SI (match_dup 5) (ashift:DWIH (match_dup 5)
(minus:QI (const_int 32) (match_dup 2))))) (minus:QI (match_dup 6) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))]) (clobber (reg:CC FLAGS_REG))])
(parallel (parallel
[(set (match_dup 5) [(set (match_dup 5)
(ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2)) (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
(ashift:SI (match_dup 3) (ashift:DWIH (match_dup 3)
(minus:QI (const_int 32) (match_dup 2))))) (minus:QI (match_dup 6) (match_dup 2)))))
(clobber (reg:CC FLAGS_REG))])] (clobber (reg:CC FLAGS_REG))])]
"split_di (&operands[0], 1, &operands[4], &operands[5]);") {
operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
(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")])
(define_expand "rotrsi3" split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
[(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;")
(define_insn "*rotrsi3_1_one_bit" (define_insn "*<rotate_insn><mode>3_1"
[(set (match_operand:SI 0 "nonimmediate_operand" "=rm") [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
(rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0") (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
(match_operand:QI 2 "const1_operand" ""))) (match_operand:QI 2 "nonmemory_operand" "c<S>")))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"(TARGET_SHIFT1 || optimize_function_for_size_p (cfun)) "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
&& ix86_binary_operator_ok (ROTATERT, SImode, operands)" {
"ror{l}\t%0" 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 "type" "rotate")
(set_attr "length_immediate" "0") (set (attr "length_immediate")
(set_attr "mode" "SI")]) (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") [(set (match_operand:DI 0 "register_operand" "=r")
(zero_extend:DI (zero_extend:DI
(rotatert:SI (match_operand:SI 1 "register_operand" "0") (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:QI 2 "const1_operand" "")))) (match_operand:QI 2 "nonmemory_operand" "cI"))))
(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"))))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)" "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
"@ {
ror{l}\t{%2, %k0|%k0, %2} if (REG_P (operands[2]))
ror{l}\t{%b2, %k0|%k0, %b2}" 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 "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")]) (set_attr "mode" "SI")])
(define_expand "rotrhi3" (define_insn "*<rotate_insn>qi3_1_slp"
[(set (match_operand:HI 0 "nonimmediate_operand" "") [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
(rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "") (any_rotate:QI (match_dup 0)
(match_operand:QI 2 "nonmemory_operand" "")))] (match_operand:QI 1 "nonmemory_operand" "cI")))
"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")))
(clobber (reg:CC FLAGS_REG))] (clobber (reg:CC FLAGS_REG))]
"ix86_binary_operator_ok (ROTATERT, HImode, operands)" "(optimize_function_for_size_p (cfun)
"@ || !TARGET_PARTIAL_REG_STALL
ror{w}\t{%2, %0|%0, %2} || (operands[1] == const1_rtx
ror{w}\t{%b2, %0|%0, %b2}" && TARGET_SHIFT1))"
[(set_attr "type" "rotate") {
(set_attr "mode" "HI")]) 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 (define_split
[(set (match_operand:HI 0 "register_operand" "") [(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))] (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)) [(parallel [(set (strict_low_part (match_dup 0))
(bswap:HI (match_dup 0))) (bswap:HI (match_dup 0)))
(clobber (reg:CC FLAGS_REG))])] (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 ;; Bit set / bit test instructions
......
2010-04-12 Uros Bizjak <ubizjak@gmail.com>
* gcc.target/i386/rotate-2.c: New test.
2010-04-12 Jason Merrill <jason@redhat.com> 2010-04-12 Jason Merrill <jason@redhat.com>
PR c++/43641 PR c++/43641
* g++.dg/cpp0x/lambda/lambda-conv4.C: New. * g++.dg/cpp0x/lambda/lambda-conv4.C: New.
* g++.dg/cpp0x/lambda/lambda-deduce2.C: New. * g++.dg/cpp0x/lambda/lambda-deduce2.C: New.
2010-04-12 Fabien Chene <fabien.chene@gmail.com> 2010-04-12 Fabien Chene <fabien.chene@gmail.com>
......
/* { 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 } } */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment