|
From: | Peter A. Zuur |
Subject: | [avr-gcc-list] AVR GCC Version 3.3 20030421 - taget mega128 |
Date: | Wed, 6 Aug 2003 08:53:23 +0200 |
I have found a bug in the AVR-GCC compiler (target
mega128) when used with any other optimization level than -O0 .
The following function which updates a crc-8 with
<octet> always returns 0 when compiled with optimization switched on.
The reason for that is that the compiler erroneously optimizes the <then> clause of the <if> statement out. unsigned char crc8(unsigned char crc, unsigned char
octet)
{ unsigned char j, tmp; j= 0;
while(j < 8) { tmp= crc ^ octet; if(tmp & 0x01) // optimized out { crc^= 0x18; // optimized out crc>>= 1; // optimized out crc|= 0x80; // optimized out } else { crc>>= 1; // always executed } octet>>= 1; // optimized out j++; } return(crc); } The offending line seems to be the _expression_ if(tmp & 0x01) With the -O0 (no optimization) this line is compiled to:
line 1: ldd r24,Y+4
// Y+4 is <tmp>
line 2: clr r25 line 3: andi r24,lo8(1) line 4: andi r25,hi8(1) line 5: sbiw r24,0 line 6: breq .L11 // Jump to else clause if Z flag set The compiler correctly expands the 8-bit unsigned char to a 16-bit int for
the _expression_ evaluation.
HOWEVER !!! What the optimizer (using -O1 or -O2 or -O3) seems to do
is:
1 - Get rid of line 5 because it thinks that subtracting 0 has no effect. 2 - Get rid of line 6 + the <true> part of the <if> clause because line 4 will always result in the Z flag to be set. It seems to me that the machine definition of the target (mega128) is
wrong.
It probably tells the compiler that the sbiw command does not affect the Z flag. Could anybody tell me whether I'm smoking my socks or confirm (and preferably fix) this bug ? Thanx
Peter
|
[Prev in Thread] | Current Thread | [Next in Thread] |