avr-gcc-list
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-gcc-list] Tablejumps - needless run time conversion to byteaddr


From: Andrew Hutchinson
Subject: Re: [avr-gcc-list] Tablejumps - needless run time conversion to byteaddress
Date: Sun, 06 Jan 2008 06:53:43 -0500
User-agent: Thunderbird 2.0.0.9 (Windows/20071031)

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,

Wouter

Hi

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
address@hidden
http://lists.nongnu.org/mailman/listinfo/avr-gcc-list






reply via email to

[Prev in Thread] Current Thread [Next in Thread]