Add ESSL 3.10 ldexp/frexp builtins

This adds new built-ins found in ESSL 3.10 section 8.3 Common
Functions.

This includes constant folding support for ldexp and support for both
GLSL and HLSL output. In HLSL these functions need to be emulated.

BUG=angleproject:1730
TEST=angle_unittests

Change-Id: I1330e69978b0cf53efbc3416150194764414e96c
Reviewed-on: https://chromium-review.googlesource.com/435342
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/common/mathutil.h b/src/common/mathutil.h
index 436fd22..9914964 100644
--- a/src/common/mathutil.h
+++ b/src/common/mathutil.h
@@ -614,6 +614,22 @@
     size_t vertexIndexCount;
 };
 
+// Combine a floating-point value representing a mantissa (x) and an integer exponent (exp) into a
+// floating-point value. As in GLSL ldexp() built-in.
+inline float Ldexp(float x, int exp)
+{
+    if (exp > 128)
+    {
+        return std::numeric_limits<float>::infinity();
+    }
+    if (exp < -126)
+    {
+        return 0.0f;
+    }
+    double result = static_cast<double>(x) * std::pow(2.0, static_cast<double>(exp));
+    return static_cast<float>(result);
+}
+
 // First, both normalized floating-point values are converted into 16-bit integer values.
 // Then, the results are packed into the returned 32-bit unsigned integer.
 // The first float value will be written to the least significant bits of the output;