re PR target/50446 ([avr] Implement rotate patterns with offset 1)
PR target/50446 * config/avr/avr.md (rotlqi3): Support all offsets 0..7. (rotlqi3_4): Turn insn into expander. (*rotlqi3): New insn. (rotlhi3, rotlsi3): Support rotate left/right by 1. (*rotlhi2.1, *rotlhi2.15): New insns. (*rotlsi2.1, *rotlsi2.31): New insns. * config/avr/constraints.md (C03, C05, C06, C07): New constraints. From-SVN: r179116
This commit is contained in:
parent
9acebb8a99
commit
5d94b98863
@ -1,3 +1,14 @@
|
||||
2011-09-23 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
PR target/50446
|
||||
* config/avr/avr.md (rotlqi3): Support all offsets 0..7.
|
||||
(rotlqi3_4): Turn insn into expander.
|
||||
(*rotlqi3): New insn.
|
||||
(rotlhi3, rotlsi3): Support rotate left/right by 1.
|
||||
(*rotlhi2.1, *rotlhi2.15): New insns.
|
||||
(*rotlsi2.1, *rotlsi2.31): New insns.
|
||||
* config/avr/constraints.md (C03, C05, C06, C07): New constraints.
|
||||
|
||||
2011-09-23 Bin Cheng <bin.cheng@arm.com>
|
||||
|
||||
* config/arm/bpabi.h (BE8_LINK_SPEC): Add cortex-m arch
|
||||
|
@ -2391,22 +2391,37 @@
|
||||
(define_expand "rotlqi3"
|
||||
[(set (match_operand:QI 0 "register_operand" "")
|
||||
(rotate:QI (match_operand:QI 1 "register_operand" "")
|
||||
(match_operand:QI 2 "const_int_operand" "")))]
|
||||
(match_operand:QI 2 "const_0_to_7_operand" "")))]
|
||||
""
|
||||
"
|
||||
{
|
||||
if (!CONST_INT_P (operands[2]) || (INTVAL (operands[2]) != 4))
|
||||
{
|
||||
if (!CONST_INT_P (operands[2]))
|
||||
FAIL;
|
||||
}")
|
||||
|
||||
(define_insn "rotlqi3_4"
|
||||
[(set (match_operand:QI 0 "register_operand" "=r")
|
||||
(rotate:QI (match_operand:QI 1 "register_operand" "0")
|
||||
(const_int 4)))]
|
||||
operands[2] = gen_int_mode (INTVAL (operands[2]) & 7, QImode);
|
||||
})
|
||||
|
||||
;; Expander used by __builtin_avr_swap
|
||||
(define_expand "rotlqi3_4"
|
||||
[(set (match_operand:QI 0 "register_operand" "")
|
||||
(rotate:QI (match_operand:QI 1 "register_operand" "")
|
||||
(const_int 4)))])
|
||||
|
||||
(define_insn "*rotlqi3"
|
||||
[(set (match_operand:QI 0 "register_operand" "=r,r,r ,r ,r ,r ,r ,r")
|
||||
(rotate:QI (match_operand:QI 1 "register_operand" "0,0,0 ,0 ,0 ,0 ,0 ,0")
|
||||
(match_operand:QI 2 "const_0_to_7_operand" "P,K,C03,C04,C05,C06,C07,L")))]
|
||||
""
|
||||
"swap %0"
|
||||
[(set_attr "length" "1")
|
||||
(set_attr "cc" "none")])
|
||||
"@
|
||||
lsl %0\;adc %0,__zero_reg__
|
||||
lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
|
||||
swap %0\;bst %0,0\;ror %0\;bld %0,7
|
||||
swap %0
|
||||
swap %0\;lsl %0\;adc %0,__zero_reg__
|
||||
swap %0\;lsl %0\;adc %0,__zero_reg__\;lsl %0\;adc %0,__zero_reg__
|
||||
bst %0,0\;ror %0\;bld %0,7
|
||||
"
|
||||
[(set_attr "length" "2,4,4,1,3,5,3,0")
|
||||
(set_attr "cc" "set_n,set_n,clobber,none,set_n,set_n,clobber,none")])
|
||||
|
||||
;; Split all rotates of HI,SI and DImode registers where rotation is by
|
||||
;; a whole number of bytes. The split creates the appropriate moves and
|
||||
@ -2418,6 +2433,9 @@
|
||||
(define_mode_attr rotx [(DI "&r,&r,X") (SI "&r,&r,X") (HI "X,X,X")])
|
||||
(define_mode_attr rotsmode [(DI "QI") (SI "HI") (HI "QI")])
|
||||
|
||||
;; "rotlhi3"
|
||||
;; "rotlsi3"
|
||||
;; "rotldi3"
|
||||
(define_expand "rotl<mode>3"
|
||||
[(parallel [(set (match_operand:HIDI 0 "register_operand" "")
|
||||
(rotate:HIDI (match_operand:HIDI 1 "register_operand" "")
|
||||
@ -2425,18 +2443,69 @@
|
||||
(clobber (match_dup 3))])]
|
||||
""
|
||||
{
|
||||
if (CONST_INT_P (operands[2])
|
||||
&& 0 == INTVAL (operands[2]) % 8)
|
||||
int offset;
|
||||
|
||||
if (!CONST_INT_P (operands[2]))
|
||||
FAIL;
|
||||
|
||||
offset = INTVAL (operands[2]);
|
||||
|
||||
if (0 == offset % 8)
|
||||
{
|
||||
if (AVR_HAVE_MOVW && 0 == INTVAL (operands[2]) % 16)
|
||||
if (AVR_HAVE_MOVW && 0 == offset % 16)
|
||||
operands[3] = gen_rtx_SCRATCH (<rotsmode>mode);
|
||||
else
|
||||
operands[3] = gen_rtx_SCRATCH (QImode);
|
||||
}
|
||||
else if (<MODE>mode != DImode
|
||||
&& (offset == 1
|
||||
|| offset == GET_MODE_BITSIZE (<MODE>mode) -1))
|
||||
{
|
||||
/*; Support rotate left/right by 1 */
|
||||
|
||||
emit_move_insn (operands[0],
|
||||
gen_rtx_ROTATE (<MODE>mode, operands[1], operands[2]));
|
||||
DONE;
|
||||
}
|
||||
else
|
||||
FAIL;
|
||||
})
|
||||
|
||||
(define_insn "*rotlhi2.1"
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(rotate:HI (match_operand:HI 1 "register_operand" "0")
|
||||
(const_int 1)))]
|
||||
""
|
||||
"lsl %A0\;rol %B0\;adc %A0,__zero_reg__"
|
||||
[(set_attr "length" "3")
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "*rotlhi2.15"
|
||||
[(set (match_operand:HI 0 "register_operand" "=r")
|
||||
(rotate:HI (match_operand:HI 1 "register_operand" "0")
|
||||
(const_int 15)))]
|
||||
""
|
||||
"bst %A0,0\;ror %B0\;ror %A0\;bld %B0,7"
|
||||
[(set_attr "length" "3")
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "*rotlsi2.1"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(rotate:SI (match_operand:SI 1 "register_operand" "0")
|
||||
(const_int 1)))]
|
||||
""
|
||||
"lsl %A0\;rol %B0\;rol %C0\;rol %D0\;adc %A0,__zero_reg__"
|
||||
[(set_attr "length" "5")
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
(define_insn "*rotlsi2.31"
|
||||
[(set (match_operand:SI 0 "register_operand" "=r")
|
||||
(rotate:SI (match_operand:SI 1 "register_operand" "0")
|
||||
(const_int 31)))]
|
||||
""
|
||||
"bst %A0,0\;ror %D0\;ror %C0\;ror %B0\;ror %A0\;bld %D0,7"
|
||||
[(set_attr "length" "6")
|
||||
(set_attr "cc" "clobber")])
|
||||
|
||||
;; Overlapping non-HImode registers often (but not always) need a scratch.
|
||||
;; The best we can do is use early clobber alternative "#&r" so that
|
||||
@ -2444,7 +2513,11 @@
|
||||
;; allocation does not prefer non-overlapping.
|
||||
|
||||
|
||||
; Split word aligned rotates using scratch that is mode dependent.
|
||||
;; Split word aligned rotates using scratch that is mode dependent.
|
||||
|
||||
;; "*rotwhi"
|
||||
;; "*rotwsi"
|
||||
;; "*rotwdi"
|
||||
(define_insn_and_split "*rotw<mode>"
|
||||
[(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
|
||||
(rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
|
||||
@ -2462,7 +2535,11 @@
|
||||
})
|
||||
|
||||
|
||||
; Split byte aligned rotates using scratch that is always QI mode.
|
||||
;; Split byte aligned rotates using scratch that is always QI mode.
|
||||
|
||||
;; "*rotbhi"
|
||||
;; "*rotbsi"
|
||||
;; "*rotbdi"
|
||||
(define_insn_and_split "*rotb<mode>"
|
||||
[(set (match_operand:HIDI 0 "register_operand" "=r,r,#&r")
|
||||
(rotate:HIDI (match_operand:HIDI 1 "register_operand" "0,r,r")
|
||||
|
@ -108,11 +108,31 @@
|
||||
(and (match_code "mem")
|
||||
(match_test "extra_constraint_Q (op)")))
|
||||
|
||||
(define_constraint "C03"
|
||||
"Constant integer 3."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 3")))
|
||||
|
||||
(define_constraint "C04"
|
||||
"Constant integer 4."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 4")))
|
||||
|
||||
(define_constraint "C05"
|
||||
"Constant integer 5."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 5")))
|
||||
|
||||
(define_constraint "C06"
|
||||
"Constant integer 6."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 6")))
|
||||
|
||||
(define_constraint "C07"
|
||||
"Constant integer 7."
|
||||
(and (match_code "const_int")
|
||||
(match_test "ival == 7")))
|
||||
|
||||
(define_constraint "Ca2"
|
||||
"Constant 2-byte integer that allows AND without clobber register."
|
||||
(and (match_code "const_int")
|
||||
|
Loading…
Reference in New Issue
Block a user