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