SIMD Vectors
Zynx provides a built-in vector<T, N> type for SIMD (Single Instruction, Multiple Data) operations. This type is intended for data-parallel workloads and maps directly to hardware vector registers using the backend C compiler's vector extensions (for example, __attribute__((vector_size)) in GCC and Clang).
Use SIMD vectors when you need predictable, low-level control over packed numeric data and are comfortable with the target platform's vector semantics.
Declaration
A vector is declared with an element type T and a constant size N:
let v: vector<i32, 4>;
The size N must be a positive compile-time constant. The element type T must be a numeric type that the backend can map to a hardware SIMD lane.
Initialization and Assignment
Vectors can be initialized from standard Zynx arrays of the same size. This allows for straightforward data loading from regular aggregates:
let data: i32[4] = [1, 2, 3, 4];
let v: vector<i32, 4> = data;
You can also use array-like literals directly when initializing a vector, as long as the literal length matches the vector size:
let v2: vector<i32, 2> = [10, 20];
Operations
Vectors support a subset of arithmetic and bitwise operators. These operations are performed element-wise by the hardware and lowered to the platform's SIMD instruction set.
let a: vector<i32, 4> = [1, 1, 1, 1];
let b: vector<i32, 4> = [2, 2, 2, 2];
let c = a + b; // [3, 3, 3, 3]
let d = c * 2; // [6, 6, 6, 6]
let e = d >> 1; // [3, 3, 3, 3]
Supported Operators
- Arithmetic:
+,-,*,/,% - Bitwise:
&,|,^,<<,>>,~ - Compound assignment:
+=,-=,*=,/=,%=,&=,|=,^=,<<=,>>=
Notes:
- Operations are applied lane-wise across all elements.
- Vector operations do not use Zynx's default checked arithmetic (overflow checks); they follow the native SIMD behavior of the target, typically wrapping on overflow.
Element Access
You can access individual elements of a vector using standard subscript syntax:
let v: vector<i32, 4> = [10, 20, 30, 40];
let first = v[0]; // 10
// let x = v[4]; // Panics: index out of bounds
Safety
- Zynx performs runtime bounds checking on vector subscripts.
- Accessing an index
>= Ntriggers a panic, preserving memory safety.
Safety and Hardening
- Type validation: The compiler ensures that
vector<T, N>is only instantiated with supported numeric element types (T) and positive integer constants (N). - Initialization safety:
- Assigning from a fixed-size array or literal requires the same length; mismatches are diagnosed at compile time.
- Assigning from a dynamic array (for example,
v = my_array) performs a runtime size check in non-release builds to ensure the array length exactly matches the vector size.
- Arithmetic: Vector arithmetic is performed using native SIMD instructions. Overflow checks are disabled for vectors to follow standard hardware semantics.
- Literals: Vectors can be initialized directly with array-like literals:
The compiler validates the literal size at compile time.
let v: vector<i32, 2> = [1, 2];