Hi guys,
Looking for independent confirmation of this before I file a bug report for GCC.
It seems the newer GCC versions (4.8.1 tested here) the compiler will emit jump table optimizations for switch-case statements in some circumstances -- but the generated assembly is invalid in some cases. Specifically, it uses regular LPM instructions to fetch the table contents from FLASH memory, without regard to devices with larger FLASH memory spaces than the standard instruction allows. When used on a >64KB device, this causes the jump target to be pulled pseudo-randomly from FLASH.
Can anyone else see this? When compiling a bootloader for a AT90USB1287, I get:
switch (USB_ControlRequest.bRequest) 1efae: 30 91 84 02 lds r19, 0x0284 1efb2: 83 2f mov r24, r19 1efb4: 90 e0 ldi r25, 0x00 ; 0 1efb6: 8a 30 cpi r24, 0x0A ; 10 1efb8: 91 05 cpc r25, r1 1efba: 08 f0 brcs .+2 ; 0x1efbe1efbc: c4 c0 rjmp .+392 ; 0x1f146 1efbe: fc 01 movw r30, r24 1efc0: e4 5b subi r30, 0xB4 ; 180 1efc2: ff 40 sbci r31, 0x0F ; 15 1efc4: 63 c2 rjmp .+1222 ; 0x1f48c <__tablejump2__> {
Which leads to:
0001f48c <__tablejump2__>: 1f48c: ee 0f add r30, r30 1f48e: ff 1f adc r31, r31 0001f490 <__tablejump__>: 1f490: 05 90 lpm r0, Z+ 1f492: f4 91 lpm r31, Z 1f494: e0 2d mov r30, r0 1f496: 09 94 ijmp
Which then explodes, as the LPM in __tablejump__ doesn't work on a .text section that is relocated to 0x1E000.
I can patch this in the meantime with -fno-jump-tables but I'd like to file a proper report if someone else can confirm it so that it gets fixed.
- Dean :twisted: