xref: /aosp_15_r20/external/deqp/framework/delibs/debase/deFloat16.c (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Base Portability Library
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2014 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief 16-bit floating-point math.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "deFloat16.h"
25*35238bceSAndroid Build Coastguard Worker 
26*35238bceSAndroid Build Coastguard Worker DE_BEGIN_EXTERN_C
27*35238bceSAndroid Build Coastguard Worker 
deFloat32To16(float val32)28*35238bceSAndroid Build Coastguard Worker deFloat16 deFloat32To16(float val32)
29*35238bceSAndroid Build Coastguard Worker {
30*35238bceSAndroid Build Coastguard Worker     uint32_t sign;
31*35238bceSAndroid Build Coastguard Worker     int expotent;
32*35238bceSAndroid Build Coastguard Worker     uint32_t mantissa;
33*35238bceSAndroid Build Coastguard Worker     union
34*35238bceSAndroid Build Coastguard Worker     {
35*35238bceSAndroid Build Coastguard Worker         float f;
36*35238bceSAndroid Build Coastguard Worker         uint32_t u;
37*35238bceSAndroid Build Coastguard Worker     } x;
38*35238bceSAndroid Build Coastguard Worker 
39*35238bceSAndroid Build Coastguard Worker     x.f      = val32;
40*35238bceSAndroid Build Coastguard Worker     sign     = (x.u >> 16u) & 0x00008000u;
41*35238bceSAndroid Build Coastguard Worker     expotent = (int)((x.u >> 23u) & 0x000000ffu) - (127 - 15);
42*35238bceSAndroid Build Coastguard Worker     mantissa = x.u & 0x007fffffu;
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker     if (expotent <= 0)
45*35238bceSAndroid Build Coastguard Worker     {
46*35238bceSAndroid Build Coastguard Worker         if (expotent < -10)
47*35238bceSAndroid Build Coastguard Worker         {
48*35238bceSAndroid Build Coastguard Worker             /* Rounds to zero. */
49*35238bceSAndroid Build Coastguard Worker             return (deFloat16)sign;
50*35238bceSAndroid Build Coastguard Worker         }
51*35238bceSAndroid Build Coastguard Worker 
52*35238bceSAndroid Build Coastguard Worker         /* Converted to denormalized half, add leading 1 to significand. */
53*35238bceSAndroid Build Coastguard Worker         mantissa = mantissa | 0x00800000u;
54*35238bceSAndroid Build Coastguard Worker 
55*35238bceSAndroid Build Coastguard Worker         /* Round mantissa to nearest (10+e) */
56*35238bceSAndroid Build Coastguard Worker         {
57*35238bceSAndroid Build Coastguard Worker             uint32_t t = 14u - expotent;
58*35238bceSAndroid Build Coastguard Worker             uint32_t a = (1u << (t - 1u)) - 1u;
59*35238bceSAndroid Build Coastguard Worker             uint32_t b = (mantissa >> t) & 1u;
60*35238bceSAndroid Build Coastguard Worker 
61*35238bceSAndroid Build Coastguard Worker             mantissa = (mantissa + a + b) >> t;
62*35238bceSAndroid Build Coastguard Worker         }
63*35238bceSAndroid Build Coastguard Worker 
64*35238bceSAndroid Build Coastguard Worker         return (deFloat16)(sign | mantissa);
65*35238bceSAndroid Build Coastguard Worker     }
66*35238bceSAndroid Build Coastguard Worker     else if (expotent == 0xff - (127 - 15))
67*35238bceSAndroid Build Coastguard Worker     {
68*35238bceSAndroid Build Coastguard Worker         if (mantissa == 0u)
69*35238bceSAndroid Build Coastguard Worker         {
70*35238bceSAndroid Build Coastguard Worker             /* InF */
71*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u);
72*35238bceSAndroid Build Coastguard Worker         }
73*35238bceSAndroid Build Coastguard Worker         else
74*35238bceSAndroid Build Coastguard Worker         {
75*35238bceSAndroid Build Coastguard Worker             /* NaN */
76*35238bceSAndroid Build Coastguard Worker             mantissa >>= 13u;
77*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u | mantissa | (mantissa == 0u));
78*35238bceSAndroid Build Coastguard Worker         }
79*35238bceSAndroid Build Coastguard Worker     }
80*35238bceSAndroid Build Coastguard Worker     else
81*35238bceSAndroid Build Coastguard Worker     {
82*35238bceSAndroid Build Coastguard Worker         /* Normalized float. */
83*35238bceSAndroid Build Coastguard Worker         mantissa = mantissa + 0x00000fffu + ((mantissa >> 13u) & 1u);
84*35238bceSAndroid Build Coastguard Worker 
85*35238bceSAndroid Build Coastguard Worker         if (mantissa & 0x00800000u)
86*35238bceSAndroid Build Coastguard Worker         {
87*35238bceSAndroid Build Coastguard Worker             /* Overflow in mantissa. */
88*35238bceSAndroid Build Coastguard Worker             mantissa = 0u;
89*35238bceSAndroid Build Coastguard Worker             expotent += 1;
90*35238bceSAndroid Build Coastguard Worker         }
91*35238bceSAndroid Build Coastguard Worker 
92*35238bceSAndroid Build Coastguard Worker         if (expotent > 30)
93*35238bceSAndroid Build Coastguard Worker         {
94*35238bceSAndroid Build Coastguard Worker             /* \todo [pyry] Cause hw fp overflow */
95*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u);
96*35238bceSAndroid Build Coastguard Worker         }
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker         return (deFloat16)(sign | ((uint32_t)expotent << 10u) | (mantissa >> 13u));
99*35238bceSAndroid Build Coastguard Worker     }
100*35238bceSAndroid Build Coastguard Worker }
101*35238bceSAndroid Build Coastguard Worker 
deFloat64To16(double val64)102*35238bceSAndroid Build Coastguard Worker deFloat16 deFloat64To16(double val64)
103*35238bceSAndroid Build Coastguard Worker {
104*35238bceSAndroid Build Coastguard Worker     uint64_t sign;
105*35238bceSAndroid Build Coastguard Worker     long expotent;
106*35238bceSAndroid Build Coastguard Worker     uint64_t mantissa;
107*35238bceSAndroid Build Coastguard Worker     union
108*35238bceSAndroid Build Coastguard Worker     {
109*35238bceSAndroid Build Coastguard Worker         double f;
110*35238bceSAndroid Build Coastguard Worker         uint64_t u;
111*35238bceSAndroid Build Coastguard Worker     } x;
112*35238bceSAndroid Build Coastguard Worker 
113*35238bceSAndroid Build Coastguard Worker     x.f      = val64;
114*35238bceSAndroid Build Coastguard Worker     sign     = (x.u >> 48u) & 0x00008000u;
115*35238bceSAndroid Build Coastguard Worker     expotent = (long int)((x.u >> 52u) & 0x000007ffu) - (1023 - 15);
116*35238bceSAndroid Build Coastguard Worker     mantissa = x.u & 0x00fffffffffffffu;
117*35238bceSAndroid Build Coastguard Worker 
118*35238bceSAndroid Build Coastguard Worker     if (expotent <= 0)
119*35238bceSAndroid Build Coastguard Worker     {
120*35238bceSAndroid Build Coastguard Worker         if (expotent < -10)
121*35238bceSAndroid Build Coastguard Worker         {
122*35238bceSAndroid Build Coastguard Worker             /* Rounds to zero. */
123*35238bceSAndroid Build Coastguard Worker             return (deFloat16)sign;
124*35238bceSAndroid Build Coastguard Worker         }
125*35238bceSAndroid Build Coastguard Worker 
126*35238bceSAndroid Build Coastguard Worker         /* Converted to denormalized half, add leading 1 to significand. */
127*35238bceSAndroid Build Coastguard Worker         mantissa = mantissa | 0x0010000000000000u;
128*35238bceSAndroid Build Coastguard Worker 
129*35238bceSAndroid Build Coastguard Worker         /* Round mantissa to nearest (10+e) */
130*35238bceSAndroid Build Coastguard Worker         {
131*35238bceSAndroid Build Coastguard Worker             uint64_t t = 43u - expotent;
132*35238bceSAndroid Build Coastguard Worker             uint64_t a = (1u << (t - 1u)) - 1u;
133*35238bceSAndroid Build Coastguard Worker             uint64_t b = (mantissa >> t) & 1u;
134*35238bceSAndroid Build Coastguard Worker 
135*35238bceSAndroid Build Coastguard Worker             mantissa = (mantissa + a + b) >> t;
136*35238bceSAndroid Build Coastguard Worker         }
137*35238bceSAndroid Build Coastguard Worker 
138*35238bceSAndroid Build Coastguard Worker         return (deFloat16)(sign | mantissa);
139*35238bceSAndroid Build Coastguard Worker     }
140*35238bceSAndroid Build Coastguard Worker     else if (expotent == 0x7ff - (1023 - 15))
141*35238bceSAndroid Build Coastguard Worker     {
142*35238bceSAndroid Build Coastguard Worker         if (mantissa == 0u)
143*35238bceSAndroid Build Coastguard Worker         {
144*35238bceSAndroid Build Coastguard Worker             /* InF */
145*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u);
146*35238bceSAndroid Build Coastguard Worker         }
147*35238bceSAndroid Build Coastguard Worker         else
148*35238bceSAndroid Build Coastguard Worker         {
149*35238bceSAndroid Build Coastguard Worker             /* NaN */
150*35238bceSAndroid Build Coastguard Worker             mantissa >>= 42u;
151*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u | mantissa | (mantissa == 0u));
152*35238bceSAndroid Build Coastguard Worker         }
153*35238bceSAndroid Build Coastguard Worker     }
154*35238bceSAndroid Build Coastguard Worker     else
155*35238bceSAndroid Build Coastguard Worker     {
156*35238bceSAndroid Build Coastguard Worker         /* Normalized float. */
157*35238bceSAndroid Build Coastguard Worker         mantissa = mantissa + 0x000001ffffffffffu + ((mantissa >> 42u) & 1u);
158*35238bceSAndroid Build Coastguard Worker 
159*35238bceSAndroid Build Coastguard Worker         if (mantissa & 0x010000000000000u)
160*35238bceSAndroid Build Coastguard Worker         {
161*35238bceSAndroid Build Coastguard Worker             /* Overflow in mantissa. */
162*35238bceSAndroid Build Coastguard Worker             mantissa = 0u;
163*35238bceSAndroid Build Coastguard Worker             expotent += 1;
164*35238bceSAndroid Build Coastguard Worker         }
165*35238bceSAndroid Build Coastguard Worker 
166*35238bceSAndroid Build Coastguard Worker         if (expotent > 30)
167*35238bceSAndroid Build Coastguard Worker         {
168*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u);
169*35238bceSAndroid Build Coastguard Worker         }
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker         return (deFloat16)(sign | ((uint32_t)expotent << 10u) | (mantissa >> 42u));
172*35238bceSAndroid Build Coastguard Worker     }
173*35238bceSAndroid Build Coastguard Worker }
174*35238bceSAndroid Build Coastguard Worker 
175*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
176*35238bceSAndroid Build Coastguard Worker  * \brief Round the given number `val` to nearest even by discarding
177*35238bceSAndroid Build Coastguard Worker  *        the last `numBitsToDiscard` bits.
178*35238bceSAndroid Build Coastguard Worker  * \param val value to round
179*35238bceSAndroid Build Coastguard Worker  * \param numBitsToDiscard number of (least significant) bits to discard
180*35238bceSAndroid Build Coastguard Worker  * \return The rounded value with the last `numBitsToDiscard` removed
181*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
roundToNearestEven(uint32_t val,const uint32_t numBitsToDiscard)182*35238bceSAndroid Build Coastguard Worker static uint32_t roundToNearestEven(uint32_t val, const uint32_t numBitsToDiscard)
183*35238bceSAndroid Build Coastguard Worker {
184*35238bceSAndroid Build Coastguard Worker     const uint32_t lastBits = val & ((1 << numBitsToDiscard) - 1);
185*35238bceSAndroid Build Coastguard Worker     const uint32_t headBit  = val & (1 << (numBitsToDiscard - 1));
186*35238bceSAndroid Build Coastguard Worker 
187*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBitsToDiscard > 0 && numBitsToDiscard < 32); /* Make sure no overflow. */
188*35238bceSAndroid Build Coastguard Worker     val >>= numBitsToDiscard;
189*35238bceSAndroid Build Coastguard Worker 
190*35238bceSAndroid Build Coastguard Worker     if (headBit == 0)
191*35238bceSAndroid Build Coastguard Worker     {
192*35238bceSAndroid Build Coastguard Worker         return val;
193*35238bceSAndroid Build Coastguard Worker     }
194*35238bceSAndroid Build Coastguard Worker     else if (headBit == lastBits)
195*35238bceSAndroid Build Coastguard Worker     {
196*35238bceSAndroid Build Coastguard Worker         if ((val & 0x1) == 0x1)
197*35238bceSAndroid Build Coastguard Worker         {
198*35238bceSAndroid Build Coastguard Worker             return val + 1;
199*35238bceSAndroid Build Coastguard Worker         }
200*35238bceSAndroid Build Coastguard Worker         else
201*35238bceSAndroid Build Coastguard Worker         {
202*35238bceSAndroid Build Coastguard Worker             return val;
203*35238bceSAndroid Build Coastguard Worker         }
204*35238bceSAndroid Build Coastguard Worker     }
205*35238bceSAndroid Build Coastguard Worker     else
206*35238bceSAndroid Build Coastguard Worker     {
207*35238bceSAndroid Build Coastguard Worker         return val + 1;
208*35238bceSAndroid Build Coastguard Worker     }
209*35238bceSAndroid Build Coastguard Worker }
210*35238bceSAndroid Build Coastguard Worker 
deFloat32To16Round(float val32,deRoundingMode mode)211*35238bceSAndroid Build Coastguard Worker deFloat16 deFloat32To16Round(float val32, deRoundingMode mode)
212*35238bceSAndroid Build Coastguard Worker {
213*35238bceSAndroid Build Coastguard Worker     union
214*35238bceSAndroid Build Coastguard Worker     {
215*35238bceSAndroid Build Coastguard Worker         float f;    /* Interpret as 32-bit float */
216*35238bceSAndroid Build Coastguard Worker         uint32_t u; /* Interpret as 32-bit unsigned integer */
217*35238bceSAndroid Build Coastguard Worker     } x;
218*35238bceSAndroid Build Coastguard Worker     uint32_t sign;  /* sign : 0000 0000 0000 0000 X000 0000 0000 0000 */
219*35238bceSAndroid Build Coastguard Worker     uint32_t exp32; /* exp32: biased exponent for 32-bit floats */
220*35238bceSAndroid Build Coastguard Worker     int exp16;      /* exp16: biased exponent for 16-bit floats */
221*35238bceSAndroid Build Coastguard Worker     uint32_t mantissa;
222*35238bceSAndroid Build Coastguard Worker 
223*35238bceSAndroid Build Coastguard Worker     /* We only support these two rounding modes for now */
224*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(mode == DE_ROUNDINGMODE_TO_ZERO || mode == DE_ROUNDINGMODE_TO_NEAREST_EVEN);
225*35238bceSAndroid Build Coastguard Worker 
226*35238bceSAndroid Build Coastguard Worker     x.f      = val32;
227*35238bceSAndroid Build Coastguard Worker     sign     = (x.u >> 16u) & 0x00008000u;
228*35238bceSAndroid Build Coastguard Worker     exp32    = (x.u >> 23u) & 0x000000ffu;
229*35238bceSAndroid Build Coastguard Worker     exp16    = (int)(exp32)-127 + 15; /* 15/127: exponent bias for 16-bit/32-bit floats */
230*35238bceSAndroid Build Coastguard Worker     mantissa = x.u & 0x007fffffu;
231*35238bceSAndroid Build Coastguard Worker 
232*35238bceSAndroid Build Coastguard Worker     /* Case: zero and denormalized floats */
233*35238bceSAndroid Build Coastguard Worker     if (exp32 == 0)
234*35238bceSAndroid Build Coastguard Worker     {
235*35238bceSAndroid Build Coastguard Worker         /* Denormalized floats are < 2^(1-127), not representable in 16-bit floats, rounding to zero. */
236*35238bceSAndroid Build Coastguard Worker         return (deFloat16)sign;
237*35238bceSAndroid Build Coastguard Worker     }
238*35238bceSAndroid Build Coastguard Worker     /* Case: Inf and NaN */
239*35238bceSAndroid Build Coastguard Worker     else if (exp32 == 0x000000ffu)
240*35238bceSAndroid Build Coastguard Worker     {
241*35238bceSAndroid Build Coastguard Worker         if (mantissa == 0u)
242*35238bceSAndroid Build Coastguard Worker         {
243*35238bceSAndroid Build Coastguard Worker             /* Inf */
244*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u);
245*35238bceSAndroid Build Coastguard Worker         }
246*35238bceSAndroid Build Coastguard Worker         else
247*35238bceSAndroid Build Coastguard Worker         {
248*35238bceSAndroid Build Coastguard Worker             /* NaN */
249*35238bceSAndroid Build Coastguard Worker             mantissa >>= 13u; /* 16-bit floats has 10-bit for mantissa, 13-bit less than 32-bit floats. */
250*35238bceSAndroid Build Coastguard Worker             /* Make sure we don't turn NaN into zero by | (mantissa == 0). */
251*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u | mantissa | (mantissa == 0u));
252*35238bceSAndroid Build Coastguard Worker         }
253*35238bceSAndroid Build Coastguard Worker     }
254*35238bceSAndroid Build Coastguard Worker     /* The following are cases for normalized floats.
255*35238bceSAndroid Build Coastguard Worker      *
256*35238bceSAndroid Build Coastguard Worker      * * If exp16 is less than 0, we are experiencing underflow for the exponent. To encode this underflowed exponent,
257*35238bceSAndroid Build Coastguard Worker      *   we can only shift the mantissa further right.
258*35238bceSAndroid Build Coastguard Worker      *   The real exponent is exp16 - 15. A denormalized 16-bit float can represent -14 via its exponent.
259*35238bceSAndroid Build Coastguard Worker      *   Note that the most significant bit in the mantissa of a denormalized float is already -1 as for exponent.
260*35238bceSAndroid Build Coastguard Worker      *   So, we just need to right shift the mantissa -exp16 bits.
261*35238bceSAndroid Build Coastguard Worker      * * If exp16 is 0, mantissa shifting requirement is similar to the above.
262*35238bceSAndroid Build Coastguard Worker      * * If exp16 is greater than 30 (0b11110), we are experiencing overflow for the exponent of 16-bit normalized floats.
263*35238bceSAndroid Build Coastguard Worker      */
264*35238bceSAndroid Build Coastguard Worker     /* Case: normalized floats -> zero */
265*35238bceSAndroid Build Coastguard Worker     else if (exp16 < -10)
266*35238bceSAndroid Build Coastguard Worker     {
267*35238bceSAndroid Build Coastguard Worker         /* 16-bit floats have only 10 bits for mantissa. Minimal 16-bit denormalized float is (2^-10) * (2^-14). */
268*35238bceSAndroid Build Coastguard Worker         /* Expecting a number < (2^-10) * (2^-14) here, not representable, round to zero. */
269*35238bceSAndroid Build Coastguard Worker         return (deFloat16)sign;
270*35238bceSAndroid Build Coastguard Worker     }
271*35238bceSAndroid Build Coastguard Worker     /* Case: normalized floats -> zero and denormalized halfs */
272*35238bceSAndroid Build Coastguard Worker     else if (exp16 <= 0)
273*35238bceSAndroid Build Coastguard Worker     {
274*35238bceSAndroid Build Coastguard Worker         /* Add the implicit leading 1 in mormalized float to mantissa. */
275*35238bceSAndroid Build Coastguard Worker         mantissa |= 0x00800000u;
276*35238bceSAndroid Build Coastguard Worker         /* We have a (23 + 1)-bit mantissa, but 16-bit floats only expect 10-bit mantissa.
277*35238bceSAndroid Build Coastguard Worker          * Need to discard the last 14-bits considering rounding mode.
278*35238bceSAndroid Build Coastguard Worker          * We also need to shift right -exp16 bits to encode the underflowed exponent.
279*35238bceSAndroid Build Coastguard Worker          */
280*35238bceSAndroid Build Coastguard Worker         if (mode == DE_ROUNDINGMODE_TO_ZERO)
281*35238bceSAndroid Build Coastguard Worker         {
282*35238bceSAndroid Build Coastguard Worker             mantissa >>= (14 - exp16);
283*35238bceSAndroid Build Coastguard Worker         }
284*35238bceSAndroid Build Coastguard Worker         else
285*35238bceSAndroid Build Coastguard Worker         {
286*35238bceSAndroid Build Coastguard Worker             /* mantissa in the above may exceed 10-bits, in which case overflow happens.
287*35238bceSAndroid Build Coastguard Worker              * The overflowed bit is automatically carried to exponent then.
288*35238bceSAndroid Build Coastguard Worker              */
289*35238bceSAndroid Build Coastguard Worker             mantissa = roundToNearestEven(mantissa, 14 - exp16);
290*35238bceSAndroid Build Coastguard Worker         }
291*35238bceSAndroid Build Coastguard Worker         return (deFloat16)(sign | mantissa);
292*35238bceSAndroid Build Coastguard Worker     }
293*35238bceSAndroid Build Coastguard Worker     /* Case: normalized floats -> normalized floats */
294*35238bceSAndroid Build Coastguard Worker     else if (exp16 <= 30)
295*35238bceSAndroid Build Coastguard Worker     {
296*35238bceSAndroid Build Coastguard Worker         if (mode == DE_ROUNDINGMODE_TO_ZERO)
297*35238bceSAndroid Build Coastguard Worker         {
298*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | ((uint32_t)exp16 << 10u) | (mantissa >> 13u));
299*35238bceSAndroid Build Coastguard Worker         }
300*35238bceSAndroid Build Coastguard Worker         else
301*35238bceSAndroid Build Coastguard Worker         {
302*35238bceSAndroid Build Coastguard Worker             mantissa = roundToNearestEven(mantissa, 13);
303*35238bceSAndroid Build Coastguard Worker             /* Handle overflow. exp16 may overflow (and become Inf) itself, but that's correct. */
304*35238bceSAndroid Build Coastguard Worker             exp16 = (exp16 << 10u) + (mantissa & (1 << 10));
305*35238bceSAndroid Build Coastguard Worker             mantissa &= (1u << 10) - 1;
306*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | ((uint32_t)exp16) | mantissa);
307*35238bceSAndroid Build Coastguard Worker         }
308*35238bceSAndroid Build Coastguard Worker     }
309*35238bceSAndroid Build Coastguard Worker     /* Case: normalized floats (too large to be representable as 16-bit floats) */
310*35238bceSAndroid Build Coastguard Worker     else
311*35238bceSAndroid Build Coastguard Worker     {
312*35238bceSAndroid Build Coastguard Worker         /* According to IEEE Std 754-2008 Section 7.4,
313*35238bceSAndroid Build Coastguard Worker          * * roundTiesToEven and roundTiesToAway carry all overflows to Inf with the sign
314*35238bceSAndroid Build Coastguard Worker          *   of the intermediate  result.
315*35238bceSAndroid Build Coastguard Worker          * * roundTowardZero carries all overflows to the format's largest finite number
316*35238bceSAndroid Build Coastguard Worker          *   with the sign of the intermediate result.
317*35238bceSAndroid Build Coastguard Worker          */
318*35238bceSAndroid Build Coastguard Worker         if (mode == DE_ROUNDINGMODE_TO_ZERO)
319*35238bceSAndroid Build Coastguard Worker         {
320*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7bffu); /* 111 1011 1111 1111 */
321*35238bceSAndroid Build Coastguard Worker         }
322*35238bceSAndroid Build Coastguard Worker         else
323*35238bceSAndroid Build Coastguard Worker         {
324*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | (0x1f << 10));
325*35238bceSAndroid Build Coastguard Worker         }
326*35238bceSAndroid Build Coastguard Worker     }
327*35238bceSAndroid Build Coastguard Worker 
328*35238bceSAndroid Build Coastguard Worker     /* Make compiler happy */
329*35238bceSAndroid Build Coastguard Worker     return (deFloat16)0;
330*35238bceSAndroid Build Coastguard Worker }
331*35238bceSAndroid Build Coastguard Worker 
332*35238bceSAndroid Build Coastguard Worker /*--------------------------------------------------------------------*//*!
333*35238bceSAndroid Build Coastguard Worker  * \brief Round the given number `val` to nearest even by discarding
334*35238bceSAndroid Build Coastguard Worker  *        the last `numBitsToDiscard` bits.
335*35238bceSAndroid Build Coastguard Worker  * \param val value to round
336*35238bceSAndroid Build Coastguard Worker  * \param numBitsToDiscard number of (least significant) bits to discard
337*35238bceSAndroid Build Coastguard Worker  * \return The rounded value with the last `numBitsToDiscard` removed
338*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
roundToNearestEven64(uint64_t val,const uint64_t numBitsToDiscard)339*35238bceSAndroid Build Coastguard Worker static uint64_t roundToNearestEven64(uint64_t val, const uint64_t numBitsToDiscard)
340*35238bceSAndroid Build Coastguard Worker {
341*35238bceSAndroid Build Coastguard Worker     const uint64_t lastBits = val & (((uint64_t)1 << numBitsToDiscard) - 1);
342*35238bceSAndroid Build Coastguard Worker     const uint64_t headBit  = val & ((uint64_t)1 << (numBitsToDiscard - 1));
343*35238bceSAndroid Build Coastguard Worker 
344*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(numBitsToDiscard > 0 && numBitsToDiscard < 64); /* Make sure no overflow. */
345*35238bceSAndroid Build Coastguard Worker     val >>= numBitsToDiscard;
346*35238bceSAndroid Build Coastguard Worker 
347*35238bceSAndroid Build Coastguard Worker     if (headBit == 0)
348*35238bceSAndroid Build Coastguard Worker     {
349*35238bceSAndroid Build Coastguard Worker         return val;
350*35238bceSAndroid Build Coastguard Worker     }
351*35238bceSAndroid Build Coastguard Worker     else if (headBit == lastBits)
352*35238bceSAndroid Build Coastguard Worker     {
353*35238bceSAndroid Build Coastguard Worker         if ((val & 0x1) == 0x1)
354*35238bceSAndroid Build Coastguard Worker         {
355*35238bceSAndroid Build Coastguard Worker             return val + 1;
356*35238bceSAndroid Build Coastguard Worker         }
357*35238bceSAndroid Build Coastguard Worker         else
358*35238bceSAndroid Build Coastguard Worker         {
359*35238bceSAndroid Build Coastguard Worker             return val;
360*35238bceSAndroid Build Coastguard Worker         }
361*35238bceSAndroid Build Coastguard Worker     }
362*35238bceSAndroid Build Coastguard Worker     else
363*35238bceSAndroid Build Coastguard Worker     {
364*35238bceSAndroid Build Coastguard Worker         return val + 1;
365*35238bceSAndroid Build Coastguard Worker     }
366*35238bceSAndroid Build Coastguard Worker }
367*35238bceSAndroid Build Coastguard Worker 
deFloat64To16Round(double val64,deRoundingMode mode)368*35238bceSAndroid Build Coastguard Worker deFloat16 deFloat64To16Round(double val64, deRoundingMode mode)
369*35238bceSAndroid Build Coastguard Worker {
370*35238bceSAndroid Build Coastguard Worker     union
371*35238bceSAndroid Build Coastguard Worker     {
372*35238bceSAndroid Build Coastguard Worker         double f;   /* Interpret as 64-bit float */
373*35238bceSAndroid Build Coastguard Worker         uint64_t u; /* Interpret as 64-bit unsigned integer */
374*35238bceSAndroid Build Coastguard Worker     } x;
375*35238bceSAndroid Build Coastguard Worker     uint64_t sign;  /* sign : 0000 0000 0000 0000 X000 0000 0000 0000 */
376*35238bceSAndroid Build Coastguard Worker     uint64_t exp64; /* exp32: biased exponent for 64-bit floats */
377*35238bceSAndroid Build Coastguard Worker     int exp16;      /* exp16: biased exponent for 16-bit floats */
378*35238bceSAndroid Build Coastguard Worker     uint64_t mantissa;
379*35238bceSAndroid Build Coastguard Worker 
380*35238bceSAndroid Build Coastguard Worker     /* We only support these two rounding modes for now */
381*35238bceSAndroid Build Coastguard Worker     DE_ASSERT(mode == DE_ROUNDINGMODE_TO_ZERO || mode == DE_ROUNDINGMODE_TO_NEAREST_EVEN);
382*35238bceSAndroid Build Coastguard Worker 
383*35238bceSAndroid Build Coastguard Worker     x.f      = val64;
384*35238bceSAndroid Build Coastguard Worker     sign     = (x.u >> 48u) & 0x00008000u;
385*35238bceSAndroid Build Coastguard Worker     exp64    = (x.u >> 52u) & 0x000007ffu;
386*35238bceSAndroid Build Coastguard Worker     exp16    = (int)(exp64)-1023 + 15; /* 15/127: exponent bias for 16-bit/32-bit floats */
387*35238bceSAndroid Build Coastguard Worker     mantissa = x.u & 0x00fffffffffffffu;
388*35238bceSAndroid Build Coastguard Worker 
389*35238bceSAndroid Build Coastguard Worker     /* Case: zero and denormalized floats */
390*35238bceSAndroid Build Coastguard Worker     if (exp64 == 0)
391*35238bceSAndroid Build Coastguard Worker     {
392*35238bceSAndroid Build Coastguard Worker         /* Denormalized floats are < 2^(1-1023), not representable in 16-bit floats, rounding to zero. */
393*35238bceSAndroid Build Coastguard Worker         return (deFloat16)sign;
394*35238bceSAndroid Build Coastguard Worker     }
395*35238bceSAndroid Build Coastguard Worker     /* Case: Inf and NaN */
396*35238bceSAndroid Build Coastguard Worker     else if (exp64 == 0x000007ffu)
397*35238bceSAndroid Build Coastguard Worker     {
398*35238bceSAndroid Build Coastguard Worker         if (mantissa == 0u)
399*35238bceSAndroid Build Coastguard Worker         {
400*35238bceSAndroid Build Coastguard Worker             /* Inf */
401*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u);
402*35238bceSAndroid Build Coastguard Worker         }
403*35238bceSAndroid Build Coastguard Worker         else
404*35238bceSAndroid Build Coastguard Worker         {
405*35238bceSAndroid Build Coastguard Worker             /* NaN */
406*35238bceSAndroid Build Coastguard Worker             mantissa >>= 42u; /* 16-bit floats has 10-bit for mantissa, 42-bit less than 64-bit floats. */
407*35238bceSAndroid Build Coastguard Worker             /* Make sure we don't turn NaN into zero by | (mantissa == 0). */
408*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7c00u | mantissa | (mantissa == 0u));
409*35238bceSAndroid Build Coastguard Worker         }
410*35238bceSAndroid Build Coastguard Worker     }
411*35238bceSAndroid Build Coastguard Worker     /* The following are cases for normalized floats.
412*35238bceSAndroid Build Coastguard Worker      *
413*35238bceSAndroid Build Coastguard Worker      * * If exp16 is less than 0, we are experiencing underflow for the exponent. To encode this underflowed exponent,
414*35238bceSAndroid Build Coastguard Worker      *   we can only shift the mantissa further right.
415*35238bceSAndroid Build Coastguard Worker      *   The real exponent is exp16 - 15. A denormalized 16-bit float can represent -14 via its exponent.
416*35238bceSAndroid Build Coastguard Worker      *   Note that the most significant bit in the mantissa of a denormalized float is already -1 as for exponent.
417*35238bceSAndroid Build Coastguard Worker      *   So, we just need to right shift the mantissa -exp16 bits.
418*35238bceSAndroid Build Coastguard Worker      * * If exp16 is 0, mantissa shifting requirement is similar to the above.
419*35238bceSAndroid Build Coastguard Worker      * * If exp16 is greater than 30 (0b11110), we are experiencing overflow for the exponent of 16-bit normalized floats.
420*35238bceSAndroid Build Coastguard Worker      */
421*35238bceSAndroid Build Coastguard Worker     /* Case: normalized floats -> zero */
422*35238bceSAndroid Build Coastguard Worker     else if (exp16 < -10)
423*35238bceSAndroid Build Coastguard Worker     {
424*35238bceSAndroid Build Coastguard Worker         /* 16-bit floats have only 10 bits for mantissa. Minimal 16-bit denormalized float is (2^-10) * (2^-14). */
425*35238bceSAndroid Build Coastguard Worker         /* Expecting a number < (2^-10) * (2^-14) here, not representable, round to zero. */
426*35238bceSAndroid Build Coastguard Worker         return (deFloat16)sign;
427*35238bceSAndroid Build Coastguard Worker     }
428*35238bceSAndroid Build Coastguard Worker     /* Case: normalized floats -> zero and denormalized halfs */
429*35238bceSAndroid Build Coastguard Worker     else if (exp16 <= 0)
430*35238bceSAndroid Build Coastguard Worker     {
431*35238bceSAndroid Build Coastguard Worker         /* Add the implicit leading 1 in mormalized float to mantissa. */
432*35238bceSAndroid Build Coastguard Worker         mantissa |= 0x0010000000000000u;
433*35238bceSAndroid Build Coastguard Worker         /* We have a (23 + 1)-bit mantissa, but 16-bit floats only expect 10-bit mantissa.
434*35238bceSAndroid Build Coastguard Worker          * Need to discard the last 14-bits considering rounding mode.
435*35238bceSAndroid Build Coastguard Worker          * We also need to shift right -exp16 bits to encode the underflowed exponent.
436*35238bceSAndroid Build Coastguard Worker          */
437*35238bceSAndroid Build Coastguard Worker         if (mode == DE_ROUNDINGMODE_TO_ZERO)
438*35238bceSAndroid Build Coastguard Worker         {
439*35238bceSAndroid Build Coastguard Worker             mantissa >>= (43 - exp16);
440*35238bceSAndroid Build Coastguard Worker         }
441*35238bceSAndroid Build Coastguard Worker         else
442*35238bceSAndroid Build Coastguard Worker         {
443*35238bceSAndroid Build Coastguard Worker             /* mantissa in the above may exceed 10-bits, in which case overflow happens.
444*35238bceSAndroid Build Coastguard Worker              * The overflowed bit is automatically carried to exponent then.
445*35238bceSAndroid Build Coastguard Worker              */
446*35238bceSAndroid Build Coastguard Worker             mantissa = roundToNearestEven64(mantissa, 43 - exp16);
447*35238bceSAndroid Build Coastguard Worker         }
448*35238bceSAndroid Build Coastguard Worker         return (deFloat16)(sign | mantissa);
449*35238bceSAndroid Build Coastguard Worker     }
450*35238bceSAndroid Build Coastguard Worker     /* Case: normalized floats -> normalized floats */
451*35238bceSAndroid Build Coastguard Worker     else if (exp16 <= 30)
452*35238bceSAndroid Build Coastguard Worker     {
453*35238bceSAndroid Build Coastguard Worker         if (mode == DE_ROUNDINGMODE_TO_ZERO)
454*35238bceSAndroid Build Coastguard Worker         {
455*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | ((uint32_t)exp16 << 10u) | (mantissa >> 42u));
456*35238bceSAndroid Build Coastguard Worker         }
457*35238bceSAndroid Build Coastguard Worker         else
458*35238bceSAndroid Build Coastguard Worker         {
459*35238bceSAndroid Build Coastguard Worker             mantissa = roundToNearestEven64(mantissa, 42);
460*35238bceSAndroid Build Coastguard Worker             /* Handle overflow. exp16 may overflow (and become Inf) itself, but that's correct. */
461*35238bceSAndroid Build Coastguard Worker             exp16 = (exp16 << 10u) + (deFloat16)(mantissa & (1 << 10));
462*35238bceSAndroid Build Coastguard Worker             mantissa &= (1u << 10) - 1;
463*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | ((uint32_t)exp16) | mantissa);
464*35238bceSAndroid Build Coastguard Worker         }
465*35238bceSAndroid Build Coastguard Worker     }
466*35238bceSAndroid Build Coastguard Worker     /* Case: normalized floats (too large to be representable as 16-bit floats) */
467*35238bceSAndroid Build Coastguard Worker     else
468*35238bceSAndroid Build Coastguard Worker     {
469*35238bceSAndroid Build Coastguard Worker         /* According to IEEE Std 754-2008 Section 7.4,
470*35238bceSAndroid Build Coastguard Worker          * * roundTiesToEven and roundTiesToAway carry all overflows to Inf with the sign
471*35238bceSAndroid Build Coastguard Worker          *   of the intermediate  result.
472*35238bceSAndroid Build Coastguard Worker          * * roundTowardZero carries all overflows to the format's largest finite number
473*35238bceSAndroid Build Coastguard Worker          *   with the sign of the intermediate result.
474*35238bceSAndroid Build Coastguard Worker          */
475*35238bceSAndroid Build Coastguard Worker         if (mode == DE_ROUNDINGMODE_TO_ZERO)
476*35238bceSAndroid Build Coastguard Worker         {
477*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | 0x7bffu); /* 111 1011 1111 1111 */
478*35238bceSAndroid Build Coastguard Worker         }
479*35238bceSAndroid Build Coastguard Worker         else
480*35238bceSAndroid Build Coastguard Worker         {
481*35238bceSAndroid Build Coastguard Worker             return (deFloat16)(sign | (0x1f << 10));
482*35238bceSAndroid Build Coastguard Worker         }
483*35238bceSAndroid Build Coastguard Worker     }
484*35238bceSAndroid Build Coastguard Worker 
485*35238bceSAndroid Build Coastguard Worker     /* Make compiler happy */
486*35238bceSAndroid Build Coastguard Worker     return (deFloat16)0;
487*35238bceSAndroid Build Coastguard Worker }
488*35238bceSAndroid Build Coastguard Worker 
deFloat16To32(deFloat16 val16)489*35238bceSAndroid Build Coastguard Worker float deFloat16To32(deFloat16 val16)
490*35238bceSAndroid Build Coastguard Worker {
491*35238bceSAndroid Build Coastguard Worker     uint32_t sign;
492*35238bceSAndroid Build Coastguard Worker     uint32_t expotent;
493*35238bceSAndroid Build Coastguard Worker     uint32_t mantissa;
494*35238bceSAndroid Build Coastguard Worker     union
495*35238bceSAndroid Build Coastguard Worker     {
496*35238bceSAndroid Build Coastguard Worker         float f;
497*35238bceSAndroid Build Coastguard Worker         uint32_t u;
498*35238bceSAndroid Build Coastguard Worker     } x;
499*35238bceSAndroid Build Coastguard Worker 
500*35238bceSAndroid Build Coastguard Worker     x.u = 0u;
501*35238bceSAndroid Build Coastguard Worker 
502*35238bceSAndroid Build Coastguard Worker     sign     = ((uint32_t)val16 >> 15u) & 0x00000001u;
503*35238bceSAndroid Build Coastguard Worker     expotent = ((uint32_t)val16 >> 10u) & 0x0000001fu;
504*35238bceSAndroid Build Coastguard Worker     mantissa = (uint32_t)val16 & 0x000003ffu;
505*35238bceSAndroid Build Coastguard Worker 
506*35238bceSAndroid Build Coastguard Worker     if (expotent == 0u)
507*35238bceSAndroid Build Coastguard Worker     {
508*35238bceSAndroid Build Coastguard Worker         if (mantissa == 0u)
509*35238bceSAndroid Build Coastguard Worker         {
510*35238bceSAndroid Build Coastguard Worker             /* +/- 0 */
511*35238bceSAndroid Build Coastguard Worker             x.u = sign << 31u;
512*35238bceSAndroid Build Coastguard Worker             return x.f;
513*35238bceSAndroid Build Coastguard Worker         }
514*35238bceSAndroid Build Coastguard Worker         else
515*35238bceSAndroid Build Coastguard Worker         {
516*35238bceSAndroid Build Coastguard Worker             /* Denormalized, normalize it. */
517*35238bceSAndroid Build Coastguard Worker 
518*35238bceSAndroid Build Coastguard Worker             while (!(mantissa & 0x00000400u))
519*35238bceSAndroid Build Coastguard Worker             {
520*35238bceSAndroid Build Coastguard Worker                 mantissa <<= 1u;
521*35238bceSAndroid Build Coastguard Worker                 expotent -= 1u;
522*35238bceSAndroid Build Coastguard Worker             }
523*35238bceSAndroid Build Coastguard Worker 
524*35238bceSAndroid Build Coastguard Worker             expotent += 1u;
525*35238bceSAndroid Build Coastguard Worker             mantissa &= ~0x00000400u;
526*35238bceSAndroid Build Coastguard Worker         }
527*35238bceSAndroid Build Coastguard Worker     }
528*35238bceSAndroid Build Coastguard Worker     else if (expotent == 31u)
529*35238bceSAndroid Build Coastguard Worker     {
530*35238bceSAndroid Build Coastguard Worker         if (mantissa == 0u)
531*35238bceSAndroid Build Coastguard Worker         {
532*35238bceSAndroid Build Coastguard Worker             /* +/- InF */
533*35238bceSAndroid Build Coastguard Worker             x.u = (sign << 31u) | 0x7f800000u;
534*35238bceSAndroid Build Coastguard Worker             return x.f;
535*35238bceSAndroid Build Coastguard Worker         }
536*35238bceSAndroid Build Coastguard Worker         else
537*35238bceSAndroid Build Coastguard Worker         {
538*35238bceSAndroid Build Coastguard Worker             /* +/- NaN */
539*35238bceSAndroid Build Coastguard Worker             x.u = (sign << 31u) | 0x7f800000u | (mantissa << 13u);
540*35238bceSAndroid Build Coastguard Worker             return x.f;
541*35238bceSAndroid Build Coastguard Worker         }
542*35238bceSAndroid Build Coastguard Worker     }
543*35238bceSAndroid Build Coastguard Worker 
544*35238bceSAndroid Build Coastguard Worker     expotent = expotent + (127u - 15u);
545*35238bceSAndroid Build Coastguard Worker     mantissa = mantissa << 13u;
546*35238bceSAndroid Build Coastguard Worker 
547*35238bceSAndroid Build Coastguard Worker     x.u = (sign << 31u) | (expotent << 23u) | mantissa;
548*35238bceSAndroid Build Coastguard Worker     return x.f;
549*35238bceSAndroid Build Coastguard Worker }
550*35238bceSAndroid Build Coastguard Worker 
deFloat16To64(deFloat16 val16)551*35238bceSAndroid Build Coastguard Worker double deFloat16To64(deFloat16 val16)
552*35238bceSAndroid Build Coastguard Worker {
553*35238bceSAndroid Build Coastguard Worker     uint64_t sign;
554*35238bceSAndroid Build Coastguard Worker     uint64_t expotent;
555*35238bceSAndroid Build Coastguard Worker     uint64_t mantissa;
556*35238bceSAndroid Build Coastguard Worker     union
557*35238bceSAndroid Build Coastguard Worker     {
558*35238bceSAndroid Build Coastguard Worker         double f;
559*35238bceSAndroid Build Coastguard Worker         uint64_t u;
560*35238bceSAndroid Build Coastguard Worker     } x;
561*35238bceSAndroid Build Coastguard Worker 
562*35238bceSAndroid Build Coastguard Worker     x.u = 0u;
563*35238bceSAndroid Build Coastguard Worker 
564*35238bceSAndroid Build Coastguard Worker     sign     = ((uint32_t)val16 >> 15u) & 0x00000001u;
565*35238bceSAndroid Build Coastguard Worker     expotent = ((uint32_t)val16 >> 10u) & 0x0000001fu;
566*35238bceSAndroid Build Coastguard Worker     mantissa = (uint32_t)val16 & 0x000003ffu;
567*35238bceSAndroid Build Coastguard Worker 
568*35238bceSAndroid Build Coastguard Worker     if (expotent == 0u)
569*35238bceSAndroid Build Coastguard Worker     {
570*35238bceSAndroid Build Coastguard Worker         if (mantissa == 0u)
571*35238bceSAndroid Build Coastguard Worker         {
572*35238bceSAndroid Build Coastguard Worker             /* +/- 0 */
573*35238bceSAndroid Build Coastguard Worker             x.u = sign << 63u;
574*35238bceSAndroid Build Coastguard Worker             return x.f;
575*35238bceSAndroid Build Coastguard Worker         }
576*35238bceSAndroid Build Coastguard Worker         else
577*35238bceSAndroid Build Coastguard Worker         {
578*35238bceSAndroid Build Coastguard Worker             /* Denormalized, normalize it. */
579*35238bceSAndroid Build Coastguard Worker 
580*35238bceSAndroid Build Coastguard Worker             while (!(mantissa & 0x00000400u))
581*35238bceSAndroid Build Coastguard Worker             {
582*35238bceSAndroid Build Coastguard Worker                 mantissa <<= 1u;
583*35238bceSAndroid Build Coastguard Worker                 expotent -= 1u;
584*35238bceSAndroid Build Coastguard Worker             }
585*35238bceSAndroid Build Coastguard Worker 
586*35238bceSAndroid Build Coastguard Worker             expotent += 1u;
587*35238bceSAndroid Build Coastguard Worker             mantissa &= ~0x00000400u;
588*35238bceSAndroid Build Coastguard Worker         }
589*35238bceSAndroid Build Coastguard Worker     }
590*35238bceSAndroid Build Coastguard Worker     else if (expotent == 31u)
591*35238bceSAndroid Build Coastguard Worker     {
592*35238bceSAndroid Build Coastguard Worker         if (mantissa == 0u)
593*35238bceSAndroid Build Coastguard Worker         {
594*35238bceSAndroid Build Coastguard Worker             /* +/- InF */
595*35238bceSAndroid Build Coastguard Worker             x.u = (sign << 63u) | 0x7ff0000000000000u;
596*35238bceSAndroid Build Coastguard Worker             return x.f;
597*35238bceSAndroid Build Coastguard Worker         }
598*35238bceSAndroid Build Coastguard Worker         else
599*35238bceSAndroid Build Coastguard Worker         {
600*35238bceSAndroid Build Coastguard Worker             /* +/- NaN */
601*35238bceSAndroid Build Coastguard Worker             x.u = (sign << 63u) | 0x7ff0000000000000u | (mantissa << 42u);
602*35238bceSAndroid Build Coastguard Worker             return x.f;
603*35238bceSAndroid Build Coastguard Worker         }
604*35238bceSAndroid Build Coastguard Worker     }
605*35238bceSAndroid Build Coastguard Worker 
606*35238bceSAndroid Build Coastguard Worker     expotent = expotent + (1023u - 15u);
607*35238bceSAndroid Build Coastguard Worker     mantissa = mantissa << 42u;
608*35238bceSAndroid Build Coastguard Worker 
609*35238bceSAndroid Build Coastguard Worker     x.u = (sign << 63u) | (expotent << 52u) | mantissa;
610*35238bceSAndroid Build Coastguard Worker     return x.f;
611*35238bceSAndroid Build Coastguard Worker }
612*35238bceSAndroid Build Coastguard Worker 
613*35238bceSAndroid Build Coastguard Worker DE_END_EXTERN_C
614