Added NaN and Inf SIMD optimization

This commit is contained in:
Christophe Riccio 2016-05-28 03:09:22 +02:00
parent 1381a95938
commit 79894a58cc

View File

@ -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/