diff --git a/include/QF/simd/vec4d.h b/include/QF/simd/vec4d.h index d608933f5..11e173eff 100644 --- a/include/QF/simd/vec4d.h +++ b/include/QF/simd/vec4d.h @@ -133,6 +133,14 @@ qrotd (vec4d_t a, vec4d_t b) return q; } +vec4d_t qconjd (vec4d_t q) __attribute__((const)); +vec4d_t +qconjd (vec4d_t q) +{ + const vec4l_t neg = { 1lu << 63, 1lu << 63, 1lu << 63, 0 }; + return _mm256_xor_pd (q, (__m256d) neg); +} + vec4d_t loadvec3d (const double v3[]) __attribute__((pure, access(read_only, 1))); vec4d_t loadvec3d (const double v3[]) @@ -153,4 +161,22 @@ void storevec3d (double v3[3], vec4d_t v4) v3[2] = v4[2]; } +vec4d_t vceild (vec4d_t v) __attribute__((const)); +vec4d_t vceild (vec4d_t v) +{ + return _mm256_ceil_pd (v); +} + +vec4d_t vfloord (vec4d_t v) __attribute__((const)); +vec4d_t vfloord (vec4d_t v) +{ + return _mm256_floor_pd (v); +} + +vec4d_t vtruncd (vec4d_t v) __attribute__((const)); +vec4d_t vtruncd (vec4d_t v) +{ + return _mm256_round_pd (v, _MM_FROUND_TRUNC); +} + #endif//__QF_simd_vec4d_h diff --git a/include/QF/simd/vec4f.h b/include/QF/simd/vec4f.h index ea92b81d9..e2e09c341 100644 --- a/include/QF/simd/vec4f.h +++ b/include/QF/simd/vec4f.h @@ -127,6 +127,18 @@ qrotf (vec4f_t a, vec4f_t b) return q; } +/** Return the conjugate of the quaternion. + * + * That is, [-x, -y, -z, w]. + */ +vec4f_t qconjf (vec4f_t q) __attribute__((const)); +vec4f_t +qconjf (vec4f_t q) +{ + const vec4i_t neg = { 1u << 31, 1u << 31, 1u << 31, 0 }; + return _mm_xor_ps (q, (__m128) neg); +} + vec4f_t loadvec3f (const float v3[3]) __attribute__((pure, access(read_only, 1))); vec4f_t loadvec3f (const float v3[3]) @@ -156,4 +168,22 @@ void storevec3f (float v3[3], vec4f_t v4) v3[2] = v4[2]; } +vec4f_t vceilf (vec4f_t v) __attribute__((const)); +vec4f_t vceilf (vec4f_t v) +{ + return _mm_ceil_ps (v); +} + +vec4f_t vfloorf (vec4f_t v) __attribute__((const)); +vec4f_t vfloorf (vec4f_t v) +{ + return _mm_floor_ps (v); +} + +vec4f_t vtruncf (vec4f_t v) __attribute__((const)); +vec4f_t vtruncf (vec4f_t v) +{ + return _mm_round_ps (v, _MM_FROUND_TRUNC); +} + #endif//__QF_simd_vec4f_h diff --git a/libs/util/test/test-simd.c b/libs/util/test/test-simd.c index ec1b145ac..8fcc6935c 100644 --- a/libs/util/test/test-simd.c +++ b/libs/util/test/test-simd.c @@ -39,6 +39,46 @@ typedef struct { vec4f_t ulp_errors; } vec4f_test_t; +static vec4d_t tvtruncd (vec4d_t v, vec4d_t ignore) +{ + return vtruncd (v); +} + +static vec4d_t tvceild (vec4d_t v, vec4d_t ignore) +{ + return vceild (v); +} + +static vec4d_t tvfloord (vec4d_t v, vec4d_t ignore) +{ + return vfloord (v); +} + +static vec4d_t tqconjd (vec4d_t v, vec4d_t ignore) +{ + return qconjd (v); +} + +static vec4f_t tvtruncf (vec4f_t v, vec4f_t ignore) +{ + return vtruncf (v); +} + +static vec4f_t tvceilf (vec4f_t v, vec4f_t ignore) +{ + return vceilf (v); +} + +static vec4f_t tvfloorf (vec4f_t v, vec4f_t ignore) +{ + return vfloorf (v); +} + +static vec4f_t tqconjf (vec4f_t v, vec4f_t ignore) +{ + return qconjf (v); +} + static vec4d_test_t vec4d_tests[] = { // 3D dot products { dotd, right, right, one }, @@ -140,6 +180,11 @@ static vec4d_test_t vec4d_tests[] = { { qrotd, up, forward, { -s05, 0, 0, s05 }, { 1.1e-16, 0, 0, 0} }, { qrotd, up, up, qident }, + + { tvtruncd, { 1.1, 2.9, -1.1, -2.9 }, {}, { 1, 2, -1, -2 } }, + { tvceild, { 1.1, 2.9, -1.1, -2.9 }, {}, { 2, 3, -1, -2 } }, + { tvfloord, { 1.1, 2.9, -1.1, -2.9 }, {}, { 1, 2, -2, -3 } }, + { tqconjd, one, {}, { -1, -1, -1, 1 } }, }; #define num_vec4d_tests (sizeof (vec4d_tests) / (sizeof (vec4d_tests[0]))) @@ -226,6 +271,11 @@ static vec4f_test_t vec4f_tests[] = { { qrotf, up, right, { 0, s05, 0, s05 } }, { qrotf, up, forward, { -s05, 0, 0, s05 } }, { qrotf, up, up, qident }, + + { tvtruncf, { 1.1, 2.9, -1.1, -2.9 }, {}, { 1, 2, -1, -2 } }, + { tvceilf, { 1.1, 2.9, -1.1, -2.9 }, {}, { 2, 3, -1, -2 } }, + { tvfloorf, { 1.1, 2.9, -1.1, -2.9 }, {}, { 1, 2, -2, -3 } }, + { tqconjf, one, {}, { -1, -1, -1, 1 } }, }; #define num_vec4f_tests (sizeof (vec4f_tests) / (sizeof (vec4f_tests[0])))