diff options
author | denisc <denisc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-10-01 14:59:35 +0000 |
---|---|---|
committer | denisc <denisc@138bc75d-0d04-0410-961f-82ee72b054a4> | 2000-10-01 14:59:35 +0000 |
commit | 28f5cc4d325f2d665c4df19ce266f464afcd1eec (patch) | |
tree | 8c695a7c168d8eb986d8ef74735bcd0f123f22ac | |
parent | ab0147ae01f04eba02f2ab8a476fde4a0af8ef41 (diff) | |
download | gcc-28f5cc4d325f2d665c4df19ce266f464afcd1eec.tar.gz |
* config/avr/avr.c (ashlhi3_out, ashlsi3_out, ashrhi3_out,
ashrsi3_out, lshrhi3_out, lshrsi3_out): Optimize more cases
with known shift count.
* config/avr/avr.md (ashlsi3, ashrsi3, lshrsi3):
New alternative for shift count 2 with no scratch register.
(ashlhi3, ashlsi3): Change "cc" attribute from "clobber" to
"set_n" for shift counts 1 and 2.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@36685 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/config/avr/avr.c | 330 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 54 |
3 files changed, 348 insertions, 46 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 15e6d46ae99..848e7da4b82 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2000-09-30 Marek Michalkiewicz <marekm@linux.org.pl> + + * config/avr/avr.c (ashlhi3_out, ashlsi3_out, ashrhi3_out, + ashrsi3_out, lshrhi3_out, lshrsi3_out): Optimize more cases + with known shift count. + * config/avr/avr.md (ashlsi3, ashrsi3, lshrsi3): + New alternative for shift count 2 with no scratch register. + (ashlhi3, ashlsi3): Change "cc" attribute from "clobber" to + "set_n" for shift counts 1 and 2. + 2000-09-30 Geoff Keating <geoffk@cygnus.com> * config/rs6000/rs6000.md (movsi_to_cr): Remove the USE. Calculate diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index df1949b82ec..7382d185244 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -2870,8 +2870,6 @@ ashlhi3_out (insn, operands, len) switch (INTVAL (operands[2])) { - default: len = t; break; - case 1: *len = 2; return (AS1 (lsl,%A0) CR_TAB @@ -2881,16 +2879,103 @@ ashlhi3_out (insn, operands, len) *len = 4; return (AS1 (lsl,%A0) CR_TAB AS1 (rol,%B0) CR_TAB - AS1 (lsl,%0) CR_TAB + AS1 (lsl,%A0) CR_TAB AS1 (rol,%B0)); + case 7: + *len = 5; + return (AS1 (lsr,%B0) CR_TAB + AS2 (mov,%B0,%A0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (ror,%B0) CR_TAB + AS1 (ror,%A0)); + case 8: if (true_regnum (operands[0]) + 1 == true_regnum (operands[1])) return *len = 1, AS1 (clr,%A0); else return *len = 2, (AS2 (mov,%B0,%A1) CR_TAB AS1 (clr,%A0)); + + case 9: + *len = 3; + return (AS2 (mov,%B0,%A0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (lsl,%B0)); + + case 10: + *len = 4; + return (AS2 (mov,%B0,%A0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (lsl,%B0) CR_TAB + AS1 (lsl,%B0)); + + case 11: + *len = 5; + return (AS2 (mov,%B0,%A0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (lsl,%B0) CR_TAB + AS1 (lsl,%B0) CR_TAB + AS1 (lsl,%B0)); + + case 12: + if (test_hard_reg_class (LD_REGS, operands[0])) + { + *len = 4; + return (AS2 (mov,%B0,%A0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (swap,%B0) CR_TAB + AS2 (andi,%B0,0xf0)); + } + /* %3 is a scratch register from class LD_REGS */ + *len = 5; + return (AS2 (mov,%B0,%A0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (swap,%B0) CR_TAB + AS2 (ldi,%3,0xf0) CR_TAB + AS2 (and,%B0,%3)); + + case 13: + if (test_hard_reg_class (LD_REGS, operands[0])) + { + *len = 5; + return (AS2 (mov,%B0,%A0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (swap,%B0) CR_TAB + AS1 (lsl,%B0) CR_TAB + AS2 (andi,%B0,0xe0)); + } + if (AVR_ENHANCED) + { + *len = 5; + return (AS2 (ldi,%3,0x20) CR_TAB + AS2 (mul,%A0,%3) CR_TAB + AS2 (mov,%B0,r0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (clr,__zero_reg__)); + } + break; + + case 14: + if (AVR_ENHANCED) + { + *len = 5; + return (AS2 (ldi,%3,0x40) CR_TAB + AS2 (mul,%A0,%3) CR_TAB + AS2 (mov,%B0,r0) CR_TAB + AS1 (clr,%A0) CR_TAB + AS1 (clr,__zero_reg__)); + } + break; + + case 15: + *len = 4; + return (AS1 (clr,%B0) CR_TAB + AS1 (lsr,%A0) CR_TAB + AS1 (ror,%B0) CR_TAB + AS1 (clr,%A0)); } + len = t; } if (len) *len = 4; @@ -2919,8 +3004,6 @@ ashlsi3_out (insn, operands, len) switch (INTVAL (operands[2])) { - default: len = t; break; - case 1: *len = 4; return (AS1 (lsl,%A0) CR_TAB @@ -2928,6 +3011,18 @@ ashlsi3_out (insn, operands, len) AS1 (rol,%C0) CR_TAB AS1 (rol,%D0)); + case 2: + /* Loop is one word smaller, but slower and needs a register. */ + *len = 8; + return (AS1 (lsl,%A0) CR_TAB + AS1 (rol,%B0) CR_TAB + AS1 (rol,%C0) CR_TAB + AS1 (rol,%D0) CR_TAB + AS1 (lsl,%A0) CR_TAB + AS1 (rol,%B0) CR_TAB + AS1 (rol,%C0) CR_TAB + AS1 (rol,%D0)); + case 8: { int reg0 = true_regnum (operands[0]); @@ -2994,7 +3089,17 @@ ashlsi3_out (insn, operands, len) AS1 (clr,%B0) CR_TAB AS1 (clr,%A0)); } + + case 31: + *len = 6; + return (AS1 (clr,%D0) CR_TAB + AS1 (lsr,%A0) CR_TAB + AS1 (ror,%D0) CR_TAB + AS1 (clr,%C0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (clr,%A0)); } + len = t; } if (len) *len = 6; @@ -3096,8 +3201,6 @@ ashrhi3_out (insn, operands, len) switch (INTVAL (operands[2])) { - default: len = t; break; - case 1: *len=2; return (AS1 (asr,%B0) CR_TAB @@ -3110,6 +3213,13 @@ ashrhi3_out (insn, operands, len) AS1 (asr,%B0) CR_TAB AS1 (ror,%A0)); + case 7: + *len = 4; + return (AS1 (lsl,%A0) CR_TAB + AS2 (mov,%A0,%B0) CR_TAB + AS1 (rol,%A0) CR_TAB + AS2 (sbc,%B0,%B0)); + case 8: if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1) return *len = 4, (AS2 (mov,%A0,%B1) CR_TAB @@ -3121,11 +3231,71 @@ ashrhi3_out (insn, operands, len) AS2 (sbrc,%A0,7) CR_TAB AS1 (dec,%B0)); + case 9: + *len = 4; + return (AS2 (mov,%A0,%B0) CR_TAB + AS1 (lsl,%B0) CR_TAB + AS2 (sbc,%B0,%B0) CR_TAB + AS1 (asr,%A0)); + + case 10: + *len = 5; + return (AS2 (mov,%A0,%B0) CR_TAB + AS1 (lsl,%B0) CR_TAB + AS2 (sbc,%B0,%B0) CR_TAB + AS1 (asr,%A0) CR_TAB + AS1 (asr,%A0)); + + case 11: + if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0])) + { + *len = 5; + return (AS2 (ldi,%3,0x20) CR_TAB + AS2 (muls,%B0,%3) CR_TAB + AS2 (mov,%A0,r1) CR_TAB + AS2 (sbc,%B0,%B0) CR_TAB + AS1 (clr,__zero_reg__)); + } + break; + + case 12: + if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0])) + { + *len = 5; + return (AS2 (ldi,%3,0x10) CR_TAB + AS2 (muls,%B0,%3) CR_TAB + AS2 (mov,%A0,r1) CR_TAB + AS2 (sbc,%B0,%B0) CR_TAB + AS1 (clr,__zero_reg__)); + } + break; + + case 13: + if (AVR_ENHANCED && test_hard_reg_class (LD_REGS, operands[0])) + { + *len = 5; + return (AS2 (ldi,%3,0x08) CR_TAB + AS2 (muls,%B0,%3) CR_TAB + AS2 (mov,%A0,r1) CR_TAB + AS2 (sbc,%B0,%B0) CR_TAB + AS1 (clr,__zero_reg__)); + } + break; + + case 14: + *len = 5; + return (AS1 (lsl,%B0) CR_TAB + AS2 (sbc,%A0,%A0) CR_TAB + AS1 (lsl,%B0) CR_TAB + AS2 (mov,%B0,%A0) CR_TAB + AS1 (rol,%A0)); + case 15: return *len = 3, (AS1 (lsl,%B0) CR_TAB AS2 (sbc,%A0,%A0) CR_TAB AS2 (mov,%B0,%A0)); } + len = t; } if (len) *len = 4; @@ -3154,8 +3324,6 @@ ashrsi3_out (insn, operands, len) switch (INTVAL (operands[2])) { - default: len = t; break; - case 1: *len=4; return (AS1 (asr,%D0) CR_TAB @@ -3163,6 +3331,18 @@ ashrsi3_out (insn, operands, len) AS1 (ror,%B0) CR_TAB AS1 (ror,%A0)); + case 2: + /* Loop is one word smaller, but slower and needs a register. */ + *len = 8; + return (AS1 (asr,%D0) CR_TAB + AS1 (ror,%C0) CR_TAB + AS1 (ror,%B0) CR_TAB + AS1 (ror,%A0) CR_TAB + AS1 (asr,%D0) CR_TAB + AS1 (ror,%C0) CR_TAB + AS1 (ror,%B0) CR_TAB + AS1 (ror,%A0)); + case 8: { int reg0 = true_regnum (operands[0]); @@ -3240,7 +3420,21 @@ ashrsi3_out (insn, operands, len) AS1 (com,%D0) CR_TAB AS2 (mov,%B0,%D0) CR_TAB AS2 (mov,%C0,%D0)); + + case 31: + if (AVR_ENHANCED) + return *len = 4, (AS1 (lsl,%D0) CR_TAB + AS2 (sbc,%A0,%A0) CR_TAB + AS2 (mov,%B0,%A0) CR_TAB + AS2 (movw,%C0,%A0)); + else + return *len = 5, (AS1 (lsl,%D0) CR_TAB + AS2 (sbc,%A0,%A0) CR_TAB + AS2 (mov,%B0,%A0) CR_TAB + AS2 (mov,%C0,%A0) CR_TAB + AS2 (mov,%D0,%A0)); } + len = t; } if (len) *len = 6; @@ -3367,8 +3561,6 @@ lshrhi3_out (insn, operands, len) switch (INTVAL (operands[2])) { - default: len = t; break; - case 1: *len = 2; return (AS1 (lsr,%B0) CR_TAB @@ -3380,14 +3572,93 @@ lshrhi3_out (insn, operands, len) AS1 (ror,%A0) CR_TAB AS1 (lsr,%B0) CR_TAB AS1 (ror,%A0)); - + + case 7: + *len = 5; + return (AS1 (lsl,%A0) CR_TAB + AS2 (mov,%A0,%B0) CR_TAB + AS1 (rol,%A0) CR_TAB + AS2 (sbc,%B0,%B0) CR_TAB + AS1 (neg,%B0)); + case 8: if (true_regnum (operands[0]) != true_regnum (operands[1]) + 1) return *len = 2, (AS2 (mov,%A0,%B1) CR_TAB AS1 (clr,%B0)); else return *len = 1, AS1 (clr,%B0); - + + case 9: + *len = 3; + return (AS2 (mov,%A0,%B0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (lsr,%A0)); + + case 10: + *len = 4; + return (AS2 (mov,%A0,%B0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (lsr,%A0) CR_TAB + AS1 (lsr,%A0)); + + case 11: + *len = 5; + return (AS2 (mov,%A0,%B0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (lsr,%A0) CR_TAB + AS1 (lsr,%A0) CR_TAB + AS1 (lsr,%A0)); + + case 12: + if (test_hard_reg_class (LD_REGS, operands[0])) + { + *len = 4; + return (AS2 (mov,%A0,%B0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (swap,%A0) CR_TAB + AS2 (andi,%A0,0x0f)); + } + /* %3 is a scratch register from class LD_REGS */ + *len = 5; + return (AS2 (mov,%A0,%B0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (swap,%A0) CR_TAB + AS2 (ldi,%3,0x0f) CR_TAB + AS2 (and,%A0,%3)); + + case 13: + if (test_hard_reg_class (LD_REGS, operands[0])) + { + *len = 5; + return (AS2 (mov,%A0,%B0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (swap,%A0) CR_TAB + AS1 (lsr,%A0) CR_TAB + AS2 (andi,%A0,0x07)); + } + if (AVR_ENHANCED) + { + *len = 5; + return (AS2 (ldi,%3,0x08) CR_TAB + AS2 (mul,%B0,%3) CR_TAB + AS2 (mov,%A0,r1) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (clr,__zero_reg__)); + } + break; + + case 14: + if (AVR_ENHANCED) + { + *len = 5; + return (AS2 (ldi,%3,0x04) CR_TAB + AS2 (mul,%B0,%3) CR_TAB + AS2 (mov,%A0,r1) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (clr,__zero_reg__)); + } + break; + case 15: *len = 4; return (AS1 (lsl,%B0) CR_TAB @@ -3395,6 +3666,7 @@ lshrhi3_out (insn, operands, len) AS1 (neg,%A0) CR_TAB AS1 (clr,%B0)); } + len = t; } if (len) *len = 4; @@ -3422,15 +3694,25 @@ lshrsi3_out (insn, operands, len) switch (INTVAL (operands[2])) { - default: len = t; break; - case 1: *len = 4; - return (AS1 (lsr,%D0) CR_TAB + return (AS1 (lsr,%D0) CR_TAB AS1 (ror,%C0) CR_TAB AS1 (ror,%B0) CR_TAB AS1 (ror,%A0)); - + + case 2: + /* Loop is one word smaller, but slower and needs a register. */ + *len = 8; + return (AS1 (lsr,%D0) CR_TAB + AS1 (ror,%C0) CR_TAB + AS1 (ror,%B0) CR_TAB + AS1 (ror,%A0) CR_TAB + AS1 (lsr,%D0) CR_TAB + AS1 (ror,%C0) CR_TAB + AS1 (ror,%B0) CR_TAB + AS1 (ror,%A0)); + case 8: { int reg0 = true_regnum (operands[0]); @@ -3487,7 +3769,17 @@ lshrsi3_out (insn, operands, len) return *len = 3, (AS1 (clr,%B0) CR_TAB AS1 (clr,%C0) CR_TAB AS1 (clr,%D0)); + + case 31: + *len = 6; + return (AS1 (clr,%A0) CR_TAB + AS2 (sbrc,%D0,7) CR_TAB + AS1 (inc,%A0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (clr,%C0) CR_TAB + AS1 (clr,%D0)); } + len = t; } if (len) *len = 6; @@ -4546,8 +4838,8 @@ avr_hard_regno_mode_ok (regno, mode) { if (mode == QImode) return 1; - if (regno < 24 && !AVR_ENHANCED) - return 1; + /* if (regno < 24 && !AVR_ENHANCED) + return 1;*/ return !(regno & 1); } diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 98694a37397..772a124b5e4 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -893,19 +893,19 @@ (match_operand:QI 2 "general_operand" "r,P,O,K,i,Qm"))) (clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))] "" - "* return ashlhi3_out (insn,operands, NULL);" + "* return ashlhi3_out (insn, operands, NULL);" [(set_attr "length" "7,2,4,2,5,8") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) + (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")]) (define_insn "ashlsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") - (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,i,Qm"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d,X"))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") + (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,P,O,K,i,Qm"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))] "" - "* return ashlsi3_out (insn,operands, NULL);" - [(set_attr "length" "9,4,4,7,10") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")]) + "* return ashlsi3_out (insn, operands, NULL);" + [(set_attr "length" "9,4,4,8,7,10") + (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")]) ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; arithmetic shift right @@ -925,19 +925,19 @@ (match_operand:QI 2 "general_operand" "r,P,K,O,i,Qm"))) (clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))] "" - "* return ashrhi3_out (insn,operands, NULL);" + "* return ashrhi3_out (insn, operands, NULL);" [(set_attr "length" "7,2,4,2,5,8") (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) (define_insn "ashrsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,i,Qm"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d,X"))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,P,O,K,i,Qm"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))] "" - "* return ashrsi3_out (insn,operands, NULL);" - [(set_attr "length" "9,4,6,7,10") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")]) + "* return ashrsi3_out (insn, operands, NULL);" + [(set_attr "length" "9,4,6,8,7,10") + (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; logical shift right @@ -947,7 +947,7 @@ (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0") (match_operand:QI 2 "general_operand" "r,n,n,Qm")))] "" - "* return lshrqi3_out (insn,operands, NULL);" + "* return lshrqi3_out (insn, operands, NULL);" [(set_attr "length" "6,4,6,7") (set_attr "cc" "clobber,set_czn,set_czn,clobber")]) @@ -957,19 +957,19 @@ (match_operand:QI 2 "general_operand" "r,P,K,O,i,Qm"))) (clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))] "" - "* return lshrhi3_out (insn,operands, NULL);" + "* return lshrhi3_out (insn, operands, NULL);" [(set_attr "length" "7,2,4,2,5,8") (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) (define_insn "lshrsi3" - [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,i,Qm"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d,X"))] - "" - "* return lshrsi3_out (insn,operands, NULL);" - [(set_attr "length" "9,4,4,7,10") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")]) + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,P,O,K,i,Qm"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d,X"))] + "" + "* return lshrsi3_out (insn, operands, NULL);" + [(set_attr "length" "9,4,4,8,7,10") + (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) ;; abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) abs(x) ;; abs |