Design Document for AVR Port

From SDCC wiki
Jump to: navigation, search
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.

II) Pointers 
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      -  Parameter 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).

Christoph Redecker "AVR Assembler Tutorial" p. 9 suggests speeding up interrupt routines by reserving one register that is only used by interrupt routines, and never used in the main code.

Consider maybe tweaking this to be compatible with the AVR-libc calling convention.

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 the first parameter in
Each parameter that doesn't entirely fit in those registers will be entirely passed on the stack
(we won't put part of a parameter in registers and part on the stack).

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.

Further reading

Personal tools