IAR provides two calling conventions — one old, which is used in version 1.x of the compiler, and one new, which is the default. For both calling conventions, the registers available for passing parameters are: R16–R23. Parameters are allocated to registers using a first-fit algorithm, using parameter alignment requirements according to Table 2-2.
Parameters | Alignment | Passed in registers |
---|---|---|
8-bit values | 1 | R16, R17, R18, R19, R20, R21, R22, R23 |
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 |
64-bit values | 8 | R23:R22:R21:R20:R19:R18:R17:R16 |
In the default-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 default-calling convention. Below are three examples of combinations of register assignments in the default-calling convention.
Example 1:
void function(char __far * a, int b, char c, int d)
This would result in a being 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).
Example 2:
void function(char a, int b, long c, char d)
This would result in a being allocated to R16 (first fit), b to R19:R18 (alignment), c toR23:R22:R21:R20 (first fit), and d to R17 (first fit).
Example 3:
void function(char a, char __far * b, int c, int d)
This would result in a being allocated to R16, b to R22:R21:R20, c to R19:R18, and d to the stack.
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. Table 2-3 shows some of the possible combinations:
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 |
In the old calling convention, the registers available for returning values are R16-R19. The default-calling convention can use the registers R16-R23 for returning values.
Return values | Passed in registers |
---|---|
8-bit values | R16 |
16-bit values | R17:R16 |
24-bit values | R18:R17:R16 |
32-bit values | R19:R18:R17:R16 |
64-bit values | R23:R22:R21:R20:R19:R18:R17:R16 |