xref: /aosp_15_r20/external/mesa3d/src/compiler/glsl/float64.glsl (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1*61046927SAndroid Build Coastguard Worker/*
2*61046927SAndroid Build Coastguard Worker * The implementations contained in this file are heavily based on the
3*61046927SAndroid Build Coastguard Worker * implementations found in the Berkeley SoftFloat library. As such, they are
4*61046927SAndroid Build Coastguard Worker * licensed under the same 3-clause BSD license:
5*61046927SAndroid Build Coastguard Worker *
6*61046927SAndroid Build Coastguard Worker * License for Berkeley SoftFloat Release 3e
7*61046927SAndroid Build Coastguard Worker *
8*61046927SAndroid Build Coastguard Worker * John R. Hauser
9*61046927SAndroid Build Coastguard Worker * 2018 January 20
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The following applies to the whole of SoftFloat Release 3e as well as to
12*61046927SAndroid Build Coastguard Worker * each source file individually.
13*61046927SAndroid Build Coastguard Worker *
14*61046927SAndroid Build Coastguard Worker * Copyright 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018 The Regents of the
15*61046927SAndroid Build Coastguard Worker * University of California.  All rights reserved.
16*61046927SAndroid Build Coastguard Worker *
17*61046927SAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
18*61046927SAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are met:
19*61046927SAndroid Build Coastguard Worker *
20*61046927SAndroid Build Coastguard Worker *  1. Redistributions of source code must retain the above copyright notice,
21*61046927SAndroid Build Coastguard Worker *     this list of conditions, and the following disclaimer.
22*61046927SAndroid Build Coastguard Worker *
23*61046927SAndroid Build Coastguard Worker *  2. Redistributions in binary form must reproduce the above copyright
24*61046927SAndroid Build Coastguard Worker *     notice, this list of conditions, and the following disclaimer in the
25*61046927SAndroid Build Coastguard Worker *     documentation and/or other materials provided with the distribution.
26*61046927SAndroid Build Coastguard Worker *
27*61046927SAndroid Build Coastguard Worker *  3. Neither the name of the University nor the names of its contributors
28*61046927SAndroid Build Coastguard Worker *     may be used to endorse or promote products derived from this software
29*61046927SAndroid Build Coastguard Worker *     without specific prior written permission.
30*61046927SAndroid Build Coastguard Worker *
31*61046927SAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS", AND ANY
32*61046927SAndroid Build Coastguard Worker * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
33*61046927SAndroid Build Coastguard Worker * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ARE
34*61046927SAndroid Build Coastguard Worker * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
35*61046927SAndroid Build Coastguard Worker * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
36*61046927SAndroid Build Coastguard Worker * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37*61046927SAndroid Build Coastguard Worker * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
38*61046927SAndroid Build Coastguard Worker * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39*61046927SAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40*61046927SAndroid Build Coastguard Worker * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41*61046927SAndroid Build Coastguard Worker*/
42*61046927SAndroid Build Coastguard Worker
43*61046927SAndroid Build Coastguard Worker#version 400
44*61046927SAndroid Build Coastguard Worker#extension GL_ARB_gpu_shader_int64 : enable
45*61046927SAndroid Build Coastguard Worker#extension GL_ARB_shader_bit_encoding : enable
46*61046927SAndroid Build Coastguard Worker#extension GL_EXT_shader_integer_mix : enable
47*61046927SAndroid Build Coastguard Worker#extension GL_MESA_shader_integer_functions : enable
48*61046927SAndroid Build Coastguard Worker
49*61046927SAndroid Build Coastguard Worker#pragma warning(off)
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker/* Software IEEE floating-point rounding mode.
52*61046927SAndroid Build Coastguard Worker * GLSL spec section "4.7.1 Range and Precision":
53*61046927SAndroid Build Coastguard Worker * The rounding mode cannot be set and is undefined.
54*61046927SAndroid Build Coastguard Worker * But here, we are able to define the rounding mode at the compilation time.
55*61046927SAndroid Build Coastguard Worker */
56*61046927SAndroid Build Coastguard Worker#define FLOAT_ROUND_NEAREST_EVEN    0
57*61046927SAndroid Build Coastguard Worker#define FLOAT_ROUND_TO_ZERO         1
58*61046927SAndroid Build Coastguard Worker#define FLOAT_ROUND_DOWN            2
59*61046927SAndroid Build Coastguard Worker#define FLOAT_ROUND_UP              3
60*61046927SAndroid Build Coastguard Worker#define FLOAT_ROUNDING_MODE         FLOAT_ROUND_NEAREST_EVEN
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker/* Relax propagation of NaN.  Binary operations with a NaN source will still
63*61046927SAndroid Build Coastguard Worker * produce a NaN result, but it won't follow strict IEEE rules.
64*61046927SAndroid Build Coastguard Worker */
65*61046927SAndroid Build Coastguard Worker#define RELAXED_NAN_PROPAGATION
66*61046927SAndroid Build Coastguard Worker
67*61046927SAndroid Build Coastguard Worker/* Absolute value of a Float64 :
68*61046927SAndroid Build Coastguard Worker * Clear the sign bit
69*61046927SAndroid Build Coastguard Worker */
70*61046927SAndroid Build Coastguard Workeruint64_t
71*61046927SAndroid Build Coastguard Worker__fabs64(uint64_t __a)
72*61046927SAndroid Build Coastguard Worker{
73*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
74*61046927SAndroid Build Coastguard Worker   a.y &= 0x7FFFFFFFu;
75*61046927SAndroid Build Coastguard Worker   return packUint2x32(a);
76*61046927SAndroid Build Coastguard Worker}
77*61046927SAndroid Build Coastguard Worker
78*61046927SAndroid Build Coastguard Worker/* Returns 1 if the double-precision floating-point value `a' is a NaN;
79*61046927SAndroid Build Coastguard Worker * otherwise returns 0.
80*61046927SAndroid Build Coastguard Worker */
81*61046927SAndroid Build Coastguard Workerbool
82*61046927SAndroid Build Coastguard Worker__is_nan(uint64_t __a)
83*61046927SAndroid Build Coastguard Worker{
84*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
85*61046927SAndroid Build Coastguard Worker   return (0xFFE00000u <= (a.y<<1)) &&
86*61046927SAndroid Build Coastguard Worker      ((a.x != 0u) || ((a.y & 0x000FFFFFu) != 0u));
87*61046927SAndroid Build Coastguard Worker}
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker/* Negate value of a Float64 :
90*61046927SAndroid Build Coastguard Worker * Toggle the sign bit
91*61046927SAndroid Build Coastguard Worker */
92*61046927SAndroid Build Coastguard Workeruint64_t
93*61046927SAndroid Build Coastguard Worker__fneg64(uint64_t __a)
94*61046927SAndroid Build Coastguard Worker{
95*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
96*61046927SAndroid Build Coastguard Worker   a.y ^= (1u << 31);
97*61046927SAndroid Build Coastguard Worker   return packUint2x32(a);
98*61046927SAndroid Build Coastguard Worker}
99*61046927SAndroid Build Coastguard Worker
100*61046927SAndroid Build Coastguard Workeruint64_t
101*61046927SAndroid Build Coastguard Worker__fsign64(uint64_t __a)
102*61046927SAndroid Build Coastguard Worker{
103*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
104*61046927SAndroid Build Coastguard Worker   uvec2 retval;
105*61046927SAndroid Build Coastguard Worker   retval.x = 0u;
106*61046927SAndroid Build Coastguard Worker   retval.y = mix((a.y & 0x80000000u) | 0x3FF00000u, 0u, (a.y << 1 | a.x) == 0u);
107*61046927SAndroid Build Coastguard Worker   return packUint2x32(retval);
108*61046927SAndroid Build Coastguard Worker}
109*61046927SAndroid Build Coastguard Worker
110*61046927SAndroid Build Coastguard Worker/* Returns the fraction bits of the double-precision floating-point value `a'.*/
111*61046927SAndroid Build Coastguard Workeruint
112*61046927SAndroid Build Coastguard Worker__extractFloat64FracLo(uint64_t a)
113*61046927SAndroid Build Coastguard Worker{
114*61046927SAndroid Build Coastguard Worker   return unpackUint2x32(a).x;
115*61046927SAndroid Build Coastguard Worker}
116*61046927SAndroid Build Coastguard Worker
117*61046927SAndroid Build Coastguard Workeruint
118*61046927SAndroid Build Coastguard Worker__extractFloat64FracHi(uint64_t a)
119*61046927SAndroid Build Coastguard Worker{
120*61046927SAndroid Build Coastguard Worker   return unpackUint2x32(a).y & 0x000FFFFFu;
121*61046927SAndroid Build Coastguard Worker}
122*61046927SAndroid Build Coastguard Worker
123*61046927SAndroid Build Coastguard Worker/* Returns the exponent bits of the double-precision floating-point value `a'.*/
124*61046927SAndroid Build Coastguard Workerint
125*61046927SAndroid Build Coastguard Worker__extractFloat64Exp(uint64_t __a)
126*61046927SAndroid Build Coastguard Worker{
127*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
128*61046927SAndroid Build Coastguard Worker   return int((a.y>>20) & 0x7FFu);
129*61046927SAndroid Build Coastguard Worker}
130*61046927SAndroid Build Coastguard Worker
131*61046927SAndroid Build Coastguard Workerbool
132*61046927SAndroid Build Coastguard Worker__feq64_nonnan(uint64_t __a, uint64_t __b)
133*61046927SAndroid Build Coastguard Worker{
134*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
135*61046927SAndroid Build Coastguard Worker   uvec2 b = unpackUint2x32(__b);
136*61046927SAndroid Build Coastguard Worker   return (a.x == b.x) &&
137*61046927SAndroid Build Coastguard Worker          ((a.y == b.y) || ((a.x == 0u) && (((a.y | b.y)<<1) == 0u)));
138*61046927SAndroid Build Coastguard Worker}
139*61046927SAndroid Build Coastguard Worker
140*61046927SAndroid Build Coastguard Worker/* Returns true if the double-precision floating-point value `a' is equal to the
141*61046927SAndroid Build Coastguard Worker * corresponding value `b', and false otherwise.  The comparison is performed
142*61046927SAndroid Build Coastguard Worker * according to the IEEE Standard for Floating-Point Arithmetic.
143*61046927SAndroid Build Coastguard Worker */
144*61046927SAndroid Build Coastguard Workerbool
145*61046927SAndroid Build Coastguard Worker__feq64(uint64_t a, uint64_t b)
146*61046927SAndroid Build Coastguard Worker{
147*61046927SAndroid Build Coastguard Worker   if (__is_nan(a) || __is_nan(b))
148*61046927SAndroid Build Coastguard Worker      return false;
149*61046927SAndroid Build Coastguard Worker
150*61046927SAndroid Build Coastguard Worker   return __feq64_nonnan(a, b);
151*61046927SAndroid Build Coastguard Worker}
152*61046927SAndroid Build Coastguard Worker
153*61046927SAndroid Build Coastguard Worker/* Returns true if the double-precision floating-point value `a' is not equal
154*61046927SAndroid Build Coastguard Worker * to the corresponding value `b', and false otherwise.  The comparison is
155*61046927SAndroid Build Coastguard Worker * performed according to the IEEE Standard for Floating-Point Arithmetic.
156*61046927SAndroid Build Coastguard Worker */
157*61046927SAndroid Build Coastguard Workerbool
158*61046927SAndroid Build Coastguard Worker__fneu64(uint64_t a, uint64_t b)
159*61046927SAndroid Build Coastguard Worker{
160*61046927SAndroid Build Coastguard Worker   if (__is_nan(a) || __is_nan(b))
161*61046927SAndroid Build Coastguard Worker      return true;
162*61046927SAndroid Build Coastguard Worker
163*61046927SAndroid Build Coastguard Worker   return !__feq64_nonnan(a, b);
164*61046927SAndroid Build Coastguard Worker}
165*61046927SAndroid Build Coastguard Worker
166*61046927SAndroid Build Coastguard Worker/* Returns the sign bit of the double-precision floating-point value `a'.*/
167*61046927SAndroid Build Coastguard Workeruint
168*61046927SAndroid Build Coastguard Worker__extractFloat64Sign(uint64_t a)
169*61046927SAndroid Build Coastguard Worker{
170*61046927SAndroid Build Coastguard Worker   return unpackUint2x32(a).y & 0x80000000u;
171*61046927SAndroid Build Coastguard Worker}
172*61046927SAndroid Build Coastguard Worker
173*61046927SAndroid Build Coastguard Worker/* Returns true if the signed 64-bit value formed by concatenating `a0' and
174*61046927SAndroid Build Coastguard Worker * `a1' is less than the signed 64-bit value formed by concatenating `b0' and
175*61046927SAndroid Build Coastguard Worker * `b1'.  Otherwise, returns false.
176*61046927SAndroid Build Coastguard Worker */
177*61046927SAndroid Build Coastguard Workerbool
178*61046927SAndroid Build Coastguard Workerilt64(uint a0, uint a1, uint b0, uint b1)
179*61046927SAndroid Build Coastguard Worker{
180*61046927SAndroid Build Coastguard Worker   return (int(a0) < int(b0)) || ((a0 == b0) && (a1 < b1));
181*61046927SAndroid Build Coastguard Worker}
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Workerbool
184*61046927SAndroid Build Coastguard Worker__flt64_nonnan(uint64_t __a, uint64_t __b)
185*61046927SAndroid Build Coastguard Worker{
186*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
187*61046927SAndroid Build Coastguard Worker   uvec2 b = unpackUint2x32(__b);
188*61046927SAndroid Build Coastguard Worker
189*61046927SAndroid Build Coastguard Worker   /* IEEE 754 floating point numbers are specifically designed so that, with
190*61046927SAndroid Build Coastguard Worker    * two exceptions, values can be compared by bit-casting to signed integers
191*61046927SAndroid Build Coastguard Worker    * with the same number of bits.
192*61046927SAndroid Build Coastguard Worker    *
193*61046927SAndroid Build Coastguard Worker    * From https://en.wikipedia.org/wiki/IEEE_754-1985#Comparing_floating-point_numbers:
194*61046927SAndroid Build Coastguard Worker    *
195*61046927SAndroid Build Coastguard Worker    *    When comparing as 2's-complement integers: If the sign bits differ,
196*61046927SAndroid Build Coastguard Worker    *    the negative number precedes the positive number, so 2's complement
197*61046927SAndroid Build Coastguard Worker    *    gives the correct result (except that negative zero and positive zero
198*61046927SAndroid Build Coastguard Worker    *    should be considered equal). If both values are positive, the 2's
199*61046927SAndroid Build Coastguard Worker    *    complement comparison again gives the correct result. Otherwise (two
200*61046927SAndroid Build Coastguard Worker    *    negative numbers), the correct FP ordering is the opposite of the 2's
201*61046927SAndroid Build Coastguard Worker    *    complement ordering.
202*61046927SAndroid Build Coastguard Worker    *
203*61046927SAndroid Build Coastguard Worker    * The logic implied by the above quotation is:
204*61046927SAndroid Build Coastguard Worker    *
205*61046927SAndroid Build Coastguard Worker    *    !both_are_zero(a, b) && (both_negative(a, b) ? a > b : a < b)
206*61046927SAndroid Build Coastguard Worker    *
207*61046927SAndroid Build Coastguard Worker    * This is equivalent to
208*61046927SAndroid Build Coastguard Worker    *
209*61046927SAndroid Build Coastguard Worker    *    fneu(a, b) && (both_negative(a, b) ? a >= b : a < b)
210*61046927SAndroid Build Coastguard Worker    *
211*61046927SAndroid Build Coastguard Worker    *    fneu(a, b) && (both_negative(a, b) ? !(a < b) : a < b)
212*61046927SAndroid Build Coastguard Worker    *
213*61046927SAndroid Build Coastguard Worker    *    fneu(a, b) && ((both_negative(a, b) && !(a < b)) ||
214*61046927SAndroid Build Coastguard Worker    *                  (!both_negative(a, b) && (a < b)))
215*61046927SAndroid Build Coastguard Worker    *
216*61046927SAndroid Build Coastguard Worker    * (A!|B)&(A|!B) is (A xor B) which is implemented here using !=.
217*61046927SAndroid Build Coastguard Worker    *
218*61046927SAndroid Build Coastguard Worker    *    fneu(a, b) && (both_negative(a, b) != (a < b))
219*61046927SAndroid Build Coastguard Worker    */
220*61046927SAndroid Build Coastguard Worker   bool lt = ilt64(a.y, a.x, b.y, b.x);
221*61046927SAndroid Build Coastguard Worker   bool both_negative = (a.y & b.y & 0x80000000u) != 0;
222*61046927SAndroid Build Coastguard Worker
223*61046927SAndroid Build Coastguard Worker   return !__feq64_nonnan(__a, __b) && (lt != both_negative);
224*61046927SAndroid Build Coastguard Worker}
225*61046927SAndroid Build Coastguard Worker
226*61046927SAndroid Build Coastguard Workerbool
227*61046927SAndroid Build Coastguard Worker__flt64_nonnan_minmax(uint64_t __a, uint64_t __b)
228*61046927SAndroid Build Coastguard Worker{
229*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
230*61046927SAndroid Build Coastguard Worker   uvec2 b = unpackUint2x32(__b);
231*61046927SAndroid Build Coastguard Worker
232*61046927SAndroid Build Coastguard Worker   /* See __flt64_nonnan. For implementing fmin/fmax, we compare -0 < 0, so the
233*61046927SAndroid Build Coastguard Worker    * implied logic is a bit simpler:
234*61046927SAndroid Build Coastguard Worker    *
235*61046927SAndroid Build Coastguard Worker    *    both_negative(a, b) ? a > b : a < b
236*61046927SAndroid Build Coastguard Worker    *
237*61046927SAndroid Build Coastguard Worker    * If a == b, it doesn't matter what we return, so that's equivalent to:
238*61046927SAndroid Build Coastguard Worker    *
239*61046927SAndroid Build Coastguard Worker    *    both_negative(a, b) ? a >= b : a < b
240*61046927SAndroid Build Coastguard Worker    *    both_negative(a, b) ? !(a < b) : a < b
241*61046927SAndroid Build Coastguard Worker    *    both_negative(a, b) ^ (a < b)
242*61046927SAndroid Build Coastguard Worker    *
243*61046927SAndroid Build Coastguard Worker    * XOR is again implemented using !=.
244*61046927SAndroid Build Coastguard Worker    */
245*61046927SAndroid Build Coastguard Worker   bool lt = ilt64(a.y, a.x, b.y, b.x);
246*61046927SAndroid Build Coastguard Worker   bool both_negative = (a.y & b.y & 0x80000000u) != 0;
247*61046927SAndroid Build Coastguard Worker
248*61046927SAndroid Build Coastguard Worker   return (lt != both_negative);
249*61046927SAndroid Build Coastguard Worker}
250*61046927SAndroid Build Coastguard Worker
251*61046927SAndroid Build Coastguard Worker/* Returns true if the double-precision floating-point value `a' is less than
252*61046927SAndroid Build Coastguard Worker * the corresponding value `b', and false otherwise.  The comparison is performed
253*61046927SAndroid Build Coastguard Worker * according to the IEEE Standard for Floating-Point Arithmetic.
254*61046927SAndroid Build Coastguard Worker */
255*61046927SAndroid Build Coastguard Workerbool
256*61046927SAndroid Build Coastguard Worker__flt64(uint64_t a, uint64_t b)
257*61046927SAndroid Build Coastguard Worker{
258*61046927SAndroid Build Coastguard Worker   /* This weird layout matters.  Doing the "obvious" thing results in extra
259*61046927SAndroid Build Coastguard Worker    * flow control being inserted to implement the short-circuit evaluation
260*61046927SAndroid Build Coastguard Worker    * rules.  Flow control is bad!
261*61046927SAndroid Build Coastguard Worker    */
262*61046927SAndroid Build Coastguard Worker   bool x = !__is_nan(a);
263*61046927SAndroid Build Coastguard Worker   bool y = !__is_nan(b);
264*61046927SAndroid Build Coastguard Worker   bool z = __flt64_nonnan(a, b);
265*61046927SAndroid Build Coastguard Worker
266*61046927SAndroid Build Coastguard Worker   return (x && y && z);
267*61046927SAndroid Build Coastguard Worker}
268*61046927SAndroid Build Coastguard Worker
269*61046927SAndroid Build Coastguard Worker/* Returns true if the double-precision floating-point value `a' is greater
270*61046927SAndroid Build Coastguard Worker * than or equal to * the corresponding value `b', and false otherwise.  The
271*61046927SAndroid Build Coastguard Worker * comparison is performed * according to the IEEE Standard for Floating-Point
272*61046927SAndroid Build Coastguard Worker * Arithmetic.
273*61046927SAndroid Build Coastguard Worker */
274*61046927SAndroid Build Coastguard Workerbool
275*61046927SAndroid Build Coastguard Worker__fge64(uint64_t a, uint64_t b)
276*61046927SAndroid Build Coastguard Worker{
277*61046927SAndroid Build Coastguard Worker   /* This weird layout matters.  Doing the "obvious" thing results in extra
278*61046927SAndroid Build Coastguard Worker    * flow control being inserted to implement the short-circuit evaluation
279*61046927SAndroid Build Coastguard Worker    * rules.  Flow control is bad!
280*61046927SAndroid Build Coastguard Worker    */
281*61046927SAndroid Build Coastguard Worker   bool x = !__is_nan(a);
282*61046927SAndroid Build Coastguard Worker   bool y = !__is_nan(b);
283*61046927SAndroid Build Coastguard Worker   bool z = !__flt64_nonnan(a, b);
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker   return (x && y && z);
286*61046927SAndroid Build Coastguard Worker}
287*61046927SAndroid Build Coastguard Worker
288*61046927SAndroid Build Coastguard Workeruint64_t
289*61046927SAndroid Build Coastguard Worker__fsat64(uint64_t __a)
290*61046927SAndroid Build Coastguard Worker{
291*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
292*61046927SAndroid Build Coastguard Worker
293*61046927SAndroid Build Coastguard Worker   /* fsat(NaN) should be zero. */
294*61046927SAndroid Build Coastguard Worker   if (__is_nan(__a) || int(a.y) < 0)
295*61046927SAndroid Build Coastguard Worker      return 0ul;
296*61046927SAndroid Build Coastguard Worker
297*61046927SAndroid Build Coastguard Worker   /* IEEE 754 floating point numbers are specifically designed so that, with
298*61046927SAndroid Build Coastguard Worker    * two exceptions, values can be compared by bit-casting to signed integers
299*61046927SAndroid Build Coastguard Worker    * with the same number of bits.
300*61046927SAndroid Build Coastguard Worker    *
301*61046927SAndroid Build Coastguard Worker    * From https://en.wikipedia.org/wiki/IEEE_754-1985#Comparing_floating-point_numbers:
302*61046927SAndroid Build Coastguard Worker    *
303*61046927SAndroid Build Coastguard Worker    *    When comparing as 2's-complement integers: If the sign bits differ,
304*61046927SAndroid Build Coastguard Worker    *    the negative number precedes the positive number, so 2's complement
305*61046927SAndroid Build Coastguard Worker    *    gives the correct result (except that negative zero and positive zero
306*61046927SAndroid Build Coastguard Worker    *    should be considered equal). If both values are positive, the 2's
307*61046927SAndroid Build Coastguard Worker    *    complement comparison again gives the correct result. Otherwise (two
308*61046927SAndroid Build Coastguard Worker    *    negative numbers), the correct FP ordering is the opposite of the 2's
309*61046927SAndroid Build Coastguard Worker    *    complement ordering.
310*61046927SAndroid Build Coastguard Worker    *
311*61046927SAndroid Build Coastguard Worker    * We know that both values are not negative, and we know that at least one
312*61046927SAndroid Build Coastguard Worker    * value is not zero.  Therefore, we can just use the 2's complement
313*61046927SAndroid Build Coastguard Worker    * comparison ordering.
314*61046927SAndroid Build Coastguard Worker    */
315*61046927SAndroid Build Coastguard Worker   if (ilt64(0x3FF00000, 0x00000000, a.y, a.x))
316*61046927SAndroid Build Coastguard Worker      return 0x3FF0000000000000ul;
317*61046927SAndroid Build Coastguard Worker
318*61046927SAndroid Build Coastguard Worker   return __a;
319*61046927SAndroid Build Coastguard Worker}
320*61046927SAndroid Build Coastguard Worker
321*61046927SAndroid Build Coastguard Worker/* Adds the 64-bit value formed by concatenating `a0' and `a1' to the 64-bit
322*61046927SAndroid Build Coastguard Worker * value formed by concatenating `b0' and `b1'.  Addition is modulo 2^64, so
323*61046927SAndroid Build Coastguard Worker * any carry out is lost.  The result is broken into two 32-bit pieces which
324*61046927SAndroid Build Coastguard Worker * are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
325*61046927SAndroid Build Coastguard Worker */
326*61046927SAndroid Build Coastguard Workervoid
327*61046927SAndroid Build Coastguard Worker__add64(uint a0, uint a1, uint b0, uint b1,
328*61046927SAndroid Build Coastguard Worker        out uint z0Ptr,
329*61046927SAndroid Build Coastguard Worker        out uint z1Ptr)
330*61046927SAndroid Build Coastguard Worker{
331*61046927SAndroid Build Coastguard Worker   uint z1 = a1 + b1;
332*61046927SAndroid Build Coastguard Worker   z1Ptr = z1;
333*61046927SAndroid Build Coastguard Worker   z0Ptr = a0 + b0 + uint(z1 < a1);
334*61046927SAndroid Build Coastguard Worker}
335*61046927SAndroid Build Coastguard Worker
336*61046927SAndroid Build Coastguard Worker
337*61046927SAndroid Build Coastguard Worker/* Subtracts the 64-bit value formed by concatenating `b0' and `b1' from the
338*61046927SAndroid Build Coastguard Worker * 64-bit value formed by concatenating `a0' and `a1'.  Subtraction is modulo
339*61046927SAndroid Build Coastguard Worker * 2^64, so any borrow out (carry out) is lost.  The result is broken into two
340*61046927SAndroid Build Coastguard Worker * 32-bit pieces which are stored at the locations pointed to by `z0Ptr' and
341*61046927SAndroid Build Coastguard Worker * `z1Ptr'.
342*61046927SAndroid Build Coastguard Worker */
343*61046927SAndroid Build Coastguard Workervoid
344*61046927SAndroid Build Coastguard Worker__sub64(uint a0, uint a1, uint b0, uint b1,
345*61046927SAndroid Build Coastguard Worker        out uint z0Ptr,
346*61046927SAndroid Build Coastguard Worker        out uint z1Ptr)
347*61046927SAndroid Build Coastguard Worker{
348*61046927SAndroid Build Coastguard Worker   z1Ptr = a1 - b1;
349*61046927SAndroid Build Coastguard Worker   z0Ptr = a0 - b0 - uint(a1 < b1);
350*61046927SAndroid Build Coastguard Worker}
351*61046927SAndroid Build Coastguard Worker
352*61046927SAndroid Build Coastguard Worker/* Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the
353*61046927SAndroid Build Coastguard Worker * number of bits given in `count'.  If any nonzero bits are shifted off, they
354*61046927SAndroid Build Coastguard Worker * are "jammed" into the least significant bit of the result by setting the
355*61046927SAndroid Build Coastguard Worker * least significant bit to 1.  The value of `count' can be arbitrarily large;
356*61046927SAndroid Build Coastguard Worker * in particular, if `count' is greater than 64, the result will be either 0
357*61046927SAndroid Build Coastguard Worker * or 1, depending on whether the concatenation of `a0' and `a1' is zero or
358*61046927SAndroid Build Coastguard Worker * nonzero.  The result is broken into two 32-bit pieces which are stored at
359*61046927SAndroid Build Coastguard Worker * the locations pointed to by `z0Ptr' and `z1Ptr'.
360*61046927SAndroid Build Coastguard Worker */
361*61046927SAndroid Build Coastguard Workervoid
362*61046927SAndroid Build Coastguard Worker__shift64RightJamming(uint a0,
363*61046927SAndroid Build Coastguard Worker                      uint a1,
364*61046927SAndroid Build Coastguard Worker                      int count,
365*61046927SAndroid Build Coastguard Worker                      out uint z0Ptr,
366*61046927SAndroid Build Coastguard Worker                      out uint z1Ptr)
367*61046927SAndroid Build Coastguard Worker{
368*61046927SAndroid Build Coastguard Worker   uint z0;
369*61046927SAndroid Build Coastguard Worker   uint z1;
370*61046927SAndroid Build Coastguard Worker   int negCount = (-count) & 31;
371*61046927SAndroid Build Coastguard Worker
372*61046927SAndroid Build Coastguard Worker   z0 = mix(0u, a0, count == 0);
373*61046927SAndroid Build Coastguard Worker   z0 = mix(z0, (a0 >> count), count < 32);
374*61046927SAndroid Build Coastguard Worker
375*61046927SAndroid Build Coastguard Worker   z1 = uint((a0 | a1) != 0u); /* count >= 64 */
376*61046927SAndroid Build Coastguard Worker   uint z1_lt64 = (a0>>(count & 31)) | uint(((a0<<negCount) | a1) != 0u);
377*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, z1_lt64, count < 64);
378*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, (a0 | uint(a1 != 0u)), count == 32);
379*61046927SAndroid Build Coastguard Worker   uint z1_lt32 = (a0<<negCount) | (a1>>count) | uint ((a1<<negCount) != 0u);
380*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, z1_lt32, count < 32);
381*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, a1, count == 0);
382*61046927SAndroid Build Coastguard Worker   z1Ptr = z1;
383*61046927SAndroid Build Coastguard Worker   z0Ptr = z0;
384*61046927SAndroid Build Coastguard Worker}
385*61046927SAndroid Build Coastguard Worker
386*61046927SAndroid Build Coastguard Worker/* Shifts the 96-bit value formed by concatenating `a0', `a1', and `a2' right
387*61046927SAndroid Build Coastguard Worker * by 32 _plus_ the number of bits given in `count'.  The shifted result is
388*61046927SAndroid Build Coastguard Worker * at most 64 nonzero bits; these are broken into two 32-bit pieces which are
389*61046927SAndroid Build Coastguard Worker * stored at the locations pointed to by `z0Ptr' and `z1Ptr'.  The bits shifted
390*61046927SAndroid Build Coastguard Worker * off form a third 32-bit result as follows:  The _last_ bit shifted off is
391*61046927SAndroid Build Coastguard Worker * the most-significant bit of the extra result, and the other 31 bits of the
392*61046927SAndroid Build Coastguard Worker * extra result are all zero if and only if _all_but_the_last_ bits shifted off
393*61046927SAndroid Build Coastguard Worker * were all zero.  This extra result is stored in the location pointed to by
394*61046927SAndroid Build Coastguard Worker * `z2Ptr'.  The value of `count' can be arbitrarily large.
395*61046927SAndroid Build Coastguard Worker *     (This routine makes more sense if `a0', `a1', and `a2' are considered
396*61046927SAndroid Build Coastguard Worker * to form a fixed-point value with binary point between `a1' and `a2'.  This
397*61046927SAndroid Build Coastguard Worker * fixed-point value is shifted right by the number of bits given in `count',
398*61046927SAndroid Build Coastguard Worker * and the integer part of the result is returned at the locations pointed to
399*61046927SAndroid Build Coastguard Worker * by `z0Ptr' and `z1Ptr'.  The fractional part of the result may be slightly
400*61046927SAndroid Build Coastguard Worker * corrupted as described above, and is returned at the location pointed to by
401*61046927SAndroid Build Coastguard Worker * `z2Ptr'.)
402*61046927SAndroid Build Coastguard Worker */
403*61046927SAndroid Build Coastguard Workervoid
404*61046927SAndroid Build Coastguard Worker__shift64ExtraRightJamming(uint a0, uint a1, uint a2,
405*61046927SAndroid Build Coastguard Worker                           int count,
406*61046927SAndroid Build Coastguard Worker                           out uint z0Ptr,
407*61046927SAndroid Build Coastguard Worker                           out uint z1Ptr,
408*61046927SAndroid Build Coastguard Worker                           out uint z2Ptr)
409*61046927SAndroid Build Coastguard Worker{
410*61046927SAndroid Build Coastguard Worker   uint z0 = 0u;
411*61046927SAndroid Build Coastguard Worker   uint z1;
412*61046927SAndroid Build Coastguard Worker   uint z2;
413*61046927SAndroid Build Coastguard Worker   int negCount = (-count) & 31;
414*61046927SAndroid Build Coastguard Worker
415*61046927SAndroid Build Coastguard Worker   z2 = mix(uint(a0 != 0u), a0, count == 64);
416*61046927SAndroid Build Coastguard Worker   z2 = mix(z2, a0 << negCount, count < 64);
417*61046927SAndroid Build Coastguard Worker   z2 = mix(z2, a1 << negCount, count < 32);
418*61046927SAndroid Build Coastguard Worker
419*61046927SAndroid Build Coastguard Worker   z1 = mix(0u, (a0 >> (count & 31)), count < 64);
420*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, (a0<<negCount) | (a1>>count), count < 32);
421*61046927SAndroid Build Coastguard Worker
422*61046927SAndroid Build Coastguard Worker   a2 = mix(a2 | a1, a2, count < 32);
423*61046927SAndroid Build Coastguard Worker   z0 = mix(z0, a0 >> count, count < 32);
424*61046927SAndroid Build Coastguard Worker   z2 |= uint(a2 != 0u);
425*61046927SAndroid Build Coastguard Worker
426*61046927SAndroid Build Coastguard Worker   z0 = mix(z0, 0u, (count == 32));
427*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, a0, (count == 32));
428*61046927SAndroid Build Coastguard Worker   z2 = mix(z2, a1, (count == 32));
429*61046927SAndroid Build Coastguard Worker   z0 = mix(z0, a0, (count == 0));
430*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, a1, (count == 0));
431*61046927SAndroid Build Coastguard Worker   z2 = mix(z2, a2, (count == 0));
432*61046927SAndroid Build Coastguard Worker   z2Ptr = z2;
433*61046927SAndroid Build Coastguard Worker   z1Ptr = z1;
434*61046927SAndroid Build Coastguard Worker   z0Ptr = z0;
435*61046927SAndroid Build Coastguard Worker}
436*61046927SAndroid Build Coastguard Worker
437*61046927SAndroid Build Coastguard Worker/* Shifts the 64-bit value formed by concatenating `a0' and `a1' left by the
438*61046927SAndroid Build Coastguard Worker * number of bits given in `count'.  Any bits shifted off are lost.  The value
439*61046927SAndroid Build Coastguard Worker * of `count' must be less than 32.  The result is broken into two 32-bit
440*61046927SAndroid Build Coastguard Worker * pieces which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
441*61046927SAndroid Build Coastguard Worker */
442*61046927SAndroid Build Coastguard Workervoid
443*61046927SAndroid Build Coastguard Worker__shortShift64Left(uint a0, uint a1,
444*61046927SAndroid Build Coastguard Worker                   int count,
445*61046927SAndroid Build Coastguard Worker                   out uint z0Ptr,
446*61046927SAndroid Build Coastguard Worker                   out uint z1Ptr)
447*61046927SAndroid Build Coastguard Worker{
448*61046927SAndroid Build Coastguard Worker   z1Ptr = a1<<count;
449*61046927SAndroid Build Coastguard Worker   z0Ptr = mix((a0 << count | (a1 >> ((-count) & 31))), a0, count == 0);
450*61046927SAndroid Build Coastguard Worker}
451*61046927SAndroid Build Coastguard Worker
452*61046927SAndroid Build Coastguard Worker/* Packs the sign `zSign', the exponent `zExp', and the significand formed by
453*61046927SAndroid Build Coastguard Worker * the concatenation of `zFrac0' and `zFrac1' into a double-precision floating-
454*61046927SAndroid Build Coastguard Worker * point value, returning the result.  After being shifted into the proper
455*61046927SAndroid Build Coastguard Worker * positions, the three fields `zSign', `zExp', and `zFrac0' are simply added
456*61046927SAndroid Build Coastguard Worker * together to form the most significant 32 bits of the result.  This means
457*61046927SAndroid Build Coastguard Worker * that any integer portion of `zFrac0' will be added into the exponent.  Since
458*61046927SAndroid Build Coastguard Worker * a properly normalized significand will have an integer portion equal to 1,
459*61046927SAndroid Build Coastguard Worker * the `zExp' input should be 1 less than the desired result exponent whenever
460*61046927SAndroid Build Coastguard Worker * `zFrac0' and `zFrac1' concatenated form a complete, normalized significand.
461*61046927SAndroid Build Coastguard Worker */
462*61046927SAndroid Build Coastguard Workeruint64_t
463*61046927SAndroid Build Coastguard Worker__packFloat64(uint zSign, int zExp, uint zFrac0, uint zFrac1)
464*61046927SAndroid Build Coastguard Worker{
465*61046927SAndroid Build Coastguard Worker   uvec2 z;
466*61046927SAndroid Build Coastguard Worker
467*61046927SAndroid Build Coastguard Worker   z.y = zSign + (uint(zExp) << 20) + zFrac0;
468*61046927SAndroid Build Coastguard Worker   z.x = zFrac1;
469*61046927SAndroid Build Coastguard Worker   return packUint2x32(z);
470*61046927SAndroid Build Coastguard Worker}
471*61046927SAndroid Build Coastguard Worker
472*61046927SAndroid Build Coastguard Worker/* Takes an abstract floating-point value having sign `zSign', exponent `zExp',
473*61046927SAndroid Build Coastguard Worker * and extended significand formed by the concatenation of `zFrac0', `zFrac1',
474*61046927SAndroid Build Coastguard Worker * and `zFrac2', and returns the proper double-precision floating-point value
475*61046927SAndroid Build Coastguard Worker * corresponding to the abstract input.  Ordinarily, the abstract value is
476*61046927SAndroid Build Coastguard Worker * simply rounded and packed into the double-precision format, with the inexact
477*61046927SAndroid Build Coastguard Worker * exception raised if the abstract input cannot be represented exactly.
478*61046927SAndroid Build Coastguard Worker * However, if the abstract value is too large, the overflow and inexact
479*61046927SAndroid Build Coastguard Worker * exceptions are raised and an infinity or maximal finite value is returned.
480*61046927SAndroid Build Coastguard Worker * If the abstract value is too small, the input value is rounded to a
481*61046927SAndroid Build Coastguard Worker * subnormal number, and the underflow and inexact exceptions are raised if the
482*61046927SAndroid Build Coastguard Worker * abstract input cannot be represented exactly as a subnormal double-precision
483*61046927SAndroid Build Coastguard Worker * floating-point number.
484*61046927SAndroid Build Coastguard Worker *     The input significand must be normalized or smaller.  If the input
485*61046927SAndroid Build Coastguard Worker * significand is not normalized, `zExp' must be 0; in that case, the result
486*61046927SAndroid Build Coastguard Worker * returned is a subnormal number, and it must not require rounding.  In the
487*61046927SAndroid Build Coastguard Worker * usual case that the input significand is normalized, `zExp' must be 1 less
488*61046927SAndroid Build Coastguard Worker * than the "true" floating-point exponent.  The handling of underflow and
489*61046927SAndroid Build Coastguard Worker * overflow follows the IEEE Standard for Floating-Point Arithmetic.
490*61046927SAndroid Build Coastguard Worker */
491*61046927SAndroid Build Coastguard Workeruint64_t
492*61046927SAndroid Build Coastguard Worker__roundAndPackFloat64(uint zSign,
493*61046927SAndroid Build Coastguard Worker                      int zExp,
494*61046927SAndroid Build Coastguard Worker                      uint zFrac0,
495*61046927SAndroid Build Coastguard Worker                      uint zFrac1,
496*61046927SAndroid Build Coastguard Worker                      uint zFrac2)
497*61046927SAndroid Build Coastguard Worker{
498*61046927SAndroid Build Coastguard Worker   bool roundNearestEven;
499*61046927SAndroid Build Coastguard Worker   bool increment;
500*61046927SAndroid Build Coastguard Worker
501*61046927SAndroid Build Coastguard Worker   roundNearestEven = FLOAT_ROUNDING_MODE == FLOAT_ROUND_NEAREST_EVEN;
502*61046927SAndroid Build Coastguard Worker   increment = int(zFrac2) < 0;
503*61046927SAndroid Build Coastguard Worker   if (!roundNearestEven) {
504*61046927SAndroid Build Coastguard Worker      if (FLOAT_ROUNDING_MODE == FLOAT_ROUND_TO_ZERO) {
505*61046927SAndroid Build Coastguard Worker         increment = false;
506*61046927SAndroid Build Coastguard Worker      } else {
507*61046927SAndroid Build Coastguard Worker         if (zSign != 0u) {
508*61046927SAndroid Build Coastguard Worker            increment = (FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN) &&
509*61046927SAndroid Build Coastguard Worker               (zFrac2 != 0u);
510*61046927SAndroid Build Coastguard Worker         } else {
511*61046927SAndroid Build Coastguard Worker            increment = (FLOAT_ROUNDING_MODE == FLOAT_ROUND_UP) &&
512*61046927SAndroid Build Coastguard Worker               (zFrac2 != 0u);
513*61046927SAndroid Build Coastguard Worker         }
514*61046927SAndroid Build Coastguard Worker      }
515*61046927SAndroid Build Coastguard Worker   }
516*61046927SAndroid Build Coastguard Worker   if (0x7FD <= zExp) {
517*61046927SAndroid Build Coastguard Worker      if ((0x7FD < zExp) ||
518*61046927SAndroid Build Coastguard Worker         ((zExp == 0x7FD) &&
519*61046927SAndroid Build Coastguard Worker            (0x001FFFFFu == zFrac0 && 0xFFFFFFFFu == zFrac1) &&
520*61046927SAndroid Build Coastguard Worker               increment)) {
521*61046927SAndroid Build Coastguard Worker         if ((FLOAT_ROUNDING_MODE == FLOAT_ROUND_TO_ZERO) ||
522*61046927SAndroid Build Coastguard Worker            ((zSign != 0u) && (FLOAT_ROUNDING_MODE == FLOAT_ROUND_UP)) ||
523*61046927SAndroid Build Coastguard Worker               ((zSign == 0u) && (FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN))) {
524*61046927SAndroid Build Coastguard Worker            return __packFloat64(zSign, 0x7FE, 0x000FFFFFu, 0xFFFFFFFFu);
525*61046927SAndroid Build Coastguard Worker         }
526*61046927SAndroid Build Coastguard Worker         return __packFloat64(zSign, 0x7FF, 0u, 0u);
527*61046927SAndroid Build Coastguard Worker      }
528*61046927SAndroid Build Coastguard Worker   }
529*61046927SAndroid Build Coastguard Worker
530*61046927SAndroid Build Coastguard Worker   if (zExp < 0) {
531*61046927SAndroid Build Coastguard Worker      __shift64ExtraRightJamming(
532*61046927SAndroid Build Coastguard Worker         zFrac0, zFrac1, zFrac2, -zExp, zFrac0, zFrac1, zFrac2);
533*61046927SAndroid Build Coastguard Worker      zExp = 0;
534*61046927SAndroid Build Coastguard Worker      if (roundNearestEven) {
535*61046927SAndroid Build Coastguard Worker         increment = zFrac2 < 0u;
536*61046927SAndroid Build Coastguard Worker      } else {
537*61046927SAndroid Build Coastguard Worker         if (zSign != 0u) {
538*61046927SAndroid Build Coastguard Worker            increment = (FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN) &&
539*61046927SAndroid Build Coastguard Worker               (zFrac2 != 0u);
540*61046927SAndroid Build Coastguard Worker         } else {
541*61046927SAndroid Build Coastguard Worker            increment = (FLOAT_ROUNDING_MODE == FLOAT_ROUND_UP) &&
542*61046927SAndroid Build Coastguard Worker               (zFrac2 != 0u);
543*61046927SAndroid Build Coastguard Worker         }
544*61046927SAndroid Build Coastguard Worker      }
545*61046927SAndroid Build Coastguard Worker   }
546*61046927SAndroid Build Coastguard Worker
547*61046927SAndroid Build Coastguard Worker   if (increment) {
548*61046927SAndroid Build Coastguard Worker      __add64(zFrac0, zFrac1, 0u, 1u, zFrac0, zFrac1);
549*61046927SAndroid Build Coastguard Worker      zFrac1 &= ~((zFrac2 + uint(zFrac2 == 0u)) & uint(roundNearestEven));
550*61046927SAndroid Build Coastguard Worker   } else {
551*61046927SAndroid Build Coastguard Worker      zExp = mix(zExp, 0, (zFrac0 | zFrac1) == 0u);
552*61046927SAndroid Build Coastguard Worker   }
553*61046927SAndroid Build Coastguard Worker   return __packFloat64(zSign, zExp, zFrac0, zFrac1);
554*61046927SAndroid Build Coastguard Worker}
555*61046927SAndroid Build Coastguard Worker
556*61046927SAndroid Build Coastguard Workeruint64_t
557*61046927SAndroid Build Coastguard Worker__roundAndPackUInt64(uint zSign, uint zFrac0, uint zFrac1, uint zFrac2)
558*61046927SAndroid Build Coastguard Worker{
559*61046927SAndroid Build Coastguard Worker   bool roundNearestEven;
560*61046927SAndroid Build Coastguard Worker   bool increment;
561*61046927SAndroid Build Coastguard Worker   uint64_t default_nan = 0xFFFFFFFFFFFFFFFFUL;
562*61046927SAndroid Build Coastguard Worker
563*61046927SAndroid Build Coastguard Worker   roundNearestEven = FLOAT_ROUNDING_MODE == FLOAT_ROUND_NEAREST_EVEN;
564*61046927SAndroid Build Coastguard Worker
565*61046927SAndroid Build Coastguard Worker   if (zFrac2 >= 0x80000000u)
566*61046927SAndroid Build Coastguard Worker      increment = false;
567*61046927SAndroid Build Coastguard Worker
568*61046927SAndroid Build Coastguard Worker   if (!roundNearestEven) {
569*61046927SAndroid Build Coastguard Worker      if (zSign != 0u) {
570*61046927SAndroid Build Coastguard Worker         if ((FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN) && (zFrac2 != 0u)) {
571*61046927SAndroid Build Coastguard Worker            increment = false;
572*61046927SAndroid Build Coastguard Worker         }
573*61046927SAndroid Build Coastguard Worker      } else {
574*61046927SAndroid Build Coastguard Worker         increment = (FLOAT_ROUNDING_MODE == FLOAT_ROUND_UP) &&
575*61046927SAndroid Build Coastguard Worker            (zFrac2 != 0u);
576*61046927SAndroid Build Coastguard Worker      }
577*61046927SAndroid Build Coastguard Worker   }
578*61046927SAndroid Build Coastguard Worker
579*61046927SAndroid Build Coastguard Worker   if (increment) {
580*61046927SAndroid Build Coastguard Worker      __add64(zFrac0, zFrac1, 0u, 1u, zFrac0, zFrac1);
581*61046927SAndroid Build Coastguard Worker      if ((zFrac0 | zFrac1) != 0u)
582*61046927SAndroid Build Coastguard Worker         zFrac1 &= ~(1u) + uint(zFrac2 == 0u) & uint(roundNearestEven);
583*61046927SAndroid Build Coastguard Worker   }
584*61046927SAndroid Build Coastguard Worker   return mix(packUint2x32(uvec2(zFrac1, zFrac0)), default_nan,
585*61046927SAndroid Build Coastguard Worker              (zSign != 0u && (zFrac0 | zFrac1) != 0u));
586*61046927SAndroid Build Coastguard Worker}
587*61046927SAndroid Build Coastguard Worker
588*61046927SAndroid Build Coastguard Workerint64_t
589*61046927SAndroid Build Coastguard Worker__roundAndPackInt64(uint zSign, uint zFrac0, uint zFrac1, uint zFrac2)
590*61046927SAndroid Build Coastguard Worker{
591*61046927SAndroid Build Coastguard Worker   bool roundNearestEven;
592*61046927SAndroid Build Coastguard Worker   bool increment;
593*61046927SAndroid Build Coastguard Worker   int64_t default_NegNaN = -0x7FFFFFFFFFFFFFFEL;
594*61046927SAndroid Build Coastguard Worker   int64_t default_PosNaN = 0xFFFFFFFFFFFFFFFFL;
595*61046927SAndroid Build Coastguard Worker
596*61046927SAndroid Build Coastguard Worker   roundNearestEven = FLOAT_ROUNDING_MODE == FLOAT_ROUND_NEAREST_EVEN;
597*61046927SAndroid Build Coastguard Worker
598*61046927SAndroid Build Coastguard Worker   if (zFrac2 >= 0x80000000u)
599*61046927SAndroid Build Coastguard Worker      increment = false;
600*61046927SAndroid Build Coastguard Worker
601*61046927SAndroid Build Coastguard Worker   if (!roundNearestEven) {
602*61046927SAndroid Build Coastguard Worker      if (zSign != 0u) {
603*61046927SAndroid Build Coastguard Worker         increment = ((FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN) &&
604*61046927SAndroid Build Coastguard Worker            (zFrac2 != 0u));
605*61046927SAndroid Build Coastguard Worker      } else {
606*61046927SAndroid Build Coastguard Worker         increment = (FLOAT_ROUNDING_MODE == FLOAT_ROUND_UP) &&
607*61046927SAndroid Build Coastguard Worker            (zFrac2 != 0u);
608*61046927SAndroid Build Coastguard Worker      }
609*61046927SAndroid Build Coastguard Worker   }
610*61046927SAndroid Build Coastguard Worker
611*61046927SAndroid Build Coastguard Worker   if (increment) {
612*61046927SAndroid Build Coastguard Worker      __add64(zFrac0, zFrac1, 0u, 1u, zFrac0, zFrac1);
613*61046927SAndroid Build Coastguard Worker      if ((zFrac0 | zFrac1) != 0u)
614*61046927SAndroid Build Coastguard Worker         zFrac1 &= ~(1u) + uint(zFrac2 == 0u) & uint(roundNearestEven);
615*61046927SAndroid Build Coastguard Worker   }
616*61046927SAndroid Build Coastguard Worker
617*61046927SAndroid Build Coastguard Worker   int64_t absZ = mix(int64_t(packUint2x32(uvec2(zFrac1, zFrac0))),
618*61046927SAndroid Build Coastguard Worker                      -int64_t(packUint2x32(uvec2(zFrac1, zFrac0))),
619*61046927SAndroid Build Coastguard Worker                      zSign != 0u);
620*61046927SAndroid Build Coastguard Worker   int64_t nan = mix(default_PosNaN, default_NegNaN, zSign != 0u);
621*61046927SAndroid Build Coastguard Worker   return mix(absZ, nan, ((zSign != 0u) != (absZ < 0)) && bool(absZ));
622*61046927SAndroid Build Coastguard Worker}
623*61046927SAndroid Build Coastguard Worker
624*61046927SAndroid Build Coastguard Worker/* Returns the number of leading 0 bits before the most-significant 1 bit of
625*61046927SAndroid Build Coastguard Worker * `a'.  If `a' is zero, 32 is returned.
626*61046927SAndroid Build Coastguard Worker */
627*61046927SAndroid Build Coastguard Workerint
628*61046927SAndroid Build Coastguard Worker__countLeadingZeros32(uint a)
629*61046927SAndroid Build Coastguard Worker{
630*61046927SAndroid Build Coastguard Worker   return 31 - findMSB(a);
631*61046927SAndroid Build Coastguard Worker}
632*61046927SAndroid Build Coastguard Worker
633*61046927SAndroid Build Coastguard Worker/* Takes an abstract floating-point value having sign `zSign', exponent `zExp',
634*61046927SAndroid Build Coastguard Worker * and significand formed by the concatenation of `zSig0' and `zSig1', and
635*61046927SAndroid Build Coastguard Worker * returns the proper double-precision floating-point value corresponding
636*61046927SAndroid Build Coastguard Worker * to the abstract input.  This routine is just like `__roundAndPackFloat64'
637*61046927SAndroid Build Coastguard Worker * except that the input significand has fewer bits and does not have to be
638*61046927SAndroid Build Coastguard Worker * normalized.  In all cases, `zExp' must be 1 less than the "true" floating-
639*61046927SAndroid Build Coastguard Worker * point exponent.
640*61046927SAndroid Build Coastguard Worker */
641*61046927SAndroid Build Coastguard Workeruint64_t
642*61046927SAndroid Build Coastguard Worker__normalizeRoundAndPackFloat64(uint zSign,
643*61046927SAndroid Build Coastguard Worker                               int zExp,
644*61046927SAndroid Build Coastguard Worker                               uint zFrac0,
645*61046927SAndroid Build Coastguard Worker                               uint zFrac1)
646*61046927SAndroid Build Coastguard Worker{
647*61046927SAndroid Build Coastguard Worker   int shiftCount;
648*61046927SAndroid Build Coastguard Worker   uint zFrac2;
649*61046927SAndroid Build Coastguard Worker
650*61046927SAndroid Build Coastguard Worker   if (zFrac0 == 0u) {
651*61046927SAndroid Build Coastguard Worker      zExp -= 32;
652*61046927SAndroid Build Coastguard Worker      zFrac0 = zFrac1;
653*61046927SAndroid Build Coastguard Worker      zFrac1 = 0u;
654*61046927SAndroid Build Coastguard Worker   }
655*61046927SAndroid Build Coastguard Worker
656*61046927SAndroid Build Coastguard Worker   shiftCount = __countLeadingZeros32(zFrac0) - 11;
657*61046927SAndroid Build Coastguard Worker   if (0 <= shiftCount) {
658*61046927SAndroid Build Coastguard Worker      zFrac2 = 0u;
659*61046927SAndroid Build Coastguard Worker      __shortShift64Left(zFrac0, zFrac1, shiftCount, zFrac0, zFrac1);
660*61046927SAndroid Build Coastguard Worker   } else {
661*61046927SAndroid Build Coastguard Worker      __shift64ExtraRightJamming(
662*61046927SAndroid Build Coastguard Worker         zFrac0, zFrac1, 0u, -shiftCount, zFrac0, zFrac1, zFrac2);
663*61046927SAndroid Build Coastguard Worker   }
664*61046927SAndroid Build Coastguard Worker   zExp -= shiftCount;
665*61046927SAndroid Build Coastguard Worker   return __roundAndPackFloat64(zSign, zExp, zFrac0, zFrac1, zFrac2);
666*61046927SAndroid Build Coastguard Worker}
667*61046927SAndroid Build Coastguard Worker
668*61046927SAndroid Build Coastguard Worker/* Takes two double-precision floating-point values `a' and `b', one of which
669*61046927SAndroid Build Coastguard Worker * is a NaN, and returns the appropriate NaN result.
670*61046927SAndroid Build Coastguard Worker */
671*61046927SAndroid Build Coastguard Workeruint64_t
672*61046927SAndroid Build Coastguard Worker__propagateFloat64NaN(uint64_t __a, uint64_t __b)
673*61046927SAndroid Build Coastguard Worker{
674*61046927SAndroid Build Coastguard Worker#if defined RELAXED_NAN_PROPAGATION
675*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
676*61046927SAndroid Build Coastguard Worker   uvec2 b = unpackUint2x32(__b);
677*61046927SAndroid Build Coastguard Worker
678*61046927SAndroid Build Coastguard Worker   return packUint2x32(uvec2(a.x | b.x, a.y | b.y));
679*61046927SAndroid Build Coastguard Worker#else
680*61046927SAndroid Build Coastguard Worker   bool aIsNaN = __is_nan(__a);
681*61046927SAndroid Build Coastguard Worker   bool bIsNaN = __is_nan(__b);
682*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
683*61046927SAndroid Build Coastguard Worker   uvec2 b = unpackUint2x32(__b);
684*61046927SAndroid Build Coastguard Worker   a.y |= 0x00080000u;
685*61046927SAndroid Build Coastguard Worker   b.y |= 0x00080000u;
686*61046927SAndroid Build Coastguard Worker
687*61046927SAndroid Build Coastguard Worker   return packUint2x32(mix(b, mix(a, b, bvec2(bIsNaN, bIsNaN)), bvec2(aIsNaN, aIsNaN)));
688*61046927SAndroid Build Coastguard Worker#endif
689*61046927SAndroid Build Coastguard Worker}
690*61046927SAndroid Build Coastguard Worker
691*61046927SAndroid Build Coastguard Worker/* If a shader is in the soft-fp64 path, it almost certainly has register
692*61046927SAndroid Build Coastguard Worker * pressure problems.  Choose a method to exchange two values that does not
693*61046927SAndroid Build Coastguard Worker * require a temporary.
694*61046927SAndroid Build Coastguard Worker */
695*61046927SAndroid Build Coastguard Worker#define EXCHANGE(a, b) \
696*61046927SAndroid Build Coastguard Worker   do {                \
697*61046927SAndroid Build Coastguard Worker       a ^= b;         \
698*61046927SAndroid Build Coastguard Worker       b ^= a;         \
699*61046927SAndroid Build Coastguard Worker       a ^= b;         \
700*61046927SAndroid Build Coastguard Worker   } while (false)
701*61046927SAndroid Build Coastguard Worker
702*61046927SAndroid Build Coastguard Worker/* Returns the result of adding the double-precision floating-point values
703*61046927SAndroid Build Coastguard Worker * `a' and `b'.  The operation is performed according to the IEEE Standard for
704*61046927SAndroid Build Coastguard Worker * Floating-Point Arithmetic.
705*61046927SAndroid Build Coastguard Worker */
706*61046927SAndroid Build Coastguard Workeruint64_t
707*61046927SAndroid Build Coastguard Worker__fadd64(uint64_t a, uint64_t b)
708*61046927SAndroid Build Coastguard Worker{
709*61046927SAndroid Build Coastguard Worker   uint aSign = __extractFloat64Sign(a);
710*61046927SAndroid Build Coastguard Worker   uint bSign = __extractFloat64Sign(b);
711*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(a);
712*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(a);
713*61046927SAndroid Build Coastguard Worker   uint bFracLo = __extractFloat64FracLo(b);
714*61046927SAndroid Build Coastguard Worker   uint bFracHi = __extractFloat64FracHi(b);
715*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(a);
716*61046927SAndroid Build Coastguard Worker   int bExp = __extractFloat64Exp(b);
717*61046927SAndroid Build Coastguard Worker   int expDiff = aExp - bExp;
718*61046927SAndroid Build Coastguard Worker   if (aSign == bSign) {
719*61046927SAndroid Build Coastguard Worker      uint zFrac0;
720*61046927SAndroid Build Coastguard Worker      uint zFrac1;
721*61046927SAndroid Build Coastguard Worker      uint zFrac2;
722*61046927SAndroid Build Coastguard Worker      int zExp;
723*61046927SAndroid Build Coastguard Worker
724*61046927SAndroid Build Coastguard Worker      if (expDiff == 0) {
725*61046927SAndroid Build Coastguard Worker         if (aExp == 0x7FF) {
726*61046927SAndroid Build Coastguard Worker            bool propagate = ((aFracHi | bFracHi) | (aFracLo| bFracLo)) != 0u;
727*61046927SAndroid Build Coastguard Worker            return mix(a, __propagateFloat64NaN(a, b), propagate);
728*61046927SAndroid Build Coastguard Worker         }
729*61046927SAndroid Build Coastguard Worker         __add64(aFracHi, aFracLo, bFracHi, bFracLo, zFrac0, zFrac1);
730*61046927SAndroid Build Coastguard Worker         if (aExp == 0)
731*61046927SAndroid Build Coastguard Worker            return __packFloat64(aSign, 0, zFrac0, zFrac1);
732*61046927SAndroid Build Coastguard Worker         zFrac2 = 0u;
733*61046927SAndroid Build Coastguard Worker         zFrac0 |= 0x00200000u;
734*61046927SAndroid Build Coastguard Worker         zExp = aExp;
735*61046927SAndroid Build Coastguard Worker         __shift64ExtraRightJamming(
736*61046927SAndroid Build Coastguard Worker            zFrac0, zFrac1, zFrac2, 1, zFrac0, zFrac1, zFrac2);
737*61046927SAndroid Build Coastguard Worker      } else {
738*61046927SAndroid Build Coastguard Worker         if (expDiff < 0) {
739*61046927SAndroid Build Coastguard Worker            EXCHANGE(aFracHi, bFracHi);
740*61046927SAndroid Build Coastguard Worker            EXCHANGE(aFracLo, bFracLo);
741*61046927SAndroid Build Coastguard Worker            EXCHANGE(aExp, bExp);
742*61046927SAndroid Build Coastguard Worker         }
743*61046927SAndroid Build Coastguard Worker
744*61046927SAndroid Build Coastguard Worker         if (aExp == 0x7FF) {
745*61046927SAndroid Build Coastguard Worker            bool propagate = (aFracHi | aFracLo) != 0u;
746*61046927SAndroid Build Coastguard Worker            return mix(__packFloat64(aSign, 0x7ff, 0u, 0u), __propagateFloat64NaN(a, b), propagate);
747*61046927SAndroid Build Coastguard Worker         }
748*61046927SAndroid Build Coastguard Worker
749*61046927SAndroid Build Coastguard Worker         expDiff = mix(abs(expDiff), abs(expDiff) - 1, bExp == 0);
750*61046927SAndroid Build Coastguard Worker         bFracHi = mix(bFracHi | 0x00100000u, bFracHi, bExp == 0);
751*61046927SAndroid Build Coastguard Worker         __shift64ExtraRightJamming(
752*61046927SAndroid Build Coastguard Worker            bFracHi, bFracLo, 0u, expDiff, bFracHi, bFracLo, zFrac2);
753*61046927SAndroid Build Coastguard Worker         zExp = aExp;
754*61046927SAndroid Build Coastguard Worker
755*61046927SAndroid Build Coastguard Worker         aFracHi |= 0x00100000u;
756*61046927SAndroid Build Coastguard Worker         __add64(aFracHi, aFracLo, bFracHi, bFracLo, zFrac0, zFrac1);
757*61046927SAndroid Build Coastguard Worker         --zExp;
758*61046927SAndroid Build Coastguard Worker         if (!(zFrac0 < 0x00200000u)) {
759*61046927SAndroid Build Coastguard Worker            __shift64ExtraRightJamming(zFrac0, zFrac1, zFrac2, 1, zFrac0, zFrac1, zFrac2);
760*61046927SAndroid Build Coastguard Worker            ++zExp;
761*61046927SAndroid Build Coastguard Worker         }
762*61046927SAndroid Build Coastguard Worker      }
763*61046927SAndroid Build Coastguard Worker      return __roundAndPackFloat64(aSign, zExp, zFrac0, zFrac1, zFrac2);
764*61046927SAndroid Build Coastguard Worker
765*61046927SAndroid Build Coastguard Worker   } else {
766*61046927SAndroid Build Coastguard Worker      int zExp;
767*61046927SAndroid Build Coastguard Worker
768*61046927SAndroid Build Coastguard Worker      __shortShift64Left(aFracHi, aFracLo, 10, aFracHi, aFracLo);
769*61046927SAndroid Build Coastguard Worker      __shortShift64Left(bFracHi, bFracLo, 10, bFracHi, bFracLo);
770*61046927SAndroid Build Coastguard Worker      if (expDiff != 0) {
771*61046927SAndroid Build Coastguard Worker         uint zFrac0;
772*61046927SAndroid Build Coastguard Worker         uint zFrac1;
773*61046927SAndroid Build Coastguard Worker
774*61046927SAndroid Build Coastguard Worker         if (expDiff < 0) {
775*61046927SAndroid Build Coastguard Worker            EXCHANGE(aFracHi, bFracHi);
776*61046927SAndroid Build Coastguard Worker            EXCHANGE(aFracLo, bFracLo);
777*61046927SAndroid Build Coastguard Worker            EXCHANGE(aExp, bExp);
778*61046927SAndroid Build Coastguard Worker            aSign ^= 0x80000000u;
779*61046927SAndroid Build Coastguard Worker         }
780*61046927SAndroid Build Coastguard Worker
781*61046927SAndroid Build Coastguard Worker         if (aExp == 0x7FF) {
782*61046927SAndroid Build Coastguard Worker            bool propagate = (aFracHi | aFracLo) != 0u;
783*61046927SAndroid Build Coastguard Worker            return mix(__packFloat64(aSign, 0x7ff, 0u, 0u), __propagateFloat64NaN(a, b), propagate);
784*61046927SAndroid Build Coastguard Worker         }
785*61046927SAndroid Build Coastguard Worker
786*61046927SAndroid Build Coastguard Worker         expDiff = mix(abs(expDiff), abs(expDiff) - 1, bExp == 0);
787*61046927SAndroid Build Coastguard Worker         bFracHi = mix(bFracHi | 0x40000000u, bFracHi, bExp == 0);
788*61046927SAndroid Build Coastguard Worker         __shift64RightJamming(bFracHi, bFracLo, expDiff, bFracHi, bFracLo);
789*61046927SAndroid Build Coastguard Worker         aFracHi |= 0x40000000u;
790*61046927SAndroid Build Coastguard Worker         __sub64(aFracHi, aFracLo, bFracHi, bFracLo, zFrac0, zFrac1);
791*61046927SAndroid Build Coastguard Worker         zExp = aExp;
792*61046927SAndroid Build Coastguard Worker         --zExp;
793*61046927SAndroid Build Coastguard Worker         return __normalizeRoundAndPackFloat64(aSign, zExp - 10, zFrac0, zFrac1);
794*61046927SAndroid Build Coastguard Worker      }
795*61046927SAndroid Build Coastguard Worker      if (aExp == 0x7FF) {
796*61046927SAndroid Build Coastguard Worker         bool propagate = ((aFracHi | bFracHi) | (aFracLo | bFracLo)) != 0u;
797*61046927SAndroid Build Coastguard Worker         return mix(0xFFFFFFFFFFFFFFFFUL, __propagateFloat64NaN(a, b), propagate);
798*61046927SAndroid Build Coastguard Worker      }
799*61046927SAndroid Build Coastguard Worker      bExp = mix(bExp, 1, aExp == 0);
800*61046927SAndroid Build Coastguard Worker      aExp = mix(aExp, 1, aExp == 0);
801*61046927SAndroid Build Coastguard Worker
802*61046927SAndroid Build Coastguard Worker      uint zFrac0;
803*61046927SAndroid Build Coastguard Worker      uint zFrac1;
804*61046927SAndroid Build Coastguard Worker      uint sign_of_difference = 0;
805*61046927SAndroid Build Coastguard Worker      if (bFracHi < aFracHi) {
806*61046927SAndroid Build Coastguard Worker         __sub64(aFracHi, aFracLo, bFracHi, bFracLo, zFrac0, zFrac1);
807*61046927SAndroid Build Coastguard Worker      }
808*61046927SAndroid Build Coastguard Worker      else if (aFracHi < bFracHi) {
809*61046927SAndroid Build Coastguard Worker         __sub64(bFracHi, bFracLo, aFracHi, aFracLo, zFrac0, zFrac1);
810*61046927SAndroid Build Coastguard Worker         sign_of_difference = 0x80000000;
811*61046927SAndroid Build Coastguard Worker      }
812*61046927SAndroid Build Coastguard Worker      else if (bFracLo <= aFracLo) {
813*61046927SAndroid Build Coastguard Worker         /* It is possible that zFrac0 and zFrac1 may be zero after this. */
814*61046927SAndroid Build Coastguard Worker         __sub64(aFracHi, aFracLo, bFracHi, bFracLo, zFrac0, zFrac1);
815*61046927SAndroid Build Coastguard Worker      }
816*61046927SAndroid Build Coastguard Worker      else {
817*61046927SAndroid Build Coastguard Worker         __sub64(bFracHi, bFracLo, aFracHi, aFracLo, zFrac0, zFrac1);
818*61046927SAndroid Build Coastguard Worker         sign_of_difference = 0x80000000;
819*61046927SAndroid Build Coastguard Worker      }
820*61046927SAndroid Build Coastguard Worker      zExp = mix(bExp, aExp, sign_of_difference == 0u);
821*61046927SAndroid Build Coastguard Worker      aSign ^= sign_of_difference;
822*61046927SAndroid Build Coastguard Worker      uint64_t retval_0 = __packFloat64(uint(FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN) << 31, 0, 0u, 0u);
823*61046927SAndroid Build Coastguard Worker      uint64_t retval_1 = __normalizeRoundAndPackFloat64(aSign, zExp - 11, zFrac0, zFrac1);
824*61046927SAndroid Build Coastguard Worker      return mix(retval_0, retval_1, zFrac0 != 0u || zFrac1 != 0u);
825*61046927SAndroid Build Coastguard Worker   }
826*61046927SAndroid Build Coastguard Worker}
827*61046927SAndroid Build Coastguard Worker
828*61046927SAndroid Build Coastguard Worker/* Multiplies the 64-bit value formed by concatenating `a0' and `a1' to the
829*61046927SAndroid Build Coastguard Worker * 64-bit value formed by concatenating `b0' and `b1' to obtain a 128-bit
830*61046927SAndroid Build Coastguard Worker * product.  The product is broken into four 32-bit pieces which are stored at
831*61046927SAndroid Build Coastguard Worker * the locations pointed to by `z0Ptr', `z1Ptr', `z2Ptr', and `z3Ptr'.
832*61046927SAndroid Build Coastguard Worker */
833*61046927SAndroid Build Coastguard Workervoid
834*61046927SAndroid Build Coastguard Worker__mul64To128(uint a0, uint a1, uint b0, uint b1,
835*61046927SAndroid Build Coastguard Worker             out uint z0Ptr,
836*61046927SAndroid Build Coastguard Worker             out uint z1Ptr,
837*61046927SAndroid Build Coastguard Worker             out uint z2Ptr,
838*61046927SAndroid Build Coastguard Worker             out uint z3Ptr)
839*61046927SAndroid Build Coastguard Worker{
840*61046927SAndroid Build Coastguard Worker   uint z0 = 0u;
841*61046927SAndroid Build Coastguard Worker   uint z1 = 0u;
842*61046927SAndroid Build Coastguard Worker   uint z2 = 0u;
843*61046927SAndroid Build Coastguard Worker   uint z3 = 0u;
844*61046927SAndroid Build Coastguard Worker   uint more1 = 0u;
845*61046927SAndroid Build Coastguard Worker   uint more2 = 0u;
846*61046927SAndroid Build Coastguard Worker
847*61046927SAndroid Build Coastguard Worker   umulExtended(a1, b1, z2, z3);
848*61046927SAndroid Build Coastguard Worker   umulExtended(a1, b0, z1, more2);
849*61046927SAndroid Build Coastguard Worker   __add64(z1, more2, 0u, z2, z1, z2);
850*61046927SAndroid Build Coastguard Worker   umulExtended(a0, b0, z0, more1);
851*61046927SAndroid Build Coastguard Worker   __add64(z0, more1, 0u, z1, z0, z1);
852*61046927SAndroid Build Coastguard Worker   umulExtended(a0, b1, more1, more2);
853*61046927SAndroid Build Coastguard Worker   __add64(more1, more2, 0u, z2, more1, z2);
854*61046927SAndroid Build Coastguard Worker   __add64(z0, z1, 0u, more1, z0, z1);
855*61046927SAndroid Build Coastguard Worker   z3Ptr = z3;
856*61046927SAndroid Build Coastguard Worker   z2Ptr = z2;
857*61046927SAndroid Build Coastguard Worker   z1Ptr = z1;
858*61046927SAndroid Build Coastguard Worker   z0Ptr = z0;
859*61046927SAndroid Build Coastguard Worker}
860*61046927SAndroid Build Coastguard Worker
861*61046927SAndroid Build Coastguard Worker/* Normalizes the subnormal double-precision floating-point value represented
862*61046927SAndroid Build Coastguard Worker * by the denormalized significand formed by the concatenation of `aFrac0' and
863*61046927SAndroid Build Coastguard Worker * `aFrac1'.  The normalized exponent is stored at the location pointed to by
864*61046927SAndroid Build Coastguard Worker * `zExpPtr'.  The most significant 21 bits of the normalized significand are
865*61046927SAndroid Build Coastguard Worker * stored at the location pointed to by `zFrac0Ptr', and the least significant
866*61046927SAndroid Build Coastguard Worker * 32 bits of the normalized significand are stored at the location pointed to
867*61046927SAndroid Build Coastguard Worker * by `zFrac1Ptr'.
868*61046927SAndroid Build Coastguard Worker */
869*61046927SAndroid Build Coastguard Workervoid
870*61046927SAndroid Build Coastguard Worker__normalizeFloat64Subnormal(uint aFrac0, uint aFrac1,
871*61046927SAndroid Build Coastguard Worker                            out int zExpPtr,
872*61046927SAndroid Build Coastguard Worker                            out uint zFrac0Ptr,
873*61046927SAndroid Build Coastguard Worker                            out uint zFrac1Ptr)
874*61046927SAndroid Build Coastguard Worker{
875*61046927SAndroid Build Coastguard Worker   int shiftCount;
876*61046927SAndroid Build Coastguard Worker   uint temp_zfrac0, temp_zfrac1;
877*61046927SAndroid Build Coastguard Worker   shiftCount = __countLeadingZeros32(mix(aFrac0, aFrac1, aFrac0 == 0u)) - 11;
878*61046927SAndroid Build Coastguard Worker   zExpPtr = mix(1 - shiftCount, -shiftCount - 31, aFrac0 == 0u);
879*61046927SAndroid Build Coastguard Worker
880*61046927SAndroid Build Coastguard Worker   temp_zfrac0 = mix(aFrac1<<shiftCount, aFrac1>>(-shiftCount), shiftCount < 0);
881*61046927SAndroid Build Coastguard Worker   temp_zfrac1 = mix(0u, aFrac1<<(shiftCount & 31), shiftCount < 0);
882*61046927SAndroid Build Coastguard Worker
883*61046927SAndroid Build Coastguard Worker   __shortShift64Left(aFrac0, aFrac1, shiftCount, zFrac0Ptr, zFrac1Ptr);
884*61046927SAndroid Build Coastguard Worker
885*61046927SAndroid Build Coastguard Worker   zFrac0Ptr = mix(zFrac0Ptr, temp_zfrac0, aFrac0 == 0);
886*61046927SAndroid Build Coastguard Worker   zFrac1Ptr = mix(zFrac1Ptr, temp_zfrac1, aFrac0 == 0);
887*61046927SAndroid Build Coastguard Worker}
888*61046927SAndroid Build Coastguard Worker
889*61046927SAndroid Build Coastguard Worker/* Returns the result of multiplying the double-precision floating-point values
890*61046927SAndroid Build Coastguard Worker * `a' and `b'.  The operation is performed according to the IEEE Standard for
891*61046927SAndroid Build Coastguard Worker * Floating-Point Arithmetic.
892*61046927SAndroid Build Coastguard Worker */
893*61046927SAndroid Build Coastguard Workeruint64_t
894*61046927SAndroid Build Coastguard Worker__fmul64(uint64_t a, uint64_t b)
895*61046927SAndroid Build Coastguard Worker{
896*61046927SAndroid Build Coastguard Worker   uint zFrac0 = 0u;
897*61046927SAndroid Build Coastguard Worker   uint zFrac1 = 0u;
898*61046927SAndroid Build Coastguard Worker   uint zFrac2 = 0u;
899*61046927SAndroid Build Coastguard Worker   uint zFrac3 = 0u;
900*61046927SAndroid Build Coastguard Worker   int zExp;
901*61046927SAndroid Build Coastguard Worker
902*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(a);
903*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(a);
904*61046927SAndroid Build Coastguard Worker   uint bFracLo = __extractFloat64FracLo(b);
905*61046927SAndroid Build Coastguard Worker   uint bFracHi = __extractFloat64FracHi(b);
906*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(a);
907*61046927SAndroid Build Coastguard Worker   uint aSign = __extractFloat64Sign(a);
908*61046927SAndroid Build Coastguard Worker   int bExp = __extractFloat64Exp(b);
909*61046927SAndroid Build Coastguard Worker   uint bSign = __extractFloat64Sign(b);
910*61046927SAndroid Build Coastguard Worker   uint zSign = aSign ^ bSign;
911*61046927SAndroid Build Coastguard Worker   if (aExp == 0x7FF) {
912*61046927SAndroid Build Coastguard Worker      if (((aFracHi | aFracLo) != 0u) ||
913*61046927SAndroid Build Coastguard Worker         ((bExp == 0x7FF) && ((bFracHi | bFracLo) != 0u))) {
914*61046927SAndroid Build Coastguard Worker         return __propagateFloat64NaN(a, b);
915*61046927SAndroid Build Coastguard Worker      }
916*61046927SAndroid Build Coastguard Worker      if ((uint(bExp) | bFracHi | bFracLo) == 0u)
917*61046927SAndroid Build Coastguard Worker            return 0xFFFFFFFFFFFFFFFFUL;
918*61046927SAndroid Build Coastguard Worker      return __packFloat64(zSign, 0x7FF, 0u, 0u);
919*61046927SAndroid Build Coastguard Worker   }
920*61046927SAndroid Build Coastguard Worker   if (bExp == 0x7FF) {
921*61046927SAndroid Build Coastguard Worker      /* a cannot be NaN, but is b NaN? */
922*61046927SAndroid Build Coastguard Worker      if ((bFracHi | bFracLo) != 0u)
923*61046927SAndroid Build Coastguard Worker#if defined RELAXED_NAN_PROPAGATION
924*61046927SAndroid Build Coastguard Worker         return b;
925*61046927SAndroid Build Coastguard Worker#else
926*61046927SAndroid Build Coastguard Worker         return __propagateFloat64NaN(a, b);
927*61046927SAndroid Build Coastguard Worker#endif
928*61046927SAndroid Build Coastguard Worker      if ((uint(aExp) | aFracHi | aFracLo) == 0u)
929*61046927SAndroid Build Coastguard Worker         return 0xFFFFFFFFFFFFFFFFUL;
930*61046927SAndroid Build Coastguard Worker      return __packFloat64(zSign, 0x7FF, 0u, 0u);
931*61046927SAndroid Build Coastguard Worker   }
932*61046927SAndroid Build Coastguard Worker   if (aExp == 0) {
933*61046927SAndroid Build Coastguard Worker      if ((aFracHi | aFracLo) == 0u)
934*61046927SAndroid Build Coastguard Worker         return __packFloat64(zSign, 0, 0u, 0u);
935*61046927SAndroid Build Coastguard Worker      __normalizeFloat64Subnormal(aFracHi, aFracLo, aExp, aFracHi, aFracLo);
936*61046927SAndroid Build Coastguard Worker   }
937*61046927SAndroid Build Coastguard Worker   if (bExp == 0) {
938*61046927SAndroid Build Coastguard Worker      if ((bFracHi | bFracLo) == 0u)
939*61046927SAndroid Build Coastguard Worker         return __packFloat64(zSign, 0, 0u, 0u);
940*61046927SAndroid Build Coastguard Worker      __normalizeFloat64Subnormal(bFracHi, bFracLo, bExp, bFracHi, bFracLo);
941*61046927SAndroid Build Coastguard Worker   }
942*61046927SAndroid Build Coastguard Worker   zExp = aExp + bExp - 0x400;
943*61046927SAndroid Build Coastguard Worker   aFracHi |= 0x00100000u;
944*61046927SAndroid Build Coastguard Worker   __shortShift64Left(bFracHi, bFracLo, 12, bFracHi, bFracLo);
945*61046927SAndroid Build Coastguard Worker   __mul64To128(
946*61046927SAndroid Build Coastguard Worker      aFracHi, aFracLo, bFracHi, bFracLo, zFrac0, zFrac1, zFrac2, zFrac3);
947*61046927SAndroid Build Coastguard Worker   __add64(zFrac0, zFrac1, aFracHi, aFracLo, zFrac0, zFrac1);
948*61046927SAndroid Build Coastguard Worker   zFrac2 |= uint(zFrac3 != 0u);
949*61046927SAndroid Build Coastguard Worker   if (0x00200000u <= zFrac0) {
950*61046927SAndroid Build Coastguard Worker      __shift64ExtraRightJamming(
951*61046927SAndroid Build Coastguard Worker         zFrac0, zFrac1, zFrac2, 1, zFrac0, zFrac1, zFrac2);
952*61046927SAndroid Build Coastguard Worker      ++zExp;
953*61046927SAndroid Build Coastguard Worker   }
954*61046927SAndroid Build Coastguard Worker   return __roundAndPackFloat64(zSign, zExp, zFrac0, zFrac1, zFrac2);
955*61046927SAndroid Build Coastguard Worker}
956*61046927SAndroid Build Coastguard Worker
957*61046927SAndroid Build Coastguard Workeruint64_t
958*61046927SAndroid Build Coastguard Worker__ffma64(uint64_t a, uint64_t b, uint64_t c)
959*61046927SAndroid Build Coastguard Worker{
960*61046927SAndroid Build Coastguard Worker   return __fadd64(__fmul64(a, b), c);
961*61046927SAndroid Build Coastguard Worker}
962*61046927SAndroid Build Coastguard Worker
963*61046927SAndroid Build Coastguard Worker/* Shifts the 64-bit value formed by concatenating `a0' and `a1' right by the
964*61046927SAndroid Build Coastguard Worker * number of bits given in `count'.  Any bits shifted off are lost.  The value
965*61046927SAndroid Build Coastguard Worker * of `count' can be arbitrarily large; in particular, if `count' is greater
966*61046927SAndroid Build Coastguard Worker * than 64, the result will be 0.  The result is broken into two 32-bit pieces
967*61046927SAndroid Build Coastguard Worker * which are stored at the locations pointed to by `z0Ptr' and `z1Ptr'.
968*61046927SAndroid Build Coastguard Worker */
969*61046927SAndroid Build Coastguard Workervoid
970*61046927SAndroid Build Coastguard Worker__shift64Right(uint a0, uint a1,
971*61046927SAndroid Build Coastguard Worker               int count,
972*61046927SAndroid Build Coastguard Worker               out uint z0Ptr,
973*61046927SAndroid Build Coastguard Worker               out uint z1Ptr)
974*61046927SAndroid Build Coastguard Worker{
975*61046927SAndroid Build Coastguard Worker   uint z0;
976*61046927SAndroid Build Coastguard Worker   uint z1;
977*61046927SAndroid Build Coastguard Worker   int negCount = (-count) & 31;
978*61046927SAndroid Build Coastguard Worker
979*61046927SAndroid Build Coastguard Worker   z0 = 0u;
980*61046927SAndroid Build Coastguard Worker   z0 = mix(z0, (a0 >> count), count < 32);
981*61046927SAndroid Build Coastguard Worker   z0 = mix(z0, a0, count == 0);
982*61046927SAndroid Build Coastguard Worker
983*61046927SAndroid Build Coastguard Worker   z1 = mix(0u, (a0 >> (count & 31)), count < 64);
984*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, (a0<<negCount) | (a1>>count), count < 32);
985*61046927SAndroid Build Coastguard Worker   z1 = mix(z1, a0, count == 0);
986*61046927SAndroid Build Coastguard Worker
987*61046927SAndroid Build Coastguard Worker   z1Ptr = z1;
988*61046927SAndroid Build Coastguard Worker   z0Ptr = z0;
989*61046927SAndroid Build Coastguard Worker}
990*61046927SAndroid Build Coastguard Worker
991*61046927SAndroid Build Coastguard Worker/* Returns the result of converting the double-precision floating-point value
992*61046927SAndroid Build Coastguard Worker * `a' to the unsigned integer format.  The conversion is performed according
993*61046927SAndroid Build Coastguard Worker * to the IEEE Standard for Floating-Point Arithmetic.
994*61046927SAndroid Build Coastguard Worker */
995*61046927SAndroid Build Coastguard Workeruint
996*61046927SAndroid Build Coastguard Worker__fp64_to_uint(uint64_t a)
997*61046927SAndroid Build Coastguard Worker{
998*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(a);
999*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(a);
1000*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(a);
1001*61046927SAndroid Build Coastguard Worker   uint aSign = __extractFloat64Sign(a);
1002*61046927SAndroid Build Coastguard Worker
1003*61046927SAndroid Build Coastguard Worker   if ((aExp == 0x7FF) && ((aFracHi | aFracLo) != 0u))
1004*61046927SAndroid Build Coastguard Worker      return 0xFFFFFFFFu;
1005*61046927SAndroid Build Coastguard Worker
1006*61046927SAndroid Build Coastguard Worker   aFracHi |= mix(0u, 0x00100000u, aExp != 0);
1007*61046927SAndroid Build Coastguard Worker
1008*61046927SAndroid Build Coastguard Worker   int shiftDist = 0x427 - aExp;
1009*61046927SAndroid Build Coastguard Worker   if (0 < shiftDist)
1010*61046927SAndroid Build Coastguard Worker      __shift64RightJamming(aFracHi, aFracLo, shiftDist, aFracHi, aFracLo);
1011*61046927SAndroid Build Coastguard Worker
1012*61046927SAndroid Build Coastguard Worker   if ((aFracHi & 0xFFFFF000u) != 0u)
1013*61046927SAndroid Build Coastguard Worker      return mix(~0u, 0u, aSign != 0u);
1014*61046927SAndroid Build Coastguard Worker
1015*61046927SAndroid Build Coastguard Worker   uint z = 0u;
1016*61046927SAndroid Build Coastguard Worker   uint zero = 0u;
1017*61046927SAndroid Build Coastguard Worker   __shift64Right(aFracHi, aFracLo, 12, zero, z);
1018*61046927SAndroid Build Coastguard Worker
1019*61046927SAndroid Build Coastguard Worker   uint expt = mix(~0u, 0u, aSign != 0u);
1020*61046927SAndroid Build Coastguard Worker
1021*61046927SAndroid Build Coastguard Worker   return mix(z, expt, (aSign != 0u) && (z != 0u));
1022*61046927SAndroid Build Coastguard Worker}
1023*61046927SAndroid Build Coastguard Worker
1024*61046927SAndroid Build Coastguard Workeruint64_t
1025*61046927SAndroid Build Coastguard Worker__uint_to_fp64(uint a)
1026*61046927SAndroid Build Coastguard Worker{
1027*61046927SAndroid Build Coastguard Worker   if (a == 0u)
1028*61046927SAndroid Build Coastguard Worker      return 0ul;
1029*61046927SAndroid Build Coastguard Worker
1030*61046927SAndroid Build Coastguard Worker   int shiftDist = __countLeadingZeros32(a) + 21;
1031*61046927SAndroid Build Coastguard Worker
1032*61046927SAndroid Build Coastguard Worker   uint aHigh = 0u;
1033*61046927SAndroid Build Coastguard Worker   uint aLow = 0u;
1034*61046927SAndroid Build Coastguard Worker   int negCount = (- shiftDist) & 31;
1035*61046927SAndroid Build Coastguard Worker
1036*61046927SAndroid Build Coastguard Worker   aHigh = mix(0u, a<< shiftDist - 32, shiftDist < 64);
1037*61046927SAndroid Build Coastguard Worker   aLow = 0u;
1038*61046927SAndroid Build Coastguard Worker   aHigh = mix(aHigh, 0u, shiftDist == 0);
1039*61046927SAndroid Build Coastguard Worker   aLow = mix(aLow, a, shiftDist ==0);
1040*61046927SAndroid Build Coastguard Worker   aHigh = mix(aHigh, a >> negCount, shiftDist < 32);
1041*61046927SAndroid Build Coastguard Worker   aLow = mix(aLow, a << shiftDist, shiftDist < 32);
1042*61046927SAndroid Build Coastguard Worker
1043*61046927SAndroid Build Coastguard Worker   return __packFloat64(0u, 0x432 - shiftDist, aHigh, aLow);
1044*61046927SAndroid Build Coastguard Worker}
1045*61046927SAndroid Build Coastguard Worker
1046*61046927SAndroid Build Coastguard Workeruint64_t
1047*61046927SAndroid Build Coastguard Worker__uint64_to_fp64(uint64_t a)
1048*61046927SAndroid Build Coastguard Worker{
1049*61046927SAndroid Build Coastguard Worker   if (a == 0u)
1050*61046927SAndroid Build Coastguard Worker      return 0ul;
1051*61046927SAndroid Build Coastguard Worker
1052*61046927SAndroid Build Coastguard Worker   uvec2 aFrac = unpackUint2x32(a);
1053*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(a);
1054*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(a);
1055*61046927SAndroid Build Coastguard Worker
1056*61046927SAndroid Build Coastguard Worker   if ((aFracHi & 0x80000000u) != 0u) {
1057*61046927SAndroid Build Coastguard Worker      __shift64RightJamming(aFracHi, aFracLo, 1, aFracHi, aFracLo);
1058*61046927SAndroid Build Coastguard Worker      return __roundAndPackFloat64(0, 0x433, aFracHi, aFracLo, 0u);
1059*61046927SAndroid Build Coastguard Worker   } else {
1060*61046927SAndroid Build Coastguard Worker      return __normalizeRoundAndPackFloat64(0, 0x432, aFrac.y, aFrac.x);
1061*61046927SAndroid Build Coastguard Worker   }
1062*61046927SAndroid Build Coastguard Worker}
1063*61046927SAndroid Build Coastguard Worker
1064*61046927SAndroid Build Coastguard Workeruint64_t
1065*61046927SAndroid Build Coastguard Worker__fp64_to_uint64(uint64_t a)
1066*61046927SAndroid Build Coastguard Worker{
1067*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(a);
1068*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(a);
1069*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(a);
1070*61046927SAndroid Build Coastguard Worker   uint aSign = __extractFloat64Sign(a);
1071*61046927SAndroid Build Coastguard Worker   uint zFrac2 = 0u;
1072*61046927SAndroid Build Coastguard Worker   uint64_t default_nan = 0xFFFFFFFFFFFFFFFFUL;
1073*61046927SAndroid Build Coastguard Worker
1074*61046927SAndroid Build Coastguard Worker   aFracHi = mix(aFracHi, aFracHi | 0x00100000u, aExp != 0);
1075*61046927SAndroid Build Coastguard Worker   int shiftCount = 0x433 - aExp;
1076*61046927SAndroid Build Coastguard Worker
1077*61046927SAndroid Build Coastguard Worker   if ( shiftCount <= 0 ) {
1078*61046927SAndroid Build Coastguard Worker      if (shiftCount < -11 && aExp == 0x7FF) {
1079*61046927SAndroid Build Coastguard Worker         if ((aFracHi | aFracLo) != 0u)
1080*61046927SAndroid Build Coastguard Worker            return __propagateFloat64NaN(a, a);
1081*61046927SAndroid Build Coastguard Worker         return mix(default_nan, a, aSign == 0u);
1082*61046927SAndroid Build Coastguard Worker      }
1083*61046927SAndroid Build Coastguard Worker      __shortShift64Left(aFracHi, aFracLo, -shiftCount, aFracHi, aFracLo);
1084*61046927SAndroid Build Coastguard Worker   } else {
1085*61046927SAndroid Build Coastguard Worker      __shift64ExtraRightJamming(aFracHi, aFracLo, zFrac2, shiftCount,
1086*61046927SAndroid Build Coastguard Worker                                 aFracHi, aFracLo, zFrac2);
1087*61046927SAndroid Build Coastguard Worker   }
1088*61046927SAndroid Build Coastguard Worker   return __roundAndPackUInt64(aSign, aFracHi, aFracLo, zFrac2);
1089*61046927SAndroid Build Coastguard Worker}
1090*61046927SAndroid Build Coastguard Worker
1091*61046927SAndroid Build Coastguard Workerint64_t
1092*61046927SAndroid Build Coastguard Worker__fp64_to_int64(uint64_t a)
1093*61046927SAndroid Build Coastguard Worker{
1094*61046927SAndroid Build Coastguard Worker   uint zFrac2 = 0u;
1095*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(a);
1096*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(a);
1097*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(a);
1098*61046927SAndroid Build Coastguard Worker   uint aSign = __extractFloat64Sign(a);
1099*61046927SAndroid Build Coastguard Worker   int64_t default_NegNaN = -0x7FFFFFFFFFFFFFFEL;
1100*61046927SAndroid Build Coastguard Worker   int64_t default_PosNaN = 0xFFFFFFFFFFFFFFFFL;
1101*61046927SAndroid Build Coastguard Worker
1102*61046927SAndroid Build Coastguard Worker   aFracHi = mix(aFracHi, aFracHi | 0x00100000u, aExp != 0);
1103*61046927SAndroid Build Coastguard Worker   int shiftCount = 0x433 - aExp;
1104*61046927SAndroid Build Coastguard Worker
1105*61046927SAndroid Build Coastguard Worker   if (shiftCount <= 0) {
1106*61046927SAndroid Build Coastguard Worker      if (shiftCount < -11 && aExp == 0x7FF) {
1107*61046927SAndroid Build Coastguard Worker         if ((aFracHi | aFracLo) != 0u)
1108*61046927SAndroid Build Coastguard Worker            return default_NegNaN;
1109*61046927SAndroid Build Coastguard Worker         return mix(default_NegNaN, default_PosNaN, aSign == 0u);
1110*61046927SAndroid Build Coastguard Worker      }
1111*61046927SAndroid Build Coastguard Worker      __shortShift64Left(aFracHi, aFracLo, -shiftCount, aFracHi, aFracLo);
1112*61046927SAndroid Build Coastguard Worker   } else {
1113*61046927SAndroid Build Coastguard Worker      __shift64ExtraRightJamming(aFracHi, aFracLo, zFrac2, shiftCount,
1114*61046927SAndroid Build Coastguard Worker                                 aFracHi, aFracLo, zFrac2);
1115*61046927SAndroid Build Coastguard Worker   }
1116*61046927SAndroid Build Coastguard Worker
1117*61046927SAndroid Build Coastguard Worker   return __roundAndPackInt64(aSign, aFracHi, aFracLo, zFrac2);
1118*61046927SAndroid Build Coastguard Worker}
1119*61046927SAndroid Build Coastguard Worker
1120*61046927SAndroid Build Coastguard Workeruint64_t
1121*61046927SAndroid Build Coastguard Worker__int64_to_fp64(int64_t a)
1122*61046927SAndroid Build Coastguard Worker{
1123*61046927SAndroid Build Coastguard Worker   if (a==0)
1124*61046927SAndroid Build Coastguard Worker      return 0ul;
1125*61046927SAndroid Build Coastguard Worker
1126*61046927SAndroid Build Coastguard Worker   uint64_t absA = mix(uint64_t(a), uint64_t(-a), a < 0);
1127*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(absA);
1128*61046927SAndroid Build Coastguard Worker   uvec2 aFrac = unpackUint2x32(absA);
1129*61046927SAndroid Build Coastguard Worker   uint zSign = uint(unpackInt2x32(a).y) & 0x80000000u;
1130*61046927SAndroid Build Coastguard Worker
1131*61046927SAndroid Build Coastguard Worker   if ((aFracHi & 0x80000000u) != 0u) {
1132*61046927SAndroid Build Coastguard Worker      return mix(0ul, __packFloat64(0x80000000u, 0x434, 0u, 0u), a < 0);
1133*61046927SAndroid Build Coastguard Worker   }
1134*61046927SAndroid Build Coastguard Worker
1135*61046927SAndroid Build Coastguard Worker   return __normalizeRoundAndPackFloat64(zSign, 0x432, aFrac.y, aFrac.x);
1136*61046927SAndroid Build Coastguard Worker}
1137*61046927SAndroid Build Coastguard Worker
1138*61046927SAndroid Build Coastguard Worker/* Returns the result of converting the double-precision floating-point value
1139*61046927SAndroid Build Coastguard Worker * `a' to the 32-bit two's complement integer format.  The conversion is
1140*61046927SAndroid Build Coastguard Worker * performed according to the IEEE Standard for Floating-Point Arithmetic---
1141*61046927SAndroid Build Coastguard Worker * which means in particular that the conversion is rounded according to the
1142*61046927SAndroid Build Coastguard Worker * current rounding mode.  If `a' is a NaN, the largest positive integer is
1143*61046927SAndroid Build Coastguard Worker * returned.  Otherwise, if the conversion overflows, the largest integer with
1144*61046927SAndroid Build Coastguard Worker * the same sign as `a' is returned.
1145*61046927SAndroid Build Coastguard Worker */
1146*61046927SAndroid Build Coastguard Workerint
1147*61046927SAndroid Build Coastguard Worker__fp64_to_int(uint64_t a)
1148*61046927SAndroid Build Coastguard Worker{
1149*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(a);
1150*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(a);
1151*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(a);
1152*61046927SAndroid Build Coastguard Worker   uint aSign = __extractFloat64Sign(a);
1153*61046927SAndroid Build Coastguard Worker
1154*61046927SAndroid Build Coastguard Worker   uint absZ = 0u;
1155*61046927SAndroid Build Coastguard Worker   uint aFracExtra = 0u;
1156*61046927SAndroid Build Coastguard Worker   int shiftCount = aExp - 0x413;
1157*61046927SAndroid Build Coastguard Worker
1158*61046927SAndroid Build Coastguard Worker   if (0 <= shiftCount) {
1159*61046927SAndroid Build Coastguard Worker      if (0x41E < aExp) {
1160*61046927SAndroid Build Coastguard Worker         if ((aExp == 0x7FF) && bool(aFracHi | aFracLo))
1161*61046927SAndroid Build Coastguard Worker            aSign = 0u;
1162*61046927SAndroid Build Coastguard Worker         return mix(0x7FFFFFFF, 0x80000000, aSign != 0u);
1163*61046927SAndroid Build Coastguard Worker      }
1164*61046927SAndroid Build Coastguard Worker      __shortShift64Left(aFracHi | 0x00100000u, aFracLo, shiftCount, absZ, aFracExtra);
1165*61046927SAndroid Build Coastguard Worker   } else {
1166*61046927SAndroid Build Coastguard Worker      if (aExp < 0x3FF)
1167*61046927SAndroid Build Coastguard Worker         return 0;
1168*61046927SAndroid Build Coastguard Worker
1169*61046927SAndroid Build Coastguard Worker      aFracHi |= 0x00100000u;
1170*61046927SAndroid Build Coastguard Worker      aFracExtra = ( aFracHi << (shiftCount & 31)) | aFracLo;
1171*61046927SAndroid Build Coastguard Worker      absZ = aFracHi >> (- shiftCount);
1172*61046927SAndroid Build Coastguard Worker   }
1173*61046927SAndroid Build Coastguard Worker
1174*61046927SAndroid Build Coastguard Worker   int z = mix(int(absZ), -int(absZ), aSign != 0u);
1175*61046927SAndroid Build Coastguard Worker   int nan = mix(0x7FFFFFFF, 0x80000000, aSign != 0u);
1176*61046927SAndroid Build Coastguard Worker   return mix(z, nan, ((aSign != 0u) != (z < 0)) && bool(z));
1177*61046927SAndroid Build Coastguard Worker}
1178*61046927SAndroid Build Coastguard Worker
1179*61046927SAndroid Build Coastguard Worker/* Returns the result of converting the 32-bit two's complement integer `a'
1180*61046927SAndroid Build Coastguard Worker * to the double-precision floating-point format.  The conversion is performed
1181*61046927SAndroid Build Coastguard Worker * according to the IEEE Standard for Floating-Point Arithmetic.
1182*61046927SAndroid Build Coastguard Worker */
1183*61046927SAndroid Build Coastguard Workeruint64_t
1184*61046927SAndroid Build Coastguard Worker__int_to_fp64(int a)
1185*61046927SAndroid Build Coastguard Worker{
1186*61046927SAndroid Build Coastguard Worker   uint zFrac0 = 0u;
1187*61046927SAndroid Build Coastguard Worker   uint zFrac1 = 0u;
1188*61046927SAndroid Build Coastguard Worker   if (a==0)
1189*61046927SAndroid Build Coastguard Worker      return __packFloat64(0u, 0, 0u, 0u);
1190*61046927SAndroid Build Coastguard Worker   uint zSign = uint(a) & 0x80000000u;
1191*61046927SAndroid Build Coastguard Worker   uint absA = mix(uint(a), uint(-a), a < 0);
1192*61046927SAndroid Build Coastguard Worker   int shiftCount = __countLeadingZeros32(absA) - 11;
1193*61046927SAndroid Build Coastguard Worker   if (0 <= shiftCount) {
1194*61046927SAndroid Build Coastguard Worker      zFrac0 = absA << shiftCount;
1195*61046927SAndroid Build Coastguard Worker      zFrac1 = 0u;
1196*61046927SAndroid Build Coastguard Worker   } else {
1197*61046927SAndroid Build Coastguard Worker      __shift64Right(absA, 0u, -shiftCount, zFrac0, zFrac1);
1198*61046927SAndroid Build Coastguard Worker   }
1199*61046927SAndroid Build Coastguard Worker   return __packFloat64(zSign, 0x412 - shiftCount, zFrac0, zFrac1);
1200*61046927SAndroid Build Coastguard Worker}
1201*61046927SAndroid Build Coastguard Worker
1202*61046927SAndroid Build Coastguard Workeruint64_t
1203*61046927SAndroid Build Coastguard Worker__bool_to_fp64(bool a)
1204*61046927SAndroid Build Coastguard Worker{
1205*61046927SAndroid Build Coastguard Worker   return packUint2x32(uvec2(0x00000000u, uint(-int(a) & 0x3ff00000)));
1206*61046927SAndroid Build Coastguard Worker}
1207*61046927SAndroid Build Coastguard Worker
1208*61046927SAndroid Build Coastguard Worker/* Packs the sign `zSign', exponent `zExp', and significand `zFrac' into a
1209*61046927SAndroid Build Coastguard Worker * single-precision floating-point value, returning the result.  After being
1210*61046927SAndroid Build Coastguard Worker * shifted into the proper positions, the three fields are simply added
1211*61046927SAndroid Build Coastguard Worker * together to form the result.  This means that any integer portion of `zSig'
1212*61046927SAndroid Build Coastguard Worker * will be added into the exponent.  Since a properly normalized significand
1213*61046927SAndroid Build Coastguard Worker * will have an integer portion equal to 1, the `zExp' input should be 1 less
1214*61046927SAndroid Build Coastguard Worker * than the desired result exponent whenever `zFrac' is a complete, normalized
1215*61046927SAndroid Build Coastguard Worker * significand.
1216*61046927SAndroid Build Coastguard Worker */
1217*61046927SAndroid Build Coastguard Workerfloat
1218*61046927SAndroid Build Coastguard Worker__packFloat32(uint zSign, int zExp, uint zFrac)
1219*61046927SAndroid Build Coastguard Worker{
1220*61046927SAndroid Build Coastguard Worker   return uintBitsToFloat(zSign + (uint(zExp)<<23) + zFrac);
1221*61046927SAndroid Build Coastguard Worker}
1222*61046927SAndroid Build Coastguard Worker
1223*61046927SAndroid Build Coastguard Worker/* Takes an abstract floating-point value having sign `zSign', exponent `zExp',
1224*61046927SAndroid Build Coastguard Worker * and significand `zFrac', and returns the proper single-precision floating-
1225*61046927SAndroid Build Coastguard Worker * point value corresponding to the abstract input.  Ordinarily, the abstract
1226*61046927SAndroid Build Coastguard Worker * value is simply rounded and packed into the single-precision format, with
1227*61046927SAndroid Build Coastguard Worker * the inexact exception raised if the abstract input cannot be represented
1228*61046927SAndroid Build Coastguard Worker * exactly.  However, if the abstract value is too large, the overflow and
1229*61046927SAndroid Build Coastguard Worker * inexact exceptions are raised and an infinity or maximal finite value is
1230*61046927SAndroid Build Coastguard Worker * returned.  If the abstract value is too small, the input value is rounded to
1231*61046927SAndroid Build Coastguard Worker * a subnormal number, and the underflow and inexact exceptions are raised if
1232*61046927SAndroid Build Coastguard Worker * the abstract input cannot be represented exactly as a subnormal single-
1233*61046927SAndroid Build Coastguard Worker * precision floating-point number.
1234*61046927SAndroid Build Coastguard Worker *     The input significand `zFrac' has its binary point between bits 30
1235*61046927SAndroid Build Coastguard Worker * and 29, which is 7 bits to the left of the usual location.  This shifted
1236*61046927SAndroid Build Coastguard Worker * significand must be normalized or smaller.  If `zFrac' is not normalized,
1237*61046927SAndroid Build Coastguard Worker * `zExp' must be 0; in that case, the result returned is a subnormal number,
1238*61046927SAndroid Build Coastguard Worker * and it must not require rounding.  In the usual case that `zFrac' is
1239*61046927SAndroid Build Coastguard Worker * normalized, `zExp' must be 1 less than the "true" floating-point exponent.
1240*61046927SAndroid Build Coastguard Worker * The handling of underflow and overflow follows the IEEE Standard for
1241*61046927SAndroid Build Coastguard Worker * Floating-Point Arithmetic.
1242*61046927SAndroid Build Coastguard Worker */
1243*61046927SAndroid Build Coastguard Workerfloat
1244*61046927SAndroid Build Coastguard Worker__roundAndPackFloat32(uint zSign, int zExp, uint zFrac)
1245*61046927SAndroid Build Coastguard Worker{
1246*61046927SAndroid Build Coastguard Worker   bool roundNearestEven;
1247*61046927SAndroid Build Coastguard Worker   int roundIncrement;
1248*61046927SAndroid Build Coastguard Worker   int roundBits;
1249*61046927SAndroid Build Coastguard Worker
1250*61046927SAndroid Build Coastguard Worker   roundNearestEven = FLOAT_ROUNDING_MODE == FLOAT_ROUND_NEAREST_EVEN;
1251*61046927SAndroid Build Coastguard Worker   roundIncrement = 0x40;
1252*61046927SAndroid Build Coastguard Worker   if (!roundNearestEven) {
1253*61046927SAndroid Build Coastguard Worker      if (FLOAT_ROUNDING_MODE == FLOAT_ROUND_TO_ZERO) {
1254*61046927SAndroid Build Coastguard Worker         roundIncrement = 0;
1255*61046927SAndroid Build Coastguard Worker      } else {
1256*61046927SAndroid Build Coastguard Worker         roundIncrement = 0x7F;
1257*61046927SAndroid Build Coastguard Worker         if (zSign != 0u) {
1258*61046927SAndroid Build Coastguard Worker            if (FLOAT_ROUNDING_MODE == FLOAT_ROUND_UP)
1259*61046927SAndroid Build Coastguard Worker               roundIncrement = 0;
1260*61046927SAndroid Build Coastguard Worker         } else {
1261*61046927SAndroid Build Coastguard Worker            if (FLOAT_ROUNDING_MODE == FLOAT_ROUND_DOWN)
1262*61046927SAndroid Build Coastguard Worker               roundIncrement = 0;
1263*61046927SAndroid Build Coastguard Worker         }
1264*61046927SAndroid Build Coastguard Worker      }
1265*61046927SAndroid Build Coastguard Worker   }
1266*61046927SAndroid Build Coastguard Worker   roundBits = int(zFrac & 0x7Fu);
1267*61046927SAndroid Build Coastguard Worker   if (0xFDu <= uint(zExp)) {
1268*61046927SAndroid Build Coastguard Worker      if ((0xFD < zExp) || ((zExp == 0xFD) && (int(zFrac) + roundIncrement) < 0))
1269*61046927SAndroid Build Coastguard Worker         return __packFloat32(zSign, 0xFF, 0u) - float(roundIncrement == 0);
1270*61046927SAndroid Build Coastguard Worker      int count = -zExp;
1271*61046927SAndroid Build Coastguard Worker      bool zexp_lt0 = zExp < 0;
1272*61046927SAndroid Build Coastguard Worker      uint zFrac_lt0 = mix(uint(zFrac != 0u), (zFrac>>count) | uint((zFrac<<((-count) & 31)) != 0u), (-zExp) < 32);
1273*61046927SAndroid Build Coastguard Worker      zFrac = mix(zFrac, zFrac_lt0, zexp_lt0);
1274*61046927SAndroid Build Coastguard Worker      roundBits = mix(roundBits, int(zFrac) & 0x7f, zexp_lt0);
1275*61046927SAndroid Build Coastguard Worker      zExp = mix(zExp, 0, zexp_lt0);
1276*61046927SAndroid Build Coastguard Worker   }
1277*61046927SAndroid Build Coastguard Worker   zFrac = (zFrac + uint(roundIncrement))>>7;
1278*61046927SAndroid Build Coastguard Worker   zFrac &= ~uint(((roundBits ^ 0x40) == 0) && roundNearestEven);
1279*61046927SAndroid Build Coastguard Worker
1280*61046927SAndroid Build Coastguard Worker   return __packFloat32(zSign, mix(zExp, 0, zFrac == 0u), zFrac);
1281*61046927SAndroid Build Coastguard Worker}
1282*61046927SAndroid Build Coastguard Worker
1283*61046927SAndroid Build Coastguard Worker/* Returns the result of converting the double-precision floating-point value
1284*61046927SAndroid Build Coastguard Worker * `a' to the single-precision floating-point format.  The conversion is
1285*61046927SAndroid Build Coastguard Worker * performed according to the IEEE Standard for Floating-Point Arithmetic.
1286*61046927SAndroid Build Coastguard Worker */
1287*61046927SAndroid Build Coastguard Workerfloat
1288*61046927SAndroid Build Coastguard Worker__fp64_to_fp32(uint64_t __a)
1289*61046927SAndroid Build Coastguard Worker{
1290*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
1291*61046927SAndroid Build Coastguard Worker   uint zFrac = 0u;
1292*61046927SAndroid Build Coastguard Worker   uint allZero = 0u;
1293*61046927SAndroid Build Coastguard Worker
1294*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(__a);
1295*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(__a);
1296*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(__a);
1297*61046927SAndroid Build Coastguard Worker   uint aSign = __extractFloat64Sign(__a);
1298*61046927SAndroid Build Coastguard Worker   if (aExp == 0x7FF) {
1299*61046927SAndroid Build Coastguard Worker      __shortShift64Left(a.y, a.x, 12, a.y, a.x);
1300*61046927SAndroid Build Coastguard Worker      float rval = uintBitsToFloat(aSign | 0x7FC00000u | (a.y>>9));
1301*61046927SAndroid Build Coastguard Worker      rval = mix(__packFloat32(aSign, 0xFF, 0u), rval, (aFracHi | aFracLo) != 0u);
1302*61046927SAndroid Build Coastguard Worker      return rval;
1303*61046927SAndroid Build Coastguard Worker   }
1304*61046927SAndroid Build Coastguard Worker   __shift64RightJamming(aFracHi, aFracLo, 22, allZero, zFrac);
1305*61046927SAndroid Build Coastguard Worker   zFrac = mix(zFrac, zFrac | 0x40000000u, aExp != 0);
1306*61046927SAndroid Build Coastguard Worker   return __roundAndPackFloat32(aSign, aExp - 0x381, zFrac);
1307*61046927SAndroid Build Coastguard Worker}
1308*61046927SAndroid Build Coastguard Worker
1309*61046927SAndroid Build Coastguard Worker/* Returns the result of converting the single-precision floating-point value
1310*61046927SAndroid Build Coastguard Worker * `a' to the double-precision floating-point format.
1311*61046927SAndroid Build Coastguard Worker */
1312*61046927SAndroid Build Coastguard Workeruint64_t
1313*61046927SAndroid Build Coastguard Worker__fp32_to_fp64(float f)
1314*61046927SAndroid Build Coastguard Worker{
1315*61046927SAndroid Build Coastguard Worker   uint a = floatBitsToUint(f);
1316*61046927SAndroid Build Coastguard Worker   uint aFrac = a & 0x007FFFFFu;
1317*61046927SAndroid Build Coastguard Worker   int aExp = int((a>>23) & 0xFFu);
1318*61046927SAndroid Build Coastguard Worker   uint aSign = a & 0x80000000u;
1319*61046927SAndroid Build Coastguard Worker   uint zFrac0 = 0u;
1320*61046927SAndroid Build Coastguard Worker   uint zFrac1 = 0u;
1321*61046927SAndroid Build Coastguard Worker
1322*61046927SAndroid Build Coastguard Worker   if (aExp == 0xFF) {
1323*61046927SAndroid Build Coastguard Worker      if (aFrac != 0u) {
1324*61046927SAndroid Build Coastguard Worker         uint nanLo = 0u;
1325*61046927SAndroid Build Coastguard Worker         uint nanHi = a<<9;
1326*61046927SAndroid Build Coastguard Worker         __shift64Right(nanHi, nanLo, 12, nanHi, nanLo);
1327*61046927SAndroid Build Coastguard Worker         nanHi |= aSign | 0x7FF80000u;
1328*61046927SAndroid Build Coastguard Worker         return packUint2x32(uvec2(nanLo, nanHi));
1329*61046927SAndroid Build Coastguard Worker      }
1330*61046927SAndroid Build Coastguard Worker      return __packFloat64(aSign, 0x7FF, 0u, 0u);
1331*61046927SAndroid Build Coastguard Worker    }
1332*61046927SAndroid Build Coastguard Worker
1333*61046927SAndroid Build Coastguard Worker   if (aExp == 0) {
1334*61046927SAndroid Build Coastguard Worker      if (aFrac == 0u)
1335*61046927SAndroid Build Coastguard Worker         return __packFloat64(aSign, 0, 0u, 0u);
1336*61046927SAndroid Build Coastguard Worker      /* Normalize subnormal */
1337*61046927SAndroid Build Coastguard Worker      int shiftCount = __countLeadingZeros32(aFrac) - 8;
1338*61046927SAndroid Build Coastguard Worker      aFrac <<= shiftCount;
1339*61046927SAndroid Build Coastguard Worker      aExp = 1 - shiftCount;
1340*61046927SAndroid Build Coastguard Worker      --aExp;
1341*61046927SAndroid Build Coastguard Worker   }
1342*61046927SAndroid Build Coastguard Worker
1343*61046927SAndroid Build Coastguard Worker   __shift64Right(aFrac, 0u, 3, zFrac0, zFrac1);
1344*61046927SAndroid Build Coastguard Worker   return __packFloat64(aSign, aExp + 0x380, zFrac0, zFrac1);
1345*61046927SAndroid Build Coastguard Worker}
1346*61046927SAndroid Build Coastguard Worker
1347*61046927SAndroid Build Coastguard Worker/* Adds the 96-bit value formed by concatenating `a0', `a1', and `a2' to the
1348*61046927SAndroid Build Coastguard Worker * 96-bit value formed by concatenating `b0', `b1', and `b2'.  Addition is
1349*61046927SAndroid Build Coastguard Worker * modulo 2^96, so any carry out is lost.  The result is broken into three
1350*61046927SAndroid Build Coastguard Worker * 32-bit pieces which are stored at the locations pointed to by `z0Ptr',
1351*61046927SAndroid Build Coastguard Worker * `z1Ptr', and `z2Ptr'.
1352*61046927SAndroid Build Coastguard Worker */
1353*61046927SAndroid Build Coastguard Workervoid
1354*61046927SAndroid Build Coastguard Worker__add96(uint a0, uint a1, uint a2,
1355*61046927SAndroid Build Coastguard Worker        uint b0, uint b1, uint b2,
1356*61046927SAndroid Build Coastguard Worker        out uint z0Ptr,
1357*61046927SAndroid Build Coastguard Worker        out uint z1Ptr,
1358*61046927SAndroid Build Coastguard Worker        out uint z2Ptr)
1359*61046927SAndroid Build Coastguard Worker{
1360*61046927SAndroid Build Coastguard Worker   uint z2 = a2 + b2;
1361*61046927SAndroid Build Coastguard Worker   uint carry1 = uint(z2 < a2);
1362*61046927SAndroid Build Coastguard Worker   uint z1 = a1 + b1;
1363*61046927SAndroid Build Coastguard Worker   uint carry0 = uint(z1 < a1);
1364*61046927SAndroid Build Coastguard Worker   uint z0 = a0 + b0;
1365*61046927SAndroid Build Coastguard Worker   z1 += carry1;
1366*61046927SAndroid Build Coastguard Worker   z0 += uint(z1 < carry1);
1367*61046927SAndroid Build Coastguard Worker   z0 += carry0;
1368*61046927SAndroid Build Coastguard Worker   z2Ptr = z2;
1369*61046927SAndroid Build Coastguard Worker   z1Ptr = z1;
1370*61046927SAndroid Build Coastguard Worker   z0Ptr = z0;
1371*61046927SAndroid Build Coastguard Worker}
1372*61046927SAndroid Build Coastguard Worker
1373*61046927SAndroid Build Coastguard Worker/* Subtracts the 96-bit value formed by concatenating `b0', `b1', and `b2' from
1374*61046927SAndroid Build Coastguard Worker * the 96-bit value formed by concatenating `a0', `a1', and `a2'.  Subtraction
1375*61046927SAndroid Build Coastguard Worker * is modulo 2^96, so any borrow out (carry out) is lost.  The result is broken
1376*61046927SAndroid Build Coastguard Worker * into three 32-bit pieces which are stored at the locations pointed to by
1377*61046927SAndroid Build Coastguard Worker * `z0Ptr', `z1Ptr', and `z2Ptr'.
1378*61046927SAndroid Build Coastguard Worker */
1379*61046927SAndroid Build Coastguard Workervoid
1380*61046927SAndroid Build Coastguard Worker__sub96(uint a0, uint a1, uint a2,
1381*61046927SAndroid Build Coastguard Worker        uint b0, uint b1, uint b2,
1382*61046927SAndroid Build Coastguard Worker        out uint z0Ptr,
1383*61046927SAndroid Build Coastguard Worker        out uint z1Ptr,
1384*61046927SAndroid Build Coastguard Worker        out uint z2Ptr)
1385*61046927SAndroid Build Coastguard Worker{
1386*61046927SAndroid Build Coastguard Worker   uint z2 = a2 - b2;
1387*61046927SAndroid Build Coastguard Worker   uint borrow1 = uint(a2 < b2);
1388*61046927SAndroid Build Coastguard Worker   uint z1 = a1 - b1;
1389*61046927SAndroid Build Coastguard Worker   uint borrow0 = uint(a1 < b1);
1390*61046927SAndroid Build Coastguard Worker   uint z0 = a0 - b0;
1391*61046927SAndroid Build Coastguard Worker   z0 -= uint(z1 < borrow1);
1392*61046927SAndroid Build Coastguard Worker   z1 -= borrow1;
1393*61046927SAndroid Build Coastguard Worker   z0 -= borrow0;
1394*61046927SAndroid Build Coastguard Worker   z2Ptr = z2;
1395*61046927SAndroid Build Coastguard Worker   z1Ptr = z1;
1396*61046927SAndroid Build Coastguard Worker   z0Ptr = z0;
1397*61046927SAndroid Build Coastguard Worker}
1398*61046927SAndroid Build Coastguard Worker
1399*61046927SAndroid Build Coastguard Worker/* Returns an approximation to the 32-bit integer quotient obtained by dividing
1400*61046927SAndroid Build Coastguard Worker * `b' into the 64-bit value formed by concatenating `a0' and `a1'.  The
1401*61046927SAndroid Build Coastguard Worker * divisor `b' must be at least 2^31.  If q is the exact quotient truncated
1402*61046927SAndroid Build Coastguard Worker * toward zero, the approximation returned lies between q and q + 2 inclusive.
1403*61046927SAndroid Build Coastguard Worker * If the exact quotient q is larger than 32 bits, the maximum positive 32-bit
1404*61046927SAndroid Build Coastguard Worker * unsigned integer is returned.
1405*61046927SAndroid Build Coastguard Worker */
1406*61046927SAndroid Build Coastguard Workeruint
1407*61046927SAndroid Build Coastguard Worker__estimateDiv64To32(uint a0, uint a1, uint b)
1408*61046927SAndroid Build Coastguard Worker{
1409*61046927SAndroid Build Coastguard Worker   uint b0;
1410*61046927SAndroid Build Coastguard Worker   uint b1;
1411*61046927SAndroid Build Coastguard Worker   uint rem0 = 0u;
1412*61046927SAndroid Build Coastguard Worker   uint rem1 = 0u;
1413*61046927SAndroid Build Coastguard Worker   uint term0 = 0u;
1414*61046927SAndroid Build Coastguard Worker   uint term1 = 0u;
1415*61046927SAndroid Build Coastguard Worker   uint z;
1416*61046927SAndroid Build Coastguard Worker
1417*61046927SAndroid Build Coastguard Worker   if (b <= a0)
1418*61046927SAndroid Build Coastguard Worker      return 0xFFFFFFFFu;
1419*61046927SAndroid Build Coastguard Worker   b0 = b>>16;
1420*61046927SAndroid Build Coastguard Worker   z = (b0<<16 <= a0) ? 0xFFFF0000u : (a0 / b0)<<16;
1421*61046927SAndroid Build Coastguard Worker   umulExtended(b, z, term0, term1);
1422*61046927SAndroid Build Coastguard Worker   __sub64(a0, a1, term0, term1, rem0, rem1);
1423*61046927SAndroid Build Coastguard Worker   while (int(rem0) < 0) {
1424*61046927SAndroid Build Coastguard Worker      z -= 0x10000u;
1425*61046927SAndroid Build Coastguard Worker      b1 = b<<16;
1426*61046927SAndroid Build Coastguard Worker      __add64(rem0, rem1, b0, b1, rem0, rem1);
1427*61046927SAndroid Build Coastguard Worker   }
1428*61046927SAndroid Build Coastguard Worker   rem0 = (rem0<<16) | (rem1>>16);
1429*61046927SAndroid Build Coastguard Worker   z |= (b0<<16 <= rem0) ? 0xFFFFu : rem0 / b0;
1430*61046927SAndroid Build Coastguard Worker   return z;
1431*61046927SAndroid Build Coastguard Worker}
1432*61046927SAndroid Build Coastguard Worker
1433*61046927SAndroid Build Coastguard Workeruint
1434*61046927SAndroid Build Coastguard Worker__sqrtOddAdjustments(int index)
1435*61046927SAndroid Build Coastguard Worker{
1436*61046927SAndroid Build Coastguard Worker   uint res = 0u;
1437*61046927SAndroid Build Coastguard Worker   if (index == 0)
1438*61046927SAndroid Build Coastguard Worker      res = 0x0004u;
1439*61046927SAndroid Build Coastguard Worker   if (index == 1)
1440*61046927SAndroid Build Coastguard Worker      res = 0x0022u;
1441*61046927SAndroid Build Coastguard Worker   if (index == 2)
1442*61046927SAndroid Build Coastguard Worker      res = 0x005Du;
1443*61046927SAndroid Build Coastguard Worker   if (index == 3)
1444*61046927SAndroid Build Coastguard Worker      res = 0x00B1u;
1445*61046927SAndroid Build Coastguard Worker   if (index == 4)
1446*61046927SAndroid Build Coastguard Worker      res = 0x011Du;
1447*61046927SAndroid Build Coastguard Worker   if (index == 5)
1448*61046927SAndroid Build Coastguard Worker      res = 0x019Fu;
1449*61046927SAndroid Build Coastguard Worker   if (index == 6)
1450*61046927SAndroid Build Coastguard Worker      res = 0x0236u;
1451*61046927SAndroid Build Coastguard Worker   if (index == 7)
1452*61046927SAndroid Build Coastguard Worker      res = 0x02E0u;
1453*61046927SAndroid Build Coastguard Worker   if (index == 8)
1454*61046927SAndroid Build Coastguard Worker      res = 0x039Cu;
1455*61046927SAndroid Build Coastguard Worker   if (index == 9)
1456*61046927SAndroid Build Coastguard Worker      res = 0x0468u;
1457*61046927SAndroid Build Coastguard Worker   if (index == 10)
1458*61046927SAndroid Build Coastguard Worker      res = 0x0545u;
1459*61046927SAndroid Build Coastguard Worker   if (index == 11)
1460*61046927SAndroid Build Coastguard Worker      res = 0x631u;
1461*61046927SAndroid Build Coastguard Worker   if (index == 12)
1462*61046927SAndroid Build Coastguard Worker      res = 0x072Bu;
1463*61046927SAndroid Build Coastguard Worker   if (index == 13)
1464*61046927SAndroid Build Coastguard Worker      res = 0x0832u;
1465*61046927SAndroid Build Coastguard Worker   if (index == 14)
1466*61046927SAndroid Build Coastguard Worker      res = 0x0946u;
1467*61046927SAndroid Build Coastguard Worker   if (index == 15)
1468*61046927SAndroid Build Coastguard Worker      res = 0x0A67u;
1469*61046927SAndroid Build Coastguard Worker
1470*61046927SAndroid Build Coastguard Worker   return res;
1471*61046927SAndroid Build Coastguard Worker}
1472*61046927SAndroid Build Coastguard Worker
1473*61046927SAndroid Build Coastguard Workeruint
1474*61046927SAndroid Build Coastguard Worker__sqrtEvenAdjustments(int index)
1475*61046927SAndroid Build Coastguard Worker{
1476*61046927SAndroid Build Coastguard Worker   uint res = 0u;
1477*61046927SAndroid Build Coastguard Worker   if (index == 0)
1478*61046927SAndroid Build Coastguard Worker      res = 0x0A2Du;
1479*61046927SAndroid Build Coastguard Worker   if (index == 1)
1480*61046927SAndroid Build Coastguard Worker      res = 0x08AFu;
1481*61046927SAndroid Build Coastguard Worker   if (index == 2)
1482*61046927SAndroid Build Coastguard Worker      res = 0x075Au;
1483*61046927SAndroid Build Coastguard Worker   if (index == 3)
1484*61046927SAndroid Build Coastguard Worker      res = 0x0629u;
1485*61046927SAndroid Build Coastguard Worker   if (index == 4)
1486*61046927SAndroid Build Coastguard Worker      res = 0x051Au;
1487*61046927SAndroid Build Coastguard Worker   if (index == 5)
1488*61046927SAndroid Build Coastguard Worker      res = 0x0429u;
1489*61046927SAndroid Build Coastguard Worker   if (index == 6)
1490*61046927SAndroid Build Coastguard Worker      res = 0x0356u;
1491*61046927SAndroid Build Coastguard Worker   if (index == 7)
1492*61046927SAndroid Build Coastguard Worker      res = 0x029Eu;
1493*61046927SAndroid Build Coastguard Worker   if (index == 8)
1494*61046927SAndroid Build Coastguard Worker      res = 0x0200u;
1495*61046927SAndroid Build Coastguard Worker   if (index == 9)
1496*61046927SAndroid Build Coastguard Worker      res = 0x0179u;
1497*61046927SAndroid Build Coastguard Worker   if (index == 10)
1498*61046927SAndroid Build Coastguard Worker      res = 0x0109u;
1499*61046927SAndroid Build Coastguard Worker   if (index == 11)
1500*61046927SAndroid Build Coastguard Worker      res = 0x00AFu;
1501*61046927SAndroid Build Coastguard Worker   if (index == 12)
1502*61046927SAndroid Build Coastguard Worker      res = 0x0068u;
1503*61046927SAndroid Build Coastguard Worker   if (index == 13)
1504*61046927SAndroid Build Coastguard Worker      res = 0x0034u;
1505*61046927SAndroid Build Coastguard Worker   if (index == 14)
1506*61046927SAndroid Build Coastguard Worker      res = 0x0012u;
1507*61046927SAndroid Build Coastguard Worker   if (index == 15)
1508*61046927SAndroid Build Coastguard Worker      res = 0x0002u;
1509*61046927SAndroid Build Coastguard Worker
1510*61046927SAndroid Build Coastguard Worker   return res;
1511*61046927SAndroid Build Coastguard Worker}
1512*61046927SAndroid Build Coastguard Worker
1513*61046927SAndroid Build Coastguard Worker/* Returns an approximation to the square root of the 32-bit significand given
1514*61046927SAndroid Build Coastguard Worker * by `a'.  Considered as an integer, `a' must be at least 2^31.  If bit 0 of
1515*61046927SAndroid Build Coastguard Worker * `aExp' (the least significant bit) is 1, the integer returned approximates
1516*61046927SAndroid Build Coastguard Worker * 2^31*sqrt(`a'/2^31), where `a' is considered an integer.  If bit 0 of `aExp'
1517*61046927SAndroid Build Coastguard Worker * is 0, the integer returned approximates 2^31*sqrt(`a'/2^30).  In either
1518*61046927SAndroid Build Coastguard Worker * case, the approximation returned lies strictly within +/-2 of the exact
1519*61046927SAndroid Build Coastguard Worker * value.
1520*61046927SAndroid Build Coastguard Worker */
1521*61046927SAndroid Build Coastguard Workeruint
1522*61046927SAndroid Build Coastguard Worker__estimateSqrt32(int aExp, uint a)
1523*61046927SAndroid Build Coastguard Worker{
1524*61046927SAndroid Build Coastguard Worker   uint z;
1525*61046927SAndroid Build Coastguard Worker
1526*61046927SAndroid Build Coastguard Worker   int index = int(a>>27 & 15u);
1527*61046927SAndroid Build Coastguard Worker   if ((aExp & 1) != 0) {
1528*61046927SAndroid Build Coastguard Worker      z = 0x4000u + (a>>17) - __sqrtOddAdjustments(index);
1529*61046927SAndroid Build Coastguard Worker      z = ((a / z)<<14) + (z<<15);
1530*61046927SAndroid Build Coastguard Worker      a >>= 1;
1531*61046927SAndroid Build Coastguard Worker   } else {
1532*61046927SAndroid Build Coastguard Worker      z = 0x8000u + (a>>17) - __sqrtEvenAdjustments(index);
1533*61046927SAndroid Build Coastguard Worker      z = a / z + z;
1534*61046927SAndroid Build Coastguard Worker      z = (0x20000u <= z) ? 0xFFFF8000u : (z<<15);
1535*61046927SAndroid Build Coastguard Worker      if (z <= a)
1536*61046927SAndroid Build Coastguard Worker         return uint(int(a)>>1);
1537*61046927SAndroid Build Coastguard Worker   }
1538*61046927SAndroid Build Coastguard Worker   return ((__estimateDiv64To32(a, 0u, z))>>1) + (z>>1);
1539*61046927SAndroid Build Coastguard Worker}
1540*61046927SAndroid Build Coastguard Worker
1541*61046927SAndroid Build Coastguard Worker/* Returns the square root of the double-precision floating-point value `a'.
1542*61046927SAndroid Build Coastguard Worker * The operation is performed according to the IEEE Standard for Floating-Point
1543*61046927SAndroid Build Coastguard Worker * Arithmetic.
1544*61046927SAndroid Build Coastguard Worker */
1545*61046927SAndroid Build Coastguard Workeruint64_t
1546*61046927SAndroid Build Coastguard Worker__fsqrt64(uint64_t a)
1547*61046927SAndroid Build Coastguard Worker{
1548*61046927SAndroid Build Coastguard Worker   uint zFrac0 = 0u;
1549*61046927SAndroid Build Coastguard Worker   uint zFrac1 = 0u;
1550*61046927SAndroid Build Coastguard Worker   uint zFrac2 = 0u;
1551*61046927SAndroid Build Coastguard Worker   uint doubleZFrac0 = 0u;
1552*61046927SAndroid Build Coastguard Worker   uint rem0 = 0u;
1553*61046927SAndroid Build Coastguard Worker   uint rem1 = 0u;
1554*61046927SAndroid Build Coastguard Worker   uint rem2 = 0u;
1555*61046927SAndroid Build Coastguard Worker   uint rem3 = 0u;
1556*61046927SAndroid Build Coastguard Worker   uint term0 = 0u;
1557*61046927SAndroid Build Coastguard Worker   uint term1 = 0u;
1558*61046927SAndroid Build Coastguard Worker   uint term2 = 0u;
1559*61046927SAndroid Build Coastguard Worker   uint term3 = 0u;
1560*61046927SAndroid Build Coastguard Worker   uint64_t default_nan = 0xFFFFFFFFFFFFFFFFUL;
1561*61046927SAndroid Build Coastguard Worker
1562*61046927SAndroid Build Coastguard Worker   uint aFracLo = __extractFloat64FracLo(a);
1563*61046927SAndroid Build Coastguard Worker   uint aFracHi = __extractFloat64FracHi(a);
1564*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(a);
1565*61046927SAndroid Build Coastguard Worker   uint aSign = __extractFloat64Sign(a);
1566*61046927SAndroid Build Coastguard Worker   if (aExp == 0x7FF) {
1567*61046927SAndroid Build Coastguard Worker      if ((aFracHi | aFracLo) != 0u)
1568*61046927SAndroid Build Coastguard Worker         return __propagateFloat64NaN(a, a);
1569*61046927SAndroid Build Coastguard Worker      if (aSign == 0u)
1570*61046927SAndroid Build Coastguard Worker         return a;
1571*61046927SAndroid Build Coastguard Worker      return default_nan;
1572*61046927SAndroid Build Coastguard Worker   }
1573*61046927SAndroid Build Coastguard Worker   if (aSign != 0u) {
1574*61046927SAndroid Build Coastguard Worker      if ((uint(aExp) | aFracHi | aFracLo) == 0u)
1575*61046927SAndroid Build Coastguard Worker         return a;
1576*61046927SAndroid Build Coastguard Worker      return default_nan;
1577*61046927SAndroid Build Coastguard Worker   }
1578*61046927SAndroid Build Coastguard Worker   if (aExp == 0) {
1579*61046927SAndroid Build Coastguard Worker      if ((aFracHi | aFracLo) == 0u)
1580*61046927SAndroid Build Coastguard Worker         return __packFloat64(0u, 0, 0u, 0u);
1581*61046927SAndroid Build Coastguard Worker      __normalizeFloat64Subnormal(aFracHi, aFracLo, aExp, aFracHi, aFracLo);
1582*61046927SAndroid Build Coastguard Worker   }
1583*61046927SAndroid Build Coastguard Worker   int zExp = ((aExp - 0x3FF)>>1) + 0x3FE;
1584*61046927SAndroid Build Coastguard Worker   aFracHi |= 0x00100000u;
1585*61046927SAndroid Build Coastguard Worker   __shortShift64Left(aFracHi, aFracLo, 11, term0, term1);
1586*61046927SAndroid Build Coastguard Worker   zFrac0 = (__estimateSqrt32(aExp, term0)>>1) + 1u;
1587*61046927SAndroid Build Coastguard Worker   if (zFrac0 == 0u)
1588*61046927SAndroid Build Coastguard Worker      zFrac0 = 0x7FFFFFFFu;
1589*61046927SAndroid Build Coastguard Worker   doubleZFrac0 = zFrac0 + zFrac0;
1590*61046927SAndroid Build Coastguard Worker   __shortShift64Left(aFracHi, aFracLo, 9 - (aExp & 1), aFracHi, aFracLo);
1591*61046927SAndroid Build Coastguard Worker   umulExtended(zFrac0, zFrac0, term0, term1);
1592*61046927SAndroid Build Coastguard Worker   __sub64(aFracHi, aFracLo, term0, term1, rem0, rem1);
1593*61046927SAndroid Build Coastguard Worker   while (int(rem0) < 0) {
1594*61046927SAndroid Build Coastguard Worker      --zFrac0;
1595*61046927SAndroid Build Coastguard Worker      doubleZFrac0 -= 2u;
1596*61046927SAndroid Build Coastguard Worker      __add64(rem0, rem1, 0u, doubleZFrac0 | 1u, rem0, rem1);
1597*61046927SAndroid Build Coastguard Worker   }
1598*61046927SAndroid Build Coastguard Worker   zFrac1 = __estimateDiv64To32(rem1, 0u, doubleZFrac0);
1599*61046927SAndroid Build Coastguard Worker   if ((zFrac1 & 0x1FFu) <= 5u) {
1600*61046927SAndroid Build Coastguard Worker      if (zFrac1 == 0u)
1601*61046927SAndroid Build Coastguard Worker         zFrac1 = 1u;
1602*61046927SAndroid Build Coastguard Worker      umulExtended(doubleZFrac0, zFrac1, term1, term2);
1603*61046927SAndroid Build Coastguard Worker      __sub64(rem1, 0u, term1, term2, rem1, rem2);
1604*61046927SAndroid Build Coastguard Worker      umulExtended(zFrac1, zFrac1, term2, term3);
1605*61046927SAndroid Build Coastguard Worker      __sub96(rem1, rem2, 0u, 0u, term2, term3, rem1, rem2, rem3);
1606*61046927SAndroid Build Coastguard Worker      while (int(rem1) < 0) {
1607*61046927SAndroid Build Coastguard Worker         --zFrac1;
1608*61046927SAndroid Build Coastguard Worker         __shortShift64Left(0u, zFrac1, 1, term2, term3);
1609*61046927SAndroid Build Coastguard Worker         term3 |= 1u;
1610*61046927SAndroid Build Coastguard Worker         term2 |= doubleZFrac0;
1611*61046927SAndroid Build Coastguard Worker         __add96(rem1, rem2, rem3, 0u, term2, term3, rem1, rem2, rem3);
1612*61046927SAndroid Build Coastguard Worker      }
1613*61046927SAndroid Build Coastguard Worker      zFrac1 |= uint((rem1 | rem2 | rem3) != 0u);
1614*61046927SAndroid Build Coastguard Worker   }
1615*61046927SAndroid Build Coastguard Worker   __shift64ExtraRightJamming(zFrac0, zFrac1, 0u, 10, zFrac0, zFrac1, zFrac2);
1616*61046927SAndroid Build Coastguard Worker   return __roundAndPackFloat64(0u, zExp, zFrac0, zFrac1, zFrac2);
1617*61046927SAndroid Build Coastguard Worker}
1618*61046927SAndroid Build Coastguard Worker
1619*61046927SAndroid Build Coastguard Workeruint64_t
1620*61046927SAndroid Build Coastguard Worker__ftrunc64(uint64_t __a)
1621*61046927SAndroid Build Coastguard Worker{
1622*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
1623*61046927SAndroid Build Coastguard Worker   int aExp = __extractFloat64Exp(__a);
1624*61046927SAndroid Build Coastguard Worker   uint zLo;
1625*61046927SAndroid Build Coastguard Worker   uint zHi;
1626*61046927SAndroid Build Coastguard Worker
1627*61046927SAndroid Build Coastguard Worker   int unbiasedExp = aExp - 1023;
1628*61046927SAndroid Build Coastguard Worker   int fracBits = 52 - unbiasedExp;
1629*61046927SAndroid Build Coastguard Worker   uint maskLo = mix(~0u << fracBits, 0u, fracBits >= 32);
1630*61046927SAndroid Build Coastguard Worker   uint maskHi = mix(~0u << (fracBits - 32), ~0u, fracBits < 33);
1631*61046927SAndroid Build Coastguard Worker   zLo = maskLo & a.x;
1632*61046927SAndroid Build Coastguard Worker   zHi = maskHi & a.y;
1633*61046927SAndroid Build Coastguard Worker
1634*61046927SAndroid Build Coastguard Worker   zLo = mix(zLo, 0u, unbiasedExp < 0);
1635*61046927SAndroid Build Coastguard Worker   zHi = mix(zHi, 0u, unbiasedExp < 0);
1636*61046927SAndroid Build Coastguard Worker   zLo = mix(zLo, a.x, unbiasedExp > 52);
1637*61046927SAndroid Build Coastguard Worker   zHi = mix(zHi, a.y, unbiasedExp > 52);
1638*61046927SAndroid Build Coastguard Worker   return packUint2x32(uvec2(zLo, zHi));
1639*61046927SAndroid Build Coastguard Worker}
1640*61046927SAndroid Build Coastguard Worker
1641*61046927SAndroid Build Coastguard Workeruint64_t
1642*61046927SAndroid Build Coastguard Worker__ffloor64(uint64_t a)
1643*61046927SAndroid Build Coastguard Worker{
1644*61046927SAndroid Build Coastguard Worker   /* The big assumption is that when 'a' is NaN, __ftrunc(a) returns a.  Based
1645*61046927SAndroid Build Coastguard Worker    * on that assumption, NaN values that don't have the sign bit will safely
1646*61046927SAndroid Build Coastguard Worker    * return NaN (identity).  This is guarded by RELAXED_NAN_PROPAGATION
1647*61046927SAndroid Build Coastguard Worker    * because otherwise the NaN should have the "signal" bit set.  The
1648*61046927SAndroid Build Coastguard Worker    * __fadd64 will ensure that occurs.
1649*61046927SAndroid Build Coastguard Worker    */
1650*61046927SAndroid Build Coastguard Worker   bool is_positive =
1651*61046927SAndroid Build Coastguard Worker#if defined RELAXED_NAN_PROPAGATION
1652*61046927SAndroid Build Coastguard Worker      int(unpackUint2x32(a).y) >= 0
1653*61046927SAndroid Build Coastguard Worker#else
1654*61046927SAndroid Build Coastguard Worker      __fge64(a, 0ul)
1655*61046927SAndroid Build Coastguard Worker#endif
1656*61046927SAndroid Build Coastguard Worker      ;
1657*61046927SAndroid Build Coastguard Worker   uint64_t tr = __ftrunc64(a);
1658*61046927SAndroid Build Coastguard Worker
1659*61046927SAndroid Build Coastguard Worker   if (is_positive || __feq64(tr, a)) {
1660*61046927SAndroid Build Coastguard Worker      return tr;
1661*61046927SAndroid Build Coastguard Worker   } else {
1662*61046927SAndroid Build Coastguard Worker      return __fadd64(tr, 0xbff0000000000000ul /* -1.0 */);
1663*61046927SAndroid Build Coastguard Worker   }
1664*61046927SAndroid Build Coastguard Worker}
1665*61046927SAndroid Build Coastguard Worker
1666*61046927SAndroid Build Coastguard Workeruint64_t
1667*61046927SAndroid Build Coastguard Worker__fround64(uint64_t __a)
1668*61046927SAndroid Build Coastguard Worker{
1669*61046927SAndroid Build Coastguard Worker   uvec2 a = unpackUint2x32(__a);
1670*61046927SAndroid Build Coastguard Worker   int unbiasedExp = __extractFloat64Exp(__a) - 1023;
1671*61046927SAndroid Build Coastguard Worker   uint aHi = a.y;
1672*61046927SAndroid Build Coastguard Worker   uint aLo = a.x;
1673*61046927SAndroid Build Coastguard Worker
1674*61046927SAndroid Build Coastguard Worker   if (unbiasedExp < 20) {
1675*61046927SAndroid Build Coastguard Worker      if (unbiasedExp < 0) {
1676*61046927SAndroid Build Coastguard Worker         if ((aHi & 0x80000000u) != 0u && aLo == 0u) {
1677*61046927SAndroid Build Coastguard Worker            return 0ul;
1678*61046927SAndroid Build Coastguard Worker         }
1679*61046927SAndroid Build Coastguard Worker         aHi &= 0x80000000u;
1680*61046927SAndroid Build Coastguard Worker         if ((a.y & 0x000FFFFFu) == 0u && a.x == 0u) {
1681*61046927SAndroid Build Coastguard Worker            aLo = 0u;
1682*61046927SAndroid Build Coastguard Worker            return packUint2x32(uvec2(aLo, aHi));
1683*61046927SAndroid Build Coastguard Worker         }
1684*61046927SAndroid Build Coastguard Worker         aHi = mix(aHi, (aHi | 0x3FF00000u), unbiasedExp == -1);
1685*61046927SAndroid Build Coastguard Worker         aLo = 0u;
1686*61046927SAndroid Build Coastguard Worker      } else {
1687*61046927SAndroid Build Coastguard Worker         uint maskExp = 0x000FFFFFu >> unbiasedExp;
1688*61046927SAndroid Build Coastguard Worker         uint lastBit = maskExp + 1;
1689*61046927SAndroid Build Coastguard Worker         aHi += 0x00080000u >> unbiasedExp;
1690*61046927SAndroid Build Coastguard Worker         if ((aHi & maskExp) == 0u)
1691*61046927SAndroid Build Coastguard Worker            aHi &= ~lastBit;
1692*61046927SAndroid Build Coastguard Worker         aHi &= ~maskExp;
1693*61046927SAndroid Build Coastguard Worker         aLo = 0u;
1694*61046927SAndroid Build Coastguard Worker      }
1695*61046927SAndroid Build Coastguard Worker   } else if (unbiasedExp > 51 || unbiasedExp == 1024) {
1696*61046927SAndroid Build Coastguard Worker      return __a;
1697*61046927SAndroid Build Coastguard Worker   } else {
1698*61046927SAndroid Build Coastguard Worker      uint maskExp = 0xFFFFFFFFu >> (unbiasedExp - 20);
1699*61046927SAndroid Build Coastguard Worker      if ((aLo & maskExp) == 0u)
1700*61046927SAndroid Build Coastguard Worker         return __a;
1701*61046927SAndroid Build Coastguard Worker      uint tmp = aLo + (1u << (51 - unbiasedExp));
1702*61046927SAndroid Build Coastguard Worker      if(tmp < aLo)
1703*61046927SAndroid Build Coastguard Worker         aHi += 1u;
1704*61046927SAndroid Build Coastguard Worker      aLo = tmp;
1705*61046927SAndroid Build Coastguard Worker      aLo &= ~maskExp;
1706*61046927SAndroid Build Coastguard Worker   }
1707*61046927SAndroid Build Coastguard Worker
1708*61046927SAndroid Build Coastguard Worker   return packUint2x32(uvec2(aLo, aHi));
1709*61046927SAndroid Build Coastguard Worker}
1710*61046927SAndroid Build Coastguard Worker
1711*61046927SAndroid Build Coastguard Workeruint64_t
1712*61046927SAndroid Build Coastguard Worker__fmin64(uint64_t a, uint64_t b)
1713*61046927SAndroid Build Coastguard Worker{
1714*61046927SAndroid Build Coastguard Worker   /* This weird layout matters.  Doing the "obvious" thing results in extra
1715*61046927SAndroid Build Coastguard Worker    * flow control being inserted to implement the short-circuit evaluation
1716*61046927SAndroid Build Coastguard Worker    * rules.  Flow control is bad!
1717*61046927SAndroid Build Coastguard Worker    */
1718*61046927SAndroid Build Coastguard Worker   bool b_nan = __is_nan(b);
1719*61046927SAndroid Build Coastguard Worker   bool a_lt_b = __flt64_nonnan_minmax(a, b);
1720*61046927SAndroid Build Coastguard Worker   bool a_nan = __is_nan(a);
1721*61046927SAndroid Build Coastguard Worker
1722*61046927SAndroid Build Coastguard Worker   return (b_nan || a_lt_b) && !a_nan ? a : b;
1723*61046927SAndroid Build Coastguard Worker}
1724*61046927SAndroid Build Coastguard Worker
1725*61046927SAndroid Build Coastguard Workeruint64_t
1726*61046927SAndroid Build Coastguard Worker__fmax64(uint64_t a, uint64_t b)
1727*61046927SAndroid Build Coastguard Worker{
1728*61046927SAndroid Build Coastguard Worker   /* This weird layout matters.  Doing the "obvious" thing results in extra
1729*61046927SAndroid Build Coastguard Worker    * flow control being inserted to implement the short-circuit evaluation
1730*61046927SAndroid Build Coastguard Worker    * rules.  Flow control is bad!
1731*61046927SAndroid Build Coastguard Worker    */
1732*61046927SAndroid Build Coastguard Worker   bool b_nan = __is_nan(b);
1733*61046927SAndroid Build Coastguard Worker   bool a_lt_b = __flt64_nonnan_minmax(a, b);
1734*61046927SAndroid Build Coastguard Worker   bool a_nan = __is_nan(a);
1735*61046927SAndroid Build Coastguard Worker
1736*61046927SAndroid Build Coastguard Worker   return (b_nan || a_lt_b) && !a_nan ? b : a;
1737*61046927SAndroid Build Coastguard Worker}
1738*61046927SAndroid Build Coastguard Worker
1739*61046927SAndroid Build Coastguard Workeruint64_t
1740*61046927SAndroid Build Coastguard Worker__ffract64(uint64_t a)
1741*61046927SAndroid Build Coastguard Worker{
1742*61046927SAndroid Build Coastguard Worker   return __fadd64(a, __fneg64(__ffloor64(a)));
1743*61046927SAndroid Build Coastguard Worker}
1744*61046927SAndroid Build Coastguard Worker
1745*61046927SAndroid Build Coastguard Workerbool
1746*61046927SAndroid Build Coastguard Worker__fisfinite64(uint64_t __a)
1747*61046927SAndroid Build Coastguard Worker{
1748*61046927SAndroid Build Coastguard Worker   return __extractFloat64Exp(__a) != 0x7ff;
1749*61046927SAndroid Build Coastguard Worker}
1750