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
This commit is contained in:
Uros Bizjak 2010-04-12 22:20:54 +02:00
parent 077c8adab1
commit e0db9cc648
4 changed files with 236 additions and 436 deletions

View File

@ -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

View File

@ -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"
[(set (match_operand:DI 0 "shiftdi_operand" "")
(rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
(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 (TARGET_64BIT)
{
ix86_expand_binary_operator (ROTATE, DImode, operands);
DONE;
}
if (!const_1_to_31_operand (operands[2], VOIDmode))
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;
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")))
(clobber (reg:CC FLAGS_REG))
(clobber (match_scratch:SI 3 "=&r"))]
"!TARGET_64BIT"
(define_expand "<rotate_insn>di3"
[(set (match_operand:DI 0 "shiftdi_operand" "")
(any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
(match_operand:QI 2 "nonmemory_operand" "")))]
""
"&& reload_completed"
{
if (TARGET_64BIT)
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;
DONE;
})
(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:DWIH 3 "=&r"))]
""
"#"
"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]);")
{
operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
(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" "")))
split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
})
(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:DWIH 3 "=&r"))]
""
"#"
"reload_completed"
[(set (match_dup 3) (match_dup 4))
(parallel
[(set (match_dup 4)
(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: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))])]
{
operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
})
(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_64BIT
&& (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
&& ix86_binary_operator_ok (ROTATE, DImode, operands)"
"rol{q}\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" "DI")])
(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 "*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"
(define_insn "*<rotate_insn>si3_1_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" ""))))
(any_rotate:SI (match_operand:SI 1 "register_operand" "0")
(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 (ROTATE, SImode, operands)"
"rol{l}\t%k0"
"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" "0")
(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_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")))
(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 (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")])
"(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" "")
(rotate: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 "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;
})
;; 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")))
(clobber (reg:CC FLAGS_REG))
(clobber (match_scratch:SI 3 "=&r"))]
"!TARGET_64BIT"
""
"&& 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)))))
(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)))))
(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")])
(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;")
(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" "")))
(clobber (reg:CC FLAGS_REG))]
"(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
&& ix86_binary_operator_ok (ROTATERT, SImode, operands)"
"ror{l}\t%0"
[(set_attr "type" "rotate")
(set_attr "length_immediate" "0")
(set_attr "mode" "SI")])
(define_insn "*rotrsi3_1_one_bit_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"))))
(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}"
[(set_attr "type" "rotate")
(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")))
(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")])
(define_split
[(set (match_operand:HI 0 "register_operand" "")
(rotatert: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 "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

View File

@ -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>

View File

@ -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 } } */