When optimization is enabled during build, the following switch statement is
compiled into assembler using a command combination (lpm r31, Z+) which
potentially results in an undefined result (see LPM description in AVR 8-bit
instruction set manual):
// successfully decoded
switch (cmdGroup)
{
case AL_CMD_GROUP_GEN:
results in:
// successfully decoded
switch (cmdGroup)
57ec: 85 2d mov r24, r5
57ee: 90 e0 ldi r25, 0x00 ; 0
57f0: fc 01 movw r30, r24
57f2: 31 97 sbiw r30, 0x01 ; 1
57f4: e2 31 cpi r30, 0x12 ; 18
57f6: f1 05 cpc r31, r1
57f8: 10 f0 brcs .+4 ; 0x57fe
<cmdExec_executeCommand+0x88>
57fa: 0c 94 75 34 jmp 0x68ea ; 0x68ea
<cmdExec_executeCommand+0x1174>
57fe: e6 50 subi r30, 0x06 ; 6
5800: ff 4f sbci r31, 0xFF ; 255
5802: ee 0f add r30, r30
5804: ff 1f adc r31, r31
5806: 05 90 lpm r0, Z+
5808: f4 91 lpm r31, Z+
580a: e0 2d mov r30, r0
580c: 19 94 eijmp
{
case AL_CMD_GROUP_GEN:
btw: The LPM statement is simply used, although the compiler does not ensure if
the NVM command is set to NOOP. It might be set to anything else like
READ_SIG_ROW - this caused a problem in my project - able to solve, but in case
of such switches within interrupt service routine, the NVM-CMD register might
be set to anything else before it may be restored after usage.
--
Summary: usage of LPM command combination with undefined result
Product: gcc
Version: 4.3.3
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: other
AssignedTo: unassigned at gcc dot gnu dot org
ReportedBy: thomas-carsten dot franke at brunel dot de
GCC host triplet: i386
GCC target triplet: avr
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44564