#ifndef __RUCC_TMMINTRIN_H
#define __RUCC_TMMINTRIN_H
#include <pmmintrin.h>
#define __RUCC_SSE_PI_OP2(__insn, __answer, __x, __y) \
__asm__("movq (%1), %%xmm0\n\tmovq (%2), %%xmm1\n\t" __insn \
" %%xmm1, %%xmm0\n\tmovq %%xmm0, (%0)" \
: \
: "r"(&(__answer)), "r"(&(__x)), "r"(&(__y)) \
: "xmm0", "xmm1", "memory")
#define __RUCC_SSE_PI_OP1(__insn, __answer, __x) \
__asm__("movq (%1), %%xmm0\n\t" __insn " %%xmm0, %%xmm0\n\tmovq %%xmm0, (%0)" \
: \
: "r"(&(__answer)), "r"(&(__x)) \
: "xmm0", "memory")
#define __RUCC_SSE_PI_HORIZONTAL(__insn, __answer, __x, __y) \
__asm__("movq (%1), %%xmm0\n\tmovq (%2), %%xmm1\n\tpunpcklqdq %%xmm1, %%xmm0\n\t" __insn \
" %%xmm0, %%xmm0\n\tmovq %%xmm0, (%0)" \
: \
: "r"(&(__answer)), "r"(&(__x)), "r"(&(__y)) \
: "xmm0", "xmm1", "memory")
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_hadd_epi16(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("phaddw", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_hadd_epi32(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("phaddd", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_hadds_epi16(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("phaddsw", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_hadd_pi16(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_HORIZONTAL("phaddw", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_hadd_pi32(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_HORIZONTAL("phaddd", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_hadds_pi16(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_HORIZONTAL("phaddsw", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_hsub_epi16(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("phsubw", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_hsub_epi32(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("phsubd", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_hsubs_epi16(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("phsubsw", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_hsub_pi16(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_HORIZONTAL("phsubw", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_hsub_pi32(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_HORIZONTAL("phsubd", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_hsubs_pi16(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_HORIZONTAL("phsubsw", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_maddubs_epi16(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("pmaddubsw", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_maddubs_pi16(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_OP2("pmaddubsw", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_mulhrs_epi16(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("pmulhrsw", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_mulhrs_pi16(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_OP2("pmulhrsw", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_shuffle_epi8(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("pshufb", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_shuffle_pi8(__m64 __X, __m64 __Y)
{
__m64 __R;
__asm__("movq (%1), %%xmm0\n\tpunpcklqdq %%xmm0, %%xmm0\n\tmovq (%2), %%xmm1\n\t"
"pshufb %%xmm1, %%xmm0\n\tmovq %%xmm0, (%0)"
:
: "r"(&__R), "r"(&__X), "r"(&__Y)
: "xmm0", "xmm1", "memory");
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_alignr_epi8(__m128i __X, __m128i __Y, const int __N)
{
__m128i __R;
__RUCC_SSE_OP2_IMM("palignr", __R, __X, __Y, __N);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_alignr_pi8(__m64 __X, __m64 __Y, const int __N)
{
__m64 __R;
__asm__("movq (%2), %%xmm0\n\tmovq (%1), %%xmm1\n\tpunpcklqdq %%xmm1, %%xmm0\n\t"
"psrldq %3, %%xmm0\n\tmovq %%xmm0, (%0)"
:
: "r"(&__R), "r"(&__X), "r"(&__Y), "i"(__N)
: "xmm0", "xmm1", "memory");
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_sign_epi8(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("psignb", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_sign_epi16(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("psignw", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_sign_epi32(__m128i __X, __m128i __Y)
{
__m128i __R;
__RUCC_SSE_OP2("psignd", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_sign_pi8(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_OP2("psignb", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_sign_pi16(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_OP2("psignw", __R, __X, __Y);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_sign_pi32(__m64 __X, __m64 __Y)
{
__m64 __R;
__RUCC_SSE_PI_OP2("psignd", __R, __X, __Y);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_abs_epi8(__m128i __X)
{
__m128i __R;
__RUCC_SSE_OP1("pabsb", __R, __X);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_abs_epi16(__m128i __X)
{
__m128i __R;
__RUCC_SSE_OP1("pabsw", __R, __X);
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("ssse3")))
_mm_abs_epi32(__m128i __X)
{
__m128i __R;
__RUCC_SSE_OP1("pabsd", __R, __X);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_abs_pi8(__m64 __X)
{
__m64 __R;
__RUCC_SSE_PI_OP1("pabsb", __R, __X);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_abs_pi16(__m64 __X)
{
__m64 __R;
__RUCC_SSE_PI_OP1("pabsw", __R, __X);
return __R;
}
static __inline__ __m64 __attribute__((__always_inline__, __target__("ssse3")))
_mm_abs_pi32(__m64 __X)
{
__m64 __R;
__RUCC_SSE_PI_OP1("pabsd", __R, __X);
return __R;
}
#endif