This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
[Bug target/19293] avr-gcc crashes when using shifts with negative shift count
- From: "bjoern dot m dot haase at web dot de" <gcc-bugzilla at gcc dot gnu dot org>
- To: gcc-bugs at gcc dot gnu dot org
- Date: 6 Jan 2005 18:57:37 -0000
- Subject: [Bug target/19293] avr-gcc crashes when using shifts with negative shift count
- References: <20050106160127.19293.bjoern.m.haase@web.de>
- Reply-to: gcc-bugzilla at gcc dot gnu dot org
------- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-06 18:57 -------
If it would be OK for GCC to simply ignore negative constant shift counts,
the following patch would do. I have tested this with the test suite for
gcc-3.4.3 . Unfortunately avr-gcc is still broken on head, so I could not test
it properly for 4.0 . I, however, expect no difficulties either.
regards,
Björn
Index: avr.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/avr/avr.c,v
retrieving revision 1.108.4.3
diff -c -1 -0 -r1.108.4.3 avr.c
*** avr.c 28 Sep 2004 01:13:55 -0000 1.108.4.3
--- avr.c 6 Jan 2005 18:44:28 -0000
***************
*** 3287,3307 ****
const char *
ashrqi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
if (!len)
len = &k;
!
switch (INTVAL (operands[2]))
{
case 1:
*len = 1;
return AS1 (asr,%0);
case 2:
*len = 2;
return (AS1 (asr,%0) CR_TAB
AS1 (asr,%0));
--- 3287,3312 ----
const char *
ashrqi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
if (!len)
len = &k;
!
! if ( (INTVAL(operands[2]) < 0) || (INTVAL(operands[2]) > 7) )
! { /* illegal shift count */
! *len = 0;
! return "";
! }
switch (INTVAL (operands[2]))
{
case 1:
*len = 1;
return AS1 (asr,%0);
case 2:
*len = 2;
return (AS1 (asr,%0) CR_TAB
AS1 (asr,%0));
***************
*** 3357,3376 ****
--- 3362,3387 ----
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k;
int *t = len;
if (!len)
len = &k;
+
+ if ( (INTVAL(operands[2]) < 0) || (INTVAL(operands[2]) > 15) )
+ { /* illegal shift count */
+ *len = 0;
+ return "";
+ }
switch (INTVAL (operands[2]))
{
case 4:
case 5:
/* XXX try to optimize this too? */
break;
case 6:
if (optimize_size)
***************
*** 3517,3537 ****
const char *
ashrsi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
int *t = len;
if (!len)
len = &k;
!
switch (INTVAL (operands[2]))
{
case 8:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
*len=6;
if (reg0 <= reg1)
return (AS2 (mov,%A0,%B1) CR_TAB
AS2 (mov,%B0,%C1) CR_TAB
--- 3528,3553 ----
const char *
ashrsi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
int *t = len;
if (!len)
len = &k;
!
! if ((INTVAL(operands[2]) < 0) || (INTVAL(operands[2])>31))
! { /* illegal shift count */
! *len = 0;
! return "";
! }
switch (INTVAL (operands[2]))
{
case 8:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
*len=6;
if (reg0 <= reg1)
return (AS2 (mov,%A0,%B1) CR_TAB
AS2 (mov,%B0,%C1) CR_TAB
***************
*** 3632,3652 ****
const char *
lshrqi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
if (!len)
len = &k;
!
switch (INTVAL (operands[2]))
{
default:
*len = 1;
return AS1 (clr,%0);
case 1:
*len = 1;
return AS1 (lsr,%0);
--- 3648,3673 ----
const char *
lshrqi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
if (!len)
len = &k;
! if ( (INTVAL(operands[2]) < 0) || (INTVAL(operands[2]) > 7) )
! { /* illegal shift count */
! *len = 0;
! return "";
! }
!
switch (INTVAL (operands[2]))
{
default:
*len = 1;
return AS1 (clr,%0);
case 1:
*len = 1;
return AS1 (lsr,%0);
***************
*** 3719,3747 ****
insn, operands, len, 1);
return "";
}
/* 16bit logic shift right ((unsigned short)x >> i) */
const char *
lshrhi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
! {
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k;
int *t = len;
if (!len)
len = &k;
switch (INTVAL (operands[2]))
{
case 4:
if (optimize_size && scratch)
break; /* 5 */
if (ldi_ok)
{
*len = 6;
return (AS1 (swap,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
--- 3740,3774 ----
insn, operands, len, 1);
return "";
}
/* 16bit logic shift right ((unsigned short)x >> i) */
const char *
lshrhi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
! {
int scratch = (GET_CODE (PATTERN (insn)) == PARALLEL);
int ldi_ok = test_hard_reg_class (LD_REGS, operands[0]);
int k;
int *t = len;
if (!len)
len = &k;
+ if ((INTVAL(operands[2]) < 0) || (INTVAL(operands[2]) > 15))
+ { /* illegal constant shift count. Do nothing */
+ *len = 0;
+ return "";
+ }
+
switch (INTVAL (operands[2]))
{
case 4:
if (optimize_size && scratch)
break; /* 5 */
if (ldi_ok)
{
*len = 6;
return (AS1 (swap,%B0) CR_TAB
AS1 (swap,%A0) CR_TAB
***************
*** 3978,3997 ****
--- 4005,4031 ----
lshrsi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
int *t = len;
if (!len)
len = &k;
+ if ((INTVAL (operands[2]) < 0) || (INTVAL (operands[2]) > 31))
+ { /* illegal constant shift count. */
+ /* do nothing. */
+ *len = 0;
+ return "";
+ };
+
switch (INTVAL (operands[2]))
{
case 8:
{
int reg0 = true_regnum (operands[0]);
int reg1 = true_regnum (operands[1]);
*len = 4;
if (reg0 <= reg1)
return (AS2 (mov,%A0,%B1) CR_TAB
AS2 (mov,%B0,%C1) CR_TAB
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19293