aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMarek Michalkiewicz <marekm@amelek.gda.pl>2005-01-26 22:44:25 +0100
committerMarek Michalkiewicz <marekm@gcc.gnu.org>2005-01-26 21:44:25 +0000
commita3cf59927ae1bfc5668a6eca5df377ce8572e783 (patch)
tree079662416201ff8fa42edb9cf9edd2f2a0575e3d /gcc
parentd487e3c10ad8ed3327106a84c27d97be497b4798 (diff)
downloadgcc-a3cf59927ae1bfc5668a6eca5df377ce8572e783.zip
gcc-a3cf59927ae1bfc5668a6eca5df377ce8572e783.tar.gz
gcc-a3cf59927ae1bfc5668a6eca5df377ce8572e783.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/avr/avr.c75
-rw-r--r--gcc/config/avr/avr.md162
3 files changed, 170 insertions, 81 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 51d5111..01cfd96 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,17 @@
+2005-01-26 Marek Michalkiewicz <marekm@amelek.gda.pl>
+
+ 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 <aldyh@redhat.com>
* doc/invoke.texi: Document -mTLS.
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 9ea890d..fffb7ba 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 0ab6e5f..eaed1d8 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