I’m implementing an AVR port to the SDCC (Small Device C Compiler) as College project. I think this will help me in improving my knowledge about AVR architecture and compiler design.
This document is inherited from SDCC AVR implementation page.
Design Document for AVR Port
The first release will support all AVR architectures except ATMega & ATtiny
(i.e. all variants with 64K or less of code/data space will be supported)
All functions will be REENTRANT .
I) Language extensions
a) Storage classes
“bit” – not applicable (will be returned to user name space)
“data” – not applicable (will be returned to user name space)
“idata” – not applicable (will be returned to user name space)
“xdata” – not applicable (will be returned to user name space)
“code” – will place variable in “code” space. NOTE code space is NOT read-only.
“eeprom”- (new) will place the variable in eeprom (read & write)
“sram” – (new) will place the variable in “SRAM” after the SFRs (default).
b) register/sfr bit access.
Operator ‘.’ will be overloaded ( the compiler will decide if it
is a structure access or register bit access depending on context)
sfr SOME_SFR = 0x40;
sfr SOME_OTHER_SFR = 0x41;
SOME_SFR.4 = 1; // set bit 4 of sfr SOME_SFR
SOME_SFR.5 = SOME_OTHER_SFR.6; // copy bit 6 of SOME_OTHER_SFR to SOME_SFR’s bit 5.
As mentioned above initial releases will NOT support ATMega.
Keeping with the three byte pointers for generic pointers,
the compiler will treat unqualified pointers as 3 byte pointers,
the storage area will be saved in the upper nibble of the third byte
(this will facilitate later support for ATMega). Here we differ for
IAR (they seem to make copies of variables in code & other address
spaces into data space, seemed like a needless waste of data space).
pointer declaration examples.
char *cp; /* generic three byte pointer */
code char *cp; /* pointer to code space */
eeprom char *cp; /* pointer to data in eepromp */
sram char *cp; /* pointer to data in SRAM space */
III) Function calls
The previous issue of function calls has been somewhat resolved.
SDCC will NOT support ATtiny & other variants (such as AT90S1200)
which have limited stack depth. It will however support variants
with 8 bit stack pointers.
IV) Register Usage
R0-R7 – Paramter passing & return value (differs from IAR I don’t
like IAR’s usage of R16-R23, specially since R0-R1 has
to be kept free anyway for divide & multiply operations)
R8-R25 – General purpose registers for local variables.
R28-R29(Y) – Stack Frame (Same as IAR)
R26-R27(X) – GPRs assigned to pointers (non generic pointers).
R30-R31(Z) – GPRs assigned to pointers (non generic pointers).
V) Parameter passing & return values
Registers R0-R7 (eight) registers will be used for parameter passing.
Unlike the 8051 port the AVR port will pass the first eight bytes of
parameters in a registers (8051 passes only yhe first parameter in
registers), the exception being.. part of a paramter will not be put
int foo (char a,long b);
R0 <- a,
R1-R4 <- b;
int foo (long a, char b, long c)
R0-R3 <- a,
R4 <- b,
(STACK) <- c;
int foo (long a,long b)
R0-R3 <- a,
R4-R7 <- b;
Return values will be placed in registers R0-R3;
VI) Memory models
The memory model will be used primarily to determine the
width of the stack pointer.
–model-small – stack pointer 8 bit
–model-large – stack pointer 16 bit.