glsl: Add utility function to extract 64-bit sign
[mesa.git] / src / compiler / glsl / float64.glsl
1 /*
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:
5 *
6 * License for Berkeley SoftFloat Release 3e
7 *
8 * John R. Hauser
9 * 2018 January 20
10 *
11 * The following applies to the whole of SoftFloat Release 3e as well as to
12 * each source file individually.
13 *
14 * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
15 * University of California. All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are met:
19 *
20 * 1. Redistributions of source code must retain the above copyright notice,
21 * this list of conditions, and the following disclaimer.
22 *
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.
26 *
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.
30 *
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.
41 */
42
43 #version 430
44 #extension GL_ARB_gpu_shader_int64 : enable
45 #extension GL_ARB_shader_bit_encoding : enable
46 #extension GL_EXT_shader_integer_mix : enable
47
48 #pragma warning(off)
49
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.
54 */
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
60
61 /* Absolute value of a Float64 :
62 * Clear the sign bit
63 */
64 uint64_t
65 __fabs64(uint64_t __a)
66 {
67 uvec2 a = unpackUint2x32(__a);
68 a.y &= 0x7FFFFFFFu;
69 return packUint2x32(a);
70 }
71
72 /* Returns 1 if the double-precision floating-point value `a' is a NaN;
73 * otherwise returns 0.
74 */
75 bool
76 __is_nan(uint64_t __a)
77 {
78 uvec2 a = unpackUint2x32(__a);
79 return (0xFFE00000u <= (a.y<<1)) &&
80 ((a.x != 0u) || ((a.y & 0x000FFFFFu) != 0u));
81 }
82
83 /* Negate value of a Float64 :
84 * Toggle the sign bit
85 */
86 uint64_t
87 __fneg64(uint64_t __a)
88 {
89 uvec2 a = unpackUint2x32(__a);
90 uint t = a.y;
91
92 t ^= (1u << 31);
93 a.y = mix(t, a.y, __is_nan(__a));
94 return packUint2x32(a);
95 }
96
97 uint64_t
98 __fsign64(uint64_t __a)
99 {
100 uvec2 a = unpackUint2x32(__a);
101 uvec2 retval;
102 retval.x = 0u;
103 retval.y = mix((a.y & 0x80000000u) | 0x3FF00000u, 0u, (a.y << 1 | a.x) == 0u);
104 return packUint2x32(retval);
105 }
106
107 /* Returns the fraction bits of the double-precision floating-point value `a'.*/
108 uint
109 __extractFloat64FracLo(uint64_t a)
110 {
111 return unpackUint2x32(a).x;
112 }
113
114 uint
115 __extractFloat64FracHi(uint64_t a)
116 {
117 return unpackUint2x32(a).y & 0x000FFFFFu;
118 }
119
120 /* Returns the exponent bits of the double-precision floating-point value `a'.*/
121 int
122 __extractFloat64Exp(uint64_t __a)
123 {
124 uvec2 a = unpackUint2x32(__a);
125 return int((a.y>>20) & 0x7FFu);
126 }
127
128 bool
129 __feq64_nonnan(uint64_t __a, uint64_t __b)
130 {
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)));
135 }
136
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.
140 */
141 bool
142 __feq64(uint64_t a, uint64_t b)
143 {
144 if (__is_nan(a) || __is_nan(b))
145 return false;
146
147 return __feq64_nonnan(a, b);
148 }
149
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.
153 */
154 bool
155 __fne64(uint64_t a, uint64_t b)
156 {
157 if (__is_nan(a) || __is_nan(b))
158 return true;
159
160 return !__feq64_nonnan(a, b);
161 }
162
163 /* Returns the sign bit of the double-precision floating-point value `a'.*/
164 uint
165 __extractFloat64Sign(uint64_t a)
166 {
167 return unpackUint2x32(a).y >> 31;
168 }