Specifications

CAVR-4
Part1. Using the compiler
Assembler language interface
103
Register assignment using the old calling convention
In the old calling convention, the two left-most parameters are passed in registers if
they are scalar and up to 32 bits in size.
The following table shows some of the possible combinations:
* Where b denotes an 8-bit data type, w denotes a 16-bit data type, and l denotes a 32-bit data
type. If the first and/or second parameter is a 3-byte pointer, it will be passed in
R16–R19 or
R20–R22 respectively.
Register assignment using the new calling convention
In the new calling convention, as many parameters as possible are passed in registers.
The remaining parameters are passed on the stack. The compiler may change the order
of the parameters in order to achieve the most efficient register usage.
The algorithm for assigning parameters to registers is quite complex in the new calling
convention. For details, you should create a list file and see how the compiler assigns the
different parameters to the available registers, see Creating skeleton code, page 96.
Below follows some examples of combinations of register assignment.
A function with the following signature (not C++):
void foo(char __far * a, int b, char c, int d)
would have a allocated to R18:R17:R16, b to R21:R20 (alignment requirement
prevents
R20:R19), c to R19 (first fit), and d to R23:R22 (first fit).
Another example:
void bar(char a, int b, long c, char d)
16-bit values 2
R17:R16, R19:R18, R21:R20, R23:R22
24-bit values 4
R18:R17:R16, R22:R21:R20
32-bit values 4
R19:R18:R17:R16, R23:R22:R21:R20
Parameters* Parameter 1 Parameter 2
f(b1,b2,…) R16 R20
f(b1,w2,…) R16 R20, R21
f(w1,l1,…) R16, R17 R20, R21, R22, R23
f(l1,b2,…) R16, R17, R18, R19 R20
f(l1,l2,…) R16, R17, R18, R19 R20, R21, R22, R23
Table 28: Passing parameters in registers
Parameters Alignment Passed in registers
Table 27: Registers used for passing parameters (Continued)