Refactor exp2().

Change-Id: I491411ba77addcb514944717b19918e4d1b98898
Reviewed-on: https://swiftshader-review.googlesource.com/16228
Tested-by: Nicolas Capens <nicolascapens@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Shader/ShaderCore.cpp b/src/Shader/ShaderCore.cpp
index c763404..883131c 100644
--- a/src/Shader/ShaderCore.cpp
+++ b/src/Shader/ShaderCore.cpp
@@ -114,35 +114,30 @@
 
 	Float4 exponential2(RValue<Float4> x, bool pp)
 	{
-		Float4 x0;
-		Float4 x1;
-		Int4 x2;
+		// This implementation is based on 2^(i + f) = 2^i * 2^f,
+		// where i is the integer part of x and f is the fraction.
 
-		x0 = x;
-
+		// For 2^i we can put the integer part directly in the exponent of
+		// the IEEE-754 floating-point number. Clamp to prevent overflow
+		// past the representation of infinity.
+		Float4 x0 = x;
 		x0 = Min(x0, As<Float4>(Int4(0x43010000)));   // 129.00000e+0f
 		x0 = Max(x0, As<Float4>(Int4(0xC2FDFFFF)));   // -126.99999e+0f
-		x1 = x0;
-		x1 -= Float4(0.5f);
-		x2 = RoundInt(x1);
-		x1 = Float4(x2);
-		x2 += Int4(0x0000007F);   // 127
-		x2 = x2 << 23;
-		x0 -= x1;
-		x1 = As<Float4>(Int4(0x3AF61905));   // 1.8775767e-3f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3C134806));   // 8.9893397e-3f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3D64AA23));   // 5.5826318e-2f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3E75EAD4));   // 2.4015361e-1f
-		x1 *= x0;
-		x1 += As<Float4>(Int4(0x3F31727B));   // 6.9315308e-1f
-		x1 *= x0;
-		x1 += Float4(1.0f);
-		x1 *= As<Float4>(x2);
 
-		return x1;
+		Int4 i = RoundInt(x0 - Float4(0.5f));
+		Float4 ii = As<Float4>((i + Int4(127)) << 23);   // Add single-precision bias, and shift into exponent.
+
+		// For the fractional part use a polynomial
+		// which approximates 2^f in the 0 to 1 range.
+		Float4 f = x0 - Float4(i);
+		Float4 ff = As<Float4>(Int4(0x3AF61905));     // 1.8775767e-3f
+		ff = ff * f + As<Float4>(Int4(0x3C134806));   // 8.9893397e-3f
+		ff = ff * f + As<Float4>(Int4(0x3D64AA23));   // 5.5826318e-2f
+		ff = ff * f + As<Float4>(Int4(0x3E75EAD4));   // 2.4015361e-1f
+		ff = ff * f + As<Float4>(Int4(0x3F31727B));   // 6.9315308e-1f
+		ff = ff * f + Float4(1.0f);
+
+		return ii * ff;
 	}
 
 	Float4 logarithm2(RValue<Float4> x, bool absolute, bool pp)