/*! @header * The interfaces declared in this header provide logical and bitwise * operations on vectors. Some of these function operate elementwise, * and some produce a scalar result that depends on all lanes of the input. * * For functions returning a boolean value, the return type in C and * Objective-C is _Bool; for C++ it is bool. * * Function Result * ------------------------------------------------------------------ * simd_all(comparison) True if and only if the comparison is true * in every vector lane. e.g.: * * if (simd_all(x == 0.0f)) { * // executed if every lane of x * // contains zero. * } * * The precise function of simd_all is to * return the high-order bit of the result * of a horizontal bitwise AND of all vector * lanes. * * simd_any(comparison) True if and only if the comparison is true * in at least one vector lane. e.g.: * * if (simd_any(x < 0.0f)) { * // executed if any lane of x * // contains a negative value. * } * * The precise function of simd_all is to * return the high-order bit of the result * of a horizontal bitwise OR of all vector * lanes. * * simd_select(x,y,mask) For each lane in the result, selects the * corresponding element of x if the high- * order bit of the corresponding element of * mask is 0, and the corresponding element * of y otherwise. * * simd_bitselect(x,y,mask) For each bit in the result, selects the * corresponding bit of x if the corresponding * bit of mask is clear, and the corresponding * of y otherwise. * * In C++, these functions are available under the simd:: namespace: * * C++ Function Equivalent C Function * -------------------------------------------------------------------- * simd::all(comparison) simd_all(comparison) * simd::any(comparison) simd_any(comparison) * simd::select(x,y,mask) simd_select(x,y,mask) * simd::bitselect(x,y,mask) simd_bitselect(x,y,mask) * * @copyright 2014-2017 Apple, Inc. All rights reserved. * @unsorted */ #ifndef SIMD_LOGIC_HEADER #define SIMD_LOGIC_HEADER #include #if SIMD_COMPILER_HAS_REQUIRED_FEATURES #include #include #ifdef __cplusplus extern "C" { #endif /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_char2 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_char3 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_char4 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_char8 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_char16 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_char32 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_char64 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uchar2 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uchar3 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uchar4 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uchar8 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uchar16 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uchar32 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uchar64 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_short2 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_short3 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_short4 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_short8 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_short16 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_short32 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ushort2 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ushort3 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ushort4 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ushort8 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ushort16 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ushort32 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_int2 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_int3 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_int4 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_int8 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_int16 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uint2 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uint3 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uint4 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uint8 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_uint16 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_long2 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_long3 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_long4 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_long8 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ulong2 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ulong3 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ulong4 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_any(simd_ulong8 x); /*! @abstract True if and only if the high-order bit of any lane of the * vector is set. * @discussion Deprecated. Use simd_any instead. */ #define vector_any simd_any /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_char2 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_char3 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_char4 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_char8 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_char16 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_char32 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_char64 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uchar2 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uchar3 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uchar4 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uchar8 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uchar16 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uchar32 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uchar64 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_short2 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_short3 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_short4 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_short8 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_short16 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_short32 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ushort2 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ushort3 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ushort4 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ushort8 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ushort16 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ushort32 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_int2 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_int3 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_int4 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_int8 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_int16 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uint2 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uint3 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uint4 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uint8 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_uint16 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_long2 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_long3 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_long4 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_long8 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ulong2 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ulong3 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ulong4 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. */ static inline SIMD_CFUNC simd_bool simd_all(simd_ulong8 x); /*! @abstract True if and only if the high-order bit of every lane of the * vector is set. * @discussion Deprecated. Use simd_all instead. */ #define vector_all simd_all /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_float2 simd_select(simd_float2 x, simd_float2 y, simd_int2 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_float3 simd_select(simd_float3 x, simd_float3 y, simd_int3 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_float4 simd_select(simd_float4 x, simd_float4 y, simd_int4 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_float8 simd_select(simd_float8 x, simd_float8 y, simd_int8 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_float16 simd_select(simd_float16 x, simd_float16 y, simd_int16 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_double2 simd_select(simd_double2 x, simd_double2 y, simd_long2 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_double3 simd_select(simd_double3 x, simd_double3 y, simd_long3 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_double4 simd_select(simd_double4 x, simd_double4 y, simd_long4 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ static inline SIMD_CFUNC simd_double8 simd_select(simd_double8 x, simd_double8 y, simd_long8 mask); /*! @abstract For each lane in the result, selects the corresponding element * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. * @discussion Deprecated. Use simd_select instead. */ #define vector_select simd_select /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_char2 simd_bitselect(simd_char2 x, simd_char2 y, simd_char2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_char3 simd_bitselect(simd_char3 x, simd_char3 y, simd_char3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_char4 simd_bitselect(simd_char4 x, simd_char4 y, simd_char4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_char8 simd_bitselect(simd_char8 x, simd_char8 y, simd_char8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_char16 simd_bitselect(simd_char16 x, simd_char16 y, simd_char16 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_char32 simd_bitselect(simd_char32 x, simd_char32 y, simd_char32 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_char64 simd_bitselect(simd_char64 x, simd_char64 y, simd_char64 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uchar2 simd_bitselect(simd_uchar2 x, simd_uchar2 y, simd_char2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uchar3 simd_bitselect(simd_uchar3 x, simd_uchar3 y, simd_char3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uchar4 simd_bitselect(simd_uchar4 x, simd_uchar4 y, simd_char4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uchar8 simd_bitselect(simd_uchar8 x, simd_uchar8 y, simd_char8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uchar16 simd_bitselect(simd_uchar16 x, simd_uchar16 y, simd_char16 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uchar32 simd_bitselect(simd_uchar32 x, simd_uchar32 y, simd_char32 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uchar64 simd_bitselect(simd_uchar64 x, simd_uchar64 y, simd_char64 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_short2 simd_bitselect(simd_short2 x, simd_short2 y, simd_short2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_short3 simd_bitselect(simd_short3 x, simd_short3 y, simd_short3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_short4 simd_bitselect(simd_short4 x, simd_short4 y, simd_short4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_short8 simd_bitselect(simd_short8 x, simd_short8 y, simd_short8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_short16 simd_bitselect(simd_short16 x, simd_short16 y, simd_short16 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_short32 simd_bitselect(simd_short32 x, simd_short32 y, simd_short32 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ushort2 simd_bitselect(simd_ushort2 x, simd_ushort2 y, simd_short2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ushort3 simd_bitselect(simd_ushort3 x, simd_ushort3 y, simd_short3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ushort4 simd_bitselect(simd_ushort4 x, simd_ushort4 y, simd_short4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ushort8 simd_bitselect(simd_ushort8 x, simd_ushort8 y, simd_short8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ushort16 simd_bitselect(simd_ushort16 x, simd_ushort16 y, simd_short16 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ushort32 simd_bitselect(simd_ushort32 x, simd_ushort32 y, simd_short32 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_int2 simd_bitselect(simd_int2 x, simd_int2 y, simd_int2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_int3 simd_bitselect(simd_int3 x, simd_int3 y, simd_int3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_int4 simd_bitselect(simd_int4 x, simd_int4 y, simd_int4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_int8 simd_bitselect(simd_int8 x, simd_int8 y, simd_int8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_int16 simd_bitselect(simd_int16 x, simd_int16 y, simd_int16 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uint2 simd_bitselect(simd_uint2 x, simd_uint2 y, simd_int2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uint3 simd_bitselect(simd_uint3 x, simd_uint3 y, simd_int3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uint4 simd_bitselect(simd_uint4 x, simd_uint4 y, simd_int4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uint8 simd_bitselect(simd_uint8 x, simd_uint8 y, simd_int8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_uint16 simd_bitselect(simd_uint16 x, simd_uint16 y, simd_int16 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_float2 simd_bitselect(simd_float2 x, simd_float2 y, simd_int2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_float3 simd_bitselect(simd_float3 x, simd_float3 y, simd_int3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_float4 simd_bitselect(simd_float4 x, simd_float4 y, simd_int4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_float8 simd_bitselect(simd_float8 x, simd_float8 y, simd_int8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_float16 simd_bitselect(simd_float16 x, simd_float16 y, simd_int16 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_long2 simd_bitselect(simd_long2 x, simd_long2 y, simd_long2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_long3 simd_bitselect(simd_long3 x, simd_long3 y, simd_long3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_long4 simd_bitselect(simd_long4 x, simd_long4 y, simd_long4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_long8 simd_bitselect(simd_long8 x, simd_long8 y, simd_long8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ulong2 simd_bitselect(simd_ulong2 x, simd_ulong2 y, simd_long2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ulong3 simd_bitselect(simd_ulong3 x, simd_ulong3 y, simd_long3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ulong4 simd_bitselect(simd_ulong4 x, simd_ulong4 y, simd_long4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_ulong8 simd_bitselect(simd_ulong8 x, simd_ulong8 y, simd_long8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_double2 simd_bitselect(simd_double2 x, simd_double2 y, simd_long2 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_double3 simd_bitselect(simd_double3 x, simd_double3 y, simd_long3 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_double4 simd_bitselect(simd_double4 x, simd_double4 y, simd_long4 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ static inline SIMD_CFUNC simd_double8 simd_bitselect(simd_double8 x, simd_double8 y, simd_long8 mask); /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. * @discussion Deprecated. Use simd_bitselect instead. */ #define vector_bitselect simd_bitselect #ifdef __cplusplus } /* extern "C" */ namespace simd { /*! @abstract True if and only if the high-order bit of every lane is set. */ template static SIMD_CPPFUNC simd_bool all(const inttypeN predicate) { return ::simd_all(predicate); } /*! @abstract True if and only if the high-order bit of any lane is set. */ template static SIMD_CPPFUNC simd_bool any(const inttypeN predicate) { return ::simd_any(predicate); } /*! @abstract Each lane of the result is selected from the corresponding lane * of x or y according to whether the high-order bit of the corresponding * lane of mask is 0 or 1, respectively. */ template static SIMD_CPPFUNC fptypeN select(const fptypeN x, const fptypeN y, const inttypeN predicate) { return ::simd_select(x,y,predicate); } /*! @abstract For each bit in the result, selects the corresponding bit of x * or y according to whether the corresponding bit of mask is 0 or 1, * respectively. */ template static SIMD_CPPFUNC typeN bitselect(const typeN x, const typeN y, const inttypeN mask) { return ::simd_bitselect(x,y,mask); } } extern "C" { #endif /* __cplusplus */ #pragma mark - Implementations static inline SIMD_CFUNC simd_bool simd_any(simd_char2 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_char16_undef(x)) & 0x3); #elif defined __arm64__ return simd_any(x.xyxy); #else union { uint16_t i; simd_char2 v; } u = { .v = x }; return (u.i & 0x8080); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_char3 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_char16_undef(x)) & 0x7); #elif defined __arm64__ return simd_any(x.xyzz); #else union { uint32_t i; simd_char3 v; } u = { .v = x }; return (u.i & 0x808080); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_char4 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_char16_undef(x)) & 0xf); #elif defined __arm64__ return simd_any(x.xyzwxyzw); #else union { uint32_t i; simd_char4 v; } u = { .v = x }; return (u.i & 0x80808080); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_char8 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_char16_undef(x)) & 0xff); #elif defined __arm64__ return vmaxv_u8(x) & 0x80; #else union { uint64_t i; simd_char8 v; } u = { .v = x }; return (u.i & 0x8080808080808080); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_char16 x) { #if defined __SSE2__ return _mm_movemask_epi8((__m128i)x); #elif defined __arm64__ return vmaxvq_u8(x) & 0x80; #else return simd_any(x.lo | x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_char32 x) { #if defined __AVX2__ return _mm256_movemask_epi8(x); #else return simd_any(x.lo | x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_char64 x) { return simd_any(x.lo | x.hi); } static inline SIMD_CFUNC simd_bool simd_any(simd_uchar2 x) { return simd_any((simd_char2)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uchar3 x) { return simd_any((simd_char3)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uchar4 x) { return simd_any((simd_char4)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uchar8 x) { return simd_any((simd_char8)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uchar16 x) { return simd_any((simd_char16)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uchar32 x) { return simd_any((simd_char32)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uchar64 x) { return simd_any((simd_char64)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_short2 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_short8_undef(x)) & 0xa); #elif defined __arm64__ return simd_any(x.xyxy); #else union { uint32_t i; simd_short2 v; } u = { .v = x }; return (u.i & 0x80008000); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_short3 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_short8_undef(x)) & 0x2a); #elif defined __arm64__ return simd_any(x.xyzz); #else union { uint64_t i; simd_short3 v; } u = { .v = x }; return (u.i & 0x800080008000); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_short4 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_short8_undef(x)) & 0xaa); #elif defined __arm64__ return vmaxv_u16(x) & 0x8000; #else union { uint64_t i; simd_short4 v; } u = { .v = x }; return (u.i & 0x8000800080008000); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_short8 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)x) & 0xaaaa); #elif defined __arm64__ return vmaxvq_u16(x) & 0x8000; #else return simd_any(x.lo | x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_short16 x) { #if defined __AVX2__ return (_mm256_movemask_epi8(x) & 0xaaaaaaaa); #else return simd_any(x.lo | x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_short32 x) { return simd_any(x.lo | x.hi); } static inline SIMD_CFUNC simd_bool simd_any(simd_ushort2 x) { return simd_any((simd_short2)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_ushort3 x) { return simd_any((simd_short3)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_ushort4 x) { return simd_any((simd_short4)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_ushort8 x) { return simd_any((simd_short8)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_ushort16 x) { return simd_any((simd_short16)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_ushort32 x) { return simd_any((simd_short32)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_int2 x) { #if defined __SSE2__ return (_mm_movemask_ps((__m128)simd_make_int4_undef(x)) & 0x3); #elif defined __arm64__ return vmaxv_u32(x) & 0x80000000; #else union { uint64_t i; simd_int2 v; } u = { .v = x }; return (u.i & 0x8000000080000000); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_int3 x) { #if defined __SSE2__ return (_mm_movemask_ps((__m128)simd_make_int4_undef(x)) & 0x7); #elif defined __arm64__ return simd_any(x.xyzz); #else return (x.x | x.y | x.z) & 0x80000000; #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_int4 x) { #if defined __SSE2__ return _mm_movemask_ps((__m128)x); #elif defined __arm64__ return vmaxvq_u32(x) & 0x80000000; #else return simd_any(x.lo | x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_int8 x) { #if defined __AVX__ return _mm256_movemask_ps(x); #else return simd_any(x.lo | x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_int16 x) { return simd_any(x.lo | x.hi); } static inline SIMD_CFUNC simd_bool simd_any(simd_uint2 x) { return simd_any((simd_int2)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uint3 x) { return simd_any((simd_int3)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uint4 x) { return simd_any((simd_int4)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uint8 x) { return simd_any((simd_int8)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_uint16 x) { return simd_any((simd_int16)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_long2 x) { #if defined __SSE2__ return _mm_movemask_pd((__m128d)x); #elif defined __arm64__ return (x.x | x.y) & 0x8000000000000000U; #else return (x.x | x.y) & 0x8000000000000000U; #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_long3 x) { #if defined __AVX__ return (_mm256_movemask_pd(simd_make_long4_undef(x)) & 0x7); #else return (x.x | x.y | x.z) & 0x8000000000000000U; #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_long4 x) { #if defined __AVX__ return _mm256_movemask_pd(x); #else return simd_any(x.lo | x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_any(simd_long8 x) { return simd_any(x.lo | x.hi); } static inline SIMD_CFUNC simd_bool simd_any(simd_ulong2 x) { return simd_any((simd_long2)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_ulong3 x) { return simd_any((simd_long3)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_ulong4 x) { return simd_any((simd_long4)x); } static inline SIMD_CFUNC simd_bool simd_any(simd_ulong8 x) { return simd_any((simd_long8)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_char2 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_char16_undef(x)) & 0x3) == 0x3; #elif defined __arm64__ return simd_all(x.xyxy); #else union { uint16_t i; simd_char2 v; } u = { .v = x }; return (u.i & 0x8080) == 0x8080; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_char3 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_char16_undef(x)) & 0x7) == 0x7; #elif defined __arm64__ return simd_all(x.xyzz); #else union { uint32_t i; simd_char3 v; } u = { .v = x }; return (u.i & 0x808080) == 0x808080; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_char4 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_char16_undef(x)) & 0xf) == 0xf; #elif defined __arm64__ return simd_all(x.xyzwxyzw); #else union { uint32_t i; simd_char4 v; } u = { .v = x }; return (u.i & 0x80808080) == 0x80808080; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_char8 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_char16_undef(x)) & 0xff) == 0xff; #elif defined __arm64__ return vminv_u8(x) & 0x80; #else union { uint64_t i; simd_char8 v; } u = { .v = x }; return (u.i & 0x8080808080808080) == 0x8080808080808080; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_char16 x) { #if defined __SSE2__ return _mm_movemask_epi8((__m128i)x) == 0xffff; #elif defined __arm64__ return vminvq_u8(x) & 0x80; #else return simd_all(x.lo & x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_char32 x) { #if defined __AVX2__ return _mm256_movemask_epi8(x) == 0xffffffff; #else return simd_all(x.lo & x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_char64 x) { return simd_all(x.lo & x.hi); } static inline SIMD_CFUNC simd_bool simd_all(simd_uchar2 x) { return simd_all((simd_char2)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uchar3 x) { return simd_all((simd_char3)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uchar4 x) { return simd_all((simd_char4)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uchar8 x) { return simd_all((simd_char8)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uchar16 x) { return simd_all((simd_char16)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uchar32 x) { return simd_all((simd_char32)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uchar64 x) { return simd_all((simd_char64)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_short2 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_short8_undef(x)) & 0xa) == 0xa; #elif defined __arm64__ return simd_all(x.xyxy); #else union { uint32_t i; simd_short2 v; } u = { .v = x }; return (u.i & 0x80008000) == 0x80008000; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_short3 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_short8_undef(x)) & 0x2a) == 0x2a; #elif defined __arm64__ return simd_all(x.xyzz); #else union { uint64_t i; simd_short3 v; } u = { .v = x }; return (u.i & 0x800080008000) == 0x800080008000; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_short4 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)simd_make_short8_undef(x)) & 0xaa) == 0xaa; #elif defined __arm64__ return vminv_u16(x) & 0x8000; #else union { uint64_t i; simd_short4 v; } u = { .v = x }; return (u.i & 0x8000800080008000) == 0x8000800080008000; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_short8 x) { #if defined __SSE2__ return (_mm_movemask_epi8((__m128i)x) & 0xaaaa) == 0xaaaa; #elif defined __arm64__ return vminvq_u16(x) & 0x8000; #else return simd_all(x.lo & x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_short16 x) { #if defined __AVX2__ return (_mm256_movemask_epi8(x) & 0xaaaaaaaa) == 0xaaaaaaaa; #else return simd_all(x.lo & x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_short32 x) { return simd_all(x.lo & x.hi); } static inline SIMD_CFUNC simd_bool simd_all(simd_ushort2 x) { return simd_all((simd_short2)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_ushort3 x) { return simd_all((simd_short3)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_ushort4 x) { return simd_all((simd_short4)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_ushort8 x) { return simd_all((simd_short8)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_ushort16 x) { return simd_all((simd_short16)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_ushort32 x) { return simd_all((simd_short32)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_int2 x) { #if defined __SSE2__ return (_mm_movemask_ps((__m128)simd_make_int4_undef(x)) & 0x3) == 0x3; #elif defined __arm64__ return vminv_u32(x) & 0x80000000; #else union { uint64_t i; simd_int2 v; } u = { .v = x }; return (u.i & 0x8000000080000000) == 0x8000000080000000; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_int3 x) { #if defined __SSE2__ return (_mm_movemask_ps((__m128)simd_make_int4_undef(x)) & 0x7) == 0x7; #elif defined __arm64__ return simd_all(x.xyzz); #else return (x.x & x.y & x.z) & 0x80000000; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_int4 x) { #if defined __SSE2__ return _mm_movemask_ps((__m128)x) == 0xf; #elif defined __arm64__ return vminvq_u32(x) & 0x80000000; #else return simd_all(x.lo & x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_int8 x) { #if defined __AVX__ return _mm256_movemask_ps(x) == 0xff; #else return simd_all(x.lo & x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_int16 x) { return simd_all(x.lo & x.hi); } static inline SIMD_CFUNC simd_bool simd_all(simd_uint2 x) { return simd_all((simd_int2)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uint3 x) { return simd_all((simd_int3)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uint4 x) { return simd_all((simd_int4)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uint8 x) { return simd_all((simd_int8)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_uint16 x) { return simd_all((simd_int16)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_long2 x) { #if defined __SSE2__ return _mm_movemask_pd((__m128d)x) == 0x3; #elif defined __arm64__ return (x.x & x.y) & 0x8000000000000000U; #else return (x.x & x.y) & 0x8000000000000000U; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_long3 x) { #if defined __AVX__ return (_mm256_movemask_pd(simd_make_long4_undef(x)) & 0x7) == 0x7; #else return (x.x & x.y & x.z) & 0x8000000000000000U; #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_long4 x) { #if defined __AVX__ return _mm256_movemask_pd(x) == 0xf; #else return simd_all(x.lo & x.hi); #endif } static inline SIMD_CFUNC simd_bool simd_all(simd_long8 x) { return simd_all(x.lo & x.hi); } static inline SIMD_CFUNC simd_bool simd_all(simd_ulong2 x) { return simd_all((simd_long2)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_ulong3 x) { return simd_all((simd_long3)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_ulong4 x) { return simd_all((simd_long4)x); } static inline SIMD_CFUNC simd_bool simd_all(simd_ulong8 x) { return simd_all((simd_long8)x); } static inline SIMD_CFUNC simd_float2 simd_select(simd_float2 x, simd_float2 y, simd_int2 mask) { return simd_make_float2(simd_select(simd_make_float4_undef(x), simd_make_float4_undef(y), simd_make_int4_undef(mask))); } static inline SIMD_CFUNC simd_float3 simd_select(simd_float3 x, simd_float3 y, simd_int3 mask) { return simd_make_float3(simd_select(simd_make_float4_undef(x), simd_make_float4_undef(y), simd_make_int4_undef(mask))); } static inline SIMD_CFUNC simd_float4 simd_select(simd_float4 x, simd_float4 y, simd_int4 mask) { #if defined __SSE4_1__ return _mm_blendv_ps(x, y, (__m128)mask); #else return simd_bitselect(x, y, mask >> 31); #endif } static inline SIMD_CFUNC simd_float8 simd_select(simd_float8 x, simd_float8 y, simd_int8 mask) { #if defined __AVX__ return _mm256_blendv_ps(x, y, mask); #else return simd_bitselect(x, y, mask >> 31); #endif } static inline SIMD_CFUNC simd_float16 simd_select(simd_float16 x, simd_float16 y, simd_int16 mask) { return simd_bitselect(x, y, mask >> 31); } static inline SIMD_CFUNC simd_double2 simd_select(simd_double2 x, simd_double2 y, simd_long2 mask) { #if defined __SSE4_1__ return _mm_blendv_pd(x, y, (__m128d)mask); #else return simd_bitselect(x, y, mask >> 63); #endif } static inline SIMD_CFUNC simd_double3 simd_select(simd_double3 x, simd_double3 y, simd_long3 mask) { return simd_make_double3(simd_select(simd_make_double4_undef(x), simd_make_double4_undef(y), simd_make_long4_undef(mask))); } static inline SIMD_CFUNC simd_double4 simd_select(simd_double4 x, simd_double4 y, simd_long4 mask) { #if defined __AVX__ return _mm256_blendv_pd(x, y, mask); #else return simd_bitselect(x, y, mask >> 63); #endif } static inline SIMD_CFUNC simd_double8 simd_select(simd_double8 x, simd_double8 y, simd_long8 mask) { return simd_bitselect(x, y, mask >> 63); } static inline SIMD_CFUNC simd_char2 simd_bitselect(simd_char2 x, simd_char2 y, simd_char2 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_char3 simd_bitselect(simd_char3 x, simd_char3 y, simd_char3 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_char4 simd_bitselect(simd_char4 x, simd_char4 y, simd_char4 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_char8 simd_bitselect(simd_char8 x, simd_char8 y, simd_char8 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_char16 simd_bitselect(simd_char16 x, simd_char16 y, simd_char16 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_char32 simd_bitselect(simd_char32 x, simd_char32 y, simd_char32 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_char64 simd_bitselect(simd_char64 x, simd_char64 y, simd_char64 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_uchar2 simd_bitselect(simd_uchar2 x, simd_uchar2 y, simd_char2 mask) { return (simd_uchar2)simd_bitselect((simd_char2)x, (simd_char2)y, mask); } static inline SIMD_CFUNC simd_uchar3 simd_bitselect(simd_uchar3 x, simd_uchar3 y, simd_char3 mask) { return (simd_uchar3)simd_bitselect((simd_char3)x, (simd_char3)y, mask); } static inline SIMD_CFUNC simd_uchar4 simd_bitselect(simd_uchar4 x, simd_uchar4 y, simd_char4 mask) { return (simd_uchar4)simd_bitselect((simd_char4)x, (simd_char4)y, mask); } static inline SIMD_CFUNC simd_uchar8 simd_bitselect(simd_uchar8 x, simd_uchar8 y, simd_char8 mask) { return (simd_uchar8)simd_bitselect((simd_char8)x, (simd_char8)y, mask); } static inline SIMD_CFUNC simd_uchar16 simd_bitselect(simd_uchar16 x, simd_uchar16 y, simd_char16 mask) { return (simd_uchar16)simd_bitselect((simd_char16)x, (simd_char16)y, mask); } static inline SIMD_CFUNC simd_uchar32 simd_bitselect(simd_uchar32 x, simd_uchar32 y, simd_char32 mask) { return (simd_uchar32)simd_bitselect((simd_char32)x, (simd_char32)y, mask); } static inline SIMD_CFUNC simd_uchar64 simd_bitselect(simd_uchar64 x, simd_uchar64 y, simd_char64 mask) { return (simd_uchar64)simd_bitselect((simd_char64)x, (simd_char64)y, mask); } static inline SIMD_CFUNC simd_short2 simd_bitselect(simd_short2 x, simd_short2 y, simd_short2 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_short3 simd_bitselect(simd_short3 x, simd_short3 y, simd_short3 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_short4 simd_bitselect(simd_short4 x, simd_short4 y, simd_short4 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_short8 simd_bitselect(simd_short8 x, simd_short8 y, simd_short8 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_short16 simd_bitselect(simd_short16 x, simd_short16 y, simd_short16 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_short32 simd_bitselect(simd_short32 x, simd_short32 y, simd_short32 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_ushort2 simd_bitselect(simd_ushort2 x, simd_ushort2 y, simd_short2 mask) { return (simd_ushort2)simd_bitselect((simd_short2)x, (simd_short2)y, mask); } static inline SIMD_CFUNC simd_ushort3 simd_bitselect(simd_ushort3 x, simd_ushort3 y, simd_short3 mask) { return (simd_ushort3)simd_bitselect((simd_short3)x, (simd_short3)y, mask); } static inline SIMD_CFUNC simd_ushort4 simd_bitselect(simd_ushort4 x, simd_ushort4 y, simd_short4 mask) { return (simd_ushort4)simd_bitselect((simd_short4)x, (simd_short4)y, mask); } static inline SIMD_CFUNC simd_ushort8 simd_bitselect(simd_ushort8 x, simd_ushort8 y, simd_short8 mask) { return (simd_ushort8)simd_bitselect((simd_short8)x, (simd_short8)y, mask); } static inline SIMD_CFUNC simd_ushort16 simd_bitselect(simd_ushort16 x, simd_ushort16 y, simd_short16 mask) { return (simd_ushort16)simd_bitselect((simd_short16)x, (simd_short16)y, mask); } static inline SIMD_CFUNC simd_ushort32 simd_bitselect(simd_ushort32 x, simd_ushort32 y, simd_short32 mask) { return (simd_ushort32)simd_bitselect((simd_short32)x, (simd_short32)y, mask); } static inline SIMD_CFUNC simd_int2 simd_bitselect(simd_int2 x, simd_int2 y, simd_int2 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_int3 simd_bitselect(simd_int3 x, simd_int3 y, simd_int3 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_int4 simd_bitselect(simd_int4 x, simd_int4 y, simd_int4 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_int8 simd_bitselect(simd_int8 x, simd_int8 y, simd_int8 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_int16 simd_bitselect(simd_int16 x, simd_int16 y, simd_int16 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_uint2 simd_bitselect(simd_uint2 x, simd_uint2 y, simd_int2 mask) { return (simd_uint2)simd_bitselect((simd_int2)x, (simd_int2)y, mask); } static inline SIMD_CFUNC simd_uint3 simd_bitselect(simd_uint3 x, simd_uint3 y, simd_int3 mask) { return (simd_uint3)simd_bitselect((simd_int3)x, (simd_int3)y, mask); } static inline SIMD_CFUNC simd_uint4 simd_bitselect(simd_uint4 x, simd_uint4 y, simd_int4 mask) { return (simd_uint4)simd_bitselect((simd_int4)x, (simd_int4)y, mask); } static inline SIMD_CFUNC simd_uint8 simd_bitselect(simd_uint8 x, simd_uint8 y, simd_int8 mask) { return (simd_uint8)simd_bitselect((simd_int8)x, (simd_int8)y, mask); } static inline SIMD_CFUNC simd_uint16 simd_bitselect(simd_uint16 x, simd_uint16 y, simd_int16 mask) { return (simd_uint16)simd_bitselect((simd_int16)x, (simd_int16)y, mask); } static inline SIMD_CFUNC simd_float2 simd_bitselect(simd_float2 x, simd_float2 y, simd_int2 mask) { return (simd_float2)simd_bitselect((simd_int2)x, (simd_int2)y, mask); } static inline SIMD_CFUNC simd_float3 simd_bitselect(simd_float3 x, simd_float3 y, simd_int3 mask) { return (simd_float3)simd_bitselect((simd_int3)x, (simd_int3)y, mask); } static inline SIMD_CFUNC simd_float4 simd_bitselect(simd_float4 x, simd_float4 y, simd_int4 mask) { return (simd_float4)simd_bitselect((simd_int4)x, (simd_int4)y, mask); } static inline SIMD_CFUNC simd_float8 simd_bitselect(simd_float8 x, simd_float8 y, simd_int8 mask) { return (simd_float8)simd_bitselect((simd_int8)x, (simd_int8)y, mask); } static inline SIMD_CFUNC simd_float16 simd_bitselect(simd_float16 x, simd_float16 y, simd_int16 mask) { return (simd_float16)simd_bitselect((simd_int16)x, (simd_int16)y, mask); } static inline SIMD_CFUNC simd_long2 simd_bitselect(simd_long2 x, simd_long2 y, simd_long2 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_long3 simd_bitselect(simd_long3 x, simd_long3 y, simd_long3 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_long4 simd_bitselect(simd_long4 x, simd_long4 y, simd_long4 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_long8 simd_bitselect(simd_long8 x, simd_long8 y, simd_long8 mask) { return (x & ~mask) | (y & mask); } static inline SIMD_CFUNC simd_ulong2 simd_bitselect(simd_ulong2 x, simd_ulong2 y, simd_long2 mask) { return (simd_ulong2)simd_bitselect((simd_long2)x, (simd_long2)y, mask); } static inline SIMD_CFUNC simd_ulong3 simd_bitselect(simd_ulong3 x, simd_ulong3 y, simd_long3 mask) { return (simd_ulong3)simd_bitselect((simd_long3)x, (simd_long3)y, mask); } static inline SIMD_CFUNC simd_ulong4 simd_bitselect(simd_ulong4 x, simd_ulong4 y, simd_long4 mask) { return (simd_ulong4)simd_bitselect((simd_long4)x, (simd_long4)y, mask); } static inline SIMD_CFUNC simd_ulong8 simd_bitselect(simd_ulong8 x, simd_ulong8 y, simd_long8 mask) { return (simd_ulong8)simd_bitselect((simd_long8)x, (simd_long8)y, mask); } static inline SIMD_CFUNC simd_double2 simd_bitselect(simd_double2 x, simd_double2 y, simd_long2 mask) { return (simd_double2)simd_bitselect((simd_long2)x, (simd_long2)y, mask); } static inline SIMD_CFUNC simd_double3 simd_bitselect(simd_double3 x, simd_double3 y, simd_long3 mask) { return (simd_double3)simd_bitselect((simd_long3)x, (simd_long3)y, mask); } static inline SIMD_CFUNC simd_double4 simd_bitselect(simd_double4 x, simd_double4 y, simd_long4 mask) { return (simd_double4)simd_bitselect((simd_long4)x, (simd_long4)y, mask); } static inline SIMD_CFUNC simd_double8 simd_bitselect(simd_double8 x, simd_double8 y, simd_long8 mask) { return (simd_double8)simd_bitselect((simd_long8)x, (simd_long8)y, mask); } #ifdef __cplusplus } #endif #endif /* SIMD_COMPILER_HAS_REQUIRED_FEATURES */ #endif /* __SIMD_LOGIC_HEADER__ */