[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