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