Thanks! This will work just fine. Seems all the attempts I made were too optimal!
Andy Wouter van Gulik wrote:
I can make GCC use a jumptable using this code: test.c =========================================== volatile int x; volatile int y; void foo (void) { x++; } void main(void) { switch(y) { case 0 : foo(); case 1 : foo(); case 2 : foo(); case 3 : foo(); case 4 : foo(); case 5 : foo(); case 6 : foo(); case 7 : foo(); case 8 : foo(); case 9 : foo(); case 10 : foo(); case 11 : foo(); case 12 : foo(); case 13 : foo(); case 14 : foo(); case 15 : foo(); case 16 : foo(); } } =========================================== Compiling using: avr-gcc -g -Os -Wall -mmcu=atmega16 -fno-inline test.c (Using no inline to keep disassembly small) gcc version 4.2.2 Gives: ======================================================================= main: .LFB3: .LM3: /* prologue: frame size=0 */ /* prologue end (size=0) */ .LM4: lds r30,y lds r31,(y)+1 cpi r30,17 cpc r31,__zero_reg__ brsh .L23 .LM5: subi r30,lo8(-(gs(.L22))) sbci r31,hi8(-(gs(.L22))) lsl r30 rol r31 lpm __tmp_reg__,Z+ lpm r31,Z mov r30,__tmp_reg__ ijmp .data .section .progmem.gcc_sw_table, "a", @progbits .p2align 1 .L22: .data .section .progmem.gcc_sw_table, "a", @progbits .p2align 1 .word gs(.L5) .word gs(.L6) .word gs(.L7) .word gs(.L8) .word gs(.L9) .word gs(.L10) .word gs(.L11) .word gs(.L12) .word gs(.L13) .word gs(.L14) .word gs(.L15) .word gs(.L16) .word gs(.L17) .word gs(.L18) .word gs(.L19) .word gs(.L20) .word gs(.L21) .text .L5: .LM6: call foo <snip> etc... ========================================================================== Some interesting notes: It works only from 17 cases and up. For smaller devices (e.g. atmega8) It works from already from 3 cases. But then an rjmp table is used. Why is GCC not using this rjmp scheme for the atmega16? Is it too difficult to predict it will not pass 4k boundary? HTH, WouterHi Does anyone have some code that creates tablejump in Avr-gcc? This is where gcc will create table instead of long line of if-then-else tests I cant seem to create enough switch cases to force one! I have been looking at compilation patterns and noticed that gcc address is multiplied by 2 to form address for LPM (table being in ROM). LPM needs byte address and gcc has word address. "lsl r30 rol r31 lpm __tmp_reg__,Z+ lpm r31,Z mov r30,__tmp_reg__ ijmp" Asm Pattern currently expects value to be in R30. However, it would appear that this would be better with a symbol rather than value in register - thus providing a means to multiply that value by 2 at compile time. (and I cant see any reason it would be called with other than constant address in ROM) Obviously, I'd like to test it. Andy _______________________________________________ AVR-GCC-list mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
_______________________________________________ AVR-GCC-list mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/avr-gcc-list
