]>
Commit | Line | Data |
---|---|---|
8d725fac AF |
1 | /* |
2 | * QEMU float support | |
3 | * | |
16017c48 PM |
4 | * The code in this source file is derived from release 2a of the SoftFloat |
5 | * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and | |
6 | * some later contributions) are provided under that license, as detailed below. | |
7 | * It has subsequently been modified by contributors to the QEMU Project, | |
8 | * so some portions are provided under: | |
9 | * the SoftFloat-2a license | |
10 | * the BSD license | |
11 | * GPL-v2-or-later | |
12 | * | |
13 | * Any future contributions to this file after December 1st 2014 will be | |
14 | * taken to be licensed under the Softfloat-2a license unless specifically | |
15 | * indicated otherwise. | |
8d725fac AF |
16 | */ |
17 | ||
a7d1ac78 PM |
18 | /* |
19 | =============================================================================== | |
20 | This C header file is part of the SoftFloat IEC/IEEE Floating-point | |
21 | Arithmetic Package, Release 2a. | |
158142c2 FB |
22 | |
23 | Written by John R. Hauser. This work was made possible in part by the | |
24 | International Computer Science Institute, located at Suite 600, 1947 Center | |
25 | Street, Berkeley, California 94704. Funding was partially provided by the | |
26 | National Science Foundation under grant MIP-9311980. The original version | |
27 | of this code was written as part of a project to build a fixed-point vector | |
28 | processor in collaboration with the University of California at Berkeley, | |
29 | overseen by Profs. Nelson Morgan and John Wawrzynek. More information | |
a7d1ac78 | 30 | is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/ |
158142c2 FB |
31 | arithmetic/SoftFloat.html'. |
32 | ||
a7d1ac78 PM |
33 | THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort |
34 | has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT | |
35 | TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO | |
36 | PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY | |
37 | AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE. | |
158142c2 FB |
38 | |
39 | Derivative works are acceptable, even for commercial purposes, so long as | |
a7d1ac78 PM |
40 | (1) they include prominent notice that the work is derivative, and (2) they |
41 | include prominent notice akin to these four paragraphs for those parts of | |
42 | this code that are retained. | |
158142c2 | 43 | |
a7d1ac78 PM |
44 | =============================================================================== |
45 | */ | |
158142c2 | 46 | |
16017c48 PM |
47 | /* BSD licensing: |
48 | * Copyright (c) 2006, Fabrice Bellard | |
49 | * All rights reserved. | |
50 | * | |
51 | * Redistribution and use in source and binary forms, with or without | |
52 | * modification, are permitted provided that the following conditions are met: | |
53 | * | |
54 | * 1. Redistributions of source code must retain the above copyright notice, | |
55 | * this list of conditions and the following disclaimer. | |
56 | * | |
57 | * 2. Redistributions in binary form must reproduce the above copyright notice, | |
58 | * this list of conditions and the following disclaimer in the documentation | |
59 | * and/or other materials provided with the distribution. | |
60 | * | |
61 | * 3. Neither the name of the copyright holder nor the names of its contributors | |
62 | * may be used to endorse or promote products derived from this software without | |
63 | * specific prior written permission. | |
64 | * | |
65 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | |
66 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
67 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
68 | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | |
69 | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
70 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | |
71 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | |
72 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | |
73 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | |
74 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | |
75 | * THE POSSIBILITY OF SUCH DAMAGE. | |
76 | */ | |
77 | ||
78 | /* Portions of this work are licensed under the terms of the GNU GPL, | |
79 | * version 2 or later. See the COPYING file in the top-level directory. | |
80 | */ | |
81 | ||
158142c2 FB |
82 | #ifndef SOFTFLOAT_H |
83 | #define SOFTFLOAT_H | |
84 | ||
1d6bda35 FB |
85 | /*---------------------------------------------------------------------------- |
86 | | Software IEC/IEEE floating-point ordering relations | |
87 | *----------------------------------------------------------------------------*/ | |
71bfd65c RH |
88 | |
89 | typedef enum { | |
1d6bda35 FB |
90 | float_relation_less = -1, |
91 | float_relation_equal = 0, | |
92 | float_relation_greater = 1, | |
93 | float_relation_unordered = 2 | |
71bfd65c | 94 | } FloatRelation; |
1d6bda35 | 95 | |
cfd88fc6 | 96 | #include "fpu/softfloat-types.h" |
e34c47ea | 97 | #include "fpu/softfloat-helpers.h" |
f279852b | 98 | #include "qemu/int128.h" |
158142c2 FB |
99 | |
100 | /*---------------------------------------------------------------------------- | |
101 | | Routine to raise any or all of the software IEC/IEEE floating-point | |
102 | | exception flags. | |
103 | *----------------------------------------------------------------------------*/ | |
149a48f6 | 104 | static inline void float_raise(uint16_t flags, float_status *status) |
622090ae RH |
105 | { |
106 | status->float_exception_flags |= flags; | |
107 | } | |
158142c2 | 108 | |
7baeabce AB |
109 | /*---------------------------------------------------------------------------- |
110 | | If `a' is denormal and we are in flush-to-zero mode then set the | |
111 | | input-denormal exception and return zero. Otherwise just return the value. | |
112 | *----------------------------------------------------------------------------*/ | |
210cbd49 | 113 | float16 float16_squash_input_denormal(float16 a, float_status *status); |
e5a41ffa PM |
114 | float32 float32_squash_input_denormal(float32 a, float_status *status); |
115 | float64 float64_squash_input_denormal(float64 a, float_status *status); | |
8282310d | 116 | bfloat16 bfloat16_squash_input_denormal(bfloat16 a, float_status *status); |
7baeabce | 117 | |
369be8f6 PM |
118 | /*---------------------------------------------------------------------------- |
119 | | Options to indicate which negations to perform in float*_muladd() | |
120 | | Using these differs from negating an input or output before calling | |
121 | | the muladd function in that this means that a NaN doesn't have its | |
122 | | sign bit inverted before it is propagated. | |
67d43538 PM |
123 | | We also support halving the result before rounding, as a special |
124 | | case to support the ARM fused-sqrt-step instruction FRSQRTS. | |
369be8f6 PM |
125 | *----------------------------------------------------------------------------*/ |
126 | enum { | |
127 | float_muladd_negate_c = 1, | |
128 | float_muladd_negate_product = 2, | |
66176802 | 129 | float_muladd_negate_result = 4, |
67d43538 | 130 | float_muladd_halve_result = 8, |
369be8f6 PM |
131 | }; |
132 | ||
158142c2 FB |
133 | /*---------------------------------------------------------------------------- |
134 | | Software IEC/IEEE integer-to-floating-point conversion routines. | |
135 | *----------------------------------------------------------------------------*/ | |
2abdfe24 RH |
136 | |
137 | float16 int16_to_float16_scalbn(int16_t a, int, float_status *status); | |
138 | float16 int32_to_float16_scalbn(int32_t a, int, float_status *status); | |
139 | float16 int64_to_float16_scalbn(int64_t a, int, float_status *status); | |
140 | float16 uint16_to_float16_scalbn(uint16_t a, int, float_status *status); | |
141 | float16 uint32_to_float16_scalbn(uint32_t a, int, float_status *status); | |
142 | float16 uint64_to_float16_scalbn(uint64_t a, int, float_status *status); | |
143 | ||
0d93d8ec | 144 | float16 int8_to_float16(int8_t a, float_status *status); |
2abdfe24 RH |
145 | float16 int16_to_float16(int16_t a, float_status *status); |
146 | float16 int32_to_float16(int32_t a, float_status *status); | |
147 | float16 int64_to_float16(int64_t a, float_status *status); | |
0d93d8ec | 148 | float16 uint8_to_float16(uint8_t a, float_status *status); |
2abdfe24 RH |
149 | float16 uint16_to_float16(uint16_t a, float_status *status); |
150 | float16 uint32_to_float16(uint32_t a, float_status *status); | |
151 | float16 uint64_to_float16(uint64_t a, float_status *status); | |
152 | ||
153 | float32 int16_to_float32_scalbn(int16_t, int, float_status *status); | |
154 | float32 int32_to_float32_scalbn(int32_t, int, float_status *status); | |
155 | float32 int64_to_float32_scalbn(int64_t, int, float_status *status); | |
156 | float32 uint16_to_float32_scalbn(uint16_t, int, float_status *status); | |
157 | float32 uint32_to_float32_scalbn(uint32_t, int, float_status *status); | |
158 | float32 uint64_to_float32_scalbn(uint64_t, int, float_status *status); | |
159 | ||
c02e1fb8 | 160 | float32 int16_to_float32(int16_t, float_status *status); |
e5a41ffa | 161 | float32 int32_to_float32(int32_t, float_status *status); |
2abdfe24 | 162 | float32 int64_to_float32(int64_t, float_status *status); |
c02e1fb8 | 163 | float32 uint16_to_float32(uint16_t, float_status *status); |
e5a41ffa | 164 | float32 uint32_to_float32(uint32_t, float_status *status); |
2abdfe24 RH |
165 | float32 uint64_to_float32(uint64_t, float_status *status); |
166 | ||
167 | float64 int16_to_float64_scalbn(int16_t, int, float_status *status); | |
168 | float64 int32_to_float64_scalbn(int32_t, int, float_status *status); | |
169 | float64 int64_to_float64_scalbn(int64_t, int, float_status *status); | |
170 | float64 uint16_to_float64_scalbn(uint16_t, int, float_status *status); | |
171 | float64 uint32_to_float64_scalbn(uint32_t, int, float_status *status); | |
172 | float64 uint64_to_float64_scalbn(uint64_t, int, float_status *status); | |
173 | ||
174 | float64 int16_to_float64(int16_t, float_status *status); | |
175 | float64 int32_to_float64(int32_t, float_status *status); | |
176 | float64 int64_to_float64(int64_t, float_status *status); | |
c02e1fb8 | 177 | float64 uint16_to_float64(uint16_t, float_status *status); |
e5a41ffa | 178 | float64 uint32_to_float64(uint32_t, float_status *status); |
2abdfe24 RH |
179 | float64 uint64_to_float64(uint64_t, float_status *status); |
180 | ||
e5a41ffa | 181 | floatx80 int32_to_floatx80(int32_t, float_status *status); |
e5a41ffa | 182 | floatx80 int64_to_floatx80(int64_t, float_status *status); |
2abdfe24 RH |
183 | |
184 | float128 int32_to_float128(int32_t, float_status *status); | |
e5a41ffa | 185 | float128 int64_to_float128(int64_t, float_status *status); |
95c1b71e | 186 | float128 int128_to_float128(Int128, float_status *status); |
e5a41ffa | 187 | float128 uint64_to_float128(uint64_t, float_status *status); |
f279852b | 188 | float128 uint128_to_float128(Int128, float_status *status); |
158142c2 | 189 | |
60011498 PB |
190 | /*---------------------------------------------------------------------------- |
191 | | Software half-precision conversion routines. | |
192 | *----------------------------------------------------------------------------*/ | |
2f6c74be | 193 | |
6fed16b2 AB |
194 | float16 float32_to_float16(float32, bool ieee, float_status *status); |
195 | float32 float16_to_float32(float16, bool ieee, float_status *status); | |
196 | float16 float64_to_float16(float64 a, bool ieee, float_status *status); | |
197 | float64 float16_to_float64(float16 a, bool ieee, float_status *status); | |
2f6c74be | 198 | |
0d93d8ec FC |
199 | int8_t float16_to_int8_scalbn(float16, FloatRoundMode, int, |
200 | float_status *status); | |
3dede407 RH |
201 | int16_t float16_to_int16_scalbn(float16, FloatRoundMode, int, float_status *); |
202 | int32_t float16_to_int32_scalbn(float16, FloatRoundMode, int, float_status *); | |
203 | int64_t float16_to_int64_scalbn(float16, FloatRoundMode, int, float_status *); | |
2f6c74be | 204 | |
0d93d8ec | 205 | int8_t float16_to_int8(float16, float_status *status); |
ab52f973 | 206 | int16_t float16_to_int16(float16, float_status *status); |
ab52f973 | 207 | int32_t float16_to_int32(float16, float_status *status); |
ab52f973 | 208 | int64_t float16_to_int64(float16, float_status *status); |
2f6c74be RH |
209 | |
210 | int16_t float16_to_int16_round_to_zero(float16, float_status *status); | |
211 | int32_t float16_to_int32_round_to_zero(float16, float_status *status); | |
ab52f973 | 212 | int64_t float16_to_int64_round_to_zero(float16, float_status *status); |
2f6c74be | 213 | |
0d93d8ec FC |
214 | uint8_t float16_to_uint8_scalbn(float16 a, FloatRoundMode, |
215 | int, float_status *status); | |
3dede407 RH |
216 | uint16_t float16_to_uint16_scalbn(float16 a, FloatRoundMode, |
217 | int, float_status *status); | |
218 | uint32_t float16_to_uint32_scalbn(float16 a, FloatRoundMode, | |
219 | int, float_status *status); | |
220 | uint64_t float16_to_uint64_scalbn(float16 a, FloatRoundMode, | |
221 | int, float_status *status); | |
2f6c74be | 222 | |
0d93d8ec | 223 | uint8_t float16_to_uint8(float16 a, float_status *status); |
2f6c74be RH |
224 | uint16_t float16_to_uint16(float16 a, float_status *status); |
225 | uint32_t float16_to_uint32(float16 a, float_status *status); | |
226 | uint64_t float16_to_uint64(float16 a, float_status *status); | |
227 | ||
228 | uint16_t float16_to_uint16_round_to_zero(float16 a, float_status *status); | |
229 | uint32_t float16_to_uint32_round_to_zero(float16 a, float_status *status); | |
ab52f973 | 230 | uint64_t float16_to_uint64_round_to_zero(float16 a, float_status *status); |
bb4d4bb3 PM |
231 | |
232 | /*---------------------------------------------------------------------------- | |
233 | | Software half-precision operations. | |
234 | *----------------------------------------------------------------------------*/ | |
6fff2167 | 235 | |
dbe4d53a | 236 | float16 float16_round_to_int(float16, float_status *status); |
6fff2167 AB |
237 | float16 float16_add(float16, float16, float_status *status); |
238 | float16 float16_sub(float16, float16, float_status *status); | |
74d707e2 | 239 | float16 float16_mul(float16, float16, float_status *status); |
d446830a | 240 | float16 float16_muladd(float16, float16, float16, int, float_status *status); |
cf07323d | 241 | float16 float16_div(float16, float16, float_status *status); |
0bfc9f19 | 242 | float16 float16_scalbn(float16, int, float_status *status); |
89360067 AB |
243 | float16 float16_min(float16, float16, float_status *status); |
244 | float16 float16_max(float16, float16, float_status *status); | |
245 | float16 float16_minnum(float16, float16, float_status *status); | |
246 | float16 float16_maxnum(float16, float16, float_status *status); | |
247 | float16 float16_minnummag(float16, float16, float_status *status); | |
248 | float16 float16_maxnummag(float16, float16, float_status *status); | |
0e903037 CMC |
249 | float16 float16_minimum_number(float16, float16, float_status *status); |
250 | float16 float16_maximum_number(float16, float16, float_status *status); | |
c13bb2da | 251 | float16 float16_sqrt(float16, float_status *status); |
71bfd65c RH |
252 | FloatRelation float16_compare(float16, float16, float_status *status); |
253 | FloatRelation float16_compare_quiet(float16, float16, float_status *status); | |
6fff2167 | 254 | |
150c7a91 RH |
255 | bool float16_is_quiet_nan(float16, float_status *status); |
256 | bool float16_is_signaling_nan(float16, float_status *status); | |
d619bb98 | 257 | float16 float16_silence_nan(float16, float_status *status); |
60011498 | 258 | |
150c7a91 | 259 | static inline bool float16_is_any_nan(float16 a) |
213ff4e6 MF |
260 | { |
261 | return ((float16_val(a) & ~0x8000) > 0x7c00); | |
262 | } | |
263 | ||
150c7a91 | 264 | static inline bool float16_is_neg(float16 a) |
f566c047 BR |
265 | { |
266 | return float16_val(a) >> 15; | |
267 | } | |
268 | ||
150c7a91 | 269 | static inline bool float16_is_infinity(float16 a) |
f566c047 BR |
270 | { |
271 | return (float16_val(a) & 0x7fff) == 0x7c00; | |
272 | } | |
273 | ||
150c7a91 | 274 | static inline bool float16_is_zero(float16 a) |
f566c047 BR |
275 | { |
276 | return (float16_val(a) & 0x7fff) == 0; | |
277 | } | |
278 | ||
150c7a91 | 279 | static inline bool float16_is_zero_or_denormal(float16 a) |
f566c047 BR |
280 | { |
281 | return (float16_val(a) & 0x7c00) == 0; | |
282 | } | |
283 | ||
a03e924c SL |
284 | static inline bool float16_is_normal(float16 a) |
285 | { | |
286 | return (((float16_val(a) >> 10) + 1) & 0x1f) >= 2; | |
287 | } | |
288 | ||
28136775 AB |
289 | static inline float16 float16_abs(float16 a) |
290 | { | |
291 | /* Note that abs does *not* handle NaN specially, nor does | |
292 | * it flush denormal inputs to zero. | |
293 | */ | |
294 | return make_float16(float16_val(a) & 0x7fff); | |
295 | } | |
5f10aef5 AB |
296 | |
297 | static inline float16 float16_chs(float16 a) | |
298 | { | |
299 | /* Note that chs does *not* handle NaN specially, nor does | |
300 | * it flush denormal inputs to zero. | |
301 | */ | |
302 | return make_float16(float16_val(a) ^ 0x8000); | |
303 | } | |
304 | ||
78b5a3e6 AB |
305 | static inline float16 float16_set_sign(float16 a, int sign) |
306 | { | |
307 | return make_float16((float16_val(a) & 0x7fff) | (sign << 15)); | |
308 | } | |
309 | ||
dd205025 KC |
310 | static inline bool float16_eq(float16 a, float16 b, float_status *s) |
311 | { | |
312 | return float16_compare(a, b, s) == float_relation_equal; | |
313 | } | |
314 | ||
315 | static inline bool float16_le(float16 a, float16 b, float_status *s) | |
316 | { | |
317 | return float16_compare(a, b, s) <= float_relation_equal; | |
318 | } | |
319 | ||
320 | static inline bool float16_lt(float16 a, float16 b, float_status *s) | |
321 | { | |
322 | return float16_compare(a, b, s) < float_relation_equal; | |
323 | } | |
324 | ||
325 | static inline bool float16_unordered(float16 a, float16 b, float_status *s) | |
326 | { | |
327 | return float16_compare(a, b, s) == float_relation_unordered; | |
328 | } | |
329 | ||
330 | static inline bool float16_eq_quiet(float16 a, float16 b, float_status *s) | |
331 | { | |
332 | return float16_compare_quiet(a, b, s) == float_relation_equal; | |
333 | } | |
334 | ||
335 | static inline bool float16_le_quiet(float16 a, float16 b, float_status *s) | |
336 | { | |
337 | return float16_compare_quiet(a, b, s) <= float_relation_equal; | |
338 | } | |
339 | ||
340 | static inline bool float16_lt_quiet(float16 a, float16 b, float_status *s) | |
341 | { | |
342 | return float16_compare_quiet(a, b, s) < float_relation_equal; | |
343 | } | |
344 | ||
345 | static inline bool float16_unordered_quiet(float16 a, float16 b, | |
346 | float_status *s) | |
347 | { | |
348 | return float16_compare_quiet(a, b, s) == float_relation_unordered; | |
349 | } | |
350 | ||
efd4829e | 351 | #define float16_zero make_float16(0) |
efd4829e | 352 | #define float16_half make_float16(0x3800) |
026e2d6e AB |
353 | #define float16_one make_float16(0x3c00) |
354 | #define float16_one_point_five make_float16(0x3e00) | |
355 | #define float16_two make_float16(0x4000) | |
356 | #define float16_three make_float16(0x4200) | |
efd4829e AB |
357 | #define float16_infinity make_float16(0x7c00) |
358 | ||
34f0c0a9 LZ |
359 | /*---------------------------------------------------------------------------- |
360 | | Software bfloat16 conversion routines. | |
361 | *----------------------------------------------------------------------------*/ | |
362 | ||
363 | bfloat16 bfloat16_round_to_int(bfloat16, float_status *status); | |
364 | bfloat16 float32_to_bfloat16(float32, float_status *status); | |
365 | float32 bfloat16_to_float32(bfloat16, float_status *status); | |
366 | bfloat16 float64_to_bfloat16(float64 a, float_status *status); | |
367 | float64 bfloat16_to_float64(bfloat16 a, float_status *status); | |
368 | ||
369 | int16_t bfloat16_to_int16_scalbn(bfloat16, FloatRoundMode, | |
370 | int, float_status *status); | |
371 | int32_t bfloat16_to_int32_scalbn(bfloat16, FloatRoundMode, | |
372 | int, float_status *status); | |
373 | int64_t bfloat16_to_int64_scalbn(bfloat16, FloatRoundMode, | |
374 | int, float_status *status); | |
375 | ||
376 | int16_t bfloat16_to_int16(bfloat16, float_status *status); | |
377 | int32_t bfloat16_to_int32(bfloat16, float_status *status); | |
378 | int64_t bfloat16_to_int64(bfloat16, float_status *status); | |
379 | ||
380 | int16_t bfloat16_to_int16_round_to_zero(bfloat16, float_status *status); | |
381 | int32_t bfloat16_to_int32_round_to_zero(bfloat16, float_status *status); | |
382 | int64_t bfloat16_to_int64_round_to_zero(bfloat16, float_status *status); | |
383 | ||
384 | uint16_t bfloat16_to_uint16_scalbn(bfloat16 a, FloatRoundMode, | |
385 | int, float_status *status); | |
386 | uint32_t bfloat16_to_uint32_scalbn(bfloat16 a, FloatRoundMode, | |
387 | int, float_status *status); | |
388 | uint64_t bfloat16_to_uint64_scalbn(bfloat16 a, FloatRoundMode, | |
389 | int, float_status *status); | |
390 | ||
391 | uint16_t bfloat16_to_uint16(bfloat16 a, float_status *status); | |
392 | uint32_t bfloat16_to_uint32(bfloat16 a, float_status *status); | |
393 | uint64_t bfloat16_to_uint64(bfloat16 a, float_status *status); | |
394 | ||
395 | uint16_t bfloat16_to_uint16_round_to_zero(bfloat16 a, float_status *status); | |
396 | uint32_t bfloat16_to_uint32_round_to_zero(bfloat16 a, float_status *status); | |
397 | uint64_t bfloat16_to_uint64_round_to_zero(bfloat16 a, float_status *status); | |
398 | ||
399 | bfloat16 int16_to_bfloat16_scalbn(int16_t a, int, float_status *status); | |
400 | bfloat16 int32_to_bfloat16_scalbn(int32_t a, int, float_status *status); | |
401 | bfloat16 int64_to_bfloat16_scalbn(int64_t a, int, float_status *status); | |
402 | bfloat16 uint16_to_bfloat16_scalbn(uint16_t a, int, float_status *status); | |
403 | bfloat16 uint32_to_bfloat16_scalbn(uint32_t a, int, float_status *status); | |
404 | bfloat16 uint64_to_bfloat16_scalbn(uint64_t a, int, float_status *status); | |
405 | ||
406 | bfloat16 int16_to_bfloat16(int16_t a, float_status *status); | |
407 | bfloat16 int32_to_bfloat16(int32_t a, float_status *status); | |
408 | bfloat16 int64_to_bfloat16(int64_t a, float_status *status); | |
409 | bfloat16 uint16_to_bfloat16(uint16_t a, float_status *status); | |
410 | bfloat16 uint32_to_bfloat16(uint32_t a, float_status *status); | |
411 | bfloat16 uint64_to_bfloat16(uint64_t a, float_status *status); | |
412 | ||
8282310d LZ |
413 | /*---------------------------------------------------------------------------- |
414 | | Software bfloat16 operations. | |
415 | *----------------------------------------------------------------------------*/ | |
416 | ||
417 | bfloat16 bfloat16_add(bfloat16, bfloat16, float_status *status); | |
418 | bfloat16 bfloat16_sub(bfloat16, bfloat16, float_status *status); | |
419 | bfloat16 bfloat16_mul(bfloat16, bfloat16, float_status *status); | |
420 | bfloat16 bfloat16_div(bfloat16, bfloat16, float_status *status); | |
421 | bfloat16 bfloat16_muladd(bfloat16, bfloat16, bfloat16, int, | |
422 | float_status *status); | |
423 | float16 bfloat16_scalbn(bfloat16, int, float_status *status); | |
424 | bfloat16 bfloat16_min(bfloat16, bfloat16, float_status *status); | |
425 | bfloat16 bfloat16_max(bfloat16, bfloat16, float_status *status); | |
426 | bfloat16 bfloat16_minnum(bfloat16, bfloat16, float_status *status); | |
427 | bfloat16 bfloat16_maxnum(bfloat16, bfloat16, float_status *status); | |
428 | bfloat16 bfloat16_minnummag(bfloat16, bfloat16, float_status *status); | |
429 | bfloat16 bfloat16_maxnummag(bfloat16, bfloat16, float_status *status); | |
0e903037 CMC |
430 | bfloat16 bfloat16_minimum_number(bfloat16, bfloat16, float_status *status); |
431 | bfloat16 bfloat16_maximum_number(bfloat16, bfloat16, float_status *status); | |
8282310d LZ |
432 | bfloat16 bfloat16_sqrt(bfloat16, float_status *status); |
433 | FloatRelation bfloat16_compare(bfloat16, bfloat16, float_status *status); | |
434 | FloatRelation bfloat16_compare_quiet(bfloat16, bfloat16, float_status *status); | |
435 | ||
5ebf5f4b LZ |
436 | bool bfloat16_is_quiet_nan(bfloat16, float_status *status); |
437 | bool bfloat16_is_signaling_nan(bfloat16, float_status *status); | |
8282310d LZ |
438 | bfloat16 bfloat16_silence_nan(bfloat16, float_status *status); |
439 | bfloat16 bfloat16_default_nan(float_status *status); | |
440 | ||
5ebf5f4b LZ |
441 | static inline bool bfloat16_is_any_nan(bfloat16 a) |
442 | { | |
443 | return ((a & ~0x8000) > 0x7F80); | |
444 | } | |
445 | ||
446 | static inline bool bfloat16_is_neg(bfloat16 a) | |
447 | { | |
448 | return a >> 15; | |
449 | } | |
450 | ||
451 | static inline bool bfloat16_is_infinity(bfloat16 a) | |
452 | { | |
453 | return (a & 0x7fff) == 0x7F80; | |
454 | } | |
455 | ||
456 | static inline bool bfloat16_is_zero(bfloat16 a) | |
457 | { | |
458 | return (a & 0x7fff) == 0; | |
459 | } | |
460 | ||
461 | static inline bool bfloat16_is_zero_or_denormal(bfloat16 a) | |
462 | { | |
463 | return (a & 0x7F80) == 0; | |
464 | } | |
465 | ||
466 | static inline bool bfloat16_is_normal(bfloat16 a) | |
467 | { | |
468 | return (((a >> 7) + 1) & 0xff) >= 2; | |
469 | } | |
470 | ||
471 | static inline bfloat16 bfloat16_abs(bfloat16 a) | |
472 | { | |
473 | /* Note that abs does *not* handle NaN specially, nor does | |
474 | * it flush denormal inputs to zero. | |
475 | */ | |
476 | return a & 0x7fff; | |
477 | } | |
478 | ||
479 | static inline bfloat16 bfloat16_chs(bfloat16 a) | |
480 | { | |
481 | /* Note that chs does *not* handle NaN specially, nor does | |
482 | * it flush denormal inputs to zero. | |
483 | */ | |
484 | return a ^ 0x8000; | |
485 | } | |
486 | ||
8282310d LZ |
487 | static inline bfloat16 bfloat16_set_sign(bfloat16 a, int sign) |
488 | { | |
489 | return (a & 0x7fff) | (sign << 15); | |
490 | } | |
491 | ||
c53b1079 RH |
492 | static inline bool bfloat16_eq(bfloat16 a, bfloat16 b, float_status *s) |
493 | { | |
494 | return bfloat16_compare(a, b, s) == float_relation_equal; | |
495 | } | |
496 | ||
497 | static inline bool bfloat16_le(bfloat16 a, bfloat16 b, float_status *s) | |
498 | { | |
499 | return bfloat16_compare(a, b, s) <= float_relation_equal; | |
500 | } | |
501 | ||
502 | static inline bool bfloat16_lt(bfloat16 a, bfloat16 b, float_status *s) | |
503 | { | |
504 | return bfloat16_compare(a, b, s) < float_relation_equal; | |
505 | } | |
506 | ||
507 | static inline bool bfloat16_unordered(bfloat16 a, bfloat16 b, float_status *s) | |
508 | { | |
509 | return bfloat16_compare(a, b, s) == float_relation_unordered; | |
510 | } | |
511 | ||
512 | static inline bool bfloat16_eq_quiet(bfloat16 a, bfloat16 b, float_status *s) | |
513 | { | |
514 | return bfloat16_compare_quiet(a, b, s) == float_relation_equal; | |
515 | } | |
516 | ||
517 | static inline bool bfloat16_le_quiet(bfloat16 a, bfloat16 b, float_status *s) | |
518 | { | |
519 | return bfloat16_compare_quiet(a, b, s) <= float_relation_equal; | |
520 | } | |
521 | ||
522 | static inline bool bfloat16_lt_quiet(bfloat16 a, bfloat16 b, float_status *s) | |
523 | { | |
524 | return bfloat16_compare_quiet(a, b, s) < float_relation_equal; | |
525 | } | |
526 | ||
527 | static inline bool bfloat16_unordered_quiet(bfloat16 a, bfloat16 b, | |
528 | float_status *s) | |
529 | { | |
530 | return bfloat16_compare_quiet(a, b, s) == float_relation_unordered; | |
531 | } | |
532 | ||
8282310d LZ |
533 | #define bfloat16_zero 0 |
534 | #define bfloat16_half 0x3f00 | |
535 | #define bfloat16_one 0x3f80 | |
536 | #define bfloat16_one_point_five 0x3fc0 | |
537 | #define bfloat16_two 0x4000 | |
538 | #define bfloat16_three 0x4040 | |
539 | #define bfloat16_infinity 0x7f80 | |
540 | ||
8559666d CL |
541 | /*---------------------------------------------------------------------------- |
542 | | The pattern for a default generated half-precision NaN. | |
543 | *----------------------------------------------------------------------------*/ | |
af39bc8c | 544 | float16 float16_default_nan(float_status *status); |
8559666d | 545 | |
158142c2 FB |
546 | /*---------------------------------------------------------------------------- |
547 | | Software IEC/IEEE single-precision conversion routines. | |
548 | *----------------------------------------------------------------------------*/ | |
2f6c74be | 549 | |
3dede407 RH |
550 | int16_t float32_to_int16_scalbn(float32, FloatRoundMode, int, float_status *); |
551 | int32_t float32_to_int32_scalbn(float32, FloatRoundMode, int, float_status *); | |
552 | int64_t float32_to_int64_scalbn(float32, FloatRoundMode, int, float_status *); | |
2f6c74be | 553 | |
0bb721d7 | 554 | int16_t float32_to_int16(float32, float_status *status); |
f4014512 | 555 | int32_t float32_to_int32(float32, float_status *status); |
2f6c74be RH |
556 | int64_t float32_to_int64(float32, float_status *status); |
557 | ||
558 | int16_t float32_to_int16_round_to_zero(float32, float_status *status); | |
f4014512 | 559 | int32_t float32_to_int32_round_to_zero(float32, float_status *status); |
2f6c74be RH |
560 | int64_t float32_to_int64_round_to_zero(float32, float_status *status); |
561 | ||
3dede407 RH |
562 | uint16_t float32_to_uint16_scalbn(float32, FloatRoundMode, int, float_status *); |
563 | uint32_t float32_to_uint32_scalbn(float32, FloatRoundMode, int, float_status *); | |
564 | uint64_t float32_to_uint64_scalbn(float32, FloatRoundMode, int, float_status *); | |
2f6c74be RH |
565 | |
566 | uint16_t float32_to_uint16(float32, float_status *status); | |
3a87d009 | 567 | uint32_t float32_to_uint32(float32, float_status *status); |
182f42fd | 568 | uint64_t float32_to_uint64(float32, float_status *status); |
2f6c74be RH |
569 | |
570 | uint16_t float32_to_uint16_round_to_zero(float32, float_status *status); | |
571 | uint32_t float32_to_uint32_round_to_zero(float32, float_status *status); | |
182f42fd | 572 | uint64_t float32_to_uint64_round_to_zero(float32, float_status *status); |
2f6c74be | 573 | |
e5a41ffa PM |
574 | float64 float32_to_float64(float32, float_status *status); |
575 | floatx80 float32_to_floatx80(float32, float_status *status); | |
576 | float128 float32_to_float128(float32, float_status *status); | |
158142c2 FB |
577 | |
578 | /*---------------------------------------------------------------------------- | |
579 | | Software IEC/IEEE single-precision operations. | |
580 | *----------------------------------------------------------------------------*/ | |
e5a41ffa PM |
581 | float32 float32_round_to_int(float32, float_status *status); |
582 | float32 float32_add(float32, float32, float_status *status); | |
583 | float32 float32_sub(float32, float32, float_status *status); | |
584 | float32 float32_mul(float32, float32, float_status *status); | |
585 | float32 float32_div(float32, float32, float_status *status); | |
586 | float32 float32_rem(float32, float32, float_status *status); | |
587 | float32 float32_muladd(float32, float32, float32, int, float_status *status); | |
588 | float32 float32_sqrt(float32, float_status *status); | |
589 | float32 float32_exp2(float32, float_status *status); | |
590 | float32 float32_log2(float32, float_status *status); | |
71bfd65c RH |
591 | FloatRelation float32_compare(float32, float32, float_status *status); |
592 | FloatRelation float32_compare_quiet(float32, float32, float_status *status); | |
e5a41ffa PM |
593 | float32 float32_min(float32, float32, float_status *status); |
594 | float32 float32_max(float32, float32, float_status *status); | |
595 | float32 float32_minnum(float32, float32, float_status *status); | |
596 | float32 float32_maxnum(float32, float32, float_status *status); | |
597 | float32 float32_minnummag(float32, float32, float_status *status); | |
598 | float32 float32_maxnummag(float32, float32, float_status *status); | |
0e903037 CMC |
599 | float32 float32_minimum_number(float32, float32, float_status *status); |
600 | float32 float32_maximum_number(float32, float32, float_status *status); | |
150c7a91 RH |
601 | bool float32_is_quiet_nan(float32, float_status *status); |
602 | bool float32_is_signaling_nan(float32, float_status *status); | |
d619bb98 | 603 | float32 float32_silence_nan(float32, float_status *status); |
e5a41ffa | 604 | float32 float32_scalbn(float32, int, float_status *status); |
158142c2 | 605 | |
a49db98d | 606 | static inline float32 float32_abs(float32 a) |
1d6bda35 | 607 | { |
37d18660 PM |
608 | /* Note that abs does *not* handle NaN specially, nor does |
609 | * it flush denormal inputs to zero. | |
610 | */ | |
f090c9d4 | 611 | return make_float32(float32_val(a) & 0x7fffffff); |
1d6bda35 FB |
612 | } |
613 | ||
a49db98d | 614 | static inline float32 float32_chs(float32 a) |
1d6bda35 | 615 | { |
37d18660 PM |
616 | /* Note that chs does *not* handle NaN specially, nor does |
617 | * it flush denormal inputs to zero. | |
618 | */ | |
f090c9d4 | 619 | return make_float32(float32_val(a) ^ 0x80000000); |
1d6bda35 FB |
620 | } |
621 | ||
150c7a91 | 622 | static inline bool float32_is_infinity(float32 a) |
c52ab6f5 | 623 | { |
dadd71a7 | 624 | return (float32_val(a) & 0x7fffffff) == 0x7f800000; |
c52ab6f5 AJ |
625 | } |
626 | ||
150c7a91 | 627 | static inline bool float32_is_neg(float32 a) |
c52ab6f5 AJ |
628 | { |
629 | return float32_val(a) >> 31; | |
630 | } | |
631 | ||
150c7a91 | 632 | static inline bool float32_is_zero(float32 a) |
c52ab6f5 AJ |
633 | { |
634 | return (float32_val(a) & 0x7fffffff) == 0; | |
635 | } | |
636 | ||
150c7a91 | 637 | static inline bool float32_is_any_nan(float32 a) |
21d6ebde PM |
638 | { |
639 | return ((float32_val(a) & ~(1 << 31)) > 0x7f800000UL); | |
640 | } | |
641 | ||
150c7a91 | 642 | static inline bool float32_is_zero_or_denormal(float32 a) |
6f3300ad PM |
643 | { |
644 | return (float32_val(a) & 0x7f800000) == 0; | |
645 | } | |
646 | ||
588e6dfd EC |
647 | static inline bool float32_is_normal(float32 a) |
648 | { | |
47393181 | 649 | return (((float32_val(a) >> 23) + 1) & 0xff) >= 2; |
588e6dfd EC |
650 | } |
651 | ||
652 | static inline bool float32_is_denormal(float32 a) | |
653 | { | |
654 | return float32_is_zero_or_denormal(a) && !float32_is_zero(a); | |
655 | } | |
656 | ||
315df0d1 EC |
657 | static inline bool float32_is_zero_or_normal(float32 a) |
658 | { | |
659 | return float32_is_normal(a) || float32_is_zero(a); | |
660 | } | |
661 | ||
a49db98d | 662 | static inline float32 float32_set_sign(float32 a, int sign) |
c30fe7df CL |
663 | { |
664 | return make_float32((float32_val(a) & 0x7fffffff) | (sign << 31)); | |
665 | } | |
666 | ||
5da2d2d8 RH |
667 | static inline bool float32_eq(float32 a, float32 b, float_status *s) |
668 | { | |
669 | return float32_compare(a, b, s) == float_relation_equal; | |
670 | } | |
671 | ||
672 | static inline bool float32_le(float32 a, float32 b, float_status *s) | |
673 | { | |
674 | return float32_compare(a, b, s) <= float_relation_equal; | |
675 | } | |
676 | ||
677 | static inline bool float32_lt(float32 a, float32 b, float_status *s) | |
678 | { | |
679 | return float32_compare(a, b, s) < float_relation_equal; | |
680 | } | |
681 | ||
682 | static inline bool float32_unordered(float32 a, float32 b, float_status *s) | |
683 | { | |
684 | return float32_compare(a, b, s) == float_relation_unordered; | |
685 | } | |
686 | ||
687 | static inline bool float32_eq_quiet(float32 a, float32 b, float_status *s) | |
688 | { | |
689 | return float32_compare_quiet(a, b, s) == float_relation_equal; | |
690 | } | |
691 | ||
692 | static inline bool float32_le_quiet(float32 a, float32 b, float_status *s) | |
693 | { | |
694 | return float32_compare_quiet(a, b, s) <= float_relation_equal; | |
695 | } | |
696 | ||
697 | static inline bool float32_lt_quiet(float32 a, float32 b, float_status *s) | |
698 | { | |
699 | return float32_compare_quiet(a, b, s) < float_relation_equal; | |
700 | } | |
701 | ||
702 | static inline bool float32_unordered_quiet(float32 a, float32 b, | |
703 | float_status *s) | |
704 | { | |
705 | return float32_compare_quiet(a, b, s) == float_relation_unordered; | |
706 | } | |
707 | ||
f090c9d4 | 708 | #define float32_zero make_float32(0) |
c30fe7df | 709 | #define float32_half make_float32(0x3f000000) |
026e2d6e AB |
710 | #define float32_one make_float32(0x3f800000) |
711 | #define float32_one_point_five make_float32(0x3fc00000) | |
712 | #define float32_two make_float32(0x40000000) | |
713 | #define float32_three make_float32(0x40400000) | |
c30fe7df | 714 | #define float32_infinity make_float32(0x7f800000) |
f090c9d4 | 715 | |
88857aca LV |
716 | /*---------------------------------------------------------------------------- |
717 | | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a | |
718 | | single-precision floating-point value, returning the result. After being | |
719 | | shifted into the proper positions, the three fields are simply added | |
720 | | together to form the result. This means that any integer portion of `zSig' | |
721 | | will be added into the exponent. Since a properly normalized significand | |
722 | | will have an integer portion equal to 1, the `zExp' input should be 1 less | |
723 | | than the desired result exponent whenever `zSig' is a complete, normalized | |
724 | | significand. | |
725 | *----------------------------------------------------------------------------*/ | |
726 | ||
c120391c | 727 | static inline float32 packFloat32(bool zSign, int zExp, uint32_t zSig) |
88857aca LV |
728 | { |
729 | return make_float32( | |
730 | (((uint32_t)zSign) << 31) + (((uint32_t)zExp) << 23) + zSig); | |
731 | } | |
732 | ||
8559666d CL |
733 | /*---------------------------------------------------------------------------- |
734 | | The pattern for a default generated single-precision NaN. | |
735 | *----------------------------------------------------------------------------*/ | |
af39bc8c | 736 | float32 float32_default_nan(float_status *status); |
8559666d | 737 | |
158142c2 FB |
738 | /*---------------------------------------------------------------------------- |
739 | | Software IEC/IEEE double-precision conversion routines. | |
740 | *----------------------------------------------------------------------------*/ | |
2f6c74be | 741 | |
3dede407 RH |
742 | int16_t float64_to_int16_scalbn(float64, FloatRoundMode, int, float_status *); |
743 | int32_t float64_to_int32_scalbn(float64, FloatRoundMode, int, float_status *); | |
744 | int64_t float64_to_int64_scalbn(float64, FloatRoundMode, int, float_status *); | |
2f6c74be | 745 | |
0bb721d7 | 746 | int16_t float64_to_int16(float64, float_status *status); |
f4014512 | 747 | int32_t float64_to_int32(float64, float_status *status); |
2f6c74be RH |
748 | int64_t float64_to_int64(float64, float_status *status); |
749 | ||
750 | int16_t float64_to_int16_round_to_zero(float64, float_status *status); | |
f4014512 | 751 | int32_t float64_to_int32_round_to_zero(float64, float_status *status); |
2f6c74be RH |
752 | int64_t float64_to_int64_round_to_zero(float64, float_status *status); |
753 | ||
3dede407 RH |
754 | uint16_t float64_to_uint16_scalbn(float64, FloatRoundMode, int, float_status *); |
755 | uint32_t float64_to_uint32_scalbn(float64, FloatRoundMode, int, float_status *); | |
756 | uint64_t float64_to_uint64_scalbn(float64, FloatRoundMode, int, float_status *); | |
2f6c74be RH |
757 | |
758 | uint16_t float64_to_uint16(float64, float_status *status); | |
3a87d009 | 759 | uint32_t float64_to_uint32(float64, float_status *status); |
2f6c74be RH |
760 | uint64_t float64_to_uint64(float64, float_status *status); |
761 | ||
762 | uint16_t float64_to_uint16_round_to_zero(float64, float_status *status); | |
3a87d009 | 763 | uint32_t float64_to_uint32_round_to_zero(float64, float_status *status); |
2f6c74be RH |
764 | uint64_t float64_to_uint64_round_to_zero(float64, float_status *status); |
765 | ||
e5a41ffa PM |
766 | float32 float64_to_float32(float64, float_status *status); |
767 | floatx80 float64_to_floatx80(float64, float_status *status); | |
768 | float128 float64_to_float128(float64, float_status *status); | |
158142c2 FB |
769 | |
770 | /*---------------------------------------------------------------------------- | |
771 | | Software IEC/IEEE double-precision operations. | |
772 | *----------------------------------------------------------------------------*/ | |
e5a41ffa | 773 | float64 float64_round_to_int(float64, float_status *status); |
e5a41ffa PM |
774 | float64 float64_add(float64, float64, float_status *status); |
775 | float64 float64_sub(float64, float64, float_status *status); | |
776 | float64 float64_mul(float64, float64, float_status *status); | |
777 | float64 float64_div(float64, float64, float_status *status); | |
778 | float64 float64_rem(float64, float64, float_status *status); | |
779 | float64 float64_muladd(float64, float64, float64, int, float_status *status); | |
780 | float64 float64_sqrt(float64, float_status *status); | |
781 | float64 float64_log2(float64, float_status *status); | |
71bfd65c RH |
782 | FloatRelation float64_compare(float64, float64, float_status *status); |
783 | FloatRelation float64_compare_quiet(float64, float64, float_status *status); | |
e5a41ffa PM |
784 | float64 float64_min(float64, float64, float_status *status); |
785 | float64 float64_max(float64, float64, float_status *status); | |
786 | float64 float64_minnum(float64, float64, float_status *status); | |
787 | float64 float64_maxnum(float64, float64, float_status *status); | |
788 | float64 float64_minnummag(float64, float64, float_status *status); | |
789 | float64 float64_maxnummag(float64, float64, float_status *status); | |
0e903037 CMC |
790 | float64 float64_minimum_number(float64, float64, float_status *status); |
791 | float64 float64_maximum_number(float64, float64, float_status *status); | |
150c7a91 RH |
792 | bool float64_is_quiet_nan(float64 a, float_status *status); |
793 | bool float64_is_signaling_nan(float64, float_status *status); | |
d619bb98 | 794 | float64 float64_silence_nan(float64, float_status *status); |
e5a41ffa | 795 | float64 float64_scalbn(float64, int, float_status *status); |
158142c2 | 796 | |
a49db98d | 797 | static inline float64 float64_abs(float64 a) |
1d6bda35 | 798 | { |
37d18660 PM |
799 | /* Note that abs does *not* handle NaN specially, nor does |
800 | * it flush denormal inputs to zero. | |
801 | */ | |
f090c9d4 | 802 | return make_float64(float64_val(a) & 0x7fffffffffffffffLL); |
1d6bda35 FB |
803 | } |
804 | ||
a49db98d | 805 | static inline float64 float64_chs(float64 a) |
1d6bda35 | 806 | { |
37d18660 PM |
807 | /* Note that chs does *not* handle NaN specially, nor does |
808 | * it flush denormal inputs to zero. | |
809 | */ | |
f090c9d4 | 810 | return make_float64(float64_val(a) ^ 0x8000000000000000LL); |
1d6bda35 FB |
811 | } |
812 | ||
150c7a91 | 813 | static inline bool float64_is_infinity(float64 a) |
c52ab6f5 AJ |
814 | { |
815 | return (float64_val(a) & 0x7fffffffffffffffLL ) == 0x7ff0000000000000LL; | |
816 | } | |
817 | ||
150c7a91 | 818 | static inline bool float64_is_neg(float64 a) |
c52ab6f5 AJ |
819 | { |
820 | return float64_val(a) >> 63; | |
821 | } | |
822 | ||
150c7a91 | 823 | static inline bool float64_is_zero(float64 a) |
c52ab6f5 AJ |
824 | { |
825 | return (float64_val(a) & 0x7fffffffffffffffLL) == 0; | |
826 | } | |
827 | ||
150c7a91 | 828 | static inline bool float64_is_any_nan(float64 a) |
21d6ebde PM |
829 | { |
830 | return ((float64_val(a) & ~(1ULL << 63)) > 0x7ff0000000000000ULL); | |
831 | } | |
832 | ||
150c7a91 | 833 | static inline bool float64_is_zero_or_denormal(float64 a) |
587eabfa AJ |
834 | { |
835 | return (float64_val(a) & 0x7ff0000000000000LL) == 0; | |
836 | } | |
837 | ||
588e6dfd EC |
838 | static inline bool float64_is_normal(float64 a) |
839 | { | |
47393181 | 840 | return (((float64_val(a) >> 52) + 1) & 0x7ff) >= 2; |
588e6dfd EC |
841 | } |
842 | ||
843 | static inline bool float64_is_denormal(float64 a) | |
844 | { | |
845 | return float64_is_zero_or_denormal(a) && !float64_is_zero(a); | |
846 | } | |
847 | ||
315df0d1 EC |
848 | static inline bool float64_is_zero_or_normal(float64 a) |
849 | { | |
850 | return float64_is_normal(a) || float64_is_zero(a); | |
851 | } | |
852 | ||
a49db98d | 853 | static inline float64 float64_set_sign(float64 a, int sign) |
c30fe7df CL |
854 | { |
855 | return make_float64((float64_val(a) & 0x7fffffffffffffffULL) | |
856 | | ((int64_t)sign << 63)); | |
857 | } | |
858 | ||
0673ecdf RH |
859 | static inline bool float64_eq(float64 a, float64 b, float_status *s) |
860 | { | |
861 | return float64_compare(a, b, s) == float_relation_equal; | |
862 | } | |
863 | ||
864 | static inline bool float64_le(float64 a, float64 b, float_status *s) | |
865 | { | |
866 | return float64_compare(a, b, s) <= float_relation_equal; | |
867 | } | |
868 | ||
869 | static inline bool float64_lt(float64 a, float64 b, float_status *s) | |
870 | { | |
871 | return float64_compare(a, b, s) < float_relation_equal; | |
872 | } | |
873 | ||
874 | static inline bool float64_unordered(float64 a, float64 b, float_status *s) | |
875 | { | |
876 | return float64_compare(a, b, s) == float_relation_unordered; | |
877 | } | |
878 | ||
879 | static inline bool float64_eq_quiet(float64 a, float64 b, float_status *s) | |
880 | { | |
881 | return float64_compare_quiet(a, b, s) == float_relation_equal; | |
882 | } | |
883 | ||
884 | static inline bool float64_le_quiet(float64 a, float64 b, float_status *s) | |
885 | { | |
886 | return float64_compare_quiet(a, b, s) <= float_relation_equal; | |
887 | } | |
888 | ||
889 | static inline bool float64_lt_quiet(float64 a, float64 b, float_status *s) | |
890 | { | |
891 | return float64_compare_quiet(a, b, s) < float_relation_equal; | |
892 | } | |
893 | ||
894 | static inline bool float64_unordered_quiet(float64 a, float64 b, | |
895 | float_status *s) | |
896 | { | |
897 | return float64_compare_quiet(a, b, s) == float_relation_unordered; | |
898 | } | |
899 | ||
f090c9d4 | 900 | #define float64_zero make_float64(0) |
026e2d6e | 901 | #define float64_half make_float64(0x3fe0000000000000LL) |
196cfc89 | 902 | #define float64_one make_float64(0x3ff0000000000000LL) |
026e2d6e AB |
903 | #define float64_one_point_five make_float64(0x3FF8000000000000ULL) |
904 | #define float64_two make_float64(0x4000000000000000ULL) | |
905 | #define float64_three make_float64(0x4008000000000000ULL) | |
8229c991 | 906 | #define float64_ln2 make_float64(0x3fe62e42fefa39efLL) |
c30fe7df | 907 | #define float64_infinity make_float64(0x7ff0000000000000LL) |
f090c9d4 | 908 | |
8559666d CL |
909 | /*---------------------------------------------------------------------------- |
910 | | The pattern for a default generated double-precision NaN. | |
911 | *----------------------------------------------------------------------------*/ | |
af39bc8c | 912 | float64 float64_default_nan(float_status *status); |
8559666d | 913 | |
42636fb9 RH |
914 | /*---------------------------------------------------------------------------- |
915 | | Software IEC/IEEE double-precision operations, rounding to single precision, | |
916 | | returning a result in double precision, with only one rounding step. | |
917 | *----------------------------------------------------------------------------*/ | |
918 | ||
919 | float64 float64r32_add(float64, float64, float_status *status); | |
920 | float64 float64r32_sub(float64, float64, float_status *status); | |
921 | float64 float64r32_mul(float64, float64, float_status *status); | |
922 | float64 float64r32_div(float64, float64, float_status *status); | |
923 | float64 float64r32_muladd(float64, float64, float64, int, float_status *status); | |
924 | float64 float64r32_sqrt(float64, float_status *status); | |
925 | ||
158142c2 FB |
926 | /*---------------------------------------------------------------------------- |
927 | | Software IEC/IEEE extended double-precision conversion routines. | |
928 | *----------------------------------------------------------------------------*/ | |
f4014512 PM |
929 | int32_t floatx80_to_int32(floatx80, float_status *status); |
930 | int32_t floatx80_to_int32_round_to_zero(floatx80, float_status *status); | |
f42c2224 PM |
931 | int64_t floatx80_to_int64(floatx80, float_status *status); |
932 | int64_t floatx80_to_int64_round_to_zero(floatx80, float_status *status); | |
e5a41ffa PM |
933 | float32 floatx80_to_float32(floatx80, float_status *status); |
934 | float64 floatx80_to_float64(floatx80, float_status *status); | |
935 | float128 floatx80_to_float128(floatx80, float_status *status); | |
158142c2 | 936 | |
0f605c88 LV |
937 | /*---------------------------------------------------------------------------- |
938 | | The pattern for an extended double-precision inf. | |
939 | *----------------------------------------------------------------------------*/ | |
940 | extern const floatx80 floatx80_infinity; | |
941 | ||
158142c2 FB |
942 | /*---------------------------------------------------------------------------- |
943 | | Software IEC/IEEE extended double-precision operations. | |
944 | *----------------------------------------------------------------------------*/ | |
0f721292 | 945 | floatx80 floatx80_round(floatx80 a, float_status *status); |
e5a41ffa PM |
946 | floatx80 floatx80_round_to_int(floatx80, float_status *status); |
947 | floatx80 floatx80_add(floatx80, floatx80, float_status *status); | |
948 | floatx80 floatx80_sub(floatx80, floatx80, float_status *status); | |
949 | floatx80 floatx80_mul(floatx80, floatx80, float_status *status); | |
950 | floatx80 floatx80_div(floatx80, floatx80, float_status *status); | |
445810ec JM |
951 | floatx80 floatx80_modrem(floatx80, floatx80, bool, uint64_t *, |
952 | float_status *status); | |
6b8b0136 | 953 | floatx80 floatx80_mod(floatx80, floatx80, float_status *status); |
e5a41ffa PM |
954 | floatx80 floatx80_rem(floatx80, floatx80, float_status *status); |
955 | floatx80 floatx80_sqrt(floatx80, float_status *status); | |
71bfd65c RH |
956 | FloatRelation floatx80_compare(floatx80, floatx80, float_status *status); |
957 | FloatRelation floatx80_compare_quiet(floatx80, floatx80, float_status *status); | |
af39bc8c AM |
958 | int floatx80_is_quiet_nan(floatx80, float_status *status); |
959 | int floatx80_is_signaling_nan(floatx80, float_status *status); | |
d619bb98 | 960 | floatx80 floatx80_silence_nan(floatx80, float_status *status); |
e5a41ffa | 961 | floatx80 floatx80_scalbn(floatx80, int, float_status *status); |
158142c2 | 962 | |
a49db98d | 963 | static inline floatx80 floatx80_abs(floatx80 a) |
1d6bda35 FB |
964 | { |
965 | a.high &= 0x7fff; | |
966 | return a; | |
967 | } | |
968 | ||
a49db98d | 969 | static inline floatx80 floatx80_chs(floatx80 a) |
1d6bda35 FB |
970 | { |
971 | a.high ^= 0x8000; | |
972 | return a; | |
973 | } | |
974 | ||
150c7a91 | 975 | static inline bool floatx80_is_infinity(floatx80 a) |
c52ab6f5 | 976 | { |
0f605c88 LV |
977 | #if defined(TARGET_M68K) |
978 | return (a.high & 0x7fff) == floatx80_infinity.high && !(a.low << 1); | |
979 | #else | |
980 | return (a.high & 0x7fff) == floatx80_infinity.high && | |
981 | a.low == floatx80_infinity.low; | |
982 | #endif | |
c52ab6f5 AJ |
983 | } |
984 | ||
150c7a91 | 985 | static inline bool floatx80_is_neg(floatx80 a) |
c52ab6f5 AJ |
986 | { |
987 | return a.high >> 15; | |
988 | } | |
989 | ||
150c7a91 | 990 | static inline bool floatx80_is_zero(floatx80 a) |
c52ab6f5 AJ |
991 | { |
992 | return (a.high & 0x7fff) == 0 && a.low == 0; | |
993 | } | |
994 | ||
150c7a91 | 995 | static inline bool floatx80_is_zero_or_denormal(floatx80 a) |
587eabfa AJ |
996 | { |
997 | return (a.high & 0x7fff) == 0; | |
998 | } | |
999 | ||
150c7a91 | 1000 | static inline bool floatx80_is_any_nan(floatx80 a) |
2bed652f PM |
1001 | { |
1002 | return ((a.high & 0x7fff) == 0x7fff) && (a.low<<1); | |
1003 | } | |
1004 | ||
c6baf650 RH |
1005 | static inline bool floatx80_eq(floatx80 a, floatx80 b, float_status *s) |
1006 | { | |
1007 | return floatx80_compare(a, b, s) == float_relation_equal; | |
1008 | } | |
1009 | ||
1010 | static inline bool floatx80_le(floatx80 a, floatx80 b, float_status *s) | |
1011 | { | |
1012 | return floatx80_compare(a, b, s) <= float_relation_equal; | |
1013 | } | |
1014 | ||
1015 | static inline bool floatx80_lt(floatx80 a, floatx80 b, float_status *s) | |
1016 | { | |
1017 | return floatx80_compare(a, b, s) < float_relation_equal; | |
1018 | } | |
1019 | ||
1020 | static inline bool floatx80_unordered(floatx80 a, floatx80 b, float_status *s) | |
1021 | { | |
1022 | return floatx80_compare(a, b, s) == float_relation_unordered; | |
1023 | } | |
1024 | ||
1025 | static inline bool floatx80_eq_quiet(floatx80 a, floatx80 b, float_status *s) | |
1026 | { | |
1027 | return floatx80_compare_quiet(a, b, s) == float_relation_equal; | |
1028 | } | |
1029 | ||
1030 | static inline bool floatx80_le_quiet(floatx80 a, floatx80 b, float_status *s) | |
1031 | { | |
1032 | return floatx80_compare_quiet(a, b, s) <= float_relation_equal; | |
1033 | } | |
1034 | ||
1035 | static inline bool floatx80_lt_quiet(floatx80 a, floatx80 b, float_status *s) | |
1036 | { | |
1037 | return floatx80_compare_quiet(a, b, s) < float_relation_equal; | |
1038 | } | |
1039 | ||
1040 | static inline bool floatx80_unordered_quiet(floatx80 a, floatx80 b, | |
1041 | float_status *s) | |
1042 | { | |
1043 | return floatx80_compare_quiet(a, b, s) == float_relation_unordered; | |
1044 | } | |
1045 | ||
d1eb8f2a AD |
1046 | /*---------------------------------------------------------------------------- |
1047 | | Return whether the given value is an invalid floatx80 encoding. | |
1048 | | Invalid floatx80 encodings arise when the integer bit is not set, but | |
1049 | | the exponent is not zero. The only times the integer bit is permitted to | |
1050 | | be zero is in subnormal numbers and the value zero. | |
1051 | | This includes what the Intel software developer's manual calls pseudo-NaNs, | |
1052 | | pseudo-infinities and un-normal numbers. It does not include | |
1053 | | pseudo-denormals, which must still be correctly handled as inputs even | |
1054 | | if they are never generated as outputs. | |
1055 | *----------------------------------------------------------------------------*/ | |
1056 | static inline bool floatx80_invalid_encoding(floatx80 a) | |
1057 | { | |
d159dd05 LV |
1058 | #if defined(TARGET_M68K) |
1059 | /*------------------------------------------------------------------------- | |
1060 | | With m68k, the explicit integer bit can be zero in the case of: | |
1061 | | - zeros (exp == 0, mantissa == 0) | |
1062 | | - denormalized numbers (exp == 0, mantissa != 0) | |
1063 | | - unnormalized numbers (exp != 0, exp < 0x7FFF) | |
1064 | | - infinities (exp == 0x7FFF, mantissa == 0) | |
1065 | | - not-a-numbers (exp == 0x7FFF, mantissa != 0) | |
1066 | | | |
1067 | | For infinities and NaNs, the explicit integer bit can be either one or | |
1068 | | zero. | |
1069 | | | |
1070 | | The IEEE 754 standard does not define a zero integer bit. Such a number | |
1071 | | is an unnormalized number. Hardware does not directly support | |
1072 | | denormalized and unnormalized numbers, but implicitly supports them by | |
1073 | | trapping them as unimplemented data types, allowing efficient conversion | |
1074 | | in software. | |
1075 | | | |
1076 | | See "M68000 FAMILY PROGRAMMER’S REFERENCE MANUAL", | |
1077 | | "1.6 FLOATING-POINT DATA TYPES" | |
1078 | *------------------------------------------------------------------------*/ | |
1079 | return false; | |
1080 | #else | |
d1eb8f2a | 1081 | return (a.low & (1ULL << 63)) == 0 && (a.high & 0x7FFF) != 0; |
d159dd05 | 1082 | #endif |
d1eb8f2a AD |
1083 | } |
1084 | ||
f3218a8d | 1085 | #define floatx80_zero make_floatx80(0x0000, 0x0000000000000000LL) |
163b3d1a | 1086 | #define floatx80_zero_init make_floatx80_init(0x0000, 0x0000000000000000LL) |
f3218a8d AJ |
1087 | #define floatx80_one make_floatx80(0x3fff, 0x8000000000000000LL) |
1088 | #define floatx80_ln2 make_floatx80(0x3ffe, 0xb17217f7d1cf79acLL) | |
c4b4c77a | 1089 | #define floatx80_pi make_floatx80(0x4000, 0xc90fdaa22168c235LL) |
f3218a8d | 1090 | #define floatx80_half make_floatx80(0x3ffe, 0x8000000000000000LL) |
f3218a8d | 1091 | |
88857aca LV |
1092 | /*---------------------------------------------------------------------------- |
1093 | | Returns the fraction bits of the extended double-precision floating-point | |
1094 | | value `a'. | |
1095 | *----------------------------------------------------------------------------*/ | |
1096 | ||
1097 | static inline uint64_t extractFloatx80Frac(floatx80 a) | |
1098 | { | |
1099 | return a.low; | |
1100 | } | |
1101 | ||
1102 | /*---------------------------------------------------------------------------- | |
1103 | | Returns the exponent bits of the extended double-precision floating-point | |
1104 | | value `a'. | |
1105 | *----------------------------------------------------------------------------*/ | |
1106 | ||
1107 | static inline int32_t extractFloatx80Exp(floatx80 a) | |
1108 | { | |
1109 | return a.high & 0x7FFF; | |
1110 | } | |
1111 | ||
1112 | /*---------------------------------------------------------------------------- | |
1113 | | Returns the sign bit of the extended double-precision floating-point value | |
1114 | | `a'. | |
1115 | *----------------------------------------------------------------------------*/ | |
1116 | ||
c120391c | 1117 | static inline bool extractFloatx80Sign(floatx80 a) |
88857aca LV |
1118 | { |
1119 | return a.high >> 15; | |
1120 | } | |
1121 | ||
1122 | /*---------------------------------------------------------------------------- | |
1123 | | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an | |
1124 | | extended double-precision floating-point value, returning the result. | |
1125 | *----------------------------------------------------------------------------*/ | |
1126 | ||
c120391c | 1127 | static inline floatx80 packFloatx80(bool zSign, int32_t zExp, uint64_t zSig) |
88857aca LV |
1128 | { |
1129 | floatx80 z; | |
1130 | ||
1131 | z.low = zSig; | |
1132 | z.high = (((uint16_t)zSign) << 15) + zExp; | |
1133 | return z; | |
1134 | } | |
1135 | ||
1136 | /*---------------------------------------------------------------------------- | |
1137 | | Normalizes the subnormal extended double-precision floating-point value | |
1138 | | represented by the denormalized significand `aSig'. The normalized exponent | |
1139 | | and significand are stored at the locations pointed to by `zExpPtr' and | |
1140 | | `zSigPtr', respectively. | |
1141 | *----------------------------------------------------------------------------*/ | |
1142 | ||
1143 | void normalizeFloatx80Subnormal(uint64_t aSig, int32_t *zExpPtr, | |
1144 | uint64_t *zSigPtr); | |
1145 | ||
1146 | /*---------------------------------------------------------------------------- | |
1147 | | Takes two extended double-precision floating-point values `a' and `b', one | |
1148 | | of which is a NaN, and returns the appropriate NaN result. If either `a' or | |
1149 | | `b' is a signaling NaN, the invalid exception is raised. | |
1150 | *----------------------------------------------------------------------------*/ | |
1151 | ||
1152 | floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, float_status *status); | |
1153 | ||
1154 | /*---------------------------------------------------------------------------- | |
1155 | | Takes an abstract floating-point value having sign `zSign', exponent `zExp', | |
1156 | | and extended significand formed by the concatenation of `zSig0' and `zSig1', | |
1157 | | and returns the proper extended double-precision floating-point value | |
1158 | | corresponding to the abstract input. Ordinarily, the abstract value is | |
1159 | | rounded and packed into the extended double-precision format, with the | |
1160 | | inexact exception raised if the abstract input cannot be represented | |
1161 | | exactly. However, if the abstract value is too large, the overflow and | |
1162 | | inexact exceptions are raised and an infinity or maximal finite value is | |
1163 | | returned. If the abstract value is too small, the input value is rounded to | |
1164 | | a subnormal number, and the underflow and inexact exceptions are raised if | |
1165 | | the abstract input cannot be represented exactly as a subnormal extended | |
1166 | | double-precision floating-point number. | |
1167 | | If `roundingPrecision' is 32 or 64, the result is rounded to the same | |
1168 | | number of bits as single or double precision, respectively. Otherwise, the | |
1169 | | result is rounded to the full precision of the extended double-precision | |
1170 | | format. | |
1171 | | The input significand must be normalized or smaller. If the input | |
1172 | | significand is not normalized, `zExp' must be 0; in that case, the result | |
1173 | | returned is a subnormal number, and it must not require rounding. The | |
1174 | | handling of underflow and overflow follows the IEC/IEEE Standard for Binary | |
1175 | | Floating-Point Arithmetic. | |
1176 | *----------------------------------------------------------------------------*/ | |
1177 | ||
8da5f1db | 1178 | floatx80 roundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, bool zSign, |
88857aca LV |
1179 | int32_t zExp, uint64_t zSig0, uint64_t zSig1, |
1180 | float_status *status); | |
1181 | ||
1182 | /*---------------------------------------------------------------------------- | |
1183 | | Takes an abstract floating-point value having sign `zSign', exponent | |
1184 | | `zExp', and significand formed by the concatenation of `zSig0' and `zSig1', | |
1185 | | and returns the proper extended double-precision floating-point value | |
1186 | | corresponding to the abstract input. This routine is just like | |
1187 | | `roundAndPackFloatx80' except that the input significand does not have to be | |
1188 | | normalized. | |
1189 | *----------------------------------------------------------------------------*/ | |
1190 | ||
8da5f1db | 1191 | floatx80 normalizeRoundAndPackFloatx80(FloatX80RoundPrec roundingPrecision, |
c120391c | 1192 | bool zSign, int32_t zExp, |
88857aca LV |
1193 | uint64_t zSig0, uint64_t zSig1, |
1194 | float_status *status); | |
1195 | ||
8559666d | 1196 | /*---------------------------------------------------------------------------- |
789ec7ce | 1197 | | The pattern for a default generated extended double-precision NaN. |
8559666d | 1198 | *----------------------------------------------------------------------------*/ |
af39bc8c | 1199 | floatx80 floatx80_default_nan(float_status *status); |
8559666d | 1200 | |
158142c2 FB |
1201 | /*---------------------------------------------------------------------------- |
1202 | | Software IEC/IEEE quadruple-precision conversion routines. | |
1203 | *----------------------------------------------------------------------------*/ | |
f4014512 PM |
1204 | int32_t float128_to_int32(float128, float_status *status); |
1205 | int32_t float128_to_int32_round_to_zero(float128, float_status *status); | |
f42c2224 | 1206 | int64_t float128_to_int64(float128, float_status *status); |
bea59230 | 1207 | Int128 float128_to_int128(float128, float_status *status); |
f42c2224 | 1208 | int64_t float128_to_int64_round_to_zero(float128, float_status *status); |
bea59230 | 1209 | Int128 float128_to_int128_round_to_zero(float128, float_status *status); |
2e6d8568 | 1210 | uint64_t float128_to_uint64(float128, float_status *status); |
4de49ddf | 1211 | Int128 float128_to_uint128(float128, float_status *status); |
2e6d8568 | 1212 | uint64_t float128_to_uint64_round_to_zero(float128, float_status *status); |
4de49ddf | 1213 | Int128 float128_to_uint128_round_to_zero(float128, float_status *status); |
e45de992 | 1214 | uint32_t float128_to_uint32(float128, float_status *status); |
fd425037 | 1215 | uint32_t float128_to_uint32_round_to_zero(float128, float_status *status); |
e5a41ffa PM |
1216 | float32 float128_to_float32(float128, float_status *status); |
1217 | float64 float128_to_float64(float128, float_status *status); | |
1218 | floatx80 float128_to_floatx80(float128, float_status *status); | |
158142c2 FB |
1219 | |
1220 | /*---------------------------------------------------------------------------- | |
1221 | | Software IEC/IEEE quadruple-precision operations. | |
1222 | *----------------------------------------------------------------------------*/ | |
e5a41ffa PM |
1223 | float128 float128_round_to_int(float128, float_status *status); |
1224 | float128 float128_add(float128, float128, float_status *status); | |
1225 | float128 float128_sub(float128, float128, float_status *status); | |
1226 | float128 float128_mul(float128, float128, float_status *status); | |
dedd123c RH |
1227 | float128 float128_muladd(float128, float128, float128, int, |
1228 | float_status *status); | |
e5a41ffa PM |
1229 | float128 float128_div(float128, float128, float_status *status); |
1230 | float128 float128_rem(float128, float128, float_status *status); | |
1231 | float128 float128_sqrt(float128, float_status *status); | |
71bfd65c RH |
1232 | FloatRelation float128_compare(float128, float128, float_status *status); |
1233 | FloatRelation float128_compare_quiet(float128, float128, float_status *status); | |
ceebc129 DH |
1234 | float128 float128_min(float128, float128, float_status *status); |
1235 | float128 float128_max(float128, float128, float_status *status); | |
1236 | float128 float128_minnum(float128, float128, float_status *status); | |
1237 | float128 float128_maxnum(float128, float128, float_status *status); | |
1238 | float128 float128_minnummag(float128, float128, float_status *status); | |
1239 | float128 float128_maxnummag(float128, float128, float_status *status); | |
0e903037 CMC |
1240 | float128 float128_minimum_number(float128, float128, float_status *status); |
1241 | float128 float128_maximum_number(float128, float128, float_status *status); | |
150c7a91 RH |
1242 | bool float128_is_quiet_nan(float128, float_status *status); |
1243 | bool float128_is_signaling_nan(float128, float_status *status); | |
d619bb98 | 1244 | float128 float128_silence_nan(float128, float_status *status); |
e5a41ffa | 1245 | float128 float128_scalbn(float128, int, float_status *status); |
158142c2 | 1246 | |
a49db98d | 1247 | static inline float128 float128_abs(float128 a) |
1d6bda35 FB |
1248 | { |
1249 | a.high &= 0x7fffffffffffffffLL; | |
1250 | return a; | |
1251 | } | |
1252 | ||
a49db98d | 1253 | static inline float128 float128_chs(float128 a) |
1d6bda35 FB |
1254 | { |
1255 | a.high ^= 0x8000000000000000LL; | |
1256 | return a; | |
1257 | } | |
1258 | ||
150c7a91 | 1259 | static inline bool float128_is_infinity(float128 a) |
c52ab6f5 AJ |
1260 | { |
1261 | return (a.high & 0x7fffffffffffffffLL) == 0x7fff000000000000LL && a.low == 0; | |
1262 | } | |
1263 | ||
150c7a91 | 1264 | static inline bool float128_is_neg(float128 a) |
c52ab6f5 AJ |
1265 | { |
1266 | return a.high >> 63; | |
1267 | } | |
1268 | ||
150c7a91 | 1269 | static inline bool float128_is_zero(float128 a) |
c52ab6f5 AJ |
1270 | { |
1271 | return (a.high & 0x7fffffffffffffffLL) == 0 && a.low == 0; | |
1272 | } | |
1273 | ||
150c7a91 | 1274 | static inline bool float128_is_zero_or_denormal(float128 a) |
587eabfa AJ |
1275 | { |
1276 | return (a.high & 0x7fff000000000000LL) == 0; | |
1277 | } | |
1278 | ||
47393181 DH |
1279 | static inline bool float128_is_normal(float128 a) |
1280 | { | |
1281 | return (((a.high >> 48) + 1) & 0x7fff) >= 2; | |
1282 | } | |
1283 | ||
1284 | static inline bool float128_is_denormal(float128 a) | |
1285 | { | |
1286 | return float128_is_zero_or_denormal(a) && !float128_is_zero(a); | |
1287 | } | |
1288 | ||
150c7a91 | 1289 | static inline bool float128_is_any_nan(float128 a) |
2bed652f PM |
1290 | { |
1291 | return ((a.high >> 48) & 0x7fff) == 0x7fff && | |
1292 | ((a.low != 0) || ((a.high & 0xffffffffffffLL) != 0)); | |
1293 | } | |
1294 | ||
b7b1ac68 RH |
1295 | static inline bool float128_eq(float128 a, float128 b, float_status *s) |
1296 | { | |
1297 | return float128_compare(a, b, s) == float_relation_equal; | |
1298 | } | |
1299 | ||
1300 | static inline bool float128_le(float128 a, float128 b, float_status *s) | |
1301 | { | |
1302 | return float128_compare(a, b, s) <= float_relation_equal; | |
1303 | } | |
1304 | ||
1305 | static inline bool float128_lt(float128 a, float128 b, float_status *s) | |
1306 | { | |
1307 | return float128_compare(a, b, s) < float_relation_equal; | |
1308 | } | |
1309 | ||
1310 | static inline bool float128_unordered(float128 a, float128 b, float_status *s) | |
1311 | { | |
1312 | return float128_compare(a, b, s) == float_relation_unordered; | |
1313 | } | |
1314 | ||
1315 | static inline bool float128_eq_quiet(float128 a, float128 b, float_status *s) | |
1316 | { | |
1317 | return float128_compare_quiet(a, b, s) == float_relation_equal; | |
1318 | } | |
1319 | ||
1320 | static inline bool float128_le_quiet(float128 a, float128 b, float_status *s) | |
1321 | { | |
1322 | return float128_compare_quiet(a, b, s) <= float_relation_equal; | |
1323 | } | |
1324 | ||
1325 | static inline bool float128_lt_quiet(float128 a, float128 b, float_status *s) | |
1326 | { | |
1327 | return float128_compare_quiet(a, b, s) < float_relation_equal; | |
1328 | } | |
1329 | ||
1330 | static inline bool float128_unordered_quiet(float128 a, float128 b, | |
1331 | float_status *s) | |
1332 | { | |
1333 | return float128_compare_quiet(a, b, s) == float_relation_unordered; | |
1334 | } | |
1335 | ||
1e397ead RH |
1336 | #define float128_zero make_float128(0, 0) |
1337 | ||
8559666d | 1338 | /*---------------------------------------------------------------------------- |
789ec7ce | 1339 | | The pattern for a default generated quadruple-precision NaN. |
8559666d | 1340 | *----------------------------------------------------------------------------*/ |
af39bc8c | 1341 | float128 float128_default_nan(float_status *status); |
8559666d | 1342 | |
175de524 | 1343 | #endif /* SOFTFLOAT_H */ |