Import with #import "std/simd".
No public declarations.
Modules / Standard library
Fixed-width SIMD vectors: u8x16, s8x16, u16x8, s16x8, u32x4, s32x4, u64x2, s64x2, f32x4 and f64x2, and their 256-bit forms such as s16x16. Import the module and call its operations through the alias: Simd :: #import "simd" sum := Simd.Add(Simd.Load(s16x8, row, 0), Simd.Splat(s16x8, 1)) Every operation gives the same bits on every target: C uses SSE2..AVX2, NEON or WebAssembly SIMD128 where they match, and Go, the VM and other C compilers compute lane by lane. Integer lanes wrap unless the operation saturates. Operations that move data between lanes, such as Shuffle, ByteShuffle, AlignBytes, Narrow and InterleaveLow, work on each 128-bit block of a 256-bit vector on its own. Lane-wise arithmetic: Add, Sub, Mul, Div (float), AddSat, SubSat (8 and 16-bit lanes), Min, Max, Average (u8, u16, rounding up), MulHigh (16-bit), MulHighRound (s16, Q15 rounding), Abs, Neg, Sign(a, b) (signed lanes: a negated where b < 0 and 0 where b is 0), AbsDiff(a, b) (|a - b| in the unsigned lanes of the same width). Bits: And, Or, Xor, AndNot(a, b) = a & ~b, Not. Compare: Equal, Less, Greater give all-ones lanes where true; float lanes give the unsigned vector of the same width. Select(mask, a, b) takes bits from a where the mask is set and from b elsewhere. Shifts: ShiftLeft, ShiftRight (arithmetic for signed lanes, logical for unsigned lanes) and ShiftRightRound take one count; ShiftLeftLanes and ShiftRightLanes take a vector of counts. A count of the lane width or more gives 0, or the sign for an arithmetic shift. ShiftRightRound(v, n) is (v >> n) plus the last bit shifted out. Bytes: ShiftBytesLeft, ShiftBytesRight and AlignBytes(high, low, n) take a constant byte count; ByteShuffle(table, indices) gives 0 for an index of 16 or more. Lanes: Make(T, ...), Splat(T, x), Zero(T), Lane(v, i), WithLane(v, i, x), Shuffle(v, i0, i1, ...) with constant indices. Memory: Load(T, data, at), LoadLow(T, data, at) reads the low 64 bits and zeroes the rest; Store(data, at, v), StoreLow(data, at, v). Slices and arrays are checked once per access; pointers are not checked. Load and LoadLow also read immutable string bytes into u8 vectors, with the same whole-access bounds check and no intermediate byte allocation. Gather(table, indices) reads 32-bit lanes from a table. Width: WidenLow, WidenHigh (half the lanes, twice as wide), Widen (a 128-bit vector to 256 bits), Narrow(T, a, b) with saturation, MulWideLow, MulWideHigh, MulAddPairs (s16 pairs to s32), MulAddPairsSat (u8 by s8 pairs to s16, saturating), AddPairs, SumAbsDiff (u8 to u64). Reductions: ReduceAdd, ReduceMin, ReduceMax, ReduceMaxIndex (the first lane holding the maximum), AllZero. Types: Reinterpret(T, v) keeps the bits, Convert(T, v) converts between integer and float lanes of the same width (float to integer truncates and saturates; NaN gives 0), Low, High and Combine split and join 256-bit vectors, InterleaveLow and InterleaveHigh merge lanes. Native vectors u8xN .. f64xN hold two 128-bit blocks in AVX2 code (a #target procedure's AVX2 copy or an AVX2 build) and one elsewhere. Lanes(T) and Blocks(T) give the count, a constant for fixed vectors. Make, Splat and Shuffle name one block's lanes; WidenLow, WidenHigh, MulWideLow, MulWideHigh and Narrow count lanes across the whole vector; LoadLow and StoreLow move half. Lane, WithLane, Widen, Low, High and Combine take none. A native vector is a plain local, parameter or result, never stored in a global, field, array, pointer or slice, and never passed into or out of a #target or #foreign procedure.
Import with #import "std/simd".
No public declarations.