diff options
author | Elie Tournier <[email protected]> | 2017-08-09 23:11:08 +0100 |
---|---|---|
committer | Matt Turner <[email protected]> | 2019-01-09 16:42:40 -0800 |
commit | cad58fc5e7aba22dee7f9099e9fc46634b6a439c (patch) | |
tree | 31693a7995cab2bfc2fe0ed43178265c2e74c62c | |
parent | 407bd1bbf93ce9690eb4c0cb93f891db377be262 (diff) |
glsl: Add "built-in" functions to do fp32_to_fp64(fp32)
Signed-off-by: Elie Tournier <[email protected]>
-rw-r--r-- | src/compiler/glsl/float64.glsl | 38 |
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); +} |