annotate libhsail-rt/rt/arithmetic.c @ 144:8f4e72ab4e11

fix segmentation fault caused by nothing next cur_op to end
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Sun, 23 Dec 2018 21:23:56 +0900
parents 84e7813d76e9
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 /* arithmetic.c -- Builtins for HSAIL arithmetic instructions for which
kono
parents:
diff changeset
2 there is no feasible direct gcc GENERIC expression.
kono
parents:
diff changeset
3
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
4 Copyright (C) 2015-2018 Free Software Foundation, Inc.
111
kono
parents:
diff changeset
5 Contributed by Pekka Jaaskelainen <pekka.jaaskelainen@parmance.com>
kono
parents:
diff changeset
6 for General Processor Tech.
kono
parents:
diff changeset
7
kono
parents:
diff changeset
8 Permission is hereby granted, free of charge, to any person obtaining a
kono
parents:
diff changeset
9 copy of this software and associated documentation files
kono
parents:
diff changeset
10 (the "Software"), to deal in the Software without restriction, including
kono
parents:
diff changeset
11 without limitation the rights to use, copy, modify, merge, publish,
kono
parents:
diff changeset
12 distribute, sublicense, and/or sell copies of the Software, and to
kono
parents:
diff changeset
13 permit persons to whom the Software is furnished to do so, subject to
kono
parents:
diff changeset
14 the following conditions:
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 The above copyright notice and this permission notice shall be included
kono
parents:
diff changeset
17 in all copies or substantial portions of the Software.
kono
parents:
diff changeset
18
kono
parents:
diff changeset
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
kono
parents:
diff changeset
20 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
kono
parents:
diff changeset
21 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
kono
parents:
diff changeset
22 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kono
parents:
diff changeset
23 DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
kono
parents:
diff changeset
24 OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
kono
parents:
diff changeset
25 USE OR OTHER DEALINGS IN THE SOFTWARE.
kono
parents:
diff changeset
26 */
kono
parents:
diff changeset
27
kono
parents:
diff changeset
28 #include <stdio.h>
kono
parents:
diff changeset
29 #include <stdint.h>
kono
parents:
diff changeset
30 #include <limits.h>
kono
parents:
diff changeset
31 #include <math.h>
kono
parents:
diff changeset
32 #include <float.h>
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 /* HSAIL defines INT_MIN % -1 to be 0 while with C it's undefined,
kono
parents:
diff changeset
35 and causes an overflow exception at least with gcc and C on IA-32. */
kono
parents:
diff changeset
36
kono
parents:
diff changeset
37 int32_t
kono
parents:
diff changeset
38 __hsail_rem_s32 (int32_t dividend, int32_t divisor)
kono
parents:
diff changeset
39 {
kono
parents:
diff changeset
40 if (dividend == INT_MIN && divisor == -1)
kono
parents:
diff changeset
41 return 0;
kono
parents:
diff changeset
42 else
kono
parents:
diff changeset
43 return dividend % divisor;
kono
parents:
diff changeset
44 }
kono
parents:
diff changeset
45
kono
parents:
diff changeset
46 int64_t
kono
parents:
diff changeset
47 __hsail_rem_s64 (int64_t dividend, int64_t divisor)
kono
parents:
diff changeset
48 {
kono
parents:
diff changeset
49 if (dividend == INT64_MIN && divisor == -1)
kono
parents:
diff changeset
50 return 0;
kono
parents:
diff changeset
51 else
kono
parents:
diff changeset
52 return dividend % divisor;
kono
parents:
diff changeset
53 }
kono
parents:
diff changeset
54
kono
parents:
diff changeset
55 /* HSAIL has defined behavior for min and max when one of the operands is
kono
parents:
diff changeset
56 NaN: in that case the other operand is returned. In C and with gcc's
kono
parents:
diff changeset
57 MIN_EXPR/MAX_EXPR, the returned operand is undefined. */
kono
parents:
diff changeset
58
kono
parents:
diff changeset
59 float
kono
parents:
diff changeset
60 __hsail_min_f32 (float a, float b)
kono
parents:
diff changeset
61 {
kono
parents:
diff changeset
62 if (isnan (a))
kono
parents:
diff changeset
63 return b;
kono
parents:
diff changeset
64 else if (isnan (b))
kono
parents:
diff changeset
65 return a;
kono
parents:
diff changeset
66 else if (a == 0.0f && b == 0.0f)
kono
parents:
diff changeset
67 return signbit (a) ? a : b;
kono
parents:
diff changeset
68 else if (a > b)
kono
parents:
diff changeset
69 return b;
kono
parents:
diff changeset
70 else
kono
parents:
diff changeset
71 return a;
kono
parents:
diff changeset
72 }
kono
parents:
diff changeset
73
kono
parents:
diff changeset
74 double
kono
parents:
diff changeset
75 __hsail_min_f64 (double a, double b)
kono
parents:
diff changeset
76 {
kono
parents:
diff changeset
77 if (isnan (a))
kono
parents:
diff changeset
78 return b;
kono
parents:
diff changeset
79 else if (isnan (b))
kono
parents:
diff changeset
80 return a;
kono
parents:
diff changeset
81 else if (a > b)
kono
parents:
diff changeset
82 return b;
kono
parents:
diff changeset
83 else
kono
parents:
diff changeset
84 return a;
kono
parents:
diff changeset
85 }
kono
parents:
diff changeset
86
kono
parents:
diff changeset
87 float
kono
parents:
diff changeset
88 __hsail_max_f32 (float a, float b)
kono
parents:
diff changeset
89 {
kono
parents:
diff changeset
90 if (isnan (a))
kono
parents:
diff changeset
91 return b;
kono
parents:
diff changeset
92 else if (isnan (b))
kono
parents:
diff changeset
93 return a;
kono
parents:
diff changeset
94 else if (a == 0.0f && b == 0.0f && signbit (a))
kono
parents:
diff changeset
95 return b;
kono
parents:
diff changeset
96 else if (a < b)
kono
parents:
diff changeset
97 return b;
kono
parents:
diff changeset
98 else
kono
parents:
diff changeset
99 return a;
kono
parents:
diff changeset
100 }
kono
parents:
diff changeset
101
kono
parents:
diff changeset
102 double
kono
parents:
diff changeset
103 __hsail_max_f64 (double a, double b)
kono
parents:
diff changeset
104 {
kono
parents:
diff changeset
105 if (isnan (a))
kono
parents:
diff changeset
106 return b;
kono
parents:
diff changeset
107 else if (isnan (b))
kono
parents:
diff changeset
108 return a;
kono
parents:
diff changeset
109 else if (a == 0.0 && b == 0.0 && signbit (a))
kono
parents:
diff changeset
110 return b;
kono
parents:
diff changeset
111 else if (a < b)
kono
parents:
diff changeset
112 return b;
kono
parents:
diff changeset
113 else
kono
parents:
diff changeset
114 return a;
kono
parents:
diff changeset
115 }
kono
parents:
diff changeset
116
kono
parents:
diff changeset
117 uint8_t
kono
parents:
diff changeset
118 __hsail_cvt_zeroi_sat_u8_f32 (float a)
kono
parents:
diff changeset
119 {
kono
parents:
diff changeset
120 if (isnan (a))
kono
parents:
diff changeset
121 return 0;
kono
parents:
diff changeset
122 if (a >= (float) UINT8_MAX)
kono
parents:
diff changeset
123 return UINT8_MAX;
kono
parents:
diff changeset
124 else if (a <= 0.0f)
kono
parents:
diff changeset
125 return 0;
kono
parents:
diff changeset
126 return (uint8_t) a;
kono
parents:
diff changeset
127 }
kono
parents:
diff changeset
128
kono
parents:
diff changeset
129 int8_t
kono
parents:
diff changeset
130 __hsail_cvt_zeroi_sat_s8_f32 (float a)
kono
parents:
diff changeset
131 {
kono
parents:
diff changeset
132 if (isnan (a))
kono
parents:
diff changeset
133 return 0;
kono
parents:
diff changeset
134 if (a >= (float) INT8_MAX)
kono
parents:
diff changeset
135 return INT8_MAX;
kono
parents:
diff changeset
136 if (a <= (float) INT8_MIN)
kono
parents:
diff changeset
137 return INT8_MIN;
kono
parents:
diff changeset
138 return (int8_t) a;
kono
parents:
diff changeset
139 }
kono
parents:
diff changeset
140
kono
parents:
diff changeset
141 uint16_t
kono
parents:
diff changeset
142 __hsail_cvt_zeroi_sat_u16_f32 (float a)
kono
parents:
diff changeset
143 {
kono
parents:
diff changeset
144 if (isnan (a))
kono
parents:
diff changeset
145 return 0;
kono
parents:
diff changeset
146 if (a >= (float) UINT16_MAX)
kono
parents:
diff changeset
147 return UINT16_MAX;
kono
parents:
diff changeset
148 else if (a <= 0.0f)
kono
parents:
diff changeset
149 return 0;
kono
parents:
diff changeset
150 return (uint16_t) a;
kono
parents:
diff changeset
151 }
kono
parents:
diff changeset
152
kono
parents:
diff changeset
153 int16_t
kono
parents:
diff changeset
154 __hsail_cvt_zeroi_sat_s16_f32 (float a)
kono
parents:
diff changeset
155 {
kono
parents:
diff changeset
156 if (isnan (a))
kono
parents:
diff changeset
157 return 0;
kono
parents:
diff changeset
158 if (a >= (float) INT16_MAX)
kono
parents:
diff changeset
159 return INT16_MAX;
kono
parents:
diff changeset
160 if (a <= (float) INT16_MIN)
kono
parents:
diff changeset
161 return INT16_MIN;
kono
parents:
diff changeset
162 return (int16_t) a;
kono
parents:
diff changeset
163 }
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 uint32_t
kono
parents:
diff changeset
166 __hsail_cvt_zeroi_sat_u32_f32 (float a)
kono
parents:
diff changeset
167 {
kono
parents:
diff changeset
168 if (isnan (a))
kono
parents:
diff changeset
169 return 0;
kono
parents:
diff changeset
170 if (a >= (float) UINT32_MAX)
kono
parents:
diff changeset
171 return UINT32_MAX;
kono
parents:
diff changeset
172 else if (a <= 0.0f)
kono
parents:
diff changeset
173 return 0;
kono
parents:
diff changeset
174 return (uint32_t) a;
kono
parents:
diff changeset
175 }
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 int32_t
kono
parents:
diff changeset
178 __hsail_cvt_zeroi_sat_s32_f32 (float a)
kono
parents:
diff changeset
179 {
kono
parents:
diff changeset
180 if (isnan (a))
kono
parents:
diff changeset
181 return 0;
kono
parents:
diff changeset
182 if (a >= (float) INT32_MAX)
kono
parents:
diff changeset
183 return INT32_MAX;
kono
parents:
diff changeset
184 if (a <= (float) INT32_MIN)
kono
parents:
diff changeset
185 return INT32_MIN;
kono
parents:
diff changeset
186 return (int32_t) a;
kono
parents:
diff changeset
187 }
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 uint64_t
kono
parents:
diff changeset
190 __hsail_cvt_zeroi_sat_u64_f32 (float a)
kono
parents:
diff changeset
191 {
kono
parents:
diff changeset
192 if (isnan (a))
kono
parents:
diff changeset
193 return 0;
kono
parents:
diff changeset
194 if (a >= (float) UINT64_MAX)
kono
parents:
diff changeset
195 return UINT64_MAX;
kono
parents:
diff changeset
196 else if (a <= 0.0f)
kono
parents:
diff changeset
197 return 0;
kono
parents:
diff changeset
198 return (uint64_t) a;
kono
parents:
diff changeset
199 }
kono
parents:
diff changeset
200
kono
parents:
diff changeset
201 int64_t
kono
parents:
diff changeset
202 __hsail_cvt_zeroi_sat_s64_f32 (float a)
kono
parents:
diff changeset
203 {
kono
parents:
diff changeset
204 if (isnan (a))
kono
parents:
diff changeset
205 return 0;
kono
parents:
diff changeset
206 if (a >= (float) INT64_MAX)
kono
parents:
diff changeset
207 return INT64_MAX;
kono
parents:
diff changeset
208 if (a <= (float) INT64_MIN)
kono
parents:
diff changeset
209 return INT64_MIN;
kono
parents:
diff changeset
210 return (int64_t) a;
kono
parents:
diff changeset
211 }
kono
parents:
diff changeset
212
kono
parents:
diff changeset
213 uint8_t
kono
parents:
diff changeset
214 __hsail_cvt_zeroi_sat_u8_f64 (double a)
kono
parents:
diff changeset
215 {
kono
parents:
diff changeset
216 if (isnan (a))
kono
parents:
diff changeset
217 return 0;
kono
parents:
diff changeset
218 if (a >= (double) UINT8_MAX)
kono
parents:
diff changeset
219 return UINT8_MAX;
kono
parents:
diff changeset
220 else if (a <= 0.0f)
kono
parents:
diff changeset
221 return 0;
kono
parents:
diff changeset
222 return (uint8_t) a;
kono
parents:
diff changeset
223 }
kono
parents:
diff changeset
224
kono
parents:
diff changeset
225 int8_t
kono
parents:
diff changeset
226 __hsail_cvt_zeroi_sat_s8_f64 (double a)
kono
parents:
diff changeset
227 {
kono
parents:
diff changeset
228 if (isnan (a))
kono
parents:
diff changeset
229 return 0;
kono
parents:
diff changeset
230 if (a >= (double) INT8_MAX)
kono
parents:
diff changeset
231 return INT8_MAX;
kono
parents:
diff changeset
232 if (a <= (double) INT8_MIN)
kono
parents:
diff changeset
233 return INT8_MIN;
kono
parents:
diff changeset
234 return (int8_t) a;
kono
parents:
diff changeset
235 }
kono
parents:
diff changeset
236
kono
parents:
diff changeset
237 uint16_t
kono
parents:
diff changeset
238 __hsail_cvt_zeroi_sat_u16_f64 (double a)
kono
parents:
diff changeset
239 {
kono
parents:
diff changeset
240 if (isnan (a))
kono
parents:
diff changeset
241 return 0;
kono
parents:
diff changeset
242 if (a >= (double) UINT16_MAX)
kono
parents:
diff changeset
243 return UINT16_MAX;
kono
parents:
diff changeset
244 else if (a <= 0.0f)
kono
parents:
diff changeset
245 return 0;
kono
parents:
diff changeset
246 return (uint16_t) a;
kono
parents:
diff changeset
247 }
kono
parents:
diff changeset
248
kono
parents:
diff changeset
249 int16_t
kono
parents:
diff changeset
250 __hsail_cvt_zeroi_sat_s16_f64 (double a)
kono
parents:
diff changeset
251 {
kono
parents:
diff changeset
252 if (isnan (a))
kono
parents:
diff changeset
253 return 0;
kono
parents:
diff changeset
254 if (a >= (double) INT16_MAX)
kono
parents:
diff changeset
255 return INT16_MAX;
kono
parents:
diff changeset
256 if (a <= (double) INT16_MIN)
kono
parents:
diff changeset
257 return INT16_MIN;
kono
parents:
diff changeset
258 return (int16_t) a;
kono
parents:
diff changeset
259 }
kono
parents:
diff changeset
260
kono
parents:
diff changeset
261 uint32_t
kono
parents:
diff changeset
262 __hsail_cvt_zeroi_sat_u32_f64 (double a)
kono
parents:
diff changeset
263 {
kono
parents:
diff changeset
264 if (isnan (a))
kono
parents:
diff changeset
265 return 0;
kono
parents:
diff changeset
266 if (a >= (double) UINT32_MAX)
kono
parents:
diff changeset
267 return UINT32_MAX;
kono
parents:
diff changeset
268 else if (a <= 0.0f)
kono
parents:
diff changeset
269 return 0;
kono
parents:
diff changeset
270 return (uint32_t) a;
kono
parents:
diff changeset
271 }
kono
parents:
diff changeset
272
kono
parents:
diff changeset
273 int32_t
kono
parents:
diff changeset
274 __hsail_cvt_zeroi_sat_s32_f64 (double a)
kono
parents:
diff changeset
275 {
kono
parents:
diff changeset
276 if (isnan (a))
kono
parents:
diff changeset
277 return 0;
kono
parents:
diff changeset
278 if (a >= (double) INT32_MAX)
kono
parents:
diff changeset
279 return INT32_MAX;
kono
parents:
diff changeset
280 if (a <= (double) INT32_MIN)
kono
parents:
diff changeset
281 return INT32_MIN;
kono
parents:
diff changeset
282 return (int32_t) a;
kono
parents:
diff changeset
283 }
kono
parents:
diff changeset
284
kono
parents:
diff changeset
285 uint64_t
kono
parents:
diff changeset
286 __hsail_cvt_zeroi_sat_u64_f64 (double a)
kono
parents:
diff changeset
287 {
kono
parents:
diff changeset
288 if (isnan (a))
kono
parents:
diff changeset
289 return 0;
kono
parents:
diff changeset
290 if (a >= (double) UINT64_MAX)
kono
parents:
diff changeset
291 return UINT64_MAX;
kono
parents:
diff changeset
292 else if (a <= 0.0f)
kono
parents:
diff changeset
293 return 0;
kono
parents:
diff changeset
294 return (uint64_t) a;
kono
parents:
diff changeset
295 }
kono
parents:
diff changeset
296
kono
parents:
diff changeset
297 int64_t
kono
parents:
diff changeset
298 __hsail_cvt_zeroi_sat_s64_f64 (double a)
kono
parents:
diff changeset
299 {
kono
parents:
diff changeset
300 if (isnan (a))
kono
parents:
diff changeset
301 return 0;
kono
parents:
diff changeset
302 if (a >= (double) INT64_MAX)
kono
parents:
diff changeset
303 return INT64_MAX;
kono
parents:
diff changeset
304 if (a <= (double) INT64_MIN)
kono
parents:
diff changeset
305 return INT64_MIN;
kono
parents:
diff changeset
306 return (int64_t) a;
kono
parents:
diff changeset
307 }
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309
kono
parents:
diff changeset
310 /* Flush the operand to zero in case it's a denormalized number.
kono
parents:
diff changeset
311 Do not cause any exceptions in case of NaNs. */
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 float
kono
parents:
diff changeset
314 __hsail_ftz_f32 (float a)
kono
parents:
diff changeset
315 {
kono
parents:
diff changeset
316 if (isnan (a) || isinf (a) || a == 0.0f)
kono
parents:
diff changeset
317 return a;
kono
parents:
diff changeset
318
kono
parents:
diff changeset
319 if (a < 0.0f)
kono
parents:
diff changeset
320 {
kono
parents:
diff changeset
321 if (-a < FLT_MIN)
kono
parents:
diff changeset
322 return -0.0f;
kono
parents:
diff changeset
323 }
kono
parents:
diff changeset
324 else
kono
parents:
diff changeset
325 {
kono
parents:
diff changeset
326 if (a < FLT_MIN)
kono
parents:
diff changeset
327 return 0.0f;
kono
parents:
diff changeset
328 }
kono
parents:
diff changeset
329 return a;
kono
parents:
diff changeset
330 }
kono
parents:
diff changeset
331
kono
parents:
diff changeset
332 #define F16_MIN (6.10e-5)
kono
parents:
diff changeset
333
kono
parents:
diff changeset
334 /* Flush the single precision operand to zero in case it's considered
kono
parents:
diff changeset
335 a denormalized number in case it was a f16. Do not cause any exceptions
kono
parents:
diff changeset
336 in case of NaNs. */
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 float
kono
parents:
diff changeset
339 __hsail_ftz_f32_f16 (float a)
kono
parents:
diff changeset
340 {
kono
parents:
diff changeset
341 if (isnan (a) || isinf (a) || a == 0.0f)
kono
parents:
diff changeset
342 return a;
kono
parents:
diff changeset
343
kono
parents:
diff changeset
344 if (a < 0.0f)
kono
parents:
diff changeset
345 {
kono
parents:
diff changeset
346 if (-a < F16_MIN)
kono
parents:
diff changeset
347 return -0.0f;
kono
parents:
diff changeset
348 }
kono
parents:
diff changeset
349 else
kono
parents:
diff changeset
350 {
kono
parents:
diff changeset
351 if (a < F16_MIN)
kono
parents:
diff changeset
352 return 0.0f;
kono
parents:
diff changeset
353 }
kono
parents:
diff changeset
354 return a;
kono
parents:
diff changeset
355 }
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 double
kono
parents:
diff changeset
358 __hsail_ftz_f64 (double a)
kono
parents:
diff changeset
359 {
kono
parents:
diff changeset
360 if (isnan (a) || isinf (a) || a == 0.0d)
kono
parents:
diff changeset
361 return a;
kono
parents:
diff changeset
362
kono
parents:
diff changeset
363 if (a < 0.0d)
kono
parents:
diff changeset
364 {
kono
parents:
diff changeset
365 if (-a < DBL_MIN)
kono
parents:
diff changeset
366 return -0.0d;
kono
parents:
diff changeset
367 }
kono
parents:
diff changeset
368 else
kono
parents:
diff changeset
369 {
kono
parents:
diff changeset
370 if (a < DBL_MIN)
kono
parents:
diff changeset
371 return 0.0d;
kono
parents:
diff changeset
372 }
kono
parents:
diff changeset
373 return a;
kono
parents:
diff changeset
374 }
kono
parents:
diff changeset
375
kono
parents:
diff changeset
376 uint32_t
kono
parents:
diff changeset
377 __hsail_borrow_u32 (uint32_t a, uint32_t b)
kono
parents:
diff changeset
378 {
kono
parents:
diff changeset
379 return __builtin_sub_overflow_p (a, b, a);
kono
parents:
diff changeset
380 }
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 uint64_t
kono
parents:
diff changeset
383 __hsail_borrow_u64 (uint64_t a, uint64_t b)
kono
parents:
diff changeset
384 {
kono
parents:
diff changeset
385 return __builtin_sub_overflow_p (a, b, a);
kono
parents:
diff changeset
386 }
kono
parents:
diff changeset
387
kono
parents:
diff changeset
388 uint32_t
kono
parents:
diff changeset
389 __hsail_carry_u32 (uint32_t a, uint32_t b)
kono
parents:
diff changeset
390 {
kono
parents:
diff changeset
391 return __builtin_add_overflow_p (a, b, a);
kono
parents:
diff changeset
392 }
kono
parents:
diff changeset
393
kono
parents:
diff changeset
394 uint64_t
kono
parents:
diff changeset
395 __hsail_carry_u64 (uint64_t a, uint64_t b)
kono
parents:
diff changeset
396 {
kono
parents:
diff changeset
397 return __builtin_add_overflow_p (a, b, a);
kono
parents:
diff changeset
398 }
kono
parents:
diff changeset
399
kono
parents:
diff changeset
400 float
kono
parents:
diff changeset
401 __hsail_fract_f32 (float a)
kono
parents:
diff changeset
402 {
kono
parents:
diff changeset
403 int exp;
kono
parents:
diff changeset
404 if (isinf (a))
kono
parents:
diff changeset
405 return signbit (a) == 0 ? 0.0f : -0.0f;
kono
parents:
diff changeset
406 if (isnan (a) || a == 0.0f)
kono
parents:
diff changeset
407 return a;
kono
parents:
diff changeset
408 else
kono
parents:
diff changeset
409 return fminf (a - floorf (a), 0x1.fffffep-1f);
kono
parents:
diff changeset
410 }
kono
parents:
diff changeset
411
kono
parents:
diff changeset
412 double
kono
parents:
diff changeset
413 __hsail_fract_f64 (double a)
kono
parents:
diff changeset
414 {
kono
parents:
diff changeset
415 int exp;
kono
parents:
diff changeset
416 if (isinf (a))
kono
parents:
diff changeset
417 return 0.0f * isinf (a);
kono
parents:
diff changeset
418 if (isnan (a) || a == 0.0f)
kono
parents:
diff changeset
419 return a;
kono
parents:
diff changeset
420 else
kono
parents:
diff changeset
421 return fmin (a - floor (a), 0x1.fffffffffffffp-1d);
kono
parents:
diff changeset
422 }
kono
parents:
diff changeset
423
kono
parents:
diff changeset
424 uint32_t
kono
parents:
diff changeset
425 __hsail_class_f32 (float a, uint32_t flags)
kono
parents:
diff changeset
426 {
kono
parents:
diff changeset
427 return (flags & 0x0001 && isnan (a) && !(*(uint32_t *) &a & (1ul << 22)))
kono
parents:
diff changeset
428 || (flags & 0x0002 && isnan (a) && (*(uint32_t *) &a & (1ul << 22)))
kono
parents:
diff changeset
429 || (flags & 0x0004 && isinf (a) && a < 0.0f)
kono
parents:
diff changeset
430 || (flags & 0x0008 && isnormal (a) && signbit (a))
kono
parents:
diff changeset
431 || (flags & 0x0010 && a < 0.0f && a > -FLT_MIN)
kono
parents:
diff changeset
432 || (flags & 0x0020 && a == 0.0f && signbit (a))
kono
parents:
diff changeset
433 || (flags & 0x0040 && a == 0.0f && !signbit (a))
kono
parents:
diff changeset
434 || (flags & 0x0080 && a > 0.0f && a < FLT_MIN)
kono
parents:
diff changeset
435 || (flags & 0x0100 && isnormal (a) && !signbit (a))
kono
parents:
diff changeset
436 || (flags & 0x0200 && isinf (a) && a >= 0.0f);
kono
parents:
diff changeset
437 }
kono
parents:
diff changeset
438
kono
parents:
diff changeset
439 uint32_t
kono
parents:
diff changeset
440 __hsail_class_f64 (double a, uint32_t flags)
kono
parents:
diff changeset
441 {
kono
parents:
diff changeset
442 return (flags & 0x0001 && isnan (a) && !(*(uint64_t *) &a & (1ul << 51)))
kono
parents:
diff changeset
443 || (flags & 0x0002 && isnan (a) && (*(uint64_t *) &a & (1ul << 51)))
kono
parents:
diff changeset
444 || (flags & 0x0004 && isinf (a) && a < 0.0f)
kono
parents:
diff changeset
445 || (flags & 0x0008 && isnormal (a) && signbit (a))
kono
parents:
diff changeset
446 || (flags & 0x0010 && a < 0.0f && a > -FLT_MIN)
kono
parents:
diff changeset
447 || (flags & 0x0020 && a == 0.0f && signbit (a))
kono
parents:
diff changeset
448 || (flags & 0x0040 && a == 0.0f && !signbit (a))
kono
parents:
diff changeset
449 || (flags & 0x0080 && a > 0.0f && a < FLT_MIN)
kono
parents:
diff changeset
450 || (flags & 0x0100 && isnormal (a) && !signbit (a))
kono
parents:
diff changeset
451 || (flags & 0x0200 && isinf (a) && a >= 0.0f);
kono
parents:
diff changeset
452 }
kono
parents:
diff changeset
453
kono
parents:
diff changeset
454
kono
parents:
diff changeset
455 /* 'class' for a f32-converted f16 which should otherwise be treated like f32
kono
parents:
diff changeset
456 except for its limits. */
kono
parents:
diff changeset
457
kono
parents:
diff changeset
458 uint32_t
kono
parents:
diff changeset
459 __hsail_class_f32_f16 (float a, uint32_t flags)
kono
parents:
diff changeset
460 {
kono
parents:
diff changeset
461 return (flags & 0x0001 && isnan (a) && !(*(uint32_t *) &a & 0x40000000))
kono
parents:
diff changeset
462 || (flags & 0x0002 && isnan (a) && (*(uint32_t *) &a & 0x40000000))
kono
parents:
diff changeset
463 || (flags & 0x0004 && isinf (a) && a < 0.0f)
kono
parents:
diff changeset
464 || (flags & 0x0008 && a != 0.0f && !isinf (a) && !isnan (a)
kono
parents:
diff changeset
465 && a <= -F16_MIN)
kono
parents:
diff changeset
466 || (flags & 0x0010 && a != 0.0f && !isinf (a) && !isnan (a) && a < 0.0f
kono
parents:
diff changeset
467 && a > -F16_MIN)
kono
parents:
diff changeset
468 || (flags & 0x0020 && a == 0.0f && signbit (a))
kono
parents:
diff changeset
469 || (flags & 0x0040 && a == 0.0f && !signbit (a))
kono
parents:
diff changeset
470 || (flags & 0x0080 && a != 0.0f && !isinf (a) && !isnan (a) && a > 0.0f
kono
parents:
diff changeset
471 && a < F16_MIN)
kono
parents:
diff changeset
472 || (flags & 0x0100 && a != 0.0f && !isinf (a) && !isnan (a)
kono
parents:
diff changeset
473 && a >= F16_MIN)
kono
parents:
diff changeset
474 || (flags & 0x0200 && isinf (a) && a >= 0.0f);
kono
parents:
diff changeset
475 }