/* Copyright (c) 2018 ZAO "MCST". All rights reserved. */

#ifndef _AMMINTRIN_H_INCLUDED
#define _AMMINTRIN_H_INCLUDED

#ifndef __SSE4A__
# error "SSE4A instruction set not enabled"
#else

/* We need definitions from the SSE3, SSE2 and SSE header files*/
#include <pmmintrin.h>

/* Define the default attributes for the functions in this file */
#define __DEFAULT_FUNCS_ATTRS __attribute__((/*__gnu_inline__,*/ __always_inline__, __artificial__))

__E2K_INLINE void __DEFAULT_FUNCS_ATTRS
_mm_stream_sd (double * __P, __m128d __Y)
{
  __builtin_ia32_movntsd (__P, (__v2df) __Y);
}

__E2K_INLINE void __DEFAULT_FUNCS_ATTRS
_mm_stream_ss (float * __P, __m128 __Y)
{
  __builtin_ia32_movntss (__P, (__v4sf) __Y);
}

__E2K_INLINE __m128i __DEFAULT_FUNCS_ATTRS
_mm_extract_si64 (__m128i __X, __m128i __Y)
{
  return (__m128i) __builtin_ia32_extrq ((__v2di) __X, (__v16qi) __Y);
}

#define _mm_extracti_si64(X, I, L)                                      \
  ((__m128i) __builtin_ia32_extrqi ((__v2di)(__m128i)(X),               \
                                    (unsigned int)(I), (unsigned int)(L)))

__E2K_INLINE __m128i __DEFAULT_FUNCS_ATTRS
_mm_insert_si64 (__m128i __X,__m128i __Y)
{
  return (__m128i) __builtin_ia32_insertq ((__v2di)__X, (__v2di)__Y);
}

#define _mm_inserti_si64(X, Y, I, L)                                    \
  ((__m128i) __builtin_ia32_insertqi ((__v2di)(__m128i)(X),             \
                                      (__v2di)(__m128i)(Y),             \
                                      (unsigned int)(I), (unsigned int)(L)))

#undef __DEFAULT_FUNCS_ATTRS

#endif /* __SSE4A__ */

#endif /* _AMMINTRIN_H_INCLUDED */
