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:

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

PortVector 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 portsNot supported: ffi_prep_cif returns FFI_BAD_TYPEDEF for any signature that mentions a vector type, including one nested inside a struct.