Vector Extensions (The GNU D Compiler)

### 2.10 Vector Extensions ¶

CPUs often support specialized vector types and vector operations (aka media instructions). Vector types are a fixed array of floating or integer types, and vector operations operate simultaneously on them.

    alias int4 = __vector(int[4]);

All the basic integer types can be used as base types, both as signed and as unsigned: `byte`, `short`, `int`, `long`. In addition, `float` and `double` can be used to build floating-point vector types, and `void` to build vectors of untyped data. Only sizes that are positive power-of-two multiples of the base type size are currently allowed.

The `core.simd` module has the following shorthand aliases for commonly supported vector types: `byte8`, `byte16`, `byte32`, `byte64`, `double1`, `double2`, `double4`, `double8`, `float2`, `float4`, `float8`, `float16`, `int2`, `int4`, `int8`, `int16`, `long1`, `long2`, `long4`, `long8`, `short4`, `short8`, `short16`, `short32`, `ubyte8`, `ubyte16`, `ubyte32`, `ubyte64`, `uint2`, `uint4`, `uint8`, `uint16`, `ulong1`, `ulong2`, `ulong4`, `ulong8`, `ushort4`, `ushort8`, `ushort16`, `ushort32`, `void8`, `void16`, `void32`, `void64`. All these aliases correspond to `__vector(type[N])`.

Which vector types are supported depends on the target. Only vector types that are implemented for the current architecture are supported at compile-time. Vector operations that are not supported in hardware cause GNU D to synthesize the instructions using a narrower mode.

    alias v4i = __vector(int[4]);
    alias v128f = __vector(float[128]);    // Error: not supported on this platform

    int4 a, b, c;

    c = a * b;    // Natively supported on x86 with SSE4
    c = a / b;    // Always synthesized

Vector types can be used with a subset of normal D operations. Currently, GNU D allows using the following operators on these types: `+, -, *, /, unary+, unary-`.

    alias int4 = __vector(int[4]);

    int4 a, b, c;

    c = a + b;

It is also possible to use shifting operators `<<`, `>>`, the modulus operator `%`, logical operations `&, |, ^`, and the complement operator `unary~` on integer-type vectors.

For convenience, it is allowed to use a binary vector operation where one operand is a scalar. In that case the compiler transforms the scalar operand into a vector where each element is the scalar from the operation. The transformation happens only if the scalar could be safely converted to the vector-element type. Consider the following code.

    alias int4 = __vector(int[4]);

    int4 a, b;
    long l;

    a = b + 1;    // a = b + [1,1,1,1];
    a = 2 * b;    // a = [2,2,2,2] * b;

    a = l + a;    // Error, incompatible types.

Vector comparison is supported with standard comparison operators: `==, !=, <, <=, >, >=`. Comparison operands can be vector expressions of integer-type or real-type. Comparison between integer-type vectors and real-type vectors are not supported. The result of the comparison is a vector of the same width and number of elements as the comparison operands with a signed integral element type.

Vectors are compared element-wise producing 0 when comparison is false and -1 (constant of the appropriate type where all bits are set) otherwise. Consider the following example.

    alias int4 = __vector(int[4]);

    int4 a = [1,2,3,4];
    int4 b = [3,2,1,4];
    int4 c;

    c = a >  b;     // The result would be [0, 0,-1, 0]
    c = a == b;     // The result would be [0,-1, 0,-1]