15.7.1 Function Parameters

The first eight working registers (W0-W7) are used for function parameters. Parameters are allocated to registers in left-to-right order, with the parameter being assigned to the first available register that is suitably aligned.

In the following example, all parameters are passed in registers, although not in the order that they appear in the declaration. This format allows the compiler to make the most efficient use of the available parameter registers.

Function Call Model

void
params0(short p0, long p1, int p2, char p3, float p4, void *p5)
{
           /*
           ** W0 p0
           ** W1 p2
           ** W3:W2 p1
           ** W4 p3
           ** W5 p5
           ** W7:W6 p4
           */
           ...
}

The next example demonstrates how structures are passed to functions. If the complete structure can fit in the available registers, then the structure is passed via registers; otherwise the structure argument will be placed onto the stack.

Function Call Model, Passing Structures

typedef struct bar {
  int i;
  double d;
} bar;

void
params1(int i, bar b) {
           /*
           ** W0 i
           ** W1 b.i
           ** W5:W2 b.d
           */

}

Parameters corresponding to the ellipses (...) of a variable-length argument list are not allocated to registers. Any parameter not allocated to registers is pushed onto the stack, in right-to-left order.

In the next example, the structure parameter cannot be placed in registers because it is too large. However, this does not prevent the next parameter from using a register spot.

Function Call Model, Stack Based Arguments

typedef struct bar {
 double d,e;
} bar;

void
params2(int i, bar b, int j) {
             /*
             ** W0 i
             ** stack b
             ** W1 j
             */
}

Accessing arguments that have been placed onto the stack depends upon whether or not a Frame Pointer has been created. Generally the compiler will produce a Frame Pointer (unless told not to do so), as stack-based parameters will be accessed via the Frame Pointer register (W14). In the preceding example, b will be accessed from W14-22. The Frame Pointer offset of negative 22 has been calculated by removing 2 bytes for the previous FP, 4 bytes for the return address, followed by 16 bytes for b.

When no Frame Pointer is used, the assembly programmer must know how much stack space has been used since entry to the procedure. If no further stack space is used, the calculation is similar to the example above. b would be accessed via W15-20; 4 bytes for the return address and 16 bytes to access the start of b.