Browse Source

Added NaN and Inf SIMD optimization

Christophe Riccio 9 years ago
parent
commit
79894a58cc
1 changed files with 20 additions and 12 deletions
  1. 20 12
      glm/simd/common.h

+ 20 - 12
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/