This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug target/19293] avr-gcc crashes when using shifts with negative shift count


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]