This section contains some examples of the calling convention in use.
Consider the function prototype:
void fun1(int u, int v)
Reading from left to right, the parameter strong/strong is passed in register R15 and v is passed in R14. The scratch registers R12 and R13 are not used to pass parameters and can be used in fun1 without needing to be preserved.
Consider the function prototype:
void fun1(int u, long v, int w)
The parameter strong/strong is passed in register R15. Because v requires two registers to hold its value it is passed in the register pair R14:R13 with R14 holding the high part of v and R13 the low part. The final parameter w is passed in R12.
Consider the function prototype:
void fun1(int u, long v, int w, int x)
The parameter strong/strong is passed in register R15. Because v requires two registers to hold its value, it is passed in the register pair R14:R13 with R14 holding the high part of v and R13 the low part. Parameter w is passed in R12. As all scratch registers are now used, x is placed onto the stack.
Consider the function prototype:
void fun1(int u, long v, long w)
The parameter strong/strong is passed in register R15. Because v requires two registers to hold its value it is passed in the register pair R14:R13 with R14 holding the high part of v and R13 the low part. When considering w, there is only one free scratch register left, which is R12. The compiler cannot fit w into a single register and therefore places the argument onto the stack—the compiler does not split the value into two and pass half in a register and half on the stack.
Consider the function prototype:
void fun1(int u, long v, long w, int x, int y)
The parameter strong/strong is passed in register R15. Because v requires two registers to hold its value it is passed in the register pair R14:R13 with R14 holding the high part of v and R13 the low part. When considering w, there is only one free scratch register left, which is R12. The compiler cannot fit w into the single register R12 and therefore places the argument onto the stack. When considering x, the compiler sees that R12 is unused and so passes x in R12. All scratch registers are used when considering y, so the argument is placed onto the stack. The parameters w and x are pushed onto the stack before the call and are pushed in reverse order, with y pushed before w.
This example shows two parameters, w and y, that are passed to the called routine on the stack, but they are separated by a parameter x that is passed in a register.