#### 2.3.8 Vector Types ¶

`libffi` can marshal vector (SIMD) types — the values produced by GCC’s `__attribute__((vector_size (N)))` and Clang’s `ext_vector_type` — on the platforms listed in the support table below. A vector is described just like a structure, except that every element pointer refers to the same fundamental scalar type and the number of elements is the number of vector lanes.

Data type: ffi_type ¶
  `size_t size`

    This must be set to `0`. `libffi` computes the storage size (see below) from the element type and lane count.

  `unsigned short alignment`

    This must be set to `0`. `libffi` computes the alignment.

  `unsigned short type`

    For a vector type, this must be set to `FFI_TYPE_VECTOR`.

  `ffi_type **elements`

    This is a ‘`NULL`’-terminated array of pointers to `ffi_type` objects. Every entry must point to the same scalar element type, and the number of entries is the vector’s lane count N (N >= 1). The element type must be one of `ffi_type_float`, `ffi_type_double`, or a fixed-width integer (`ffi_type_uint8` through `ffi_type_sint64`); `long double` and aggregate element types are not permitted.

#### Computed layout ¶

Because the caller leaves `size` and `alignment` at `0`, `libffi` derives them so that applications need not encode compiler- or platform-specific rules:

- `size` is lane\_size \times N rounded up to the next power of two. This matches Clang’s `ext_vector_type` storage — for example a three-lane `float` vector occupies 16 bytes and a three-lane `double` vector occupies 32 bytes. GCC’s `vector_size` already requires power-of-two byte totals, so the rule is identical there.
- `alignment` is `min(size, 16)`.

If the element list is heterogeneous, empty, or uses a disallowed element type, `ffi_prep_cif` returns `FFI_BAD_TYPEDEF`.

#### psABI framing ¶

At the call boundary the platform’s processor-specific ABI (AAPCS64 on AArch64, the System V x86-64 psABI on x86-64) decides how a vector is passed and returned, independently of which compiler produced it. The historical divergence between GCC’s `vector_size` and Clang’s `ext_vector_type` concerns only in-memory layout (notably the padding of odd-lane vectors such as `float3`); the power-of-two size rule above pins that layout down, so a value marshalled by `libffi` matches what a natively compiled caller or callee expects.

#### Per-port support ¶

Port | Vector support
--- | ---
AArch64 (AAPCS64) | 8- and 16-byte vectors in a single V/Q register; homogeneous vector aggregates (structs of up to four identical 8- or 16-byte vectors) in consecutive V/Q registers. A bare vector larger than 16 bytes (for example a 32-byte `double4`) has no short-vector register class and is passed and returned in memory, exactly as AAPCS64 and current compilers do.
x86-64 (System V psABI) | 8- and 16-byte vectors in an SSE register (`%xmm0` for returns). A bare vector larger than 16 bytes needs `%ymm`/`%zmm` register handling that this port does not yet implement, so `ffi_prep_cif` returns `FFI_BAD_TYPEDEF` for it.
Other ports | Not supported: `ffi_prep_cif` returns `FFI_BAD_TYPEDEF` for any signature that mentions a vector type, including one nested inside a struct.