// GNU D Compiler SIMD support functions and intrinsics.
// Copyright (C) 2022-2026 Free Software Foundation, Inc.

// GCC is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free
// Software Foundation; either version 3, or (at your option) any later
// version.

// GCC is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

module gcc.simd;

pure:
nothrow:
@safe:
@nogc:
pragma(inline, true):

/**
* Emit prefetch instruction.
* Params:
*    address = address to be prefetched
*    writeFetch = true for write fetch, false for read fetch
*    locality = 0..3 (0 meaning least local, 3 meaning most local)
*/
void prefetch(bool writeFetch, ubyte locality)(const(void)* address)
{
    static assert(locality < 4, "0..3 expected for locality");
    import gcc.builtins : __builtin_prefetch;
    __builtin_prefetch(address, writeFetch, locality);
}

/**
 * Load unaligned vector from address.
 * This is a compiler intrinsic.
 * Params:
 *    p = pointer to vector
 * Returns:
 *    vector
 */
V loadUnaligned(V)(const V* p) if (isVectorType!V);

/**
 * Store vector to unaligned address.
 * This is a compiler intrinsic.
 * Params:
 *    p = pointer to vector
 *    value = value to store
 * Returns:
 *    value
 */
V storeUnaligned(V)(V* p, V value) if (isVectorType!V);

/**
 * Construct a permutation of elements from one or two vectors, returning a
 * vector of the same type as the input vector(s). The `mask` is an integral
 * vector with the same width and element count as the output vector.
 * Params:
 *    op1 = input vector
 *    op2 = input vector
 *    mask = integer vector mask
 * Returns:
 *    vector with the same type as `op1` and `op2`
 * Example:
 * ---
 * int4 a = [1, 2, 3, 4];
 * int4 b = [5, 6, 7, 8];
 * int4 mask1 = [0, 1, 1, 3];
 * int4 mask2 = [0, 4, 2, 5];
 * assert(shuffle(a, mask1).array == [1, 2, 2, 4]);
 * assert(shuffle(a, b, mask2).array == [1, 5, 3, 6]);
 * ---
 */
template shuffle(V0, V1, M)
{
    static assert(isVectorType!V0, "first argument must be vector");
    static assert(isVectorType!V1, "second argument must be vector");
    static assert(is(BaseType!V0 == BaseType!V1),
                  "first and second argument vectors must have the same element type");
    static assert(isVectorType!M && is(BaseType!M : long),
                  "last argument must be an integer vector");
    static assert(numElements!V0 == numElements!M && numElements!V1 == numElements!M,
                  "argument vectors and mask vector should have the same number of elements");
    static assert(BaseType!V0.sizeof == BaseType!M.sizeof,
                  "argument vectors and mask vector should have the same element type size");

    V0 shuffle(V0 op1, V1 op2, M mask);
}

/// Ditto
template shuffle(V, M)
{
    static assert(isVectorType!V, "first argument must be a vector");
    static assert(isVectorType!M && is(BaseType!M : long),
                  "last argument must be an integer vector");
    static assert(numElements!V == numElements!M,
                  "argument vector and mask vector should have the same number of elements");
    static assert(BaseType!V.sizeof == BaseType!M.sizeof,
                  "argument vector and mask vector should have the same element type size");

    V shuffle(V op1, M mask)
    {
        return shuffle(op1, op1, mask);
    }
}

/**
 * Construct a permutation of elements from two vectors, returning a vector with
 * the same element type as the input vector(s), and same length as the `mask`.
 * Params:
 *    op1 = input vector
 *    op2 = input vector
 *    index = elements indices of the vectors that should be extracted and returned
 * Returns:
 *    vector with the same element type as `op1` and `op2`, but has an element count
 *    equal to the number of indices in `index`.
 * Example:
 * ---
 * int8 a = [1, -2, 3, -4, 5, -6, 7, -8];
 * int4 b = shufflevector(a, a, 0, 2, 4, 6);
 * assert(b.array == [1, 3, 5, 7]);
 * int4 c = [-2, -4, -6, -8];
 * int d = shufflevector(c, b, 4, 0, 5, 1, 6, 2, 7, 3);
 * assert(d.array == a.array);
 * ---
 */
template shufflevector(V1, V2, M...)
{
    static assert(isVectorType!V1, "first argument must be vector");
    static assert(isVectorType!V2, "second argument must be vector");
    static assert(is(BaseType!V1 == BaseType!V2),
                  "first and second argument vectors must have the same element type");
    static assert(isPowerOf2!(M.length),
                  "number of index arguments must be a power of 2");

    __vector(BaseType!V1[M.length]) shufflevector(V1 op1, V2 op2, M index);
}

/// Ditto
template shufflevector(V, index...)
{
    // Defined for compatibility with LDC.
    static assert(isVectorType!V, "first argument must be a vector type");
    static assert(numElements!V == index.length,
                  "number of index arguments must be the same number of vector elements");

    private template ctfeConstants(m...)
    {
        static if (m.length == 0) enum ctfeConstants = 1;
        else enum ctfeConstants = m[0] | ctfeConstants!(m[1 .. $]);
    }
    static assert(__traits(compiles, ctfeConstants!index),
                  "all index arguments must be compile time constants");

    private template validIndexes(m...)
    {
        static if (m.length == 0) enum validIndexes = true;
        else enum validIndexes = (cast(long)m[0] > -1) && validIndexes!(m[1 .. $]);
    }
    static assert(validIndexes!index,
                  "all index arguments must be greater than or equal to 0");

    V shufflevector(V op1, V op2)
    {
        return shufflevector(op1, op2, index);
    }
}

/**
 * Extracts a single scalar element from a vector at a specified index.
 * Defined for compatibility with LDC.
 * Params:
 *    val = vector to extract element from
 *    idx = index indicating the position from which to extract the element
 * Returns:
 *    scalar of the same type as the element type of val
 * Example:
 * ---
 * int4 a = [0, 10, 20, 30];
 * int k = extractelement!(int4, 2)(a);
 * assert(k == 20);
 * ---
 */
BaseType!V extractelement(V, int idx)(V val)
    if (isVectorType!V && idx < numElements!V)
{
    return val[idx];
}

/**
 * Inserts a scalar element into a vector at a specified index.
 * Defined for compatibility with LDC.
 * Params:
 *    val = vector to assign element to
 *    elt = scalar whose type is the element type of val
 *    idx = index indicating the position from which to extract the element
 * Returns:
 *    vector of the same type as val
 * Example:
 * ---
 * int4 a = [0, 10, 20, 30];
 * int4 b = insertelement!(int4, 2)(a, 50);
 * assert(b.array == [0, 10, 50, 30]);
 * ---
 */
V insertelement(V, int idx)(V val, BaseType!V elt)
    if (isVectorType!V && idx < numElements!V)
{
    val[idx] = elt;
    return val;
}

/**
 * Convert a vector from one integral or floating vector type to another.
 * The result is an integral or floating vector that has had every element
 * cast to the element type of the return type.
 * Params:
 *    from = input vector
 * Returns:
 *    converted vector
 * Example:
 * ---
 * int4 a = [1, -2, 3, -4];
 * float4 b = [1.5, -2.5, 3, 7];
 * assert(convertvector!float4(a).array == [1, -2, 3, -4]);
 * assert(convertvector!double4(a).array == [1, -2, 3, -4]);
 * assert(convertvector!double4(b).array == [1.5, -2.5, 3, 7]);
 * assert(convertvector!int4(b).array == [1, -2, 3, 7]);
 * ---
 */

template convertvector(V, T)
{
    static assert(isVectorType!V && (is(BaseType!V : long) || is(BaseType!V : real)),
                  "first argument must be an integer or floating vector type");
    static assert(isVectorType!T && (is(BaseType!T : long) || is(BaseType!T : real)),
                  "second argument must be an integer or floating vector");
    static assert(numElements!V == numElements!T,
                  "first and second argument vectors should have the same number of elements");

    V convertvector(T);
}

/**
 * Construct a conditional merge of elements from two vectors, returning a
 * vector of the same type as the input vector(s). The `mask` is an integral
 * vector with the same width and element count as the output vector.
 * Params:
 *    op1 = input vector
 *    op2 = input vector
 *    mask = integer vector mask
 * Returns:
 *    vector with the same type as `op1` and `op2`
 * Example:
 * ---
 * int4 a = [1, 2, 3, 4];
 * int4 b = [5, 6, 7, 8];
 * int4 mask1 = [0, 1, 1, 3];
 * int4 mask2 = [0, 4, 2, 5];
 * assert(shuffle(a, mask1).array == [1, 2, 2, 4]);
 * assert(shuffle(a, b, mask2).array == [1, 5, 3, 6]);
 * ---
 */
template blendvector(V0, V1, M)
{
    static assert(isVectorType!V0, "first argument must be vector");
    static assert(isVectorType!V1, "second argument must be vector");
    static assert(is(BaseType!V0 == BaseType!V1),
                  "first and second argument vectors must have the same element type");
    static assert(isVectorType!M && is(BaseType!M : long),
                  "last argument must be an integer vector");
    static assert(numElements!V0 == numElements!M && numElements!V1 == numElements!M,
                  "argument vectors and mask vector should have the same number of elements");
    static assert(BaseType!V0.sizeof == BaseType!M.sizeof,
                  "argument vectors and mask vector should have the same element type size");

    V0 blendvector(V0 op1, V1 op2, M mask);
}

/**
 * Perform an element-wise comparison between two vectors, producing `0` when
 * the comparison is false and `-1` (all bits are set to 1) otherwise.
 * Params:
 *    op1 = input vector
 *    op2 = input vector
 * Returns:
 *    vector of the same width and number of elements as the comparison
 *    operands with a signed integral element type
 * Example:
 * ---
 * float4 a = [1, 3, 5, 7];
 * float4 b = [2, 3, 4, 5];
 * int4 c = greaterMask!float4(a, b);
 * assert(c.array == [0, 0, -1, -1]);
 * ---
 */
V equalMask(V)(V op1, V op2) if (isVectorType!V)
{
    return op1 == op2;
}
/// Ditto
V notEqualMask(V)(V op1, V op2) if (isVectorType!V)
{
    return op1 != op2;
}
/// Ditto
V greaterMask(V)(V op1, V op2) if (isVectorType!V)
{
    return op1 > op2;
}
/// Ditto
V greaterOrEqualMask(V)(V op1, V op2) if (isVectorType!V)
{
    return op1 >= op2;
}

/**
 * Perform an element-wise logical comparison between two vectors, producing
 * `0` when the comparison is false and `-1` (all bits are set to 1) otherwise.
 * Params:
 *    op1 = input vector
 *    op2 = input vector
 * Returns:
 *    vector of the same width and number of elements as the comparison
 *    operands with a signed integral element type
 */
V notMask(V)(V op1) if (isVectorType!V)
{
    return op1 == 0;
}

/// Ditto
V andAndMask(V)(V op1, V op2) if (isVectorType!V)
{
    return (op1 != 0) & (op2 != 0);
}

/// Ditto
V orOrMask(V)(V op1, V op2) if (isVectorType!V)
{
    return (op1 != 0) | (op2 != 0);
}

// Private helper templates.
private:

enum bool isVectorType(T) = is(T : __vector(V[N]), V, size_t N);

template BaseType(V)
{
    alias typeof(V.array[0]) BaseType;
}

template numElements(V)
{
    enum numElements = V.sizeof / BaseType!(V).sizeof;
}

enum bool isPowerOf2(int Y) = Y && (Y & -Y) == Y;
