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