defocus-modules/include/defocus/intrinsic_helper.h
2023-05-23 13:20:59 +02:00

57 lines
1.9 KiB
C

#ifndef DEFOCUS_INTRINSIC_HELPER_H
#define DEFOCUS_INTRINSIC_HELPER_H
/** @file intrinsic_helper.h
* @brief Helper macros for intrinsics
*
* Assumes that at least SS3 is available.
*/
#include <immintrin.h>
#include <pmmintrin.h>
/* Shuffle mask for _mm_shuffle_epi32 */
#define DF_MAKE_SHUFFLE_MASK(x, y, z, w) (x | (y << 2) | (z << 4) | (w << 6))
#define DF_VEC_SWIZZLE_MASK(vec, mask) _mm_castsi128_ps(_mm_shuffle_epi32(_mm_castps_si128(vec), mask))
#define DF_VEC_SWIZZLE(vec, x, y, z, w) DF_VEC_SWIZZLE_MASK(vec, DF_MAKE_SHUFFLE_MASK(x, y, z, w))
// "broadcasts" element x [0, 1, 2, 3] to all elements of the result */
#define DF_VEC_SWIZZLE1(vec, x) DF_VEC_SWIZZLE_MASK(vec, DF_MAKE_SHUFFLE_MASK(x, x, x, x))
/* returns [vec0, vec0, vec2, vec2] */
#define DF_VEC_SWIZZLE_0022(vec) _mm_moveldup_ps(vec)
/* returns [vec1, vec1, vec3, vec3] */
#define DF_VEC_SWIZZLE_1133(vec) _mm_movehdup_ps(vec)
/* returns [vec1[x], vec1[y], vec2[z], vec2[w]] */
#define DF_VEC_SHUFFLE(vec1, vec2, x, y, z, w) _mm_shuffle_ps(vec1, vec2, DF_MAKE_SHUFFLE_MASK(x, y, z, w))
/* returns [vec1[0], vec1[1], vec2[0], vec2[1]] */
#define DF_VEC_SHUFFLE_0101(vec1, vec2) _mm_movelh_ps(vec1, vec2)
/* returns [vec1[2], vec1[3], vec2[2], vec2[3]] */
#define DF_VEC_SHUFFLE_2323(vec1, vec2) _mm_movehl_ps(vec2, vec1)
/* returns the n-th float inside the vector */
inline float extract_float(__m128 v, unsigned int n)
{
/* _mm_shuffle_ps expects a constant */
switch (n) {
case 0:
return _mm_cvtss_f32(_mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 0)));
case 1:
return _mm_cvtss_f32(_mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 1)));
case 2:
return _mm_cvtss_f32(_mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 2)));
case 3:
return _mm_cvtss_f32(_mm_shuffle_ps(v, v, _MM_SHUFFLE(0, 0, 0, 3)));
}
int nan = 0x7F800001;
return *(float *)&nan;
}
#endif