C calling convention

The current calling convention is somewhat simplistic; it will be tuned for performance and size before the initial release of the compiler.


 * The bytes composing numeric arguments are passed individually in registers. The order used is A, then X, then each available imaginary (zero page) register, increasing (i.e., RC0 to RC255). The Y register is not used for arguments, but Y is still caller-saved; it's reserved to help the compiler shuffle values into the appropriate locations around calls.
 * Pointers are preferentially assigned to imaginary register pairs, functioning as pointer registers (i.e., RS0=(RC0, RC1) to RS128=(RC254, RC255)). If none are available, the low and high bytes are split and passed as above.
 * If no registers remain available, any remaining bytes are passed through the soft stack.
 * The callee-saved imaginary registers, RS2 (i.e., RC4 and RC5) and RS4 (i.e., RC8 and RC9) are skipped.
 * Aggregate types (structs, arrays, etc.) are passed by pointer. The pointer is managed entirely by the caller, and may or may not be on the soft stack. The callee is free to write to the memory; the caller must consider the memory overwritten by the call. This is handled directly by Clang; LLVM itself should never see aggregates.
 * Aggregate types are returned by a pointer passed as an implicit first argument. The resulting function returns void. This is handled directly by Clang; LLVM itself should never see aggregates.
 * RS2 and RS4 (and subregisters) are callee-saved. All other ZP locations, registers, and flags are caller-saved. The gap between the callee-saved registers balances between caller- and callee-saved registers if very little of the zero page is available.
 * Variable arguments (those within the ellipses of the argument list) are passed through the stack. Named arguments before the variable arguments are passed as usual: first in registers, then stack. Note that the variable argument and regular calling convention differ; thus, variable argument functions must only be called if prototyped. The C standard requires this, but many platforms do not; their variable argument and regular calling conventions are identical. A notable exception is Apple ARM64.
 * Values may be returned on the soft stack if insufficiently many registers are available. Callers must reserve sufficient space for this as they do for arguments. The space reserved for arguments may overlap freely with the space used for return values; thus only enough space for the larger of the two need be allocated.

For insight into the design of performant calling conventions, see the following work by Davidson and Whalley. By their convention, this plaftorm uses the "smarter hybrid" method, since LLVM performs both shrink wrapping and caller save-restore placement optimizations, while using both callee-saved and caller-saved registers when appropriate.

Methods for Saving and Restoring Register Values across Function Calls: Software--Practice and Experience Vol 21(2), 149-165 (February 1991) [[Category:C]]