summaryrefslogtreecommitdiffstats
path: root/src/compiler
diff options
context:
space:
mode:
authorElie Tournier <[email protected]>2017-08-09 23:11:08 +0100
committerMatt Turner <[email protected]>2019-01-09 16:42:40 -0800
commitcad58fc5e7aba22dee7f9099e9fc46634b6a439c (patch)
tree31693a7995cab2bfc2fe0ed43178265c2e74c62c /src/compiler
parent407bd1bbf93ce9690eb4c0cb93f891db377be262 (diff)
glsl: Add "built-in" functions to do fp32_to_fp64(fp32)
Signed-off-by: Elie Tournier <[email protected]>
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/glsl/float64.glsl38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/compiler/glsl/float64.glsl b/src/compiler/glsl/float64.glsl
index 8cc0a278904..05e07d39ef6 100644
--- a/src/compiler/glsl/float64.glsl
+++ b/src/compiler/glsl/float64.glsl
@@ -1045,3 +1045,41 @@ __fp64_to_fp32(uint64_t __a)
zFrac = mix(zFrac, zFrac | 0x40000000u, aExp != 0);
return __roundAndPackFloat32(aSign, aExp - 0x381, zFrac);
}
+
+/* Returns the result of converting the single-precision floating-point value
+ * `a' to the double-precision floating-point format.
+ */
+uint64_t
+__fp32_to_fp64(float f)
+{
+ uint a = floatBitsToUint(f);
+ uint aFrac = a & 0x007FFFFFu;
+ int aExp = int((a>>23) & 0xFFu);
+ uint aSign = a>>31;
+ uint zFrac0 = 0u;
+ uint zFrac1 = 0u;
+
+ if (aExp == 0xFF) {
+ if (aFrac != 0u) {
+ uint nanLo = 0u;
+ uint nanHi = a<<9;
+ __shift64Right(nanHi, nanLo, 12, nanHi, nanLo);
+ nanHi |= ((aSign<<31) | 0x7FF80000u);
+ return packUint2x32(uvec2(nanLo, nanHi));
+ }
+ return __packFloat64(aSign, 0x7FF, 0u, 0u);
+ }
+
+ if (aExp == 0) {
+ if (aFrac == 0u)
+ return __packFloat64(aSign, 0, 0u, 0u);
+ /* Normalize subnormal */
+ int shiftCount = __countLeadingZeros32(aFrac) - 8;
+ aFrac <<= shiftCount;
+ aExp = 1 - shiftCount;
+ --aExp;
+ }
+
+ __shift64Right(aFrac, 0u, 3, zFrac0, zFrac1);
+ return __packFloat64(aSign, aExp + 0x380, zFrac0, zFrac1);
+}