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

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

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


From: Suresh B Joshi
Subject: [avr-gcc-list] Urgent Queries about AVR-GCC
Date: Tue, 3 Jun 2003 09:59:24 +0530

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):

(1) Any function whose return value is only 8 bits
    (i.e. unsigned char), the GCC-AVR compiler still
    clears the R25 register using eor R25,R25 instruction.
    The calling function only uses the R24 register
    which contains the result and ignores R25 completely.
    Thus, for every function which returns an unsigned char,
    there is a wastage of 2 bytes.
    Being 8 bit controller, many functions return unsigned char,
    so, wastage is more.

example for (1)
===============

unsigned char get_currently_selected_test(void)
{
return(currently_selected_test);
    16ca:       80 91 9c 00     lds     r24, 0x009C
    16ce:       99 27           eor     r25, r25                // THIS IS
NEVER NEEDED AND NOT USED
}
    16d0:       08 95           ret



(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.

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


(3) When calling functions within same source files, the
    use of "call" instruction need not be employed for
    AVR processors with memory higher than 8K bytes.
    Instead, it should use "rcall" by default. This will
    save 2 bytes per function call in the same file.
    Since most related functions are kept in 1 source file,
    this will be a good saving.

example for (3)
===============

int main(void)
{
     1a8:       cf e5           ldi     r28, 0x5F       ; 95
     1aa:       d4 e0           ldi     r29, 0x04       ; 4
     1ac:       de bf           out     0x3e, r29       ; 62
     1ae:       cd bf           out     0x3d, r28       ; 61
unsigned char ch, cur_test;

wdt_disable();
     1b0:       88 e1           ldi     r24, 0x18       ; 24
     1b2:       90 e0           ldi     r25, 0x00       ; 0
     1b4:       20 e0           ldi     r18, 0x00       ; 0
     1b6:       0f b6           in      r0, 0x3f        ; 63
     1b8:       f8 94           cli
     1ba:       a8 95           wdr
     1bc:       81 bd           out     0x21, r24       ; 33
     1be:       0f be           out     0x3f, r0        ; 63
     1c0:       21 bd           out     0x21, r18       ; 33
cli();
     1c2:       f8 94           cli
powerup_init(); // THIS FUNCTION IS IN SAME SOURCE FILE AS MAIN
     1c4:       0e 94 b7 01     call    0x36e           // SO, RCALL SHOULD
SUFFICE

set_power_up_defaults();        // THIS FUNCTION IS IN SAME SOURCE FILE AS
MAIN
     1c8:       0e 94 cf 01     call    0x39e           // SO, RCALL SHOULD
SUFFICE



(4) Sometimes, two consecutive "ret" instructions appear
    one after the other.

example for (4):

See example for (2), last two lines.

END OF THIS MESSAGE






reply via email to

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