1/// @ref core
2/// @file glm/detail/func_integer_simd.inl
3
4#include "../simd/integer.h"
5
6#if GLM_ARCH & GLM_ARCH_SSE2_BIT
7
8namespace glm{
9namespace detail
10{
11	template <glm::precision P>
12	struct compute_bitfieldReverseStep<uint32, P, tvec4, true, true>
13	{
14		GLM_FUNC_QUALIFIER static tvec4<uint32, P> call(tvec4<uint32, P> const & v, uint32 Mask, uint32 Shift)
15		{
16			__m128i const set0 = v.data;
17
18			__m128i const set1 = _mm_set1_epi32(Mask);
19			__m128i const and1 = _mm_and_si128(set0, set1);
20			__m128i const sft1 = _mm_slli_epi32(and1, Shift);
21
22			__m128i const set2 = _mm_andnot_si128(set0, _mm_set1_epi32(-1));
23			__m128i const and2 = _mm_and_si128(set0, set2);
24			__m128i const sft2 = _mm_srai_epi32(and2, Shift);
25
26			__m128i const or0 = _mm_or_si128(sft1, sft2);
27
28			return or0;
29		}
30	};
31
32	template <glm::precision P>
33	struct compute_bitfieldBitCountStep<uint32, P, tvec4, true, true>
34	{
35		GLM_FUNC_QUALIFIER static tvec4<uint32, P> call(tvec4<uint32, P> const & v, uint32 Mask, uint32 Shift)
36		{
37			__m128i const set0 = v.data;
38
39			__m128i const set1 = _mm_set1_epi32(Mask);
40			__m128i const and0 = _mm_and_si128(set0, set1);
41			__m128i const sft0 = _mm_slli_epi32(set0, Shift);
42			__m128i const and1 = _mm_and_si128(sft0, set1);
43			__m128i const add0 = _mm_add_epi32(and0, and1);
44
45			return add0;
46		}
47	};
48}//namespace detail
49
50#	if GLM_ARCH & GLM_ARCH_AVX_BIT
51	template <>
52	GLM_FUNC_QUALIFIER int bitCount(uint32 x)
53	{
54		return _mm_popcnt_u32(x);
55	}
56
57#	if(GLM_MODEL == GLM_MODEL_64)
58	template <>
59	GLM_FUNC_QUALIFIER int bitCount(uint64 x)
60	{
61		return static_cast<int>(_mm_popcnt_u64(x));
62	}
63#	endif//GLM_MODEL
64#	endif//GLM_ARCH
65
66}//namespace glm
67
68#endif//GLM_ARCH & GLM_ARCH_SSE2_BIT
69