diff --git a/glm/simd/common.h b/glm/simd/common.h index 6fa5d720..8cc1f637 100644 --- a/glm/simd/common.h +++ b/glm/simd/common.h @@ -127,19 +127,27 @@ GLM_FUNC_QUALIFIER __m128 glm_ssp_ps(__m128 edge0, __m128 edge1, __m128 x) return mul2; } -/// \todo -//GLM_FUNC_QUALIFIER __m128 glm_nan_ps(__m128 x) -//{ -// __m128 empty; -// return empty; -//} +// Agner Fog method +GLM_FUNC_QUALIFIER __m128 glm_nan_ps(__m128 x) +{ + __m128i const t1 = _mm_castps_si128(x); // reinterpret as 32-bit integer + __m128i const t2 = _mm_sll_epi32(t1, _mm_cvtsi32_si128(1)); // shift out sign bit + __m128i const t3 = _mm_set1_epi32(0xFF000000); // exponent mask + __m128i const t4 = _mm_and_si128(t2, t3); // exponent + __m128i const t5 = _mm_andnot_si128(t3, t2); // fraction + __m128i const Equal = _mm_cmpeq_epi32(t3, t4); + __m128i const Nequal = _mm_cmpeq_epi32(t5, _mm_set1_epi32(0)); + __m128i const And = _mm_and_si128(Equal, Nequal); + return _mm_castsi128_ps(And); // exponent = all 1s and fraction != 0 +} -/// \todo -//GLM_FUNC_QUALIFIER __m128 glm_inf_ps(__m128 x) -//{ -// __m128 empty; -// return empty; -//} +// Agner Fog method +GLM_FUNC_QUALIFIER __m128 glm_inf_ps(__m128 x) +{ + __m128i const t1 = _mm_castps_si128(x); // reinterpret as 32-bit integer + __m128i const t2 = _mm_sll_epi32(t1, _mm_cvtsi32_si128(1)); // shift out sign bit + return _mm_castsi128_ps(_mm_cmpeq_epi32(t2, _mm_set1_epi32(0xFF000000))); // exponent is all 1s, fraction is 0 +} // SSE scalar reciprocal sqrt using rsqrt op, plus one Newton-Rhaphson iteration // By Elan Ruskin, http://assemblyrequired.crashworks.org/