2 * The implementations contained in this file are heavily based on the
3 * implementations found in the Berkeley SoftFloat library. As such, they are
4 * licensed under the same 3-clause BSD license:
6 * License for Berkeley SoftFloat Release 3e
11 * The following applies to the whole of SoftFloat Release 3e as well as to
12 * each source file individually.
14 * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
15 * University of California. All rights reserved.
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are met:
20 * 1. Redistributions of source code must retain the above copyright notice,
21 * this list of conditions, and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions, and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
27 * 3. Neither the name of the University nor the names of its contributors
28 * may be used to endorse or promote products derived from this software
29 * without specific prior written permission.
31 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
32 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
34 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
35 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
44 #extension GL_ARB_gpu_shader_int64 : enable
45 #extension GL_ARB_shader_bit_encoding : enable
46 #extension GL_EXT_shader_integer_mix : enable
50 /* Software IEEE floating-point rounding mode.
51 * GLSL spec section "4.7.1 Range and Precision":
52 * The rounding mode cannot be set and is undefined.
53 * But here, we are able to define the rounding mode at the compilation time.
55 #define FLOAT_ROUND_NEAREST_EVEN 0
56 #define FLOAT_ROUND_TO_ZERO 1
57 #define FLOAT_ROUND_DOWN 2
58 #define FLOAT_ROUND_UP 3
59 #define FLOAT_ROUNDING_MODE FLOAT_ROUND_NEAREST_EVEN
61 /* Absolute value of a Float64 :
65 __fabs64(uint64_t __a)
67 uvec2 a = unpackUint2x32(__a);
69 return packUint2x32(a);
72 /* Returns 1 if the double-precision floating-point value `a' is a NaN;
73 * otherwise returns 0.
76 __is_nan(uint64_t __a)
78 uvec2 a = unpackUint2x32(__a);
79 return (0xFFE00000u <= (a.y<<1)) &&
80 ((a.x != 0u) || ((a.y & 0x000FFFFFu) != 0u));
83 /* Negate value of a Float64 :
87 __fneg64(uint64_t __a)
89 uvec2 a = unpackUint2x32(__a);
93 a.y = mix(t, a.y, __is_nan(__a));
94 return packUint2x32(a);
98 __fsign64(uint64_t __a)
100 uvec2 a = unpackUint2x32(__a);
103 retval.y = mix((a.y & 0x80000000u) | 0x3FF00000u, 0u, (a.y << 1 | a.x) == 0u);
104 return packUint2x32(retval);
107 /* Returns the fraction bits of the double-precision floating-point value `a'.*/
109 __extractFloat64FracLo(uint64_t a)
111 return unpackUint2x32(a).x;
115 __extractFloat64FracHi(uint64_t a)
117 return unpackUint2x32(a).y & 0x000FFFFFu;
120 /* Returns the exponent bits of the double-precision floating-point value `a'.*/
122 __extractFloat64Exp(uint64_t __a)
124 uvec2 a = unpackUint2x32(__a);
125 return int((a.y>>20) & 0x7FFu);
129 __feq64_nonnan(uint64_t __a, uint64_t __b)
131 uvec2 a = unpackUint2x32(__a);
132 uvec2 b = unpackUint2x32(__b);
133 return (a.x == b.x) &&
134 ((a.y == b.y) || ((a.x == 0u) && (((a.y | b.y)<<1) == 0u)));
137 /* Returns true if the double-precision floating-point value `a' is equal to the
138 * corresponding value `b', and false otherwise. The comparison is performed
139 * according to the IEEE Standard for Floating-Point Arithmetic.
142 __feq64(uint64_t a, uint64_t b)
144 if (__is_nan(a) || __is_nan(b))
147 return __feq64_nonnan(a, b);
150 /* Returns true if the double-precision floating-point value `a' is not equal
151 * to the corresponding value `b', and false otherwise. The comparison is
152 * performed according to the IEEE Standard for Floating-Point Arithmetic.
155 __fne64(uint64_t a, uint64_t b)
157 if (__is_nan(a) || __is_nan(b))
160 return !__feq64_nonnan(a, b);
163 /* Returns the sign bit of the double-precision floating-point value `a'.*/
165 __extractFloat64Sign(uint64_t a)
167 return unpackUint2x32(a).y >> 31;
170 /* Returns true if the 64-bit value formed by concatenating `a0' and `a1' is less
171 * than the 64-bit value formed by concatenating `b0' and `b1'. Otherwise,
175 lt64(uint a0, uint a1, uint b0, uint b1)
177 return (a0 < b0) || ((a0 == b0) && (a1 < b1));
181 __flt64_nonnan(uint64_t __a, uint64_t __b)
183 uvec2 a = unpackUint2x32(__a);
184 uvec2 b = unpackUint2x32(__b);
185 uint aSign = __extractFloat64Sign(__a);
186 uint bSign = __extractFloat64Sign(__b);
188 return (aSign != 0u) && ((((a.y | b.y)<<1) | a.x | b.x) != 0u);
190 return mix(lt64(a.y, a.x, b.y, b.x), lt64(b.y, b.x, a.y, a.x), aSign != 0u);
193 /* Returns true if the double-precision floating-point value `a' is less than
194 * the corresponding value `b', and false otherwise. The comparison is performed
195 * according to the IEEE Standard for Floating-Point Arithmetic.
198 __flt64(uint64_t a, uint64_t b)
200 if (__is_nan(a) || __is_nan(b))
203 return __flt64_nonnan(a, b);
206 /* Returns true if the double-precision floating-point value `a' is greater
207 * than or equal to * the corresponding value `b', and false otherwise. The
208 * comparison is performed * according to the IEEE Standard for Floating-Point
212 __fge64(uint64_t a, uint64_t b)
214 if (__is_nan(a) || __is_nan(b))
217 return !__flt64_nonnan(a, b);