# Parameter passing Parameters are passed to functions in up to six general purpose registers: R0–R5. Any parameters that cannot fit in these registers are passed on the software stack. The calling function allocates space in the lower portion of its frame for these. Each function allocates the maximum amount of space required by any of its calls in its outgoing memory arguments area. If the function does not make any calls, or if all of its calls can pass all parameters in registers, then the outgoing memory arguments area of the stack frame is not allocated. ## Fixed argument list function calls The most common case for function calls is a fixed argument length function. In C, these are functions with: - A function prototype that contains a fixed number of arguments. - No function prototype, also known as Kernighan and Ritchie (K&R) style. A variable argument length function whose prototype is missing at the call site can lead to subtle program errors. This is due to the mismatch between the parameter passing of the caller and callee. For each fixed argument length call, the parameters are processed from left to right as follows: - Any parameter (including aggregates) with size up to 64 bits is a candidate to be passed in a register. Parameters up to 32 bits in size are passed in a single register. Larger parameters are passed in a register pair. - Candidates are assigned to registers R0 through R5 in order. - Candidates larger than 32 bits are passed in a register pair. If the next available register is an odd-numbered register, that register is skipped (left unused), and the candidate is placed in the next even-odd pair. If the next available register is R5, then the candidate is passed on the stack. - Candidates larger than 64 bits are passed on the stack. The alignment rules are the same as for static data ([Memory alignment](https://docs.qualcomm.com/doc/80-N2040-23/topic/data-types.html#memory-alignment)). - Do not attempt to recover skipped parameter registers by filling them with subsequent parameters. However, we will continue using parameter registers after a candidate larger than 64 bits has been placed on the stack. - Once all the parameter registers have been filled or skipped, all remaining parameters are passed on the stack. The normal alignment rules apply ([Memory alignment](https://docs.qualcomm.com/doc/80-N2040-23/topic/data-types.html#memory-alignment)). ### Example 1: scalars extern int foo(short, float, int, double); foo(i, a, b, c); Copy to clipboard The parameters are passed as follows: i R0 a. R1 b. R2 c. R5:R4 Copy to clipboard ### Example 2: arrays and structures extern int bar(); struct {int length, width;} st1; struct {int a; int bvec[8];} st2; bar(i, st1, st2); Copy to clipboard The parameters are passed as follows: i R0 st1 R3:R2 st2.a In memory, at R29+0 st2.bvec In memory, at R29+4 Copy to clipboard Note R29 is the stack pointer (sp). ## Variable argument list function calls Variable argument list functions are a special type of function in C where the number and types of arguments can vary. The best-known example of this is the printf function in the C library, where the function’s number and type of arguments change, depending on the first argument given: a format string. In general, variable argument functions determine the number and type of their arguments by programming conventions. For these functions, we pass the named (and typed) parameters in the same manner as for fixed argument list functions. The remainder of the arguments are passed on the stack. The normal alignment rules apply ([Memory alignment](https://docs.qualcomm.com/doc/80-N2040-23/topic/data-types.html#memory-alignment)). ### Example: extern int vfoo(int, long long, short, ...); vfoo(a1, a2, a3, a4, (double)a5, a6); Copy to clipboard The parameters are passed as follows: a1 R0 a2 R3:R2 a3 R4 a4 In memory, at R29+0 a5 In memory, at R29+8, due to 8 byte alignment a6 In memory, at R29+16 Copy to clipboard Note R29 is the stack pointer (sp). ## Calling Conventions for vXi1 Call Operands The compiler follows the rules below when handling boolean vector types (`vXi1`) as call operands. Boolean vectors are passed in registers D0 (R1:0) to D15 (R16:15). - `v2i1`: Promote to `v2i32` - `v4i1`: Promote to `v4i16` - `v8i1`: Promote to `v8i8` - `vXi1` where `X` is **not a power of 2** and `X < 8`: The vector is widened to the **next power-of-two** size to maintain consistency. For example: - `v3i1`: Widened to `v4i1` - `v6i1`: Widened to `v8i1` - `vXi1` where **X is divisible by 8** and `X >= 8`: - The vector is split into `(X / 8)` vectors of type `v8i1` - Each `v8i1` is promoted to `v8i8` ## Vector register usage for function calls Vector registers V0 to V15 are used for input parameters. Registers W0 to W7 (V1:V0…) are used for Vector Pair arguments. The remaining vector parameters are on the stack. For example, the Passing Vector, VectorPair, uses V0, V3:V2. The V1 parameter is not used (the first available register used to allocate a Vector Pair should be even). However, the skipped register is reused for subsequent arguments. For instance, the argument order of Vector, VectorPair, Vector uses V0, V3:V2, V1. Vector registers V0 and V1:V0 are used for return results. Variadic vector arguments are passed on the stack. All vector registers remain *caller saves* as opposed to *callee saves*, which does not affect existing assembly or C Intrinsic applications. This includes vector predicate and vector registers. ## HVX Calling Conventions for vXi1 Call Operands HVX Boolean Vectors are passed in Vector registers V0 to V15. **HVX 64-byte Mode:** - `v16i1`: Promote to `v16i32`. - `v32i1`: Promote to `v32i16`. - `v64i1`: Promote to `v64i8`. - Where `X` is a power of 2 and `X >= 64`, then: - `vXi1` is split into `(X / 64)` vectors of type `v64i1`. - Each `v64i1` is promoted to `v64i8`. **HVX 128-byte Mode:** - `v16i1`: Widen to `v32i1` and promote to `v32i32`. - `v32i1`: Promote to `v32i32`. - `v64i1`: Promote to `v64i16`. - Where `X` is a power of 2 and `X >= 128`, then: - `vXi1` is split into `(X / 128)` vectors of type `v128i1`. - Each `v128i1` is promoted to `v128i8`. Last Published: Oct 06, 2026 [Previous Topic Stack sections](https://docs.qualcomm.com/bundle/publicresource/80-N2040-23/topics/abi-software-stack.md) [Next Topic Return values](https://docs.qualcomm.com/bundle/publicresource/80-N2040-23/topics/return-values.md)