#pragma once
#include "../math/emath.h"
#define vboolf …
#define vboold …
#define vint …
#define vuint …
#define vllong …
#define vfloat …
#define vdouble …
namespace embree
{
template<>
struct vuint<4>
{ … };
#if defined(__AVX512VL__)
__forceinline vboolf4 asBool(const vuint4& a) { return _mm_movepi32_mask(a); }
#else
__forceinline vboolf4 asBool(const vuint4& a) { … }
#endif
__forceinline vuint4 operator +(const vuint4& a) { … }
__forceinline vuint4 operator -(const vuint4& a) { … }
__forceinline vuint4 operator +(const vuint4& a, const vuint4& b) { … }
__forceinline vuint4 operator +(const vuint4& a, unsigned int b) { … }
__forceinline vuint4 operator +(unsigned int a, const vuint4& b) { … }
__forceinline vuint4 operator -(const vuint4& a, const vuint4& b) { … }
__forceinline vuint4 operator -(const vuint4& a, unsigned int b) { … }
__forceinline vuint4 operator -(unsigned int a, const vuint4& b) { … }
__forceinline vuint4 operator &(const vuint4& a, const vuint4& b) { … }
__forceinline vuint4 operator &(const vuint4& a, unsigned int b) { … }
__forceinline vuint4 operator &(unsigned int a, const vuint4& b) { … }
__forceinline vuint4 operator |(const vuint4& a, const vuint4& b) { … }
__forceinline vuint4 operator |(const vuint4& a, unsigned int b) { … }
__forceinline vuint4 operator |(unsigned int a, const vuint4& b) { … }
__forceinline vuint4 operator ^(const vuint4& a, const vuint4& b) { … }
__forceinline vuint4 operator ^(const vuint4& a, unsigned int b) { … }
__forceinline vuint4 operator ^(unsigned int a, const vuint4& b) { … }
__forceinline vuint4 operator <<(const vuint4& a, unsigned int n) { … }
__forceinline vuint4 operator >>(const vuint4& a, unsigned int n) { … }
__forceinline vuint4 sll (const vuint4& a, unsigned int b) { … }
__forceinline vuint4 sra (const vuint4& a, unsigned int b) { … }
__forceinline vuint4 srl (const vuint4& a, unsigned int b) { … }
__forceinline vuint4& operator +=(vuint4& a, const vuint4& b) { … }
__forceinline vuint4& operator +=(vuint4& a, unsigned int b) { … }
__forceinline vuint4& operator -=(vuint4& a, const vuint4& b) { … }
__forceinline vuint4& operator -=(vuint4& a, unsigned int b) { … }
__forceinline vuint4& operator &=(vuint4& a, const vuint4& b) { … }
__forceinline vuint4& operator &=(vuint4& a, unsigned int b) { … }
__forceinline vuint4& operator |=(vuint4& a, const vuint4& b) { … }
__forceinline vuint4& operator |=(vuint4& a, unsigned int b) { … }
__forceinline vuint4& operator <<=(vuint4& a, unsigned int b) { … }
__forceinline vuint4& operator >>=(vuint4& a, unsigned int b) { … }
#if defined(__AVX512VL__)
__forceinline vboolf4 operator ==(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_EQ); }
__forceinline vboolf4 operator !=(const vuint4& a, const vuint4& b) { return _mm_cmp_epu32_mask(a,b,_MM_CMPINT_NE); }
#else
__forceinline vboolf4 operator ==(const vuint4& a, const vuint4& b) { … }
__forceinline vboolf4 operator !=(const vuint4& a, const vuint4& b) { … }
#endif
__forceinline vboolf4 operator ==(const vuint4& a, unsigned int b) { … }
__forceinline vboolf4 operator ==(unsigned int a, const vuint4& b) { … }
__forceinline vboolf4 operator !=(const vuint4& a, unsigned int b) { … }
__forceinline vboolf4 operator !=(unsigned int a, const vuint4& b) { … }
__forceinline vboolf4 eq(const vuint4& a, const vuint4& b) { … }
__forceinline vboolf4 ne(const vuint4& a, const vuint4& b) { … }
#if defined(__AVX512VL__)
__forceinline vboolf4 eq(const vboolf4& mask, const vuint4& a, const vuint4& b) { return _mm_mask_cmp_epu32_mask(mask, a, b, _MM_CMPINT_EQ); }
__forceinline vboolf4 ne(const vboolf4& mask, const vuint4& a, const vuint4& b) { return _mm_mask_cmp_epu32_mask(mask, a, b, _MM_CMPINT_NE); }
#else
__forceinline vboolf4 eq(const vboolf4& mask, const vuint4& a, const vuint4& b) { … }
__forceinline vboolf4 ne(const vboolf4& mask, const vuint4& a, const vuint4& b) { … }
#endif
template<int mask>
__forceinline vuint4 select(const vuint4& t, const vuint4& f) { … }
__forceinline vuint4 unpacklo(const vuint4& a, const vuint4& b) { … }
__forceinline vuint4 unpackhi(const vuint4& a, const vuint4& b) { … }
#if defined(__aarch64__)
template<int i0, int i1, int i2, int i3>
__forceinline vuint4 shuffle(const vuint4& v) {
return vreinterpretq_s32_u8(vqtbl1q_u8( (uint8x16_t)v.v, _MN_SHUFFLE(i0, i1, i2, i3)));
}
template<int i0, int i1, int i2, int i3>
__forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) {
return vreinterpretq_s32_u8(vqtbl2q_u8( (uint8x16x2_t){(uint8x16_t)a.v, (uint8x16_t)b.v}, _MF_SHUFFLE(i0, i1, i2, i3)));
}
#else
template<int i0, int i1, int i2, int i3>
__forceinline vuint4 shuffle(const vuint4& v) { … }
template<int i0, int i1, int i2, int i3>
__forceinline vuint4 shuffle(const vuint4& a, const vuint4& b) { … }
#endif
#if defined(__SSE3__)
template<> __forceinline vuint4 shuffle<0, 0, 2, 2>(const vuint4& v) { return _mm_castps_si128(_mm_moveldup_ps(_mm_castsi128_ps(v))); }
template<> __forceinline vuint4 shuffle<1, 1, 3, 3>(const vuint4& v) { return _mm_castps_si128(_mm_movehdup_ps(_mm_castsi128_ps(v))); }
template<> __forceinline vuint4 shuffle<0, 1, 0, 1>(const vuint4& v) { return _mm_castpd_si128(_mm_movedup_pd (_mm_castsi128_pd(v))); }
#endif
template<int i>
__forceinline vuint4 shuffle(const vuint4& v) { … }
#if defined(__SSE4_1__) && !defined(__aarch64__)
template<int src> __forceinline unsigned int extract(const vuint4& b) { return _mm_extract_epi32(b, src); }
template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b) { return _mm_insert_epi32(a, b, dst); }
#else
template<int src> __forceinline unsigned int extract(const vuint4& b) { … }
template<int dst> __forceinline vuint4 insert(const vuint4& a, const unsigned b) { … }
#endif
template<> __forceinline unsigned int extract<0>(const vuint4& b) { … }
__forceinline unsigned int toScalar(const vuint4& v) { … }
#if 0
#if defined(__SSE4_1__)
__forceinline vuint4 vreduce_min(const vuint4& v) { vuint4 h = min(shuffle<1,0,3,2>(v),v); return min(shuffle<2,3,0,1>(h),h); }
__forceinline vuint4 vreduce_max(const vuint4& v) { vuint4 h = max(shuffle<1,0,3,2>(v),v); return max(shuffle<2,3,0,1>(h),h); }
__forceinline vuint4 vreduce_add(const vuint4& v) { vuint4 h = shuffle<1,0,3,2>(v) + v ; return shuffle<2,3,0,1>(h) + h ; }
__forceinline unsigned int reduce_min(const vuint4& v) { return toScalar(vreduce_min(v)); }
__forceinline unsigned int reduce_max(const vuint4& v) { return toScalar(vreduce_max(v)); }
__forceinline unsigned int reduce_add(const vuint4& v) { return toScalar(vreduce_add(v)); }
__forceinline size_t select_min(const vuint4& v) { return bsf(movemask(v == vreduce_min(v))); }
__forceinline size_t select_max(const vuint4& v) { return bsf(movemask(v == vreduce_max(v))); }
#else
__forceinline unsigned int reduce_min(const vuint4& v) { return min(v[0],v[1],v[2],v[3]); }
__forceinline unsigned int reduce_max(const vuint4& v) { return max(v[0],v[1],v[2],v[3]); }
__forceinline unsigned int reduce_add(const vuint4& v) { return v[0]+v[1]+v[2]+v[3]; }
#endif
#endif
__forceinline embree_ostream operator <<(embree_ostream cout, const vuint4& a) { … }
}
#undef vboolf
#undef vboold
#undef vint
#undef vuint
#undef vllong
#undef vfloat
#undef vdouble