[Bug target/16563] The compiler doesnt the necessary push/restore of r18/r19

em at la dot mine dot nu gcc-bugzilla@gcc.gnu.org
Wed Sep 8 13:57:00 GMT 2004


------- Additional Comments From em at la dot mine dot nu  2004-09-08 13:57 -------
I have found another bug which I think is related to this one:

typedef unsigned char u08;
typedef unsigned short u16;

#define PROGMEM __attribute__((__progmem__))

#define pgm_read_word(addr)                  \
({                                           \
     u16 __addr16 = (u16)(addr);             \
     u16 __result;                           \
     __asm__                                 \
     (                                       \
         "lpm %A0, Z+"   "\n\t"              \
         "lpm %B0, Z"    "\n\t"              \
         : "=r" (__result), "=z" (__addr16)  \
         : "1" (__addr16)                    \
     );                                      \
     __result;                               \
})

PROGMEM u16 crctbl[1] = { 0x0000 };

u08           crc[2];

void
crc16( u08 * bufptr, u16 len )
{
  *(u16*)crc = 0;
  for ( ; len--; bufptr++ )
//  *(u16*)crc = pgm_read_word( &crctbl[crc[1] ^ *bufptr] ) ^ ( crc[0] << 8 );
    *(u16*)crc = ( crc[0] << 8 ) ^ pgm_read_word( &crctbl[crc[1] ^ *bufptr] );
}

int
main( void )
{
  return 0;
}

Compiling the above .c generates wrong code for the following line
                                                                     
    *(u16*)crc = ( crc[0] << 8 ) ^ pgm_read_word( &crctbl[crc[1] ^ *bufptr] );

  9c:   80 91 60 00     lds     r24, 0x0060
  a0:   99 27           eor     r25, r25
  a2:   38 2f           mov     r19, r24
  a4:   22 27           eor     r18, r18
  a6:   20 91 61 00     lds     r18, 0x0061   <- r18 is lost here
  aa:   9d 91           ld      r25, X+
  ac:   29 27           eor     r18, r25
  ae:   e2 2f           mov     r30, r18
  b0:   ff 27           eor     r31, r31
  b2:   ee 0f           add     r30, r30
  b4:   ff 1f           adc     r31, r31
  b6:   ec 5a           subi    r30, 0xAC
  b8:   ff 4f           sbci    r31, 0xFF
  ba:   85 91           lpm     r24, Z+
  bc:   94 91           lpm     r25, Z
  be:   28 27           eor     r18, r24     <- uses the wrong value
  c0:   39 27           eor     r19, r25
  c2:   30 93 61 00     sts     0x0061, r19
  c6:   20 93 60 00     sts     0x0060, r18

If you change the line and reverse the XOR then the generated code is fine:
   *(u16*)crc = pgm_read_word( &crctbl[crc[1] ^ *bufptr] ) ^ ( crc[0] << 8 );

I'm using avr-gcc (GCC) 3.4.1 and the following flags to compile:

CPFLAGS = -g -O3 -funsigned-char -funsigned-bitfields -fpack-struct 
-fshort-enums -Wall -W
+strict-prototypes -Wa,-ahlms=$(<:.c=.lst) -mmcu=atmega16





-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16563



More information about the Gcc-bugs mailing list