[Bug target/19293] avr-gcc crashes when using shifts with negative shift count
bjoern dot m dot haase at web dot de
gcc-bugzilla@gcc.gnu.org
Wed Jan 19 21:25:00 GMT 2005
------- Additional Comments From bjoern dot m dot haase at web dot de 2005-01-19 21:25 -------
Hi,
here is the changed patch for avr.c . I hope that it is now compliant to the
gcc coding standards. I however did not understand what you have meant with
"this hunk adds spurious whitespace".
Yours,
Björn
Index: avr.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/avr/avr.c,v
retrieving revision 1.108.4.3
diff -U10 -r1.108.4.3 avr.c
--- avr.c 28 Sep 2004 01:13:55 -0000 1.108.4.3
+++ avr.c 19 Jan 2005 21:19:49 -0000
@@ -3288,20 +3288,27 @@
const char *
ashrqi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
if (!len)
len = &k;
+ /* Test for illegal or strange shift count. */
+ if ( (INTVAL (operands[2]) <= 0 ) || ( INTVAL (operands[2]) > 7) )
+ {
+ *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,20 +3364,27 @@
{
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;
+
+ /* Test for illegal or strange shift count. */
+ if ( (INTVAL (operands[2]) <= 0) || (INTVAL (operands[2]) > 15) )
+ {
+ *len = 0;
+ return "";
+ }
switch (INTVAL (operands[2]))
{
case 4:
case 5:
/* XXX try to optimize this too? */
break;
case 6:
if (optimize_size)
@@ -3517,21 +3531,27 @@
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;
-
+
+ /* Test for illegal or strange shift count. */
+ if ((INTVAL (operands[2]) <= 0) || (INTVAL (operands[2])>31))
+ {
+ *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
@@ -3633,20 +3653,27 @@
const char *
lshrqi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
if (!len)
len = &k;
+ /* Test for illegal or not useful shift count. */
+ if ( (INTVAL (operands[2]) <= 0) | (INTVAL (operands[2]) > 7) )
+ {
+ *len = 0;
+ return "";
+ }
+
switch (INTVAL (operands[2]))
{
default:
*len = 1;
return AS1 (clr,%0);
case 1:
*len = 1;
return AS1 (lsr,%0);
@@ -3719,29 +3746,36 @@
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;
+ /* Test for illegal or not useful shift count. */
+ if ((INTVAL (operands[2]) <= 0) || (INTVAL (operands[2]) > 15))
+ {
+ *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
@@ -3977,20 +4011,27 @@
const char *
lshrsi3_out (rtx insn, rtx operands[], int *len)
{
if (GET_CODE (operands[2]) == CONST_INT)
{
int k;
int *t = len;
if (!len)
len = &k;
+
+ /* Test for illegal or not useful shift counts. */
+ if ((INTVAL (operands[2]) <= 0) || (INTVAL (operands[2]) > 31))
+ {
+ *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
--
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19293
More information about the Gcc-bugs
mailing list