[Top][All Lists]
[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
Re: [avr-gcc-list] Urgent Queries about AVR-GCC,
E. Weddington <=