#ifndef __RUCC_PMMINTRIN_H
#define __RUCC_PMMINTRIN_H
#include <emmintrin.h>
#define __RUCC_SSE_OP1(__insn, __answer, __x) \
__asm__("movdqu (%1), %%xmm0\n\t" __insn " %%xmm0, %%xmm0\n\tmovdqu %%xmm0, (%0)" \
: \
: "r"(&(__answer)), "r"(&(__x)) \
: "xmm0", "memory")
#define __RUCC_SSE_OP2(__insn, __answer, __x, __y) \
__asm__("movdqu (%1), %%xmm0\n\tmovdqu (%2), %%xmm1\n\t" __insn \
" %%xmm1, %%xmm0\n\tmovdqu %%xmm0, (%0)" \
: \
: "r"(&(__answer)), "r"(&(__x)), "r"(&(__y)) \
: "xmm0", "xmm1", "memory")
#define __RUCC_SSE_OP1_IMM(__insn, __answer, __x, __imm) \
__asm__("movdqu (%1), %%xmm0\n\t" __insn " %2, %%xmm0, %%xmm0\n\tmovdqu %%xmm0, (%0)" \
: \
: "r"(&(__answer)), "r"(&(__x)), "i"(__imm) \
: "xmm0", "memory")
#define __RUCC_SSE_OP2_IMM(__insn, __answer, __x, __y, __imm) \
__asm__("movdqu (%1), %%xmm0\n\tmovdqu (%2), %%xmm1\n\t" __insn \
" %3, %%xmm1, %%xmm0\n\tmovdqu %%xmm0, (%0)" \
: \
: "r"(&(__answer)), "r"(&(__x)), "r"(&(__y)), "i"(__imm) \
: "xmm0", "xmm1", "memory")
static __inline__ __m128 __attribute__((__always_inline__, __target__("sse3")))
_mm_addsub_ps(__m128 __X, __m128 __Y)
{
__m128 __R;
__RUCC_SSE_OP2("addsubps", __R, __X, __Y);
return __R;
}
static __inline__ __m128 __attribute__((__always_inline__, __target__("sse3")))
_mm_hadd_ps(__m128 __X, __m128 __Y)
{
__m128 __R;
__RUCC_SSE_OP2("haddps", __R, __X, __Y);
return __R;
}
static __inline__ __m128 __attribute__((__always_inline__, __target__("sse3")))
_mm_hsub_ps(__m128 __X, __m128 __Y)
{
__m128 __R;
__RUCC_SSE_OP2("hsubps", __R, __X, __Y);
return __R;
}
static __inline__ __m128 __attribute__((__always_inline__, __target__("sse3")))
_mm_movehdup_ps(__m128 __X)
{
__m128 __R;
__RUCC_SSE_OP1("movshdup", __R, __X);
return __R;
}
static __inline__ __m128 __attribute__((__always_inline__, __target__("sse3")))
_mm_moveldup_ps(__m128 __X)
{
__m128 __R;
__RUCC_SSE_OP1("movsldup", __R, __X);
return __R;
}
static __inline__ __m128d __attribute__((__always_inline__, __target__("sse3")))
_mm_addsub_pd(__m128d __X, __m128d __Y)
{
__m128d __R;
__RUCC_SSE_OP2("addsubpd", __R, __X, __Y);
return __R;
}
static __inline__ __m128d __attribute__((__always_inline__, __target__("sse3")))
_mm_hadd_pd(__m128d __X, __m128d __Y)
{
__m128d __R;
__RUCC_SSE_OP2("haddpd", __R, __X, __Y);
return __R;
}
static __inline__ __m128d __attribute__((__always_inline__, __target__("sse3")))
_mm_hsub_pd(__m128d __X, __m128d __Y)
{
__m128d __R;
__RUCC_SSE_OP2("hsubpd", __R, __X, __Y);
return __R;
}
static __inline__ __m128d __attribute__((__always_inline__, __target__("sse3")))
_mm_movedup_pd(__m128d __X)
{
__m128d __R;
__RUCC_SSE_OP1("movddup", __R, __X);
return __R;
}
static __inline__ __m128d __attribute__((__always_inline__, __target__("sse3")))
_mm_loaddup_pd(double const *__P)
{
__m128d __R;
__asm__("movddup (%1), %%xmm0\n\tmovdqu %%xmm0, (%0)"
:
: "r"(&__R), "r"(__P)
: "xmm0", "memory");
return __R;
}
static __inline__ __m128i __attribute__((__always_inline__, __target__("sse3")))
_mm_lddqu_si128(__m128i const *__P)
{
__m128i __R;
__asm__("lddqu (%1), %%xmm0\n\tmovdqu %%xmm0, (%0)" : : "r"(&__R), "r"(__P) : "xmm0", "memory");
return __R;
}
#endif