/*  Copyright (c) 2020 Intel Corporation.
 *
 *  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception.
 */

#ifndef _INCLUDED_IMM
#define _INCLUDED_IMM

#include <wmmintrin.h>

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Intel(R) Advanced Vector Extensions (Intel(R) AVX) compiler intrinsics.
 */

#if defined(__INTEL_CLANG_COMPILER) && !defined(__INTEL_LLVM_COMPILER)

typedef float    __m256  __attribute__((__vector_size__(32)));
typedef double   __m256d __attribute__((__vector_size__(32)));
typedef __int64  __m256i __attribute__((__vector_size__(32)));

#else
typedef union  _MMINTRIN_TYPE(32) __m256 {
    float m256_f32[8];
} __m256;

typedef struct _MMINTRIN_TYPE(32) __m256d {
    double m256d_f64[4];
} __m256d;

typedef union  _MMINTRIN_TYPE(32) __m256i {
#if !defined(_MSC_VER)
    /*
     * To support GNU compatible intialization with initializers list,
     * make first union member to be of int64 type.
     */
    __int64             m256i_gcc_compatibility[4];
#endif
    __int8              m256i_i8[32];
    __int16             m256i_i16[16];
    __int32             m256i_i32[8];
    __int64             m256i_i64[4];
    unsigned __int8     m256i_u8[32];
    unsigned __int16    m256i_u16[16];
    unsigned __int32    m256i_u32[8];
    unsigned __int64    m256i_u64[4];
} __m256i;
#endif /* __INTEL_CLANG_COMPILER && !__INTEL_LLVM_COMPILER */


#ifndef _MSC_VER
typedef int     __v2si __attribute__ ((__vector_size__ (8)));
typedef short   __v4hi __attribute__ ((__vector_size__ (8)));
typedef char    __v8qi __attribute__ ((__vector_size__ (8)));
typedef __int64 __v1di __attribute__ ((__vector_size__ (8)));
typedef float   __v2sf __attribute__ ((__vector_size__ (8)));

typedef float   __v4sf __attribute__ ((__vector_size__ (16)));
typedef double  __v2df __attribute__ ((__vector_size__ (16)));
typedef __int64 __v2di __attribute__ ((__vector_size__ (16)));
typedef int     __v4si __attribute__ ((__vector_size__ (16)));
typedef short   __v8hi __attribute__ ((__vector_size__ (16)));
typedef char    __v16qi __attribute__((__vector_size__ (16)));

typedef double  __v4df __attribute__ ((__vector_size__ (32)));
typedef float   __v8sf __attribute__ ((__vector_size__ (32)));
typedef __int64 __v4di __attribute__ ((__vector_size__ (32)));
typedef int     __v8si __attribute__ ((__vector_size__ (32)));
typedef short   __v16hi __attribute__((__vector_size__ (32)));
typedef char    __v32qi __attribute__((__vector_size__ (32)));
#endif /* _MSC_VER */

/*
 * Compare predicates for scalar and packed compare intrinsics
 */
#define _CMP_EQ_OQ     0x00  /* Equal (ordered, nonsignaling)               */
#define _CMP_LT_OS     0x01  /* Less-than (ordered, signaling)              */
#define _CMP_LE_OS     0x02  /* Less-than-or-equal (ordered, signaling)     */
#define _CMP_UNORD_Q   0x03  /* Unordered (nonsignaling)                    */
#define _CMP_NEQ_UQ    0x04  /* Not-equal (unordered, nonsignaling)         */
#define _CMP_NLT_US    0x05  /* Not-less-than (unordered, signaling)        */
#define _CMP_NLE_US    0x06  /* Not-less-than-or-equal (unordered,
                                                        signaling)          */
#define _CMP_ORD_Q     0x07  /* Ordered (nonsignaling)                      */
#define _CMP_EQ_UQ     0x08  /* Equal (unordered, non-signaling)            */
#define _CMP_NGE_US    0x09  /* Not-greater-than-or-equal (unordered,
                                                           signaling)       */
#define _CMP_NGT_US    0x0A  /* Not-greater-than (unordered, signaling)     */
#define _CMP_FALSE_OQ  0x0B  /* False (ordered, nonsignaling)               */
#define _CMP_NEQ_OQ    0x0C  /* Not-equal (ordered, non-signaling)          */
#define _CMP_GE_OS     0x0D  /* Greater-than-or-equal (ordered, signaling)  */
#define _CMP_GT_OS     0x0E  /* Greater-than (ordered, signaling)           */
#define _CMP_TRUE_UQ   0x0F  /* True (unordered, non-signaling)             */
#define _CMP_EQ_OS     0x10  /* Equal (ordered, signaling)                  */
#define _CMP_LT_OQ     0x11  /* Less-than (ordered, nonsignaling)           */
#define _CMP_LE_OQ     0x12  /* Less-than-or-equal (ordered, nonsignaling)  */
#define _CMP_UNORD_S   0x13  /* Unordered (signaling)                       */
#define _CMP_NEQ_US    0x14  /* Not-equal (unordered, signaling)            */
#define _CMP_NLT_UQ    0x15  /* Not-less-than (unordered, nonsignaling)     */
#define _CMP_NLE_UQ    0x16  /* Not-less-than-or-equal (unordered,
                                                        nonsignaling)       */
#define _CMP_ORD_S     0x17  /* Ordered (signaling)                         */
#define _CMP_EQ_US     0x18  /* Equal (unordered, signaling)                */
#define _CMP_NGE_UQ    0x19  /* Not-greater-than-or-equal (unordered,
                                                           nonsignaling)    */
#define _CMP_NGT_UQ    0x1A  /* Not-greater-than (unordered, nonsignaling)  */
#define _CMP_FALSE_OS  0x1B  /* False (ordered, signaling)                  */
#define _CMP_NEQ_OS    0x1C  /* Not-equal (ordered, signaling)              */
#define _CMP_GE_OQ     0x1D  /* Greater-than-or-equal (ordered,
                                                       nonsignaling)        */
#define _CMP_GT_OQ     0x1E  /* Greater-than (ordered, nonsignaling)        */
#define _CMP_TRUE_US   0x1F  /* True (unordered, signaling)                 */

/*
 * feature based cpu dispatch
 */
extern void __ICL_INTRINCC _allow_cpu_features(unsigned __int64);
extern int __ICL_INTRINCC _may_i_use_cpu_feature(unsigned __int64);
#define _FEATURE_GENERIC_IA32        (1ULL     )
#define _FEATURE_FPU                 (1ULL << 1)
#define _FEATURE_CMOV                (1ULL << 2)
#define _FEATURE_MMX                 (1ULL << 3)
#define _FEATURE_FXSAVE              (1ULL << 4)
#define _FEATURE_SSE                 (1ULL << 5)
#define _FEATURE_SSE2                (1ULL << 6)
#define _FEATURE_SSE3                (1ULL << 7)
#define _FEATURE_SSSE3               (1ULL << 8)
#define _FEATURE_SSE4_1              (1ULL << 9)
#define _FEATURE_SSE4_2              (1ULL << 10)
#define _FEATURE_MOVBE               (1ULL << 11)
#define _FEATURE_POPCNT              (1ULL << 12)
#define _FEATURE_PCLMULQDQ           (1ULL << 13)
#define _FEATURE_AES                 (1ULL << 14)
#define _FEATURE_F16C                (1ULL << 15)
#define _FEATURE_AVX                 (1ULL << 16)
#define _FEATURE_RDRND               (1ULL << 17)
#define _FEATURE_FMA                 (1ULL << 18)
#define _FEATURE_BMI                 (1ULL << 19)
#define _FEATURE_LZCNT               (1ULL << 20)
#define _FEATURE_HLE                 (1ULL << 21)
#define _FEATURE_RTM                 (1ULL << 22)
#define _FEATURE_AVX2                (1ULL << 23)
#define _FEATURE_AVX512DQ            (1ULL << 24)
#define _FEATURE_PTWRITE             (1ULL << 25)
#define _FEATURE_AVX512F             (1ULL << 27)
#define _FEATURE_ADX                 (1ULL << 28)
#define _FEATURE_RDSEED              (1ULL << 29)
#define _FEATURE_AVX512IFMA52        (1ULL << 30)
#define _FEATURE_AVX512ER            (1ULL << 32)
#define _FEATURE_AVX512PF            (1ULL << 33)
#define _FEATURE_AVX512CD            (1ULL << 34)
#define _FEATURE_SHA                 (1ULL << 35)
#define _FEATURE_MPX                 (1ULL << 36)
#define _FEATURE_AVX512BW            (1ULL << 37)
#define _FEATURE_AVX512VL            (1ULL << 38)
#define _FEATURE_AVX512VBMI          (1ULL << 39)
#define _FEATURE_AVX512_4FMAPS       (1ULL << 40)
#define _FEATURE_AVX512_4VNNIW       (1ULL << 41)
#define _FEATURE_AVX512_VPOPCNTDQ    (1ULL << 42)
#define _FEATURE_AVX512_BITALG       (1ULL << 43)
#define _FEATURE_AVX512_VBMI2        (1ULL << 44)
#define _FEATURE_GFNI                (1ULL << 45)
#define _FEATURE_VAES                (1ULL << 46)
#define _FEATURE_VPCLMULQDQ          (1ULL << 47)
#define _FEATURE_AVX512_VNNI         (1ULL << 48)
#define _FEATURE_CLWB                (1ULL << 49)
#define _FEATURE_RDPID               (1ULL << 50)
#define _FEATURE_IBT                 (1ULL << 51)
#define _FEATURE_SHSTK               (1ULL << 52)
#define _FEATURE_SGX                 (1ULL << 53)
#define _FEATURE_WBNOINVD            (1ULL << 54)
#define _FEATURE_PCONFIG             (1ULL << 55)



/* Implement RDTSC and RDPMC */
extern __int64 __ICL_INTRINCC _rdtsc(void);
extern __int64 __ICL_INTRINCC _rdpmc(int);

/* Implements BSWAP */
extern int __ICL_INTRINCC _bswap(int);

/* Implement BSR and BSF */
extern int __ICL_INTRINCC _bit_scan_forward(int);
extern int __ICL_INTRINCC _bit_scan_reverse(int);

#ifndef _MSC_VER
/* Implement 32-bit BSR and BSF */
extern unsigned char __ICL_INTRINCC _BitScanForward(unsigned __int32*,
                                                    unsigned __int32);
extern unsigned char __ICL_INTRINCC _BitScanReverse(unsigned __int32*,
                                                    unsigned __int32);

#if defined(__x86_64)
/* Implement 64-bit BSR and BSF */
extern unsigned char __ICL_INTRINCC _BitScanForward64(unsigned __int32*,
                                                      unsigned __int64);
extern unsigned char __ICL_INTRINCC _BitScanReverse64(unsigned __int32*,
                                                      unsigned __int64);
#endif /* __x86_64 */

/* Implement 32-bit BT, BTC, BTR and BTS */
extern unsigned char __ICL_INTRINCC _bittest(__int32 *, __int32);
extern unsigned char __ICL_INTRINCC _bittestandcomplement(__int32 *, __int32);
extern unsigned char __ICL_INTRINCC _bittestandreset(__int32 *, __int32);
extern unsigned char __ICL_INTRINCC _bittestandset(__int32 *, __int32);

#if defined(__x86_64)
/* Implement 64-bit BT, BTC, BTR and BTS */
extern unsigned char __ICL_INTRINCC _bittest64(__int64 *, __int64);
extern unsigned char __ICL_INTRINCC _bittestandcomplement64(__int64*, __int64);
extern unsigned char __ICL_INTRINCC _bittestandreset64(__int64 *, __int64);
extern unsigned char __ICL_INTRINCC _bittestandset64(__int64 *, __int64);
#endif /* __x86_64 */
#endif /* _MSC_VER */

/* Implements a 32-bit popcount */
extern int __ICL_INTRINCC _popcnt32(int);

/* Implements short rotates */
extern unsigned short __ICL_INTRINCC _rotwl(unsigned short, int);
extern unsigned short __ICL_INTRINCC _rotwr(unsigned short, int);

/* Implements integer rotates */
extern unsigned int __ICL_CDECLCC _rotl(unsigned int, int);
extern unsigned int __ICL_CDECLCC _rotr(unsigned int, int);

/* Implements long rotates */
extern unsigned long __ICL_CDECLCC _lrotl(unsigned long, int);
extern unsigned long __ICL_CDECLCC _lrotr(unsigned long, int);

extern unsigned __int64 __ICL_CDECLCC _rotl64(unsigned __int64, int);
extern unsigned __int64 __ICL_CDECLCC _rotr64(unsigned __int64, int);

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
/*
 * User-visible synonyms for SVML intrinsics.
 */
extern __m128  __ICL_INTRINCC    _mm_acos_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_acos_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_acos_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_acos_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_acosh_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_acosh_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_acosh_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_acosh_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_asin_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_asin_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_asin_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_asin_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_asinh_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_asinh_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_asinh_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_asinh_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_atan_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_atan_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_atan_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_atan_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_atan2_ps(__m128, __m128);
extern __m128d __ICL_INTRINCC    _mm_atan2_pd(__m128d, __m128d);
extern __m256  __ICL_INTRINCC _mm256_atan2_ps(__m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_atan2_pd(__m256d, __m256d);

extern __m128  __ICL_INTRINCC    _mm_atanh_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_atanh_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_atanh_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_atanh_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_cbrt_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_cbrt_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_cbrt_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_cbrt_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_svml_ceil_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_svml_ceil_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_svml_ceil_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_svml_ceil_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_cos_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_cos_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_cos_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_cos_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_cosh_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_cosh_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_cosh_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_cosh_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_exp_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_exp_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_exp_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_exp_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_exp2_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_exp2_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_exp2_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_exp2_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_svml_floor_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_svml_floor_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_svml_floor_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_svml_floor_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_invcbrt_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_invcbrt_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_invcbrt_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_invcbrt_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_svml_sqrt_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_svml_sqrt_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_svml_sqrt_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_svml_sqrt_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_invsqrt_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_invsqrt_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_invsqrt_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_invsqrt_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_log_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_log_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_log_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_log_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_log10_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_log10_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_log10_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_log10_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_log2_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_log2_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_log2_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_log2_pd(__m256d);

extern float   __ICL_INTRINCC    _mm_nrdiv_f32(float, float);
extern __m128  __ICL_INTRINCC    _mm_nrdiv_ps(__m128, __m128);
extern __m128  __ICL_INTRINCC    _mm_masknrdiv_ps(__m128, __m128, __m128i);
extern __m256  __ICL_INTRINCC    _mm256_nrdiv_ps(__m256, __m256);
extern __m256  __ICL_INTRINCC    _mm256_masknrdiv_ps(__m256, __m256, __m256i);

extern __m128  __ICL_INTRINCC    _mm_pow_ps(__m128, __m128);
extern __m128d __ICL_INTRINCC    _mm_pow_pd(__m128d, __m128d);
extern __m256  __ICL_INTRINCC _mm256_pow_ps(__m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_pow_pd(__m256d, __m256d);

extern __m128  __ICL_INTRINCC    _mm_svml_round_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_svml_round_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_svml_round_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_svml_round_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_sin_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_sin_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_sin_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_sin_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_sincos_ps(__m128  *, __m128);
extern __m128d __ICL_INTRINCC    _mm_sincos_pd(__m128d *, __m128d);
extern __m256  __ICL_INTRINCC _mm256_sincos_ps(__m256  *, __m256);
extern __m256d __ICL_INTRINCC _mm256_sincos_pd(__m256d *, __m256d);

extern __m128  __ICL_INTRINCC    _mm_sinh_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_sinh_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_sinh_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_sinh_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_tan_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_tan_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_tan_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_tan_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_tanh_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_tanh_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_tanh_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_tanh_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_trunc_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_trunc_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_trunc_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_trunc_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_erf_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_erf_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_erf_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_erf_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_erfc_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_erfc_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_erfc_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_erfc_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_erfcinv_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_erfcinv_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_erfcinv_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_erfcinv_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_erfinv_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_erfinv_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_erfinv_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_erfinv_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_cdfnorm_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_cdfnorm_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_cdfnorm_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_cdfnorm_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_cdfnorminv_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_cdfnorminv_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_cdfnorminv_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_cdfnorminv_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_exp10_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_exp10_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_exp10_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_exp10_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_expm1_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_expm1_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_expm1_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_expm1_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_log1p_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_log1p_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_log1p_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_log1p_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_logb_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_logb_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_logb_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_logb_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_sind_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_sind_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_sind_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_sind_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_cosd_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_cosd_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_cosd_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_cosd_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_tand_ps(__m128);
extern __m128d __ICL_INTRINCC    _mm_tand_pd(__m128d);
extern __m256  __ICL_INTRINCC _mm256_tand_ps(__m256);
extern __m256d __ICL_INTRINCC _mm256_tand_pd(__m256d);

extern __m128  __ICL_INTRINCC    _mm_hypot_ps(__m128, __m128);
extern __m128d __ICL_INTRINCC    _mm_hypot_pd(__m128d, __m128d);
extern __m256  __ICL_INTRINCC _mm256_hypot_ps(__m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_hypot_pd(__m256d, __m256d);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

#define    _mm_idiv_epi32(a, b)    _mm_div_epi32((a), (b))
#define _mm256_idiv_epi32(a, b) _mm256_div_epi32((a), (b))

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
extern __m128i __ICL_INTRINCC    _mm_div_epi8(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_div_epi16(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_div_epi32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_div_epi64(__m128i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_div_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_div_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_div_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_div_epi64(__m256i, __m256i);

extern __m128i __ICL_INTRINCC    _mm_idivrem_epi32(__m128i *,
                                                   __m128i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_idivrem_epi32(__m256i *,
                                                   __m256i, __m256i);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

#define    _mm_irem_epi32(a, b)    _mm_rem_epi32((a), (b))
#define _mm256_irem_epi32(a, b) _mm256_rem_epi32((a), (b))

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
extern __m128i __ICL_INTRINCC    _mm_rem_epi8(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_rem_epi16(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_rem_epi32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_rem_epi64(__m128i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_rem_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_rem_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_rem_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_rem_epi64(__m256i, __m256i);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

#define    _mm_udiv_epi32(a, b)    _mm_div_epu32((a), (b))
#define _mm256_udiv_epi32(a, b) _mm256_div_epu32((a), (b))

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
extern __m128i __ICL_INTRINCC    _mm_div_epu8(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_div_epu16(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_div_epu32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_div_epu64(__m128i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_div_epu8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_div_epu16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_div_epu32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_div_epu64(__m256i, __m256i);

extern __m128i __ICL_INTRINCC    _mm_udivrem_epi32(__m128i *,
                                                   __m128i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_udivrem_epi32(__m256i *,
                                                   __m256i, __m256i);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

#define    _mm_urem_epi32(a, b)    _mm_rem_epu32((a), (b))
#define _mm256_urem_epi32(a, b) _mm256_rem_epu32((a), (b))

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
extern __m128i __ICL_INTRINCC    _mm_rem_epu8(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_rem_epu16(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_rem_epu32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC    _mm_rem_epu64(__m128i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_rem_epu8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_rem_epu16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_rem_epu32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_rem_epu64(__m256i, __m256i);

extern __m128 __ICL_INTRINCC    _mm_csqrt_ps(__m128);
extern __m256 __ICL_INTRINCC _mm256_csqrt_ps(__m256);

extern __m128 __ICL_INTRINCC    _mm_cexp_ps(__m128);
extern __m256 __ICL_INTRINCC _mm256_cexp_ps(__m256);

extern __m128 __ICL_INTRINCC    _mm_clog_ps(__m128);
extern __m256 __ICL_INTRINCC _mm256_clog_ps(__m256);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */


#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
/*
 * Add Packed Double Precision Floating-Point Values
 * **** VADDPD ymm1, ymm2, ymm3/m256
 * Performs an SIMD add of the four packed double-precision floating-point
 * values from the first source operand to the second source operand, and
 * stores the packed double-precision floating-point results in the
 * destination
 */
extern __m256d __ICL_INTRINCC _mm256_add_pd(__m256d, __m256d);

/*
 * Add Packed Single Precision Floating-Point Values
 * **** VADDPS ymm1, ymm2, ymm3/m256
 * Performs an SIMD add of the eight packed single-precision floating-point
 * values from the first source operand to the second source operand, and
 * stores the packed single-precision floating-point results in the
 * destination
 */
extern __m256 __ICL_INTRINCC _mm256_add_ps(__m256, __m256);

/*
 * Add/Subtract Double Precision Floating-Point Values
 * **** VADDSUBPD ymm1, ymm2, ymm3/m256
 * Adds odd-numbered double-precision floating-point values of the first
 * source operand with the corresponding double-precision floating-point
 * values from the second source operand; stores the result in the odd-numbered
 * values of the destination. Subtracts the even-numbered double-precision
 * floating-point values from the second source operand from the corresponding
 * double-precision floating values in the first source operand; stores the
 * result into the even-numbered values of the destination
 */
extern __m256d __ICL_INTRINCC _mm256_addsub_pd(__m256d, __m256d);

/*
 * Add/Subtract Packed Single Precision Floating-Point Values
 * **** VADDSUBPS ymm1, ymm2, ymm3/m256
 * Adds odd-numbered single-precision floating-point values of the first source
 * operand with the corresponding single-precision floating-point values from
 * the second source operand; stores the result in the odd-numbered values of
 * the destination. Subtracts the even-numbered single-precision floating-point
 * values from the second source operand from the corresponding
 * single-precision floating values in the first source operand; stores the
 * result into the even-numbered values of the destination
 */
extern __m256 __ICL_INTRINCC _mm256_addsub_ps(__m256, __m256);

/*
 * Bitwise Logical AND of Packed Double Precision Floating-Point Values
 * **** VANDPD ymm1, ymm2, ymm3/m256
 * Performs a bitwise logical AND of the four packed double-precision
 * floating-point values from the first source operand and the second
 * source operand, and stores the result in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_and_pd(__m256d, __m256d);

/*
 * Bitwise Logical AND of Packed Single Precision Floating-Point Values
 * **** VANDPS ymm1, ymm2, ymm3/m256
 * Performs a bitwise logical AND of the eight packed single-precision
 * floating-point values from the first source operand and the second
 * source operand, and stores the result in the destination
 */
extern __m256 __ICL_INTRINCC _mm256_and_ps(__m256, __m256);

/*
 * Bitwise Logical AND NOT of Packed Double Precision Floating-Point Values
 * **** VANDNPD ymm1, ymm2, ymm3/m256
 * Performs a bitwise logical AND NOT of the four packed double-precision
 * floating-point values from the first source operand and the second source
 * operand, and stores the result in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_andnot_pd(__m256d, __m256d);

/*
 * Bitwise Logical AND NOT of Packed Single Precision Floating-Point Values
 * **** VANDNPS ymm1, ymm2, ymm3/m256
 * Performs a bitwise logical AND NOT of the eight packed single-precision
 * floating-point values from the first source operand and the second source
 * operand, and stores the result in the destination
 */
extern __m256 __ICL_INTRINCC _mm256_andnot_ps(__m256, __m256);

/*
 * Blend Packed Double Precision Floating-Point Values
 * **** VBLENDPD ymm1, ymm2, ymm3/m256, imm8
 * Double-Precision Floating-Point values from the second source operand are
 * conditionally merged with values from the first source operand and written
 * to the destination. The immediate bits [3:0] determine whether the
 * corresponding Double-Precision Floating Point value in the destination is
 * copied from the second source or first source. If a bit in the mask,
 * corresponding to a word, is "1", then the Double-Precision Floating-Point
 * value in the second source operand is copied, else the value in the first
 * source operand is copied
 */
extern __m256d __ICL_INTRINCC _mm256_blend_pd(__m256d, __m256d, const int);

/*
 * Blend Packed Single Precision Floating-Point Values
 * **** VBLENDPS ymm1, ymm2, ymm3/m256, imm8
 * Single precision floating point values from the second source operand are
 * conditionally merged with values from the first source operand and written
 * to the destination. The immediate bits [7:0] determine whether the
 * corresponding single precision floating-point value in the destination is
 * copied from the second source or first source. If a bit in the mask,
 * corresponding to a word, is "1", then the single-precision floating-point
 * value in the second source operand is copied, else the value in the first
 * source operand is copied
 */
extern __m256 __ICL_INTRINCC _mm256_blend_ps(__m256, __m256, const int);

/*
 * Blend Packed Double Precision Floating-Point Values
 * **** VBLENDVPD ymm1, ymm2, ymm3/m256, ymm4
 * Conditionally copy each quadword data element of double-precision
 * floating-point value from the second source operand (third operand) and the
 * first source operand (second operand) depending on mask bits defined in the
 * mask register operand (fourth operand).
 */
extern __m256d __ICL_INTRINCC _mm256_blendv_pd(__m256d, __m256d, __m256d);

/*
 * Blend Packed Single Precision Floating-Point Values
 * **** VBLENDVPS ymm1, ymm2, ymm3/m256, ymm4
 * Conditionally copy each dword data element of single-precision
 * floating-point value from the second source operand (third operand) and the
 * first source operand (second operand) depending on mask bits defined in the
 * mask register operand (fourth operand).
 */
extern __m256 __ICL_INTRINCC _mm256_blendv_ps(__m256, __m256, __m256);

/*
 * Divide Packed Double-Precision Floating-Point Values
 * **** VDIVPD ymm1, ymm2, ymm3/m256
 * Performs an SIMD divide of the four packed double-precision floating-point
 * values in the first source operand by the four packed double-precision
 * floating-point values in the second source operand
 */
extern __m256d __ICL_INTRINCC _mm256_div_pd(__m256d, __m256d);

/*
 * Divide Packed Single-Precision Floating-Point Values
 * **** VDIVPS ymm1, ymm2, ymm3/m256
 * Performs an SIMD divide of the eight packed single-precision
 * floating-point values in the first source operand by the eight packed
 * single-precision floating-point values in the second source operand
 */
extern __m256 __ICL_INTRINCC _mm256_div_ps(__m256, __m256);

/*
 * Dot Product of Packed Single-Precision Floating-Point Values
 * **** VDPPS ymm1, ymm2, ymm3/m256, imm8
 * Multiplies the packed single precision floating point values in the
 * first source operand with the packed single-precision floats in the
 * second source. Each of the four resulting single-precision values is
 * conditionally summed depending on a mask extracted from the high 4 bits
 * of the immediate operand. This sum is broadcast to each of 4 positions
 * in the destination if the corresponding bit of the mask selected from
 * the low 4 bits of the immediate operand is "1". If the corresponding
 * low bit 0-3 of the mask is zero, the destination is set to zero.
 * The process is replicated for the high elements of the destination.
 */
extern __m256 __ICL_INTRINCC _mm256_dp_ps(__m256, __m256, const int);

/*
 * Add Horizontal Double Precision Floating-Point Values
 * **** VHADDPD ymm1, ymm2, ymm3/m256
 * Adds pairs of adjacent double-precision floating-point values in the
 * first source operand and second source operand and stores results in
 * the destination
 */
extern __m256d __ICL_INTRINCC _mm256_hadd_pd(__m256d, __m256d);

/*
 * Add Horizontal Single Precision Floating-Point Values
 * **** VHADDPS ymm1, ymm2, ymm3/m256
 * Adds pairs of adjacent single-precision floating-point values in the
 * first source operand and second source operand and stores results in
 * the destination
 */
extern __m256 __ICL_INTRINCC _mm256_hadd_ps(__m256, __m256);

/*
 * Subtract Horizontal Double Precision Floating-Point Values
 * **** VHSUBPD ymm1, ymm2, ymm3/m256
 * Subtract pairs of adjacent double-precision floating-point values in
 * the first source operand and second source operand and stores results
 * in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_hsub_pd(__m256d, __m256d);

/*
 * Subtract Horizontal Single Precision Floating-Point Values
 * **** VHSUBPS ymm1, ymm2, ymm3/m256
 * Subtract pairs of adjacent single-precision floating-point values in
 * the first source operand and second source operand and stores results
 * in the destination.
 */
extern __m256 __ICL_INTRINCC _mm256_hsub_ps(__m256, __m256);

/*
 * Maximum of Packed Double Precision Floating-Point Values
 * **** VMAXPD ymm1, ymm2, ymm3/m256
 * Performs an SIMD compare of the packed double-precision floating-point
 * values in the first source operand and the second source operand and
 * returns the maximum value for each pair of values to the destination
 */
extern __m256d __ICL_INTRINCC _mm256_max_pd(__m256d, __m256d);

/*
 * Maximum of Packed Single Precision Floating-Point Values
 * **** VMAXPS ymm1, ymm2, ymm3/m256
 * Performs an SIMD compare of the packed single-precision floating-point
 * values in the first source operand and the second source operand and
 * returns the maximum value for each pair of values to the destination
 */
extern __m256 __ICL_INTRINCC _mm256_max_ps(__m256, __m256);

/*
 * Minimum of Packed Double Precision Floating-Point Values
 * **** VMINPD ymm1, ymm2, ymm3/m256
 * Performs an SIMD compare of the packed double-precision floating-point
 * values in the first source operand and the second source operand and
 * returns the minimum value for each pair of values to the destination
 */
extern __m256d __ICL_INTRINCC _mm256_min_pd(__m256d, __m256d);

/*
 * Minimum of Packed Single Precision Floating-Point Values
 * **** VMINPS ymm1, ymm2, ymm3/m256
 * Performs an SIMD compare of the packed single-precision floating-point
 * values in the first source operand and the second source operand and
 * returns the minimum value for each pair of values to the destination
 */
extern __m256 __ICL_INTRINCC _mm256_min_ps(__m256, __m256);

/*
 * Multiply Packed Double Precision Floating-Point Values
 * **** VMULPD ymm1, ymm2, ymm3/m256
 * Performs a SIMD multiply of the four packed double-precision floating-point
 * values from the first Source operand to the Second Source operand, and
 * stores the packed double-precision floating-point results in the
 * destination
 */
extern __m256d __ICL_INTRINCC _mm256_mul_pd(__m256d, __m256d);

/*
 * Multiply Packed Single Precision Floating-Point Values
 * **** VMULPS ymm1, ymm2, ymm3/m256
 * Performs an SIMD multiply of the eight packed single-precision
 * floating-point values from the first source operand to the second source
 * operand, and stores the packed double-precision floating-point results in
 * the destination
 */
extern __m256 __ICL_INTRINCC _mm256_mul_ps(__m256, __m256);

/*
 * Bitwise Logical OR of Packed Double Precision Floating-Point Values
 * **** VORPD ymm1, ymm2, ymm3/m256
 * Performs a bitwise logical OR of the four packed double-precision
 * floating-point values from the first source operand and the second
 * source operand, and stores the result in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_or_pd(__m256d, __m256d);

/*
 * Bitwise Logical OR of Packed Single Precision Floating-Point Values
 * **** VORPS ymm1, ymm2, ymm3/m256
 * Performs a bitwise logical OR of the eight packed single-precision
 * floating-point values from the first source operand and the second
 * source operand, and stores the result in the destination
 */
extern __m256 __ICL_INTRINCC _mm256_or_ps(__m256, __m256);

/*
 * Shuffle Packed Double Precision Floating-Point Values
 * **** VSHUFPD ymm1, ymm2, ymm3/m256, imm8
 * Moves either of the two packed double-precision floating-point values from
 * each double quadword in the first source operand into the low quadword
 * of each double quadword of the destination; moves either of the two packed
 * double-precision floating-point values from the second source operand into
 * the high quadword of each double quadword of the destination operand.
 * The selector operand determines which values are moved to the destination
 */
extern __m256d __ICL_INTRINCC _mm256_shuffle_pd(__m256d, __m256d, const int);

/*
 * Shuffle Packed Single Precision Floating-Point Values
 * **** VSHUFPS ymm1, ymm2, ymm3/m256, imm8
 * Moves two of the four packed single-precision floating-point values
 * from each double qword of the first source operand into the low
 * quadword of each double qword of the destination; moves two of the four
 * packed single-precision floating-point values from each double qword of
 * the second source operand into to the high quadword of each double qword
 * of the destination. The selector operand determines which values are moved
 * to the destination.
 */
extern __m256 __ICL_INTRINCC _mm256_shuffle_ps(__m256, __m256, const int);

/*
 * Subtract Packed Double Precision Floating-Point Values
 * **** VSUBPD ymm1, ymm2, ymm3/m256
 * Performs an SIMD subtract of the four packed double-precision floating-point
 * values of the second Source operand from the first Source operand, and
 * stores the packed double-precision floating-point results in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_sub_pd(__m256d, __m256d);

/*
 * Subtract Packed Single Precision Floating-Point Values
 * **** VSUBPS ymm1, ymm2, ymm3/m256
 * Performs an SIMD subtract of the eight packed single-precision
 * floating-point values in the second Source operand from the First Source
 * operand, and stores the packed single-precision floating-point results in
 * the destination
 */
extern __m256 __ICL_INTRINCC _mm256_sub_ps(__m256, __m256);

/*
 * Bitwise Logical XOR of Packed Double Precision Floating-Point Values
 * **** VXORPD ymm1, ymm2, ymm3/m256
 * Performs a bitwise logical XOR of the four packed double-precision
 * floating-point values from the first source operand and the second
 * source operand, and stores the result in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_xor_pd(__m256d, __m256d);

/*
 * Bitwise Logical XOR of Packed Single Precision Floating-Point Values
 * **** VXORPS ymm1, ymm2, ymm3/m256
 * Performs a bitwise logical XOR of the eight packed single-precision
 * floating-point values from the first source operand and the second
 * source operand, and stores the result in the destination
 */
extern __m256 __ICL_INTRINCC _mm256_xor_ps(__m256, __m256);

/*
 * Compare Packed Double-Precision Floating-Point Values
 * **** VCMPPD xmm1, xmm2, xmm3/m128, imm8
 * **** VCMPPD ymm1, ymm2, ymm3/m256, imm8
 * Performs an SIMD compare of the four packed double-precision floating-point
 * values in the second source operand (third operand) and the first source
 * operand (second operand) and returns the results of the comparison to the
 * destination operand (first operand). The comparison predicate operand
 * (immediate) specifies the type of comparison performed on each of the pairs
 * of packed values.
 * For 128-bit intrinsic with compare predicate values in range 0-7 compiler
 * may generate SSE2 instructions if it is warranted for performance reasons.
 */
extern __m128d __ICL_INTRINCC _mm_cmp_pd(__m128d, __m128d, const int);
extern __m256d __ICL_INTRINCC _mm256_cmp_pd(__m256d, __m256d, const int);

/*
 * Compare Packed Single-Precision Floating-Point Values
 * **** VCMPPS xmm1, xmm2, xmm3/m256, imm8
 * **** VCMPPS ymm1, ymm2, ymm3/m256, imm8
 * Performs a SIMD compare of the packed single-precision floating-point values
 * in the second source operand (third operand) and the first source operand
 * (second operand) and returns the results of the comparison to the
 * destination operand (first operand). The comparison predicate operand
 * (immediate) specifies the type of comparison performed on each of the pairs
 * of packed values.
 * For 128-bit intrinsic with compare predicate values in range 0-7 compiler
 * may generate SSE2 instructions if it is warranted for performance reasons.
 */
extern __m128 __ICL_INTRINCC _mm_cmp_ps(__m128, __m128, const int);
extern __m256 __ICL_INTRINCC _mm256_cmp_ps(__m256, __m256, const int);

/*
 * Compare Scalar Double-Precision Floating-Point Values
 * **** VCMPSD xmm1, xmm2, xmm3/m64, imm8
 * Compares the low double-precision floating-point values in the second source
 * operand (third operand) and the first source operand (second operand) and
 * returns the results in of the comparison to the destination operand (first
 * operand). The comparison predicate operand (immediate operand) specifies the
 * type of comparison performed.
 * For compare predicate values in range 0-7 compiler may generate SSE2
 * instructions if it is warranted for performance reasons.
 */
extern __m128d __ICL_INTRINCC _mm_cmp_sd(__m128d, __m128d, const int);

/*
 * Compare Scalar Single-Precision Floating-Point Values
 * **** VCMPSS xmm1, xmm2, xmm3/m64, imm8
 * Compares the low single-precision floating-point values in the second source
 * operand (third operand) and the first source operand (second operand) and
 * returns the results of the comparison to the destination operand (first
 * operand). The comparison predicate operand (immediate operand) specifies
 * the type of comparison performed.
 * For compare predicate values in range 0-7 compiler may generate SSE2
 * instructions if it is warranted for performance reasons.
 */
extern __m128 __ICL_INTRINCC _mm_cmp_ss(__m128, __m128, const int);

/*
 * Convert Packed Doubleword Integers to
 * Packed Double-Precision Floating-Point Values
 * **** VCVTDQ2PD ymm1, xmm2/m128
 * Converts four packed signed doubleword integers in the source operand to
 * four packed double-precision floating-point values in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_cvtepi32_pd(__m128i);

/*
 * Convert Packed Doubleword Integers to
 * Packed Single-Precision Floating-Point Values
 * **** VCVTDQ2PS ymm1, ymm2/m256
 * Converts eight packed signed doubleword integers in the source operand to
 * eight packed double-precision floating-point values in the destination
 */
extern __m256  __ICL_INTRINCC _mm256_cvtepi32_ps(__m256i);

/*
 * Convert Packed Double-Precision Floating-point values to
 * Packed Single-Precision Floating-Point Values
 * **** VCVTPD2PS xmm1, ymm2/m256
 * Converts four packed double-precision floating-point values in the source
 * operand to four packed single-precision floating-point values in the
 * destination
 */
extern __m128  __ICL_INTRINCC _mm256_cvtpd_ps(__m256d);

/*
 * Convert Packed Single Precision Floating-Point Values to
 * Packed Singed Doubleword Integer Values
 * **** VCVTPS2DQ ymm1, ymm2/m256
 * Converts eight packed single-precision floating-point values in the source
 * operand to eight signed doubleword integers in the destination
 */
extern __m256i __ICL_INTRINCC _mm256_cvtps_epi32(__m256);

/*
 * Convert Packed Single Precision Floating-point values to
 * Packed Double Precision Floating-Point Values
 * **** VCVTPS2PD ymm1, xmm2/m128
 * Converts four packed single-precision floating-point values in the source
 * operand to four packed double-precision floating-point values in the
 * destination
 */
extern __m256d __ICL_INTRINCC _mm256_cvtps_pd(__m128);

/*
 * Convert with Truncation Packed Double-Precision Floating-Point values to
 * Packed Doubleword Integers
 * **** VCVTTPD2DQ xmm1, ymm2/m256
 * Converts four packed double-precision floating-point values in the source
 * operand to four packed signed doubleword integers in the destination.
 * When a conversion is inexact, a truncated (round toward zero) value is
 * returned. If a converted result is larger than the maximum signed doubleword
 * integer, the floating-point invalid exception is raised, and if this
 * exception is masked, the indefinite integer value (80000000H) is returned
*/
extern __m128i __ICL_INTRINCC _mm256_cvttpd_epi32(__m256d);

/*
 * Convert Packed Double-Precision Floating-point values to
 * Packed Doubleword Integers
 * **** VCVTPD2DQ xmm1, ymm2/m256
 * Converts four packed double-precision floating-point values in the source
 * operand to four packed signed doubleword integers in the destination
 */
extern __m128i __ICL_INTRINCC _mm256_cvtpd_epi32(__m256d);

/*
 * Convert with Truncation Packed Single Precision Floating-Point Values to
 * Packed Singed Doubleword Integer Values
 * **** VCVTTPS2DQ ymm1, ymm2/m256
 * Converts eight packed single-precision floating-point values in the source
 * operand to eight signed doubleword integers in the destination.
 * When a conversion is inexact, a truncated (round toward zero) value is
 * returned. If a converted result is larger than the maximum signed doubleword
 * integer, the floating-point invalid exception is raised, and if this
 * exception is masked, the indefinite integer value (80000000H) is returned
 */
extern __m256i __ICL_INTRINCC _mm256_cvttps_epi32(__m256);

/*
 * Extract packed floating-point values
 * **** VEXTRACTF128 xmm1/m128, ymm2, imm8
 * Extracts 128-bits of packed floating-point values from the source operand
 * at an 128-bit offset from imm8[0] into the destination
 */
extern __m128  __ICL_INTRINCC _mm256_extractf128_ps(__m256, const int);
extern __m128d __ICL_INTRINCC _mm256_extractf128_pd(__m256d, const int);
extern __m128i __ICL_INTRINCC _mm256_extractf128_si256(__m256i, const int);

/*
 * Extract scalar 8/16/32/64-bit value from __m256i value at position specified
 * by the last argument.
 */
extern int __ICL_INTRINCC _mm256_extract_epi8 (__m256i, const int);
extern int __ICL_INTRINCC _mm256_extract_epi16(__m256i, const int);
extern __int32 __ICL_INTRINCC _mm256_extract_epi32(__m256i, const int);
extern __int64 __ICL_INTRINCC _mm256_extract_epi64(__m256i, const int);

/*
 * Zero All YMM registers
 * **** VZEROALL
 * Zeros contents of all YMM registers
 */
extern void __ICL_INTRINCC _mm256_zeroall(void);

/*
 * Zero Upper bits of YMM registers
 * **** VZEROUPPER
 * Zeros the upper 128 bits of all YMM registers. The lower 128-bits of the
 * registers (the corresponding XMM registers) are unmodified
 */
extern void __ICL_INTRINCC _mm256_zeroupper(void);

/*
 * Permute Single-Precision Floating-Point Values
 * **** VPERMILPS ymm1, ymm2, ymm3/m256
 * **** VPERMILPS xmm1, xmm2, xmm3/m128
 * Permute Single-Precision Floating-Point values in the first source operand
 * using 8-bit control fields in the low bytes of corresponding elements the
 * shuffle control and store results in the destination
 */
extern __m256  __ICL_INTRINCC _mm256_permutevar_ps(__m256, __m256i);
extern __m128  __ICL_INTRINCC _mm_permutevar_ps(__m128, __m128i);

/*
 * Permute Single-Precision Floating-Point Values
 * **** VPERMILPS ymm1, ymm2/m256, imm8
 * **** VPERMILPS xmm1, xmm2/m128, imm8
 * Permute Single-Precision Floating-Point values in the first source operand
 * using four 2-bit control fields in the 8-bit immediate and store results
 * in the destination
 */
extern __m256  __ICL_INTRINCC _mm256_permute_ps(__m256, int);
extern __m128  __ICL_INTRINCC _mm_permute_ps(__m128, int);

/*
 * Permute Double-Precision Floating-Point Values
 * **** VPERMILPD ymm1, ymm2, ymm3/m256
 * **** VPERMILPD xmm1, xmm2, xmm3/m128
 * Permute Double-Precision Floating-Point values in the first source operand
 * using 8-bit control fields in the low bytes of the second source operand
 * and store results in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_permutevar_pd(__m256d, __m256i);
extern __m128d __ICL_INTRINCC _mm_permutevar_pd(__m128d, __m128i);

/*
 * Permute Double-Precision Floating-Point Values
 * **** VPERMILPD ymm1, ymm2/m256, imm8
 * **** VPERMILPD xmm1, xmm2/m128, imm8
 * Permute Double-Precision Floating-Point values in the first source operand
 * using two, 1-bit control fields in the low 2 bits of the 8-bit immediate
 * and store results in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_permute_pd(__m256d, int);
extern __m128d __ICL_INTRINCC _mm_permute_pd(__m128d, int);

/*
 * Permute Floating-Point Values
 * **** VPERM2F128 ymm1, ymm2, ymm3/m256, imm8
 * Permute 128 bit floating-point-containing fields from the first source
 * operand and second source operand using bits in the 8-bit immediate and
 * store results in the destination
 */
extern __m256  __ICL_INTRINCC _mm256_permute2f128_ps(__m256, __m256, int);
extern __m256d __ICL_INTRINCC _mm256_permute2f128_pd(__m256d, __m256d, int);
extern __m256i __ICL_INTRINCC _mm256_permute2f128_si256(__m256i, __m256i, int);

/*
 * Load with Broadcast
 * **** VBROADCASTSS ymm1, m32
 * **** VBROADCASTSS xmm1, m32
 * Load floating point values from the source operand and broadcast to all
 * elements of the destination
 */
extern __m256  __ICL_INTRINCC _mm256_broadcast_ss(float const *);
extern __m128  __ICL_INTRINCC _mm_broadcast_ss(float const *);

/*
 * Load with Broadcast
 * **** VBROADCASTSD ymm1, m64
 * Load floating point values from the source operand and broadcast to all
 * elements of the destination
 */
extern __m256d __ICL_INTRINCC _mm256_broadcast_sd(double const *);

/*
 * Load with Broadcast
 * **** VBROADCASTF128 ymm1, m128
 * Load floating point values from the source operand and broadcast to all
 * elements of the destination
 */
extern __m256  __ICL_INTRINCC _mm256_broadcast_ps(__m128 const *);
extern __m256d __ICL_INTRINCC _mm256_broadcast_pd(__m128d const *);

/*
 * Insert packed floating-point values
 * **** VINSERTF128 ymm1, ymm2, xmm3/m128, imm8
 * Performs an insertion of 128-bits of packed floating-point values from the
 * second source operand into an the destination at an 128-bit offset from
 * imm8[0]. The remaining portions of the destination are written by the
 * corresponding fields of the first source operand
 */
extern __m256  __ICL_INTRINCC _mm256_insertf128_ps(__m256, __m128, int);
extern __m256d __ICL_INTRINCC _mm256_insertf128_pd(__m256d, __m128d, int);
extern __m256i __ICL_INTRINCC _mm256_insertf128_si256(__m256i, __m128i, int);

/*
 * Insert scalar 8/16/32/64-bit value into __m256i value at position specified
 * by the last argument.
 */
extern __m256i __ICL_INTRINCC _mm256_insert_epi8 (__m256i, __int8,  const int);
extern __m256i __ICL_INTRINCC _mm256_insert_epi16(__m256i, __int16, const int);
extern __m256i __ICL_INTRINCC _mm256_insert_epi32(__m256i, __int32, const int);
extern __m256i __ICL_INTRINCC _mm256_insert_epi64(__m256i, __int64, const int);

/*
 * Move Aligned Packed Double-Precision Floating-Point Values
 * **** VMOVAPD ymm1, m256
 * **** VMOVAPD m256, ymm1
 * Moves 4 double-precision floating-point values from the source operand to
 * the destination
 */
extern __m256d __ICL_INTRINCC _mm256_load_pd(double const *);
extern void    __ICL_INTRINCC _mm256_store_pd(double *, __m256d);

/*
 * Move Aligned Packed Single-Precision Floating-Point Values
 * **** VMOVAPS ymm1, m256
 * **** VMOVAPS m256, ymm1
 * Moves 8 single-precision floating-point values from the source operand to
 * the destination
 */
extern __m256  __ICL_INTRINCC _mm256_load_ps(float const *);
extern void    __ICL_INTRINCC _mm256_store_ps(float *, __m256);

/*
 * Move Unaligned Packed Double-Precision Floating-Point Values
 * **** VMOVUPD ymm1, m256
 * **** VMOVUPD m256, ymm1
 * Moves 256 bits of packed double-precision floating-point values from the
 * source operand to the destination
 */
extern __m256d __ICL_INTRINCC _mm256_loadu_pd(double const *);
extern void    __ICL_INTRINCC _mm256_storeu_pd(double *, __m256d);

/*
 * Move Unaligned Packed Single-Precision Floating-Point Values
 * **** VMOVUPS ymm1, m256
 * **** VMOVUPS m256, ymm1
 * Moves 256 bits of packed single-precision floating-point values from the
 * source operand to the destination
 */
extern __m256  __ICL_INTRINCC _mm256_loadu_ps(float const *);
extern void    __ICL_INTRINCC _mm256_storeu_ps(float *, __m256);

/*
 * Move Aligned Packed Integer Values
 * **** VMOVDQA ymm1, m256
 * **** VMOVDQA m256, ymm1
 * Moves 256 bits of packed integer values from the source operand to the
 * destination
 */
extern __m256i __ICL_INTRINCC _mm256_load_si256(__m256i const *);
extern void    __ICL_INTRINCC _mm256_store_si256(__m256i *, __m256i);

/*
 * Move Unaligned Packed Integer Values
 * **** VMOVDQU ymm1, m256
 * **** VMOVDQU m256, ymm1
 * Moves 256 bits of packed integer values from the source operand to the
 * destination
 */
extern __m256i __ICL_INTRINCC _mm256_loadu_si256(__m256i const *);
extern void    __ICL_INTRINCC _mm256_storeu_si256(__m256i *, __m256i);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

/*
 * Load Two Unaligned Packed 128-bit Values
 * Loads two potentially unaligned 128-bit values
 * and combines them into one 256-bit value.
 *
 * The data types here (float const*, double const* and __m128i const*)
 * were chosen for consistency with the underlying _mm_loadu_{ps,pd,si128}
 * intrinsics.
 */

#define _mm256_loadu2_m128(/* float const* */ hiaddr, \
                           /* float const* */ loaddr) \
    _mm256_set_m128(_mm_loadu_ps(hiaddr), _mm_loadu_ps(loaddr))

#define _mm256_loadu2_m128d(/* double const* */ hiaddr, \
                            /* double const* */ loaddr) \
    _mm256_set_m128d(_mm_loadu_pd(hiaddr), _mm_loadu_pd(loaddr))

#define _mm256_loadu2_m128i(/* __m128i const* */ hiaddr, \
                            /* __m128i const* */ loaddr) \
    _mm256_set_m128i(_mm_loadu_si128(hiaddr), _mm_loadu_si128(loaddr))

/*
 * Store 256-bit Value To Two Unaligned 128-bit Locations
 * Stores the high and low 128-bit halves of a 256-bit value
 * to two different potentially unaligned addresses.
 */

#define _mm256_storeu2_m128(/* float* */ hiaddr, /* float* */ loaddr, \
                            /* __m256 */ a) \
    do { \
        __m256 _a = (a); /* reference a only once in macro body */ \
        _mm_storeu_ps((loaddr), _mm256_castps256_ps128(_a)); \
        _mm_storeu_ps((hiaddr), _mm256_extractf128_ps(_a, 0x1)); \
    } while (0)

#define _mm256_storeu2_m128d(/* double* */ hiaddr, /* double* */ loaddr, \
                             /* __m256d */ a) \
    do { \
        __m256d _a = (a); /* reference a only once in macro body */ \
        _mm_storeu_pd((loaddr), _mm256_castpd256_pd128(_a)); \
        _mm_storeu_pd((hiaddr), _mm256_extractf128_pd(_a, 0x1)); \
    } while (0)

#define _mm256_storeu2_m128i(/* __m128i* */ hiaddr, /* __m128i* */ loaddr, \
                             /* __m256i */ a) \
    do { \
        __m256i _a = (a); /* reference a only once in macro body */ \
        _mm_storeu_si128((loaddr), _mm256_castsi256_si128(_a)); \
        _mm_storeu_si128((hiaddr), _mm256_extractf128_si256(_a, 0x1)); \
    } while (0)

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
/*
 * Conditional SIMD Packed Loads and Stores
 * **** VMASKMOVPD xmm1, xmm2, m128
 * **** VMASKMOVPD ymm1, ymm2, m256
 * **** VMASKMOVPD m128, xmm1, xmm2
 * **** VMASKMOVPD m256, ymm1, ymm2
 *
 * Load forms:
 * Load packed values from the 128-bit (XMM forms) or 256-bit (YMM forms)
 * memory location (third operand) into the destination XMM or YMM register
 * (first operand) using a mask in the first source operand (second operand).
 *
 * Store forms:
 * Stores packed values from the XMM or YMM register in the second source
 * operand (third operand) into the 128-bit (XMM forms) or 256-bit (YMM forms)
 * memory location using a mask in first source operand (second operand).
 * Stores are atomic.
 */
extern __m256d __ICL_INTRINCC _mm256_maskload_pd(double const *, __m256i);
extern void    __ICL_INTRINCC _mm256_maskstore_pd(double *, __m256i, __m256d);
extern __m128d __ICL_INTRINCC _mm_maskload_pd(double const *, __m128i);
extern void    __ICL_INTRINCC _mm_maskstore_pd(double *, __m128i, __m128d);

/*
 * Conditional SIMD Packed Loads and Stores
 * **** VMASKMOVPS xmm1, xmm2, m128
 * **** VMASKMOVPS ymm1, ymm2, m256
 * **** VMASKMOVPS m128, xmm1, xmm2
 * **** VMASKMOVPS m256, ymm1, ymm2
 *
 * Load forms:
 * Load packed values from the 128-bit (XMM forms) or 256-bit (YMM forms)
 * memory location (third operand) into the destination XMM or YMM register
 * (first operand) using a mask in the first source operand (second operand).
 *
 * Store forms:
 * Stores packed values from the XMM or YMM register in the second source
 * operand (third operand) into the 128-bit (XMM forms) or 256-bit (YMM forms)
 * memory location using a mask in first source operand (second operand).
 * Stores are atomic.
 */
extern __m256  __ICL_INTRINCC _mm256_maskload_ps(float const *, __m256i);
extern void    __ICL_INTRINCC _mm256_maskstore_ps(float *, __m256i, __m256);
extern __m128  __ICL_INTRINCC _mm_maskload_ps(float const *, __m128i);
extern void    __ICL_INTRINCC _mm_maskstore_ps(float *, __m128i, __m128);

/*
 * Replicate Single-Precision Floating-Point Values
 * **** VMOVSHDUP ymm1, ymm2/m256
 * Duplicates odd-indexed single-precision floating-point values from the
 * source operand
 */
extern __m256  __ICL_INTRINCC _mm256_movehdup_ps(__m256);

/*
 * Replicate Single-Precision Floating-Point Values
 * **** VMOVSLDUP ymm1, ymm2/m256
 * Duplicates even-indexed single-precision floating-point values from the
 * source operand
 */
extern __m256  __ICL_INTRINCC _mm256_moveldup_ps(__m256);

/*
 * Replicate Double-Precision Floating-Point Values
 * **** VMOVDDUP ymm1, ymm2/m256
 * Duplicates even-indexed double-precision floating-point values from the
 * source operand
 */
extern __m256d __ICL_INTRINCC _mm256_movedup_pd(__m256d);

/*
 * Move Unaligned Integer
 * **** VLDDQU ymm1, m256
 * The instruction is functionally similar to VMOVDQU YMM, m256 for loading
 * from memory. That is: 32 bytes of data starting at an address specified by
 * the source memory operand are fetched from memory and placed in a
 * destination
 */
extern __m256i __ICL_INTRINCC _mm256_lddqu_si256(__m256i const *);

/*
 * Store Packed Integers Using Non-Temporal Hint
 * **** VMOVNTDQ m256, ymm1
 * Moves the packed integers in the source operand to the destination using a
 * non-temporal hint to prevent caching of the data during the write to memory
 */
extern void    __ICL_INTRINCC _mm256_stream_si256(__m256i *, __m256i);

/*
 * Store Packed Double-Precision Floating-Point Values Using Non-Temporal Hint
 * **** VMOVNTPD m256, ymm1
 * Moves the packed double-precision floating-point values in the source
 * operand to the destination operand using a non-temporal hint to prevent
 * caching of the data during the write to memory
 */
extern void    __ICL_INTRINCC _mm256_stream_pd(double *, __m256d);

/*
 * Store Packed Single-Precision Floating-Point Values Using Non-Temporal Hint
 * **** VMOVNTPS m256, ymm1
 * Moves the packed single-precision floating-point values in the source
 * operand to the destination operand using a non-temporal hint to prevent
 * caching of the data during the write to memory
 */
extern void    __ICL_INTRINCC _mm256_stream_ps(float *, __m256);

/*
 * Compute Approximate Reciprocals of Packed Single-Precision Floating-Point
 * Values
 * **** VRCPPS ymm1, ymm2/m256
 * Performs an SIMD computation of the approximate reciprocals of the eight
 * packed single precision floating-point values in the source operand and
 * stores the packed single-precision floating-point results in the destination
 */
extern __m256  __ICL_INTRINCC _mm256_rcp_ps(__m256);

/*
 * Compute Approximate Reciprocals of Square Roots of
 * Packed Single-Precision Floating-point Values
 * **** VRSQRTPS ymm1, ymm2/m256
 * Performs an SIMD computation of the approximate reciprocals of the square
 * roots of the eight packed single precision floating-point values in the
 * source operand and stores the packed single-precision floating-point results
 * in the destination
 */
extern __m256  __ICL_INTRINCC _mm256_rsqrt_ps(__m256);

/*
 * Square Root of Double-Precision Floating-Point Values
 * **** VSQRTPD ymm1, ymm2/m256
 * Performs an SIMD computation of the square roots of the two or four packed
 * double-precision floating-point values in the source operand and stores
 * the packed double-precision floating-point results in the destination
 */
extern __m256d __ICL_INTRINCC _mm256_sqrt_pd(__m256d);

/*
 * Square Root of Single-Precision Floating-Point Values
 * **** VSQRTPS ymm1, ymm2/m256
 * Performs an SIMD computation of the square roots of the eight packed
 * single-precision floating-point values in the source operand stores the
 * packed double-precision floating-point results in the destination
 */
extern __m256  __ICL_INTRINCC _mm256_sqrt_ps(__m256);

/*
 * Round Packed Double-Precision Floating-Point Values
 * **** VROUNDPD ymm1,ymm2/m256,imm8
 * Round the four Double-Precision Floating-Point Values values in the source
 * operand by the rounding mode specified in the immediate operand and place
 * the result in the destination. The rounding process rounds the input to an
 * integral value and returns the result as a double-precision floating-point
 * value. The Precision Floating Point Exception is signaled according to the
 * immediate operand. If any source operand is an SNaN then it will be
 * converted to a QNaN.
 */
extern __m256d __ICL_INTRINCC _mm256_round_pd(__m256d, int);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */
#define _mm256_ceil_pd(val)   _mm256_round_pd((val), _MM_FROUND_CEIL)
#define _mm256_floor_pd(val)  _mm256_round_pd((val), _MM_FROUND_FLOOR)

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
/*
 * Round Packed Single-Precision Floating-Point Values
 * **** VROUNDPS ymm1,ymm2/m256,imm8
 * Round the four single-precision floating-point values values in the source
 * operand by the rounding mode specified in the immediate operand and place
 * the result in the destination. The rounding process rounds the input to an
 * integral value and returns the result as a double-precision floating-point
 * value. The Precision Floating Point Exception is signaled according to the
 * immediate operand. If any source operand is an SNaN then it will be
 * converted to a QNaN.
 */
extern __m256  __ICL_INTRINCC _mm256_round_ps(__m256, int);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */
#define _mm256_ceil_ps(val)   _mm256_round_ps((val), _MM_FROUND_CEIL)
#define _mm256_floor_ps(val)  _mm256_round_ps((val), _MM_FROUND_FLOOR)

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
/*
 * Unpack and Interleave High Packed Double-Precision Floating-Point Values
 * **** VUNPCKHPD ymm1,ymm2,ymm3/m256
 * Performs an interleaved unpack of the high double-precision floating-point
 * values from the first source operand and the second source operand.
 */
extern __m256d __ICL_INTRINCC _mm256_unpackhi_pd(__m256d, __m256d);

/*
 * Unpack and Interleave High Packed Single-Precision Floating-Point Values
 * **** VUNPCKHPS ymm1,ymm2,ymm3
 * Performs an interleaved unpack of the high single-precision floating-point
 * values from the first source operand and the second source operand
 */
extern __m256  __ICL_INTRINCC _mm256_unpackhi_ps(__m256, __m256);

/*
 * Unpack and Interleave Low Packed Double-Precision Floating-Point Values
 * **** VUNPCKLPD ymm1,ymm2,ymm3/m256
 * Performs an interleaved unpack of the low double-precision floating-point
 * values from the first source operand and the second source operand
 */
extern __m256d __ICL_INTRINCC _mm256_unpacklo_pd(__m256d, __m256d);

/*
 * Unpack and Interleave Low Packed Single-Precision Floating-Point Values
 * **** VUNPCKLPS ymm1,ymm2,ymm3
 * Performs an interleaved unpack of the low single-precision floating-point
 * values from the first source operand and the second source operand
 */
extern __m256  __ICL_INTRINCC _mm256_unpacklo_ps(__m256, __m256);

/*
 * Packed Bit Test
 * **** VPTEST ymm1, ymm2/m256
 * VPTEST set the ZF flag if all bits in the result are 0 of the bitwise AND
 * of the first source operand and the second source operand. VPTEST sets the
 * CF flag if all bits in the result are 0 of the bitwise AND of the second
 * source operand and the logical NOT of the destination.
 */
extern int     __ICL_INTRINCC _mm256_testz_si256(__m256i, __m256i);
extern int     __ICL_INTRINCC _mm256_testc_si256(__m256i, __m256i);
extern int     __ICL_INTRINCC _mm256_testnzc_si256(__m256i, __m256i);

/*
 * Packed Bit Test
 * **** VTESTPD ymm1, ymm2/m256
 * **** VTESTPD xmm1, xmm2/m128
 * VTESTPD performs a bitwise comparison of all the sign bits of the
 * double-precision elements in the first source operation and corresponding
 * sign bits in the second source operand. If the AND of the two sets of bits
 * produces all zeros, the ZF is set else the ZF is clear. If the AND NOT of
 * the source sign bits with the dest sign bits produces all zeros the CF is
 * set else the CF is clear
 */
extern int     __ICL_INTRINCC _mm256_testz_pd(__m256d, __m256d);
extern int     __ICL_INTRINCC _mm256_testc_pd(__m256d, __m256d);
extern int     __ICL_INTRINCC _mm256_testnzc_pd(__m256d, __m256d);
extern int     __ICL_INTRINCC _mm_testz_pd(__m128d, __m128d);
extern int     __ICL_INTRINCC _mm_testc_pd(__m128d, __m128d);
extern int     __ICL_INTRINCC _mm_testnzc_pd(__m128d, __m128d);

/*
 * Packed Bit Test
 * **** VTESTPS ymm1, ymm2/m256
 * **** VTESTPS xmm1, xmm2/m128
 * VTESTPS performs a bitwise comparison of all the sign bits of the packed
 * single-precision elements in the first source operation and corresponding
 * sign bits in the second source operand. If the AND of the two sets of bits
 * produces all zeros, the ZF is set else the ZF is clear. If the AND NOT of
 * the source sign bits with the dest sign bits produces all zeros the CF is
 * set else the CF is clear
 */
extern int     __ICL_INTRINCC _mm256_testz_ps(__m256, __m256);
extern int     __ICL_INTRINCC _mm256_testc_ps(__m256, __m256);
extern int     __ICL_INTRINCC _mm256_testnzc_ps(__m256, __m256);
extern int     __ICL_INTRINCC _mm_testz_ps(__m128, __m128);
extern int     __ICL_INTRINCC _mm_testc_ps(__m128, __m128);
extern int     __ICL_INTRINCC _mm_testnzc_ps(__m128, __m128);

/*
 * Extract Double-Precision Floating-Point Sign mask
 * **** VMOVMSKPD r32, ymm2
 * Extracts the sign bits from the packed double-precision floating-point
 * values in the source operand, formats them into a 4-bit mask, and stores
 * the mask in the destination
 */
extern int     __ICL_INTRINCC _mm256_movemask_pd(__m256d);

/*
 * Extract Single-Precision Floating-Point Sign mask
 * **** VMOVMSKPS r32, ymm2
 * Extracts the sign bits from the packed single-precision floating-point
 * values in the source operand, formats them into a 8-bit mask, and stores
 * the mask in the destination
 */
extern int     __ICL_INTRINCC _mm256_movemask_ps(__m256);

/*
 * Return 256-bit vector with all elements set to 0
 */
extern __m256d __ICL_INTRINCC _mm256_setzero_pd(void);
extern __m256  __ICL_INTRINCC _mm256_setzero_ps(void);
extern __m256i __ICL_INTRINCC _mm256_setzero_si256(void);

/*
 * Return 256-bit vector initialized to specified arguments
 */
extern __m256d __ICL_INTRINCC _mm256_set_pd(double, double, double, double);
extern __m256  __ICL_INTRINCC _mm256_set_ps(float, float, float, float,
                                            float, float, float, float);
extern __m256i __ICL_INTRINCC _mm256_set_epi8(char, char, char, char,
                                              char, char, char, char,
                                              char, char, char, char,
                                              char, char, char, char,
                                              char, char, char, char,
                                              char, char, char, char,
                                              char, char, char, char,
                                              char, char, char, char);
extern __m256i __ICL_INTRINCC _mm256_set_epi16(short, short, short, short,
                                               short, short, short, short,
                                               short, short, short, short,
                                               short, short, short, short);
extern __m256i __ICL_INTRINCC _mm256_set_epi32(int, int, int, int,
                                               int, int, int, int);
extern __m256i __ICL_INTRINCC _mm256_set_epi64x(__int64, __int64,
                                                __int64, __int64);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

#define _mm256_set_m128(/* __m128 */ hi, /* __m128 */ lo) \
    _mm256_insertf128_ps(_mm256_castps128_ps256(lo), (hi), 0x1)

#define _mm256_set_m128d(/* __m128d */ hi, /* __m128d */ lo) \
    _mm256_insertf128_pd(_mm256_castpd128_pd256(lo), (hi), 0x1)

#define _mm256_set_m128i(/* __m128i */ hi, /* __m128i */ lo) \
    _mm256_insertf128_si256(_mm256_castsi128_si256(lo), (hi), 0x1)

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
extern __m256d __ICL_INTRINCC _mm256_setr_pd(double, double, double, double);
extern __m256  __ICL_INTRINCC _mm256_setr_ps(float, float, float, float,
                                             float, float, float, float);
extern __m256i __ICL_INTRINCC _mm256_setr_epi8(char, char, char, char,
                                               char, char, char, char,
                                               char, char, char, char,
                                               char, char, char, char,
                                               char, char, char, char,
                                               char, char, char, char,
                                               char, char, char, char,
                                               char, char, char, char);
extern __m256i __ICL_INTRINCC _mm256_setr_epi16(short, short, short, short,
                                                short, short, short, short,
                                                short, short, short, short,
                                                short, short, short, short);
extern __m256i __ICL_INTRINCC _mm256_setr_epi32(int, int, int, int,
                                                int, int, int, int);
extern __m256i __ICL_INTRINCC _mm256_setr_epi64x(__int64, __int64,
                                                 __int64, __int64);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */
#define _mm256_setr_m128(lo, hi)    _mm256_set_m128((hi), (lo))
#define _mm256_setr_m128d(lo, hi)   _mm256_set_m128d((hi), (lo))
#define _mm256_setr_m128i(lo, hi)   _mm256_set_m128i((hi), (lo))

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
/*
 * Return 256-bit vector with all elements initialized to specified scalar
 */
extern __m256d __ICL_INTRINCC _mm256_set1_pd(double);
extern __m256  __ICL_INTRINCC _mm256_set1_ps(float);
extern __m256i __ICL_INTRINCC _mm256_set1_epi8(char);
extern __m256i __ICL_INTRINCC _mm256_set1_epi16(short);
extern __m256i __ICL_INTRINCC _mm256_set1_epi32(int);
extern __m256i __ICL_INTRINCC _mm256_set1_epi64x(long long);

/*
 * Support intrinsics to do vector type casts. These intrinsics do not
 * introduce extra moves to generated code. When cast is done from a 128 to
 * 256-bit type the low 128 bits of the 256-bit result contain source
 * parameter value; the upper 128 bits of the result are undefined
 */
extern __m256  __ICL_INTRINCC _mm256_castpd_ps(__m256d);
extern __m256d __ICL_INTRINCC _mm256_castps_pd(__m256);
extern __m256i __ICL_INTRINCC _mm256_castps_si256(__m256);
extern __m256i __ICL_INTRINCC _mm256_castpd_si256(__m256d);
extern __m256  __ICL_INTRINCC _mm256_castsi256_ps(__m256i);
extern __m256d __ICL_INTRINCC _mm256_castsi256_pd(__m256i);
extern __m128  __ICL_INTRINCC _mm256_castps256_ps128(__m256);
extern __m128d __ICL_INTRINCC _mm256_castpd256_pd128(__m256d);
extern __m128i __ICL_INTRINCC _mm256_castsi256_si128(__m256i);
extern __m256  __ICL_INTRINCC _mm256_castps128_ps256(__m128);
extern __m256d __ICL_INTRINCC _mm256_castpd128_pd256(__m128d);
extern __m256i __ICL_INTRINCC _mm256_castsi128_si256(__m128i);

extern __m256  __ICL_INTRINCC _mm256_zextps128_ps256(__m128);
extern __m256d __ICL_INTRINCC _mm256_zextpd128_pd256(__m128d);
extern __m256i __ICL_INTRINCC _mm256_zextsi128_si256(__m128i);

/* Implement 64-bit version of BSWAP.  Reverses the byte order of x */
extern __int64 __ICL_INTRINCC _bswap64(__int64);

/* Implement RDTSCP */
extern unsigned __int64 __ICL_INTRINCC __rdtscp(unsigned int *);

/*  Implement RDPID */
extern unsigned int __ICL_INTRINCC _rdpid_u32(void);

/*  Implement ENCLU */
extern unsigned int __ICL_INTRINCC _enclu_u32(const int, size_t __data[]);

/*  Implement ENCLS */
extern unsigned int __ICL_INTRINCC _encls_u32(const int, size_t __data[]);

/*  Implement ENCLV */
extern unsigned int __ICL_INTRINCC _enclv_u32(const int, size_t __data[]);

/*  Implement PCONFIG */
extern unsigned int __ICL_INTRINCC _pconfig_u32(const int, size_t __data[]);

/*
 * Implement 64-bit version of POPCNT.
 * Counts the number of set bits in 64-bit integer word.
 */
extern int __ICL_INTRINCC _popcnt64(__int64);

/*
 * Support for half-float conversions to/from normal float.
 * Immediate argument is used for special MXCSR overrides.
 */
extern __m256  __ICL_INTRINCC _mm256_cvtph_ps(__m128i);
extern __m128i __ICL_INTRINCC _mm256_cvtps_ph(__m256, int);

/*
 * Support for casting between various INT, FP types.
 * Note that these do no conversion of values, they just change
 * the type.
 */
extern unsigned __int32 __ICL_INTRINCC _castf32_u32(float);
extern unsigned __int64 __ICL_INTRINCC _castf64_u64(double);
extern float            __ICL_INTRINCC _castu32_f32(unsigned __int32);
extern double           __ICL_INTRINCC _castu64_f64(unsigned __int64);

/*
 * Return a vector with undefined elements. It is recommended to use the
 * result of this intrinsic as an argument of another intrinsic when we don't
 * care about its value but need it to be initialized.
 */
extern __m128  __ICL_INTRINCC _mm_undefined_ps(void);
extern __m128d __ICL_INTRINCC _mm_undefined_pd(void);
extern __m128i __ICL_INTRINCC _mm_undefined_si128(void);
extern __m256  __ICL_INTRINCC _mm256_undefined_ps(void);
extern __m256d __ICL_INTRINCC _mm256_undefined_pd(void);
extern __m256i __ICL_INTRINCC _mm256_undefined_si256(void);

/*
 * Cache line flush optimized.
 */
extern void __ICL_INTRINCC _mm_clflushopt(void const *);

/*
 * Cache line demote.
 */
extern void __ICL_INTRINCC _mm_cldemote(void const *);

/*
 * Persistent Memory Instruction Support.
 */
extern void __ICL_INTRINCC _mm_clwb(void const *);

/*
 *  Direct store instructions
 */

/* Implement MOVDIRI */
extern void __ICL_INTRINCC _directstoreu_u32(void *dst, unsigned int val);
extern void __ICL_INTRINCC _directstoreu_u64(void *dst, unsigned __int64 val);

/* Implement MOVDIR64B */
extern void __ICL_INTRINCC _movdir64b(void *dst, const void *src);


/*
 *  User Wait Instructions Support.
 */

/* Implement UMONITOR */
extern void __ICL_INTRINCC _umonitor(void *);
/* Implement UMWAIT */
extern unsigned char __ICL_INTRINCC _umwait(unsigned int, unsigned __int64);
/* Implement TPAUSE */
extern unsigned char __ICL_INTRINCC _tpause(unsigned int, unsigned __int64);

#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

#define _clflushopt     _mm_clflushopt
#define _cldemote       _mm_cldemote
#define _clwb           _mm_clwb


/*
 * The list of extended control registers.
 * Currently, the list includes only one register.
 */
#define _XCR_XFEATURE_ENABLED_MASK 0

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
/* Returns the content of the specified extended control register */
extern unsigned __int64 __ICL_INTRINCC _xgetbv(unsigned int);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

#define _XCR0_X87       (1ULL << 0)
#define _XCR0_SSE       (1ULL << 1)
#define _XCR0_AVX       (1ULL << 2)

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
/* Writes the value to the specified extended control register */
extern void __ICL_INTRINCC _xsetbv(unsigned int, unsigned __int64);


/*
 * Performs a full or partial save of the enabled processor state components
 * using the the specified memory address location and a mask.
 */
extern void __ICL_INTRINCC _xsave(void *, unsigned __int64);
#if defined(__x86_64) || defined(_M_X64)
extern void __ICL_INTRINCC _xsave64(void *, unsigned __int64);
#endif

/*
 * Performs a full or partial save of the enabled processor state components
 * using the the specified memory address location and a mask.
 * Optimize the state save operation if possible.
 */
extern void __ICL_INTRINCC _xsaveopt(void *, unsigned __int64);
#if defined(__x86_64) || defined(_M_X64)
extern void __ICL_INTRINCC _xsaveopt64(void *, unsigned __int64);
#endif

/*
 * Performs a full or partial restore of the enabled processor states
 * using the state information stored in the specified memory address location
 * and a mask.
 */
extern void __ICL_INTRINCC _xrstor(void *, unsigned __int64);
#if defined(__x86_64) || defined(_M_X64)
extern void __ICL_INTRINCC _xrstor64(void *, unsigned __int64);
#endif

/*
 * xsave/xrstor with compaction and with supervisor state.
 */

extern void __ICL_INTRINCC _xsavec(void*, unsigned __int64);
extern void __ICL_INTRINCC _xsaves(void*, unsigned __int64);
extern void __ICL_INTRINCC _xrstors(const void*, unsigned __int64);
#if defined(__x86_64) || defined(_M_X64)
extern void __ICL_INTRINCC _xsavec64(void*, unsigned __int64);
extern void __ICL_INTRINCC _xsaves64(void*, unsigned __int64);
extern void __ICL_INTRINCC _xrstors64(const void*, unsigned __int64);
#endif

/*
 * Saves the current state of the x87 FPU, MMX technology, XMM,
 * and MXCSR registers to the specified 512-byte memory location.
 */
extern void __ICL_INTRINCC _fxsave(void *);
#if defined(__x86_64) || defined(_M_X64)
extern void __ICL_INTRINCC _fxsave64(void *);
#endif

/*
 * Restore the current state of the x87 FPU, MMX technology, XMM,
 * and MXCSR registers from the specified 512-byte memory location.
 */
extern void __ICL_INTRINCC _fxrstor(void *);
#if defined(__x86_64) || defined(_M_X64)
extern void __ICL_INTRINCC _fxrstor64(void *);
#endif

/*
 * Perform one attempt to generate a hardware generated random value
 * accordingly to the NIST SP 800-90A standard.
 * The generated value is written to the given memory location and the success
 * status is returned: 1 if the hardware could generate a valid random number
 * and 0 otherwise.
 */
extern int __ICL_INTRINCC _rdrand16_step(unsigned short *);
extern int __ICL_INTRINCC _rdrand32_step(unsigned int *);
extern int __ICL_INTRINCC _rdrand64_step(unsigned __int64 *);

#if defined(__x86_64) || defined(_M_X64)
/*
 * Return the value of the FS/GS segment base register.
 */
extern unsigned int     __ICL_INTRINCC _readfsbase_u32();
extern unsigned int     __ICL_INTRINCC _readgsbase_u32();
extern unsigned __int64 __ICL_INTRINCC _readfsbase_u64();
extern unsigned __int64 __ICL_INTRINCC _readgsbase_u64();

/*
 * Write the value to the FS/GS segment base register.
 */
extern void __ICL_INTRINCC _writefsbase_u32(unsigned int);
extern void __ICL_INTRINCC _writegsbase_u32(unsigned int);
extern void __ICL_INTRINCC _writefsbase_u64(unsigned __int64);
extern void __ICL_INTRINCC _writegsbase_u64(unsigned __int64);
#endif

/*
 * Perform FMA (Fused Multiply-and-Add) operations.
 */
extern __m128  __ICL_INTRINCC _mm_fmadd_ps(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fmadd_pd(__m128d, __m128d, __m128d);
extern __m128  __ICL_INTRINCC _mm_fmadd_ss(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fmadd_sd(__m128d, __m128d, __m128d);
extern __m128  __ICL_INTRINCC _mm_fmsub_ps(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fmsub_pd(__m128d, __m128d, __m128d);
extern __m128  __ICL_INTRINCC _mm_fmsub_ss(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fmsub_sd(__m128d, __m128d, __m128d);
extern __m128  __ICL_INTRINCC _mm_fnmadd_ps(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fnmadd_pd(__m128d, __m128d, __m128d);
extern __m128  __ICL_INTRINCC _mm_fnmadd_ss(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fnmadd_sd(__m128d, __m128d, __m128d);
extern __m128  __ICL_INTRINCC _mm_fnmsub_ps(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fnmsub_pd(__m128d, __m128d, __m128d);
extern __m128  __ICL_INTRINCC _mm_fnmsub_ss(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fnmsub_sd(__m128d, __m128d, __m128d);

extern __m256  __ICL_INTRINCC _mm256_fmadd_ps(__m256, __m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_fmadd_pd(__m256d, __m256d, __m256d);
extern __m256  __ICL_INTRINCC _mm256_fmsub_ps(__m256, __m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_fmsub_pd(__m256d, __m256d, __m256d);
extern __m256  __ICL_INTRINCC _mm256_fnmadd_ps(__m256, __m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_fnmadd_pd(__m256d, __m256d, __m256d);
extern __m256  __ICL_INTRINCC _mm256_fnmsub_ps(__m256, __m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_fnmsub_pd(__m256d, __m256d, __m256d);


/*
 * Fused Multiply-and-Add/Subtract__and Multiply-and-Subtract/Add operations.
 */
extern __m128  __ICL_INTRINCC _mm_fmaddsub_ps(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fmaddsub_pd(__m128d, __m128d, __m128d);
extern __m128  __ICL_INTRINCC _mm_fmsubadd_ps(__m128, __m128, __m128);
extern __m128d __ICL_INTRINCC _mm_fmsubadd_pd(__m128d, __m128d, __m128d);

extern __m256  __ICL_INTRINCC _mm256_fmaddsub_ps(__m256, __m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_fmaddsub_pd(__m256d, __m256d, __m256d);
extern __m256  __ICL_INTRINCC _mm256_fmsubadd_ps(__m256, __m256, __m256);
extern __m256d __ICL_INTRINCC _mm256_fmsubadd_pd(__m256d, __m256d, __m256d);


/*
 * Integer 256-bit vector comparison operations.
 */
extern __m256i __ICL_INTRINCC _mm256_cmpeq_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_cmpeq_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_cmpeq_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_cmpeq_epi64(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_cmpgt_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_cmpgt_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_cmpgt_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_cmpgt_epi64(__m256i, __m256i);


/*
 * Integer 256-bit vector MIN/MAX operations.
 */
extern __m256i __ICL_INTRINCC _mm256_max_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_max_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_max_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_max_epu8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_max_epu16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_max_epu32(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_min_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_min_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_min_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_min_epu8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_min_epu16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_min_epu32(__m256i, __m256i);


/*
 * Integer 128-bit vector logical operations.
 */
extern __m128i __ICL_INTRINCC _mm_or_epi32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_or_epi64(__m128i, __m128i);

extern __m128i __ICL_INTRINCC _mm_xor_epi32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_xor_epi64(__m128i, __m128i);


/*
 * Integer 256-bit vector logical operations.
 */
extern __m256i __ICL_INTRINCC _mm256_and_si256(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_andnot_si256(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_or_si256(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_xor_si256(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_or_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_or_epi64(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_xor_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_xor_epi64(__m256i, __m256i);


/*
 * Integer 256-bit vector arithmetic operations.
 */
extern __m256i __ICL_INTRINCC _mm256_abs_epi8(__m256i);
extern __m256i __ICL_INTRINCC _mm256_abs_epi16(__m256i);
extern __m256i __ICL_INTRINCC _mm256_abs_epi32(__m256i);

extern __m256i __ICL_INTRINCC _mm256_add_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_add_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_add_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_add_epi64(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_adds_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_adds_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_adds_epu8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_adds_epu16(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_sub_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_sub_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_sub_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_sub_epi64(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_subs_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_subs_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_subs_epu8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_subs_epu16(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_avg_epu8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_avg_epu16(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_hadd_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_hadd_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_hadds_epi16(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_hsub_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_hsub_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_hsubs_epi16(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_madd_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_maddubs_epi16(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_mulhi_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_mulhi_epu16(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_mullo_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_mullo_epi32(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_mul_epu32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_mul_epi32(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_sign_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_sign_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_sign_epi32(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_mulhrs_epi16(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_sad_epu8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_mpsadbw_epu8(__m256i, __m256i, const int);


/*
 * Integer 256-bit vector arithmetic/logical shift operations.
 */
extern __m256i __ICL_INTRINCC _mm256_bslli_epi128(__m256i, const int);
extern __m256i __ICL_INTRINCC _mm256_slli_si256(__m256i, const int);
extern __m256i __ICL_INTRINCC _mm256_bsrli_epi128(__m256i, const int);
extern __m256i __ICL_INTRINCC _mm256_srli_si256(__m256i, const int);

extern __m256i __ICL_INTRINCC _mm256_sll_epi16(__m256i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_sll_epi32(__m256i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_sll_epi64(__m256i, __m128i);

extern __m256i __ICL_INTRINCC _mm256_slli_epi16(__m256i, int);
extern __m256i __ICL_INTRINCC _mm256_slli_epi32(__m256i, int);
extern __m256i __ICL_INTRINCC _mm256_slli_epi64(__m256i, int);

extern __m256i __ICL_INTRINCC _mm256_sllv_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_sllv_epi64(__m256i, __m256i);

extern __m128i __ICL_INTRINCC _mm_sllv_epi32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_sllv_epi64(__m128i, __m128i);

extern __m256i __ICL_INTRINCC _mm256_sra_epi16(__m256i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_sra_epi32(__m256i, __m128i);

extern __m256i __ICL_INTRINCC _mm256_srai_epi16(__m256i, int);
extern __m256i __ICL_INTRINCC _mm256_srai_epi32(__m256i, int);

extern __m256i __ICL_INTRINCC _mm256_srav_epi32(__m256i, __m256i);

extern __m128i __ICL_INTRINCC _mm_srav_epi32(__m128i, __m128i);

extern __m256i __ICL_INTRINCC _mm256_srl_epi16(__m256i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_srl_epi32(__m256i, __m128i);
extern __m256i __ICL_INTRINCC _mm256_srl_epi64(__m256i, __m128i);

extern __m256i __ICL_INTRINCC _mm256_srli_epi16(__m256i, int);
extern __m256i __ICL_INTRINCC _mm256_srli_epi32(__m256i, int);
extern __m256i __ICL_INTRINCC _mm256_srli_epi64(__m256i, int);

extern __m256i __ICL_INTRINCC _mm256_srlv_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_srlv_epi64(__m256i, __m256i);

extern __m128i __ICL_INTRINCC _mm_srlv_epi32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_srlv_epi64(__m128i, __m128i);


/*
 * Integer 128/256-bit vector pack/blend/shuffle/insert/extract operations.
 */
extern __m128i __ICL_INTRINCC _mm_blend_epi32(__m128i, __m128i, const int);

extern __m256i __ICL_INTRINCC _mm256_blend_epi32(__m256i,__m256i, const int);

extern __m256i __ICL_INTRINCC _mm256_alignr_epi8(__m256i, __m256i, const int);

extern __m256i __ICL_INTRINCC _mm256_blendv_epi8(__m256i, __m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_blend_epi16(__m256i, __m256i, const int);

extern __m256i __ICL_INTRINCC _mm256_packs_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_packs_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_packus_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_packus_epi32(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_unpackhi_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_unpackhi_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_unpackhi_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_unpackhi_epi64(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_unpacklo_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_unpacklo_epi16(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_unpacklo_epi32(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_unpacklo_epi64(__m256i, __m256i);

extern __m256i __ICL_INTRINCC _mm256_shuffle_epi8(__m256i, __m256i);
extern __m256i __ICL_INTRINCC _mm256_shuffle_epi32(__m256i, const int);

extern __m256i __ICL_INTRINCC _mm256_shufflehi_epi16(__m256i, const int);
extern __m256i __ICL_INTRINCC _mm256_shufflelo_epi16(__m256i, const int);

extern __m128i __ICL_INTRINCC _mm256_extracti128_si256(__m256i, const int);
extern __m256i __ICL_INTRINCC _mm256_inserti128_si256(__m256i, __m128i,
                                                      const int);


/*
 * Scalar to 128/256-bit vector broadcast operations.
 */
extern __m128  __ICL_INTRINCC _mm_broadcastss_ps(__m128);
extern __m128d __ICL_INTRINCC _mm_broadcastsd_pd(__m128d);

extern __m128i __ICL_INTRINCC _mm_broadcastb_epi8(__m128i);
extern __m128i __ICL_INTRINCC _mm_broadcastw_epi16(__m128i);
extern __m128i __ICL_INTRINCC _mm_broadcastd_epi32(__m128i);
extern __m128i __ICL_INTRINCC _mm_broadcastq_epi64(__m128i);

extern __m256  __ICL_INTRINCC _mm256_broadcastss_ps(__m128);
extern __m256d __ICL_INTRINCC _mm256_broadcastsd_pd(__m128d);

extern __m256i __ICL_INTRINCC _mm256_broadcastb_epi8(__m128i);
extern __m256i __ICL_INTRINCC _mm256_broadcastw_epi16(__m128i);
extern __m256i __ICL_INTRINCC _mm256_broadcastd_epi32(__m128i);
extern __m256i __ICL_INTRINCC _mm256_broadcastq_epi64(__m128i);
/* Compatibility with clang and gcc */
extern __m256i __ICL_INTRINCC _mm_broadcastsi128_si256(__m128i);
extern __m256i __ICL_INTRINCC _mm256_broadcastsi128_si256(__m128i);

/*
 * Integer 256-bit vector signed/unsigned extension operations.
 */
extern __m256i __ICL_INTRINCC _mm256_cvtepi8_epi16(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepi8_epi32(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepi8_epi64(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepi16_epi32(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepi16_epi64(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepi32_epi64(__m128i);

extern __m256i __ICL_INTRINCC _mm256_cvtepu8_epi16(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepu8_epi32(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepu8_epi64(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepu16_epi32(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepu16_epi64(__m128i);
extern __m256i __ICL_INTRINCC _mm256_cvtepu32_epi64(__m128i);

/*
 * Returns lowest element of vector as a scalar.
 */
extern float   __ICL_INTRINCC _mm256_cvtss_f32(__m256);
extern double  __ICL_INTRINCC _mm256_cvtsd_f64(__m256d);
extern int     __ICL_INTRINCC _mm256_cvtsi256_si32(__m256i);

/*
 * Returns a 32-bit mask made up of the most significant bit of each byte
 * of the 256-bit vector source operand.
 */
extern int __ICL_INTRINCC _mm256_movemask_epi8(__m256i);


/*
 * Masked load/store operations.
 */
extern __m128i __ICL_INTRINCC _mm_maskload_epi32(int const *,
                                                 __m128i);
extern __m128i __ICL_INTRINCC _mm_maskload_epi64(__int64 const *,
                                                 __m128i);

extern void __ICL_INTRINCC _mm_maskstore_epi32(int *,
                                               __m128i,
                                               __m128i);
extern void __ICL_INTRINCC _mm_maskstore_epi64(__int64 *,
                                               __m128i,
                                               __m128i);

extern __m256i __ICL_INTRINCC _mm256_maskload_epi32(int const *,
                                                    __m256i);
extern __m256i __ICL_INTRINCC _mm256_maskload_epi64(__int64 const *,
                                                    __m256i);

extern void __ICL_INTRINCC _mm256_maskstore_epi32(int *,
                                                  __m256i,
                                                  __m256i);
extern void __ICL_INTRINCC _mm256_maskstore_epi64(__int64 *,
                                                  __m256i,
                                                  __m256i);


/*
 * Permute elements in vector operations.
 */
extern __m256i __ICL_INTRINCC _mm256_permutevar8x32_epi32(__m256i, __m256i);
extern __m256  __ICL_INTRINCC _mm256_permutevar8x32_ps(__m256, __m256i);

extern __m256i __ICL_INTRINCC _mm256_permute4x64_epi64(__m256i, const int);
extern __m256d __ICL_INTRINCC _mm256_permute4x64_pd(__m256d, const int);

extern __m256i __ICL_INTRINCC _mm256_permute2x128_si256(__m256i, __m256i,
                                                        const int);


/*
 * Load 32-bytes from memory using non-temporal aligned hint.
 */
extern __m256i  __ICL_INTRINCC _mm256_stream_load_si256(__m256i const *);


/*
 * Masked GATHER from memory to vector register operations.
 */
extern __m256d __ICL_INTRINCC _mm256_mask_i32gather_pd(__m256d,
                                                       double const *,
                                                       __m128i,
                                                       __m256d,
                                                       const int);
extern __m256  __ICL_INTRINCC _mm256_mask_i32gather_ps(__m256,
                                                       float const *,
                                                       __m256i,
                                                       __m256,
                                                       const int);
extern __m256d __ICL_INTRINCC _mm256_mask_i64gather_pd(__m256d,
                                                       double const *,
                                                       __m256i,
                                                       __m256d,
                                                       const int);
extern __m128  __ICL_INTRINCC _mm256_mask_i64gather_ps(__m128,
                                                       float const *,
                                                       __m256i,
                                                       __m128,
                                                       const int);

extern __m128d __ICL_INTRINCC _mm_mask_i32gather_pd(__m128d,
                                                    double const *,
                                                    __m128i,
                                                    __m128d,
                                                    const int);
extern __m128  __ICL_INTRINCC _mm_mask_i32gather_ps(__m128,
                                                    float const *,
                                                    __m128i,
                                                    __m128,
                                                    const int);
extern __m128d __ICL_INTRINCC _mm_mask_i64gather_pd(__m128d,
                                                    double const *,
                                                    __m128i,
                                                    __m128d,
                                                    const int);
extern __m128  __ICL_INTRINCC _mm_mask_i64gather_ps(__m128,
                                                    float const *,
                                                    __m128i,
                                                    __m128,
                                                    const int);


extern __m256i __ICL_INTRINCC _mm256_mask_i32gather_epi32(__m256i,
                                                          int const *,
                                                          __m256i,
                                                          __m256i,
                                                          const int);
extern __m256i __ICL_INTRINCC _mm256_mask_i32gather_epi64(__m256i,
                                                          __int64 const *,
                                                          __m128i,
                                                          __m256i,
                                                          const int);
extern __m128i __ICL_INTRINCC _mm256_mask_i64gather_epi32(__m128i,
                                                          int     const *,
                                                          __m256i,
                                                          __m128i,
                                                          const int);
extern __m256i __ICL_INTRINCC _mm256_mask_i64gather_epi64(__m256i,
                                                          __int64 const *,
                                                          __m256i,
                                                          __m256i,
                                                          const int);

extern __m128i __ICL_INTRINCC _mm_mask_i32gather_epi32(__m128i,
                                                       int const *,
                                                       __m128i,
                                                       __m128i,
                                                       const int);
extern __m128i __ICL_INTRINCC _mm_mask_i32gather_epi64(__m128i,
                                                       __int64 const *,
                                                       __m128i,
                                                       __m128i,
                                                       const int);
extern __m128i __ICL_INTRINCC _mm_mask_i64gather_epi32(__m128i,
                                                       int     const *,
                                                       __m128i,
                                                       __m128i,
                                                       const int);
extern __m128i __ICL_INTRINCC _mm_mask_i64gather_epi64(__m128i,
                                                       __int64 const *,
                                                       __m128i,
                                                       __m128i,
                                                       const int);


/*
 * GATHER from memory to vector register operations.
 */
extern __m256d __ICL_INTRINCC _mm256_i32gather_pd(double const *,
                                                  __m128i,
                                                  const int);
extern __m256  __ICL_INTRINCC _mm256_i32gather_ps(float  const *,
                                                  __m256i,
                                                  const int);
extern __m256d __ICL_INTRINCC _mm256_i64gather_pd(double const *,
                                                  __m256i,
                                                  const int);
extern __m128  __ICL_INTRINCC _mm256_i64gather_ps(float  const *,
                                                  __m256i,
                                                  const int);

extern __m128d __ICL_INTRINCC _mm_i32gather_pd(double const *,
                                               __m128i,
                                               const int);
extern __m128  __ICL_INTRINCC _mm_i32gather_ps(float  const *,
                                               __m128i,
                                               const int);
extern __m128d __ICL_INTRINCC _mm_i64gather_pd(double const *,
                                               __m128i,
                                               const int);
extern __m128  __ICL_INTRINCC _mm_i64gather_ps(float  const *,
                                               __m128i,
                                               const int);

extern __m256i __ICL_INTRINCC _mm256_i32gather_epi32(int const *,
                                                     __m256i,
                                                     const int);
extern __m256i __ICL_INTRINCC _mm256_i32gather_epi64(__int64 const *,
                                                     __m128i,
                                                     const int);
extern __m128i __ICL_INTRINCC _mm256_i64gather_epi32(int const *,
                                                     __m256i,
                                                     const int);
extern __m256i __ICL_INTRINCC _mm256_i64gather_epi64(__int64 const *,
                                                     __m256i,
                                                     const int);

extern __m128i __ICL_INTRINCC _mm_i32gather_epi32(int const *,
                                                  __m128i,
                                                  const int);
extern __m128i __ICL_INTRINCC _mm_i32gather_epi64(__int64 const *,
                                                  __m128i,
                                                  const int);
extern __m128i __ICL_INTRINCC _mm_i64gather_epi32(int     const *,
                                                  __m128i,
                                                  const int);
extern __m128i __ICL_INTRINCC _mm_i64gather_epi64(__int64 const *,
                                                  __m128i,
                                                  const int);
#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

/*
 * A collection of operations to manipulate integer data at bit-granularity.
 */
extern unsigned int     __ICL_INTRINCC _bextr_u32(unsigned int,
                                                  unsigned int,
                                                  unsigned int);
extern unsigned int     __ICL_INTRINCC _bextr2_u32(unsigned int,
                                                   unsigned int);
extern unsigned int     __ICL_INTRINCC _blsi_u32(unsigned int);
extern unsigned int     __ICL_INTRINCC _blsmsk_u32(unsigned int);
extern unsigned int     __ICL_INTRINCC _blsr_u32(unsigned int);
extern unsigned int     __ICL_INTRINCC _bzhi_u32(unsigned int,
                                                 unsigned int);
extern unsigned int     __ICL_INTRINCC _pext_u32(unsigned int,
                                                 unsigned int);
extern unsigned int     __ICL_INTRINCC _pdep_u32(unsigned int,
                                                 unsigned int);
extern unsigned int     __ICL_INTRINCC _andn_u32(unsigned int,
                                                 unsigned int);

#define __blsr_u32(arg) _blsr_u32(arg)
#define __blsi_u32(arg) _blsi_u32(arg)
#define __blsmsk_u32(arg) _blsmsk_u32(arg)
#define __bextr_u32(arg1, arg2) _bextr2_u32((arg1),(arg2))
#define __tzcnt_u32(arg) _tzcnt_u32(arg)
#define __andn_u32(arg1, arg2) _andn_u32((arg1),(arg2))

#if defined(__x86_64) || defined(_M_X64)
extern unsigned __int64 __ICL_INTRINCC _bextr_u64(unsigned __int64,
                                                  unsigned int,
                                                  unsigned int);
extern unsigned __int64 __ICL_INTRINCC _bextr2_u64(unsigned __int64,
                                                   unsigned __int64);
extern unsigned __int64 __ICL_INTRINCC _blsi_u64(unsigned __int64);
extern unsigned __int64 __ICL_INTRINCC _blsmsk_u64(unsigned __int64);
extern unsigned __int64 __ICL_INTRINCC _blsr_u64(unsigned __int64);
extern unsigned __int64 __ICL_INTRINCC _bzhi_u64(unsigned __int64,
                                                 unsigned int);
extern unsigned __int64 __ICL_INTRINCC _pext_u64(unsigned __int64,
                                                 unsigned __int64);
extern unsigned __int64 __ICL_INTRINCC _pdep_u64(unsigned __int64,
                                                 unsigned __int64);
extern unsigned __int64 __ICL_INTRINCC _andn_u64(unsigned __int64,
                                                 unsigned __int64);

#define __blsr_u64(arg) _blsr_u64(arg)
#define __blsi_u64(arg) _blsi_u64(arg)
#define __blsmsk_u64(arg) _blsmsk_u64(arg)
#define __bextr_u64(arg1, arg2) _bextr2_u64((arg1), (arg2))
#define __tzcnt_u64(arg) _tzcnt_u64(arg)
#define __andn_u64(arg1, arg2) _andn_u64((arg1), (arg2))
#endif

/*
 * Leading zero bit count.
 *
 *    Counts the number of leading zero bits in a source operand.
 *    Returns operand size as output when source operand is zero.
 */
extern unsigned int     __ICL_INTRINCC _lzcnt_u32(unsigned int);
#if defined(__x86_64) || defined(_M_X64)
extern unsigned __int64 __ICL_INTRINCC _lzcnt_u64(unsigned __int64);
#endif

/*
 * Trailing zero bit count.
 *
 *    Searches the source operand (r2) for the least significant set bit
 *    (1 bit).  If a least significant 1 bit is found, its bit index is
 *    returned, otherwise the result is the number of bits in the operand size.
 */
extern unsigned int     __ICL_INTRINCC _tzcnt_u32(unsigned int);
#if defined(__x86_64) || defined(_M_X64)
extern unsigned __int64 __ICL_INTRINCC _tzcnt_u64(unsigned __int64);
#endif



/*
 * Operation targeted to system software that manages processor context IDs.
 */
extern void __ICL_INTRINCC _invpcid(unsigned int /* type */,
                                    void * /* descriptor */);


/*
 * Support for RTM/HLE+ intrinsics.
 */
#define _XBEGIN_STARTED          (~0u)
#define _XABORT_EXPLICIT         (1 << 0)
#define _XABORT_RETRY            (1 << 1)
#define _XABORT_CONFLICT         (1 << 2)
#define _XABORT_CAPACITY         (1 << 3)
#define _XABORT_DEBUG            (1 << 4)
#define _XABORT_NESTED           (1 << 5)
#define _XABORT_CODE(x)          ((unsigned char)(((x) >> 24) & 0xFF))

extern unsigned int     __ICL_INTRINCC _xbegin(void);
extern void             __ICL_INTRINCC _xend(void);
extern void             __ICL_INTRINCC _xabort(const unsigned int);
extern unsigned char    __ICL_INTRINCC _xtest(void);

/*
 * Perform one attempt to generate a hardware generated random value
 * accordingly to the NIST SP 800-90B/C standards.
 * The generated value is written to the given memory location and the success
 * status is returned: 1 if the hardware could generate a valid random number
 * and 0 otherwise.
 */
extern int __ICL_INTRINCC _rdseed16_step(unsigned short *);
extern int __ICL_INTRINCC _rdseed32_step(unsigned int *);
extern int __ICL_INTRINCC _rdseed64_step(unsigned __int64 *);


/*
 * Perform add with carry operation via adc instruction.
 */
extern unsigned char __ICL_INTRINCC _addcarry_u32(unsigned char /*c_in*/,
                                                  unsigned int /*src1*/,
                                                  unsigned int /*src2*/,
                                                  unsigned int * /*out*/);

extern unsigned char __ICL_INTRINCC _addcarry_u64(unsigned char /*c_in*/,
                                                  unsigned __int64 /*src1*/,
                                                  unsigned __int64 /*src2*/,
                                                  unsigned __int64 * /*out*/);

/*
 * Perform subtract with borrow operation via sbb instruction.
 */
extern unsigned char __ICL_INTRINCC _subborrow_u32(unsigned char /*b_in*/,
                                                   unsigned int /*src1*/,
                                                   unsigned int /*src2*/,
                                                   unsigned int * /*out*/);

extern unsigned char __ICL_INTRINCC _subborrow_u64(unsigned char /*b_in*/,
                                                   unsigned __int64 /*src1*/,
                                                   unsigned __int64 /*src2*/,
                                                   unsigned __int64 * /*out*/);
/*
 * Perform add with carry operation via instruction affecting
 * either OF or CF flag but not both at the same time to indicate
 * carry out condition.
 */
extern unsigned char __ICL_INTRINCC _addcarryx_u32(unsigned char /*c_in*/,
                                                   unsigned int /*src1*/,
                                                   unsigned int /*src2*/,
                                                   unsigned int * /*out*/);

extern unsigned char __ICL_INTRINCC _addcarryx_u64(unsigned char /*c_in*/,
                                                   unsigned __int64 /*src1*/,
                                                   unsigned __int64 /*src2*/,
                                                   unsigned __int64 * /*out*/);

#ifdef __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES
extern __m128i __ICL_INTRINCC _mm_loadu_si16(void const*);
extern __m128i __ICL_INTRINCC _mm_loadu_si32(void const*);
extern __m128i __ICL_INTRINCC _mm_loadu_si64(void const*);

extern void __ICL_INTRINCC _mm_storeu_si16(void*, __m128i);
extern void __ICL_INTRINCC _mm_storeu_si32(void*, __m128i);
extern void __ICL_INTRINCC _mm_storeu_si64(void*, __m128i);

extern __m128i __ICL_INTRINCC _mm_load_epi32(void const*);
extern __m128i __ICL_INTRINCC _mm_load_epi64(void const*);
extern __m256i __ICL_INTRINCC _mm256_load_epi32(void const*);
extern __m256i __ICL_INTRINCC _mm256_load_epi64(void const*);

extern void __ICL_INTRINCC _mm_store_epi32(void*, __m128i);
extern void __ICL_INTRINCC _mm_store_epi64(void*, __m128i);
extern void __ICL_INTRINCC _mm256_store_epi32(void*, __m256i);
extern void __ICL_INTRINCC _mm256_store_epi64(void*, __m256i);

extern __m128i __ICL_INTRINCC _mm_loadu_epi8(void const*);
extern __m128i __ICL_INTRINCC _mm_loadu_epi16(void const*);
extern __m128i __ICL_INTRINCC _mm_loadu_epi32(void const*);
extern __m128i __ICL_INTRINCC _mm_loadu_epi64(void const*);
extern __m256i __ICL_INTRINCC _mm256_loadu_epi8(void const*);
extern __m256i __ICL_INTRINCC _mm256_loadu_epi16(void const*);
extern __m256i __ICL_INTRINCC _mm256_loadu_epi32(void const*);
extern __m256i __ICL_INTRINCC _mm256_loadu_epi64(void const*);

extern void __ICL_INTRINCC _mm_storeu_epi8(void*, __m128i);
extern void __ICL_INTRINCC _mm_storeu_epi16(void*, __m128i);
extern void __ICL_INTRINCC _mm_storeu_epi32(void*, __m128i);
extern void __ICL_INTRINCC _mm_storeu_epi64(void*, __m128i);
extern void __ICL_INTRINCC _mm256_storeu_epi8(void*, __m256i);
extern void __ICL_INTRINCC _mm256_storeu_epi16(void*, __m256i);
extern void __ICL_INTRINCC _mm256_storeu_epi32(void*, __m256i);
extern void __ICL_INTRINCC _mm256_storeu_epi64(void*, __m256i);

/*
 * Perform load a big-endian value from memory.
 */
extern short   __ICL_INTRINCC _loadbe_i16(void const*);
extern int     __ICL_INTRINCC _loadbe_i32(void const*);
extern __int64 __ICL_INTRINCC _loadbe_i64(void const*);

/*
 * Perform store a value to memory as big-endian.
 */
extern void __ICL_INTRINCC _storebe_i16(void *, short);
extern void __ICL_INTRINCC _storebe_i32(void *, int);
extern void __ICL_INTRINCC _storebe_i64(void *, __int64);

/*
 * Intel(R) Secure Hash Algorithm Extensions (Intel(R) SHA Extensions).
 */
extern __m128i __ICL_INTRINCC _mm_sha1msg1_epu32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_sha1msg2_epu32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_sha1nexte_epu32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_sha1rnds4_epu32(__m128i, __m128i, const int);

extern __m128i __ICL_INTRINCC _mm_sha256msg1_epu32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_sha256msg2_epu32(__m128i, __m128i);
extern __m128i __ICL_INTRINCC _mm_sha256rnds2_epu32(__m128i, __m128i, __m128i);

/*
 * Perform unsigned multiply without affecting flags.
 */
extern unsigned int     __ICL_INTRINCC  _mulx_u32(unsigned int,
                                                  unsigned int,
                                                  unsigned int *);
#if defined(__x86_64) || defined(_M_X64)
extern unsigned __int64 __ICL_INTRINCC  _mulx_u64(unsigned __int64,
                                                  unsigned __int64,
                                                  unsigned __int64 *);
#endif

/*
 * Write Data to a Processor Trace Packet
 */
extern void __ICL_INTRINCC _ptwrite32(unsigned int);
#if defined(__x86_64) || defined(_M_X64)
extern void __ICL_INTRINCC _ptwrite64(unsigned __int64);
#endif

extern void __ICL_INTRINCC _wbinvd(void);
extern void __ICL_INTRINCC _wbnoinvd(void);

extern int __ICL_INTRINCC _enqcmd(void *dst, const void *src);
extern int __ICL_INTRINCC _enqcmds(void *dst, const void *src);

#endif /* __INTEL_COMPILER_USE_INTRINSIC_PROTOTYPES */

/*
 * Intel(R) Memory Protection Extensions (Intel(R) MPX).
 */
extern void * __ICL_INTRINCC _bnd_set_ptr_bounds(const void *, size_t);
extern void * __ICL_INTRINCC _bnd_narrow_ptr_bounds(const void *, const void *,
                                                    size_t);
extern void * __ICL_INTRINCC _bnd_copy_ptr_bounds(const void *, const void *);
extern void * __ICL_INTRINCC _bnd_init_ptr_bounds(const void *);
extern void __ICL_INTRINCC _bnd_store_ptr_bounds(const void **, const void *);
extern void __ICL_INTRINCC _bnd_chk_ptr_lbounds(const void *);
extern void __ICL_INTRINCC _bnd_chk_ptr_ubounds(const void *);
extern void __ICL_INTRINCC _bnd_chk_ptr_bounds(const void *, size_t);
extern const void * __ICL_INTRINCC _bnd_get_ptr_lbound(const void *);
extern const void * __ICL_INTRINCC _bnd_get_ptr_ubound(const void *);

#ifdef __cplusplus
}
#endif

#include <zmmintrin.h>

#endif /* _INCLUDED_IMM */
