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
This commit is contained in:
Marek Michalkiewicz 2005-01-26 22:44:25 +01:00 committed by Marek Michalkiewicz
parent d487e3c10a
commit a3cf59927a
3 changed files with 170 additions and 81 deletions

View file

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

View file

@ -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]);

View file

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