In certain cases (for example, for C procedures that use varargs), it is useful to form a contiguous in-memory structure that includes the contents of all of the formal parameter values. In nearly all cases, a compiler can arrange to allocate and initialize this structure so that the parameter values that are passed in registers are placed adjacent to the parameters that are passed on the stack (without making a copy of the stack arguments). Storage for the parameters passed in registers is called the argument home area (see Figures 3-1 and 3-2). The resulting in-memory homed argument list structure is illustrated in Figure 4-1.
Because it is generally not possible to tell statically whether a particular argument is an integer or floating-point argument, it is necessary to store both integer and floating-point register argument contents in this structure. However, it is sometimes possible to determine statically that there are no floating arguments anywhere at all (either in registers or on the stack), in which case the first six entries can be omitted. To facilitate this special case, the address used to reference this structure is always the address of the first integer argument position.
The C language type va_list is defined as follows:
typedef longlong quad;
typedef struct {
quad *base;
int offset;
} va_list;
To load the next integer argument, read the quadword at location (base + offset)), and add 8 to offset. To load the next floating argument, if offset is less than or equal 6*8, read the quadword at location (base + offset - 6*8)); otherwise, read the quadword at location (base + offset); in either case add 8 to offset.
Figure 4-1 In-Memory Homed Argument List Structure
octaword aligned
+----------------+
| flt arg #1:F16 | :-48 <- start of argument block
+----------------+
| F17 | :-40
+----------------+
| F18 | :-32
+----------------+
| F19 | :-24
+----------------+
| F20 | :-16
+----------------+
| flt arg #6:F21 | :-8
+----------------+
| int arg #1:R16 | :0 <- start of contiguous integer arguments
+----------------+
| R17 | :8
+----------------+
| R18 | :16
+----------------+
| R19 | :24
+----------------+
| R20 | :32
+----------------+
| int arg #6:R21 | :40
+----------------+
| arg #7: memory | :48 <- SP on entry (octaword aligned)
+----------------+
: memory :
| |