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: Wouter van Gulik
Subject: RE: [avr-gcc-list] Tablejumps - needless run time conversion to byteaddress
Date: Sat, 5 Jan 2008 21:53:39 +0100

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]