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

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

Re: [avr-gcc-list] Urgent Queries about AVR-GCC


From: E. Weddington
Subject: Re: [avr-gcc-list] Urgent Queries about AVR-GCC
Date: Tue, 03 Jun 2003 06:04:22 -0600


Suresh B Joshi wrote:

> sent by Suresh Joshi (address@hidden)
>
> Hi all,
>
> I request for urgent help/work-around about the followings:-
>
> I wish to report the following 4 observations which
> tend to "eat-away" a lot of AVR flash memory, without
> any known reason (I tried AVR-GCC.EXE (GCC) 3.3 20030421 (prerelease)
> and AVR-GCC.EXE (GCC) 3.2 20020616 (experimental) for mega161):
>
>

>
>
> (2) When using the switch statement, even if the control
>     expression is an unsigned char variable, it is promoted
>     to 16 bit unsigned int, by eor R25,R25 instruction.
>     Further, each case expression is also promoted to 16 bit
>     integer (even if casted or defined by enum or otherwise)
>     and 16 bit comparision is done using cpi r24, casevalue
>     and cpc r25,r1 which wastes 2 bytes for each case comparison.
>     In my application, there are huge number of switch
>     statements and replacing by "if-else if" kills the code
>     readability.
>     "An example project" in the AVR-GCC libc PDF file shows
>     a more efficient 'switch' which uses sbiw instruction:
>     36: 00 97 sbiw r24, 0x00 ; 0
>     38: a1 f0 breq .+40 ; 0x62
>     I have verified this against native Borland C++ 5.5 free
>     command line compiler on a PC. This compiler uses
>     8 bit comparisons (using AL register) if the
>     control expression is unsigned char variable. It
>     truncates all case expressions to 8 bit.
>

This has to be checked against the C standard (Jörg, do you know if this
applies?). Just because Borland C++ 5.5 does one thing, doesn't mean that it's
using ISO C only.

"if-else-if" can still be readable if you write it as:
if(cond)
{
}
else if(cond)
{
}
else if(cond)
{
}
else
{
}


>
> example for (2)
> ===============
>
> switch((unsigned char)currently_selected_test)
>     17d0:       80 91 9c 00     lds     r24, 0x009C
>     17d4:       99 27           eor     r25, r25                        //
> CONTROL EXPR. INTEGER PROMOTED (NOT NEEDED)
>     17d6:       83 30           cpi     r24, 0x03       ; 3
>     17d8:       91 05           cpc     r25, r1                 // COMPARING
> ZERO WITH ZERO (NOT NEEDED)
>     17da:       81 f0           breq    .+32            ; 0x17fc
>     17dc:       84 30           cpi     r24, 0x04       ; 4
>     17de:       91 05           cpc     r25, r1                 // COMPARING
> ZERO WITH ZERO (NOT NEEDED)
>     17e0:       1c f4           brge    .+6             ; 0x17e8
>     17e2:       02 97           sbiw    r24, 0x02       ; 2
>     17e4:       39 f0           breq    .+14            ; 0x17f4
>         {
>         case TEST_SISI: sisi_test(' '); break;
>         case TEST_ABLB: ablb_test(' '); break;
>         case TEST_AUTO: auto_test(' '); break;
>         case TEST_TD: td_test(' '); break;
>         }
> }
>     17e6:       08 95           ret
>     17e8:       85 30           cpi     r24, 0x05       ; 5
>     17ea:       91 05           cpc     r25, r1
>     17ec:       59 f0           breq    .+22            ; 0x1804
>     17ee:       06 97           sbiw    r24, 0x06       ; 6
>     17f0:       69 f0           breq    .+26            ; 0x180c
>     17f2:       08 95           ret
>     17f4:       80 e2           ldi     r24, 0x20       ; 32
>     17f6:       0e 94 2a 0e     call    0x1c54
>     17fa:       08 95           ret
>     17fc:       80 e2           ldi     r24, 0x20       ; 32
>     17fe:       0e 94 83 0d     call    0x1b06
>     1802:       08 95           ret
>     1804:       80 e2           ldi     r24, 0x20       ; 32
>     1806:       0e 94 6c 0c     call    0x18d8
>     180a:       08 95           ret
>     180c:       80 e2           ldi     r24, 0x20       ; 32
>     180e:       0e 94 0b 0c     call    0x1816
>     1812:       08 95           ret
>     1814:       08 95           ret                     // ret SHOULD NOT
> APPEAR ONE BELOW THE OTHER
>

The "2 rets" are probably an artifact of your C code. You will have to post a
listing of mixed C and assembly. I highly doubt the compiler is generating a
spurious ret.

Eric Weddington



reply via email to

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