From a3cf59927ae1bfc5668a6eca5df377ce8572e783 Mon Sep 17 00:00:00 2001 From: Marek Michalkiewicz Date: Wed, 26 Jan 2005 22:44:25 +0100 Subject: [PATCH] re PR target/19293 (avr-gcc crashes when using shifts with negative shift count) PR target/19293 PR target/19329 * config/avr/avr.c (notice_update_cc): Only set condition code for ashrqi3 if shift count > 0. (out_shift_with_cnt): Handle shift count <= 0 as a no-op. (ashlqi3_out, ashlhi3_out, ashlsi3_out, ashrqi3_out, ashrhi3_out, ashrsi3_out, lshrqi3_out, lshrhi3_out, lshrsi3_out): Handle shift count <= 0 as a no-op, and shift count >= width by copying zero or sign bit to all bits of the result. * config/avr/avr.md (all shifts): Add alternatives for zero shift count, with attribute "length" set to 0 and "cc" set to "none". From-SVN: r94288 --- gcc/ChangeLog | 14 ++++ gcc/config/avr/avr.c | 75 +++++++++++++++++++ gcc/config/avr/avr.md | 162 +++++++++++++++++++++--------------------- 3 files changed, 170 insertions(+), 81 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 51d5111b9b2..01cfd967d78 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2005-01-26 Marek Michalkiewicz + + PR target/19293 + PR target/19329 + * config/avr/avr.c (notice_update_cc): Only set condition code for + ashrqi3 if shift count > 0. + (out_shift_with_cnt): Handle shift count <= 0 as a no-op. + (ashlqi3_out, ashlhi3_out, ashlsi3_out, ashrqi3_out, ashrhi3_out, + ashrsi3_out, lshrqi3_out, lshrhi3_out, lshrsi3_out): Handle shift + count <= 0 as a no-op, and shift count >= width by copying zero + or sign bit to all bits of the result. + * config/avr/avr.md (all shifts): Add alternatives for zero shift + count, with attribute "length" set to 0 and "cc" set to "none". + 2005-01-26 Aldy Hernandez * doc/invoke.texi: Document -mTLS. diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c index 9ea890ddbdc..fffb7badabe 100644 --- a/gcc/config/avr/avr.c +++ b/gcc/config/avr/avr.c @@ -1229,6 +1229,7 @@ notice_update_cc (rtx body ATTRIBUTE_UNUSED, rtx insn) rtx x = XEXP (src, 1); if (GET_CODE (x) == CONST_INT + && INTVAL (x) > 0 && INTVAL (x) != 6) { cc_status.value1 = SET_DEST (set); @@ -2749,6 +2750,13 @@ out_shift_with_cnt (const char *template, rtx insn, rtx operands[], int count = INTVAL (operands[2]); int max_len = 10; /* If larger than this, always use a loop. */ + if (count <= 0) + { + if (len) + *len = 0; + return; + } + if (count < 8 && !scratch) use_zero_reg = 1; @@ -2871,6 +2879,9 @@ ashlqi3_out (rtx insn, rtx operands[], int *len) switch (INTVAL (operands[2])) { default: + if (INTVAL (operands[2]) < 8) + break; + *len = 1; return AS1 (clr,%0); @@ -2967,6 +2978,14 @@ ashlhi3_out (rtx insn, rtx operands[], int *len) switch (INTVAL (operands[2])) { + default: + if (INTVAL (operands[2]) < 16) + break; + + *len = 2; + return (AS1 (clr,%B0) CR_TAB + AS1 (clr,%A0)); + case 4: if (optimize_size && scratch) break; /* 5 */ @@ -3218,6 +3237,20 @@ ashlsi3_out (rtx insn, rtx operands[], int *len) switch (INTVAL (operands[2])) { + default: + if (INTVAL (operands[2]) < 32) + break; + + if (AVR_ENHANCED) + return *len = 3, (AS1 (clr,%D0) CR_TAB + AS1 (clr,%C0) CR_TAB + AS2 (movw,%A0,%C0)); + *len = 4; + return (AS1 (clr,%D0) CR_TAB + AS1 (clr,%C0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (clr,%A0)); + case 8: { int reg0 = true_regnum (operands[0]); @@ -3356,6 +3389,11 @@ ashrqi3_out (rtx insn, rtx operands[], int *len) AS2 (bld,%0,0)); default: + if (INTVAL (operands[2]) < 8) + break; + + /* fall through */ + case 7: *len = 2; return (AS1 (lsl,%0) CR_TAB @@ -3519,6 +3557,12 @@ ashrhi3_out (rtx insn, rtx operands[], int *len) AS2 (mov,%B0,%A0) CR_TAB AS1 (rol,%A0)); + default: + if (INTVAL (operands[2]) < 16) + break; + + /* fall through */ + case 15: return *len = 3, (AS1 (lsl,%B0) CR_TAB AS2 (sbc,%A0,%A0) CR_TAB @@ -3626,6 +3670,12 @@ ashrsi3_out (rtx insn, rtx operands[], int *len) AS2 (mov,%B0,%D0) CR_TAB AS2 (mov,%C0,%D0)); + default: + if (INTVAL (operands[2]) < 32) + break; + + /* fall through */ + case 31: if (AVR_ENHANCED) return *len = 4, (AS1 (lsl,%D0) CR_TAB @@ -3664,6 +3714,9 @@ lshrqi3_out (rtx insn, rtx operands[], int *len) switch (INTVAL (operands[2])) { default: + if (INTVAL (operands[2]) < 8) + break; + *len = 1; return AS1 (clr,%0); @@ -3758,6 +3811,14 @@ lshrhi3_out (rtx insn, rtx operands[], int *len) switch (INTVAL (operands[2])) { + default: + if (INTVAL (operands[2]) < 16) + break; + + *len = 2; + return (AS1 (clr,%B0) CR_TAB + AS1 (clr,%A0)); + case 4: if (optimize_size && scratch) break; /* 5 */ @@ -4008,6 +4069,20 @@ lshrsi3_out (rtx insn, rtx operands[], int *len) switch (INTVAL (operands[2])) { + default: + if (INTVAL (operands[2]) < 32) + break; + + if (AVR_ENHANCED) + return *len = 3, (AS1 (clr,%D0) CR_TAB + AS1 (clr,%C0) CR_TAB + AS2 (movw,%A0,%C0)); + *len = 4; + return (AS1 (clr,%D0) CR_TAB + AS1 (clr,%C0) CR_TAB + AS1 (clr,%B0) CR_TAB + AS1 (clr,%A0)); + case 8: { int reg0 = true_regnum (operands[0]); diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 0ab6e5f467c..eaed1d89cf8 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -1167,31 +1167,31 @@ ;; arithmetic shift left (define_insn "ashlqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,!d,r,r") - (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,K,n,n,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") + (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))] "" "* return ashlqi3_out (insn, operands, NULL);" - [(set_attr "length" "5,1,2,4,6,9") - (set_attr "cc" "clobber,set_czn,set_czn,set_czn,set_czn,clobber")]) + [(set_attr "length" "5,0,1,2,4,6,9") + (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) (define_insn "ashlhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") - (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashift:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return ashlhi3_out (insn, operands, NULL);" - [(set_attr "length" "6,2,2,4,10,10") - (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")]) + [(set_attr "length" "6,0,2,2,4,10,10") + (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) (define_insn "ashlsi3" - [(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,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return ashlsi3_out (insn, operands, NULL);" - [(set_attr "length" "8,4,4,8,10,12") - (set_attr "cc" "clobber,set_n,clobber,set_n,clobber,clobber")]) + [(set_attr "length" "8,0,4,4,8,10,12") + (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -1207,14 +1207,14 @@ FAIL;") (define_insn "*ashlhi3_const" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") - (ashift:HI (match_operand:HI 1 "register_operand" "0,r,0,0") - (match_operand:QI 2 "const_int_operand" "P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") + (ashift:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" "* return ashlhi3_out (insn, operands, NULL);" - [(set_attr "length" "2,2,4,10") - (set_attr "cc" "set_n,clobber,set_n,clobber")]) + [(set_attr "length" "0,2,2,4,10") + (set_attr "cc" "none,set_n,clobber,set_n,clobber")]) (define_peephole2 [(match_scratch:QI 3 "d") @@ -1228,44 +1228,44 @@ FAIL;") (define_insn "*ashlsi3_const" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (ashift:SI (match_operand:SI 1 "register_operand" "0,r,0") - (match_operand:QI 2 "const_int_operand" "P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (ashift:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" "* return ashlsi3_out (insn, operands, NULL);" - [(set_attr "length" "4,4,10") - (set_attr "cc" "set_n,clobber,clobber")]) + [(set_attr "length" "0,4,4,10") + (set_attr "cc" "none,set_n,clobber,clobber")]) ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; arithmetic shift right (define_insn "ashrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r") - (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,K,n,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r,r") + (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,K,n,Qm")))] "" "* return ashrqi3_out (insn, operands, NULL);" - [(set_attr "length" "5,1,2,5,9") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber")]) + [(set_attr "length" "5,0,1,2,5,9") + (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber")]) (define_insn "ashrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return ashrhi3_out (insn, operands, NULL);" - [(set_attr "length" "6,2,4,4,10,10") - (set_attr "cc" "clobber,clobber,set_n,clobber,clobber,clobber")]) + [(set_attr "length" "6,0,2,4,4,10,10") + (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) (define_insn "ashrsi3" - [(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,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return ashrsi3_out (insn, operands, NULL);" - [(set_attr "length" "8,4,6,8,10,12") - (set_attr "cc" "clobber,clobber,set_n,clobber,clobber,clobber")]) + [(set_attr "length" "8,0,4,6,8,10,12") + (set_attr "cc" "clobber,none,clobber,set_n,clobber,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -1281,14 +1281,14 @@ FAIL;") (define_insn "*ashrhi3_const" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") - (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,r,0,0") - (match_operand:QI 2 "const_int_operand" "P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") + (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" "* return ashrhi3_out (insn, operands, NULL);" - [(set_attr "length" "2,4,4,10") - (set_attr "cc" "clobber,set_n,clobber,clobber")]) + [(set_attr "length" "0,2,4,4,10") + (set_attr "cc" "none,clobber,set_n,clobber,clobber")]) (define_peephole2 [(match_scratch:QI 3 "d") @@ -1302,44 +1302,44 @@ FAIL;") (define_insn "*ashrsi3_const" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,r,0") - (match_operand:QI 2 "const_int_operand" "P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" "* return ashrsi3_out (insn, operands, NULL);" - [(set_attr "length" "4,4,10") - (set_attr "cc" "clobber,set_n,clobber")]) + [(set_attr "length" "0,4,4,10") + (set_attr "cc" "none,clobber,set_n,clobber")]) ;; >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> >> ;; logical shift right (define_insn "lshrqi3" - [(set (match_operand:QI 0 "register_operand" "=r,r,r,!d,r,r") - (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,K,n,n,Qm")))] + [(set (match_operand:QI 0 "register_operand" "=r,r,r,r,!d,r,r") + (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,K,n,n,Qm")))] "" "* return lshrqi3_out (insn, operands, NULL);" - [(set_attr "length" "5,1,2,4,6,9") - (set_attr "cc" "clobber,set_czn,set_czn,set_czn,set_czn,clobber")]) + [(set_attr "length" "5,0,1,2,4,6,9") + (set_attr "cc" "clobber,none,set_czn,set_czn,set_czn,set_czn,clobber")]) (define_insn "lshrhi3" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r") - (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0,0") - (match_operand:QI 2 "general_operand" "r,P,O,K,n,Qm")))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r,r,r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return lshrhi3_out (insn, operands, NULL);" - [(set_attr "length" "6,2,2,4,10,10") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) + [(set_attr "length" "6,0,2,2,4,10,10") + (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) (define_insn "lshrsi3" - [(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,n,Qm")))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0") + (match_operand:QI 2 "general_operand" "r,L,P,O,K,n,Qm")))] "" "* return lshrsi3_out (insn, operands, NULL);" - [(set_attr "length" "8,4,4,8,10,12") - (set_attr "cc" "clobber,clobber,clobber,clobber,clobber,clobber")]) + [(set_attr "length" "8,0,4,4,8,10,12") + (set_attr "cc" "clobber,none,clobber,clobber,clobber,clobber,clobber")]) ;; Optimize if a scratch register from LD_REGS happens to be available. @@ -1355,14 +1355,14 @@ FAIL;") (define_insn "*lshrhi3_const" - [(set (match_operand:HI 0 "register_operand" "=r,r,r,r") - (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,r,0,0") - (match_operand:QI 2 "const_int_operand" "P,O,K,n"))) - (clobber (match_scratch:QI 3 "=X,X,X,&d"))] + [(set (match_operand:HI 0 "register_operand" "=r,r,r,r,r") + (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0,r,0,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,K,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,X,&d"))] "reload_completed" "* return lshrhi3_out (insn, operands, NULL);" - [(set_attr "length" "2,2,4,10") - (set_attr "cc" "clobber,clobber,clobber,clobber")]) + [(set_attr "length" "0,2,2,4,10") + (set_attr "cc" "none,clobber,clobber,clobber,clobber")]) (define_peephole2 [(match_scratch:QI 3 "d") @@ -1376,14 +1376,14 @@ FAIL;") (define_insn "*lshrsi3_const" - [(set (match_operand:SI 0 "register_operand" "=r,r,r") - (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,r,0") - (match_operand:QI 2 "const_int_operand" "P,O,n"))) - (clobber (match_scratch:QI 3 "=X,X,&d"))] + [(set (match_operand:SI 0 "register_operand" "=r,r,r,r") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,r,0") + (match_operand:QI 2 "const_int_operand" "L,P,O,n"))) + (clobber (match_scratch:QI 3 "=X,X,X,&d"))] "reload_completed" "* return lshrsi3_out (insn, operands, NULL);" - [(set_attr "length" "4,4,10") - (set_attr "cc" "clobber,clobber,clobber")]) + [(set_attr "length" "0,4,4,10") + (set_attr "cc" "none,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 -- 2.30.2