]>
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 | 16 | */ |
158142c2 | 17 | |
a7d1ac78 PM |
18 | /* |
19 | =============================================================================== | |
158142c2 | 20 | This C source fragment is part of the SoftFloat IEC/IEEE Floating-point |
a7d1ac78 | 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 | ||
213ff4e6 MF |
82 | #if defined(TARGET_XTENSA) |
83 | /* Define for architectures which deviate from IEEE in not supporting | |
84 | * signaling NaNs (so all NaNs are treated as quiet). | |
85 | */ | |
86 | #define NO_SIGNALING_NANS 1 | |
87 | #endif | |
88 | ||
789ec7ce PB |
89 | /*---------------------------------------------------------------------------- |
90 | | The pattern for a default generated half-precision NaN. | |
91 | *----------------------------------------------------------------------------*/ | |
af39bc8c AM |
92 | float16 float16_default_nan(float_status *status) |
93 | { | |
789ec7ce | 94 | #if defined(TARGET_ARM) |
af39bc8c | 95 | return const_float16(0x7E00); |
789ec7ce | 96 | #else |
af39bc8c AM |
97 | if (status->snan_bit_is_one) { |
98 | return const_float16(0x7DFF); | |
99 | } else { | |
a7c04d54 AM |
100 | #if defined(TARGET_MIPS) |
101 | return const_float16(0x7E00); | |
102 | #else | |
af39bc8c | 103 | return const_float16(0xFE00); |
a7c04d54 | 104 | #endif |
af39bc8c | 105 | } |
789ec7ce | 106 | #endif |
af39bc8c | 107 | } |
789ec7ce PB |
108 | |
109 | /*---------------------------------------------------------------------------- | |
110 | | The pattern for a default generated single-precision NaN. | |
111 | *----------------------------------------------------------------------------*/ | |
af39bc8c AM |
112 | float32 float32_default_nan(float_status *status) |
113 | { | |
e5b0cbe8 | 114 | #if defined(TARGET_SPARC) || defined(TARGET_M68K) |
af39bc8c | 115 | return const_float32(0x7FFFFFFF); |
b81fe822 | 116 | #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \ |
996a729f | 117 | defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE) |
af39bc8c | 118 | return const_float32(0x7FC00000); |
005fa38d RH |
119 | #elif defined(TARGET_HPPA) |
120 | return const_float32(0x7FA00000); | |
789ec7ce | 121 | #else |
af39bc8c AM |
122 | if (status->snan_bit_is_one) { |
123 | return const_float32(0x7FBFFFFF); | |
124 | } else { | |
a7c04d54 AM |
125 | #if defined(TARGET_MIPS) |
126 | return const_float32(0x7FC00000); | |
127 | #else | |
af39bc8c | 128 | return const_float32(0xFFC00000); |
a7c04d54 | 129 | #endif |
af39bc8c | 130 | } |
789ec7ce | 131 | #endif |
af39bc8c | 132 | } |
789ec7ce PB |
133 | |
134 | /*---------------------------------------------------------------------------- | |
135 | | The pattern for a default generated double-precision NaN. | |
136 | *----------------------------------------------------------------------------*/ | |
af39bc8c AM |
137 | float64 float64_default_nan(float_status *status) |
138 | { | |
e5b0cbe8 | 139 | #if defined(TARGET_SPARC) || defined(TARGET_M68K) |
af39bc8c | 140 | return const_float64(LIT64(0x7FFFFFFFFFFFFFFF)); |
2daea9c1 AJ |
141 | #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \ |
142 | defined(TARGET_S390X) | |
af39bc8c | 143 | return const_float64(LIT64(0x7FF8000000000000)); |
005fa38d RH |
144 | #elif defined(TARGET_HPPA) |
145 | return const_float64(LIT64(0x7FF4000000000000)); | |
789ec7ce | 146 | #else |
af39bc8c AM |
147 | if (status->snan_bit_is_one) { |
148 | return const_float64(LIT64(0x7FF7FFFFFFFFFFFF)); | |
149 | } else { | |
a7c04d54 AM |
150 | #if defined(TARGET_MIPS) |
151 | return const_float64(LIT64(0x7FF8000000000000)); | |
152 | #else | |
af39bc8c | 153 | return const_float64(LIT64(0xFFF8000000000000)); |
a7c04d54 | 154 | #endif |
af39bc8c | 155 | } |
789ec7ce | 156 | #endif |
af39bc8c | 157 | } |
789ec7ce PB |
158 | |
159 | /*---------------------------------------------------------------------------- | |
160 | | The pattern for a default generated extended double-precision NaN. | |
161 | *----------------------------------------------------------------------------*/ | |
af39bc8c AM |
162 | floatx80 floatx80_default_nan(float_status *status) |
163 | { | |
164 | floatx80 r; | |
e5b0cbe8 LV |
165 | #if defined(TARGET_M68K) |
166 | r.low = LIT64(0xFFFFFFFFFFFFFFFF); | |
167 | r.high = 0x7FFF; | |
168 | #else | |
af39bc8c AM |
169 | if (status->snan_bit_is_one) { |
170 | r.low = LIT64(0xBFFFFFFFFFFFFFFF); | |
171 | r.high = 0x7FFF; | |
172 | } else { | |
173 | r.low = LIT64(0xC000000000000000); | |
174 | r.high = 0xFFFF; | |
175 | } | |
e5b0cbe8 | 176 | #endif |
af39bc8c AM |
177 | return r; |
178 | } | |
789ec7ce PB |
179 | |
180 | /*---------------------------------------------------------------------------- | |
af39bc8c | 181 | | The pattern for a default generated quadruple-precision NaN. |
789ec7ce | 182 | *----------------------------------------------------------------------------*/ |
af39bc8c AM |
183 | float128 float128_default_nan(float_status *status) |
184 | { | |
185 | float128 r; | |
186 | ||
187 | if (status->snan_bit_is_one) { | |
188 | r.low = LIT64(0xFFFFFFFFFFFFFFFF); | |
189 | r.high = LIT64(0x7FFF7FFFFFFFFFFF); | |
190 | } else { | |
191 | r.low = LIT64(0x0000000000000000); | |
5d51eaea | 192 | #if defined(TARGET_S390X) || defined(TARGET_PPC) |
af39bc8c | 193 | r.high = LIT64(0x7FFF800000000000); |
789ec7ce | 194 | #else |
af39bc8c | 195 | r.high = LIT64(0xFFFF800000000000); |
789ec7ce | 196 | #endif |
af39bc8c AM |
197 | } |
198 | return r; | |
199 | } | |
789ec7ce | 200 | |
158142c2 FB |
201 | /*---------------------------------------------------------------------------- |
202 | | Raises the exceptions specified by `flags'. Floating-point traps can be | |
203 | | defined here if desired. It is currently not possible for such a trap | |
204 | | to substitute a result value. If traps are not implemented, this routine | |
205 | | should be simply `float_exception_flags |= flags;'. | |
206 | *----------------------------------------------------------------------------*/ | |
207 | ||
dfd60767 | 208 | void float_raise(uint8_t flags, float_status *status) |
158142c2 | 209 | { |
a2f2d288 | 210 | status->float_exception_flags |= flags; |
158142c2 FB |
211 | } |
212 | ||
213 | /*---------------------------------------------------------------------------- | |
214 | | Internal canonical NaN format. | |
215 | *----------------------------------------------------------------------------*/ | |
216 | typedef struct { | |
217 | flag sign; | |
bb98fe42 | 218 | uint64_t high, low; |
158142c2 FB |
219 | } commonNaNT; |
220 | ||
213ff4e6 | 221 | #ifdef NO_SIGNALING_NANS |
af39bc8c | 222 | int float16_is_quiet_nan(float16 a_, float_status *status) |
213ff4e6 MF |
223 | { |
224 | return float16_is_any_nan(a_); | |
225 | } | |
226 | ||
af39bc8c | 227 | int float16_is_signaling_nan(float16 a_, float_status *status) |
213ff4e6 MF |
228 | { |
229 | return 0; | |
230 | } | |
231 | #else | |
bb4d4bb3 PM |
232 | /*---------------------------------------------------------------------------- |
233 | | Returns 1 if the half-precision floating-point value `a' is a quiet | |
234 | | NaN; otherwise returns 0. | |
235 | *----------------------------------------------------------------------------*/ | |
236 | ||
af39bc8c | 237 | int float16_is_quiet_nan(float16 a_, float_status *status) |
bb4d4bb3 PM |
238 | { |
239 | uint16_t a = float16_val(a_); | |
af39bc8c AM |
240 | if (status->snan_bit_is_one) { |
241 | return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); | |
242 | } else { | |
243 | return ((a & ~0x8000) >= 0x7C80); | |
244 | } | |
bb4d4bb3 PM |
245 | } |
246 | ||
247 | /*---------------------------------------------------------------------------- | |
248 | | Returns 1 if the half-precision floating-point value `a' is a signaling | |
249 | | NaN; otherwise returns 0. | |
250 | *----------------------------------------------------------------------------*/ | |
251 | ||
af39bc8c | 252 | int float16_is_signaling_nan(float16 a_, float_status *status) |
bb4d4bb3 PM |
253 | { |
254 | uint16_t a = float16_val(a_); | |
af39bc8c AM |
255 | if (status->snan_bit_is_one) { |
256 | return ((a & ~0x8000) >= 0x7C80); | |
257 | } else { | |
258 | return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF); | |
259 | } | |
bb4d4bb3 | 260 | } |
213ff4e6 | 261 | #endif |
bb4d4bb3 PM |
262 | |
263 | /*---------------------------------------------------------------------------- | |
264 | | Returns a quiet NaN if the half-precision floating point value `a' is a | |
265 | | signaling NaN; otherwise returns `a'. | |
266 | *----------------------------------------------------------------------------*/ | |
af39bc8c | 267 | float16 float16_maybe_silence_nan(float16 a_, float_status *status) |
bb4d4bb3 | 268 | { |
af39bc8c AM |
269 | if (float16_is_signaling_nan(a_, status)) { |
270 | if (status->snan_bit_is_one) { | |
271 | return float16_default_nan(status); | |
272 | } else { | |
273 | uint16_t a = float16_val(a_); | |
274 | a |= (1 << 9); | |
275 | return make_float16(a); | |
276 | } | |
bb4d4bb3 PM |
277 | } |
278 | return a_; | |
279 | } | |
280 | ||
f591e1be PM |
281 | /*---------------------------------------------------------------------------- |
282 | | Returns the result of converting the half-precision floating-point NaN | |
283 | | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid | |
284 | | exception is raised. | |
285 | *----------------------------------------------------------------------------*/ | |
286 | ||
e5a41ffa | 287 | static commonNaNT float16ToCommonNaN(float16 a, float_status *status) |
f591e1be PM |
288 | { |
289 | commonNaNT z; | |
290 | ||
af39bc8c | 291 | if (float16_is_signaling_nan(a, status)) { |
ff32e16e PM |
292 | float_raise(float_flag_invalid, status); |
293 | } | |
f591e1be PM |
294 | z.sign = float16_val(a) >> 15; |
295 | z.low = 0; | |
a59eaea6 | 296 | z.high = ((uint64_t) float16_val(a)) << 54; |
f591e1be PM |
297 | return z; |
298 | } | |
299 | ||
600e30d2 PM |
300 | /*---------------------------------------------------------------------------- |
301 | | Returns the result of converting the canonical NaN `a' to the half- | |
302 | | precision floating-point format. | |
303 | *----------------------------------------------------------------------------*/ | |
304 | ||
e5a41ffa | 305 | static float16 commonNaNToFloat16(commonNaNT a, float_status *status) |
600e30d2 | 306 | { |
a59eaea6 | 307 | uint16_t mantissa = a.high >> 54; |
600e30d2 | 308 | |
a2f2d288 | 309 | if (status->default_nan_mode) { |
af39bc8c | 310 | return float16_default_nan(status); |
600e30d2 PM |
311 | } |
312 | ||
313 | if (mantissa) { | |
314 | return make_float16(((((uint16_t) a.sign) << 15) | |
315 | | (0x1F << 10) | mantissa)); | |
316 | } else { | |
af39bc8c | 317 | return float16_default_nan(status); |
600e30d2 PM |
318 | } |
319 | } | |
320 | ||
213ff4e6 | 321 | #ifdef NO_SIGNALING_NANS |
af39bc8c | 322 | int float32_is_quiet_nan(float32 a_, float_status *status) |
213ff4e6 MF |
323 | { |
324 | return float32_is_any_nan(a_); | |
325 | } | |
326 | ||
af39bc8c | 327 | int float32_is_signaling_nan(float32 a_, float_status *status) |
213ff4e6 MF |
328 | { |
329 | return 0; | |
330 | } | |
331 | #else | |
158142c2 | 332 | /*---------------------------------------------------------------------------- |
5a6932d5 TS |
333 | | Returns 1 if the single-precision floating-point value `a' is a quiet |
334 | | NaN; otherwise returns 0. | |
158142c2 FB |
335 | *----------------------------------------------------------------------------*/ |
336 | ||
af39bc8c | 337 | int float32_is_quiet_nan(float32 a_, float_status *status) |
158142c2 | 338 | { |
f090c9d4 | 339 | uint32_t a = float32_val(a_); |
af39bc8c AM |
340 | if (status->snan_bit_is_one) { |
341 | return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF); | |
342 | } else { | |
343 | return ((uint32_t)(a << 1) >= 0xFF800000); | |
344 | } | |
158142c2 FB |
345 | } |
346 | ||
347 | /*---------------------------------------------------------------------------- | |
348 | | Returns 1 if the single-precision floating-point value `a' is a signaling | |
349 | | NaN; otherwise returns 0. | |
350 | *----------------------------------------------------------------------------*/ | |
351 | ||
af39bc8c | 352 | int float32_is_signaling_nan(float32 a_, float_status *status) |
158142c2 | 353 | { |
f090c9d4 | 354 | uint32_t a = float32_val(a_); |
af39bc8c AM |
355 | if (status->snan_bit_is_one) { |
356 | return ((uint32_t)(a << 1) >= 0xFF800000); | |
357 | } else { | |
358 | return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF); | |
359 | } | |
158142c2 | 360 | } |
213ff4e6 | 361 | #endif |
158142c2 | 362 | |
b408dbde PM |
363 | /*---------------------------------------------------------------------------- |
364 | | Returns a quiet NaN if the single-precision floating point value `a' is a | |
365 | | signaling NaN; otherwise returns `a'. | |
366 | *----------------------------------------------------------------------------*/ | |
367 | ||
af39bc8c | 368 | float32 float32_maybe_silence_nan(float32 a_, float_status *status) |
b408dbde | 369 | { |
af39bc8c AM |
370 | if (float32_is_signaling_nan(a_, status)) { |
371 | if (status->snan_bit_is_one) { | |
005fa38d RH |
372 | #ifdef TARGET_HPPA |
373 | uint32_t a = float32_val(a_); | |
374 | a &= ~0x00400000; | |
375 | a |= 0x00200000; | |
376 | return make_float32(a); | |
377 | #else | |
af39bc8c | 378 | return float32_default_nan(status); |
005fa38d | 379 | #endif |
af39bc8c AM |
380 | } else { |
381 | uint32_t a = float32_val(a_); | |
382 | a |= (1 << 22); | |
383 | return make_float32(a); | |
384 | } | |
b408dbde PM |
385 | } |
386 | return a_; | |
387 | } | |
388 | ||
158142c2 FB |
389 | /*---------------------------------------------------------------------------- |
390 | | Returns the result of converting the single-precision floating-point NaN | |
391 | | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid | |
392 | | exception is raised. | |
393 | *----------------------------------------------------------------------------*/ | |
394 | ||
e5a41ffa | 395 | static commonNaNT float32ToCommonNaN(float32 a, float_status *status) |
158142c2 FB |
396 | { |
397 | commonNaNT z; | |
398 | ||
af39bc8c | 399 | if (float32_is_signaling_nan(a, status)) { |
ff32e16e PM |
400 | float_raise(float_flag_invalid, status); |
401 | } | |
a59eaea6 | 402 | z.sign = float32_val(a) >> 31; |
158142c2 | 403 | z.low = 0; |
a59eaea6 | 404 | z.high = ((uint64_t)float32_val(a)) << 41; |
158142c2 | 405 | return z; |
158142c2 FB |
406 | } |
407 | ||
408 | /*---------------------------------------------------------------------------- | |
409 | | Returns the result of converting the canonical NaN `a' to the single- | |
410 | | precision floating-point format. | |
411 | *----------------------------------------------------------------------------*/ | |
412 | ||
e5a41ffa | 413 | static float32 commonNaNToFloat32(commonNaNT a, float_status *status) |
158142c2 | 414 | { |
a59eaea6 | 415 | uint32_t mantissa = a.high >> 41; |
bcd4d9af | 416 | |
a2f2d288 | 417 | if (status->default_nan_mode) { |
af39bc8c | 418 | return float32_default_nan(status); |
bcd4d9af CL |
419 | } |
420 | ||
af39bc8c | 421 | if (mantissa) { |
85016c98 | 422 | return make_float32( |
a59eaea6 | 423 | (((uint32_t)a.sign) << 31) | 0x7F800000 | (a.high >> 41)); |
af39bc8c AM |
424 | } else { |
425 | return float32_default_nan(status); | |
426 | } | |
158142c2 FB |
427 | } |
428 | ||
354f211b PM |
429 | /*---------------------------------------------------------------------------- |
430 | | Select which NaN to propagate for a two-input operation. | |
431 | | IEEE754 doesn't specify all the details of this, so the | |
432 | | algorithm is target-specific. | |
433 | | The routine is passed various bits of information about the | |
434 | | two NaNs and should return 0 to select NaN a and 1 for NaN b. | |
435 | | Note that signalling NaNs are always squashed to quiet NaNs | |
1f398e08 AJ |
436 | | by the caller, by calling floatXX_maybe_silence_nan() before |
437 | | returning them. | |
354f211b PM |
438 | | |
439 | | aIsLargerSignificand is only valid if both a and b are NaNs | |
440 | | of some kind, and is true if a has the larger significand, | |
441 | | or if both a and b have the same significand but a is | |
442 | | positive but b is negative. It is only needed for the x87 | |
443 | | tie-break rule. | |
444 | *----------------------------------------------------------------------------*/ | |
445 | ||
011da610 PM |
446 | #if defined(TARGET_ARM) |
447 | static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, | |
448 | flag aIsLargerSignificand) | |
449 | { | |
450 | /* ARM mandated NaN propagation rules: take the first of: | |
451 | * 1. A if it is signaling | |
452 | * 2. B if it is signaling | |
453 | * 3. A (quiet) | |
454 | * 4. B (quiet) | |
455 | * A signaling NaN is always quietened before returning it. | |
456 | */ | |
457 | if (aIsSNaN) { | |
458 | return 0; | |
459 | } else if (bIsSNaN) { | |
460 | return 1; | |
461 | } else if (aIsQNaN) { | |
462 | return 0; | |
463 | } else { | |
464 | return 1; | |
465 | } | |
466 | } | |
005fa38d | 467 | #elif defined(TARGET_MIPS) || defined(TARGET_HPPA) |
084d19ba AJ |
468 | static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, |
469 | flag aIsLargerSignificand) | |
470 | { | |
471 | /* According to MIPS specifications, if one of the two operands is | |
472 | * a sNaN, a new qNaN has to be generated. This is done in | |
473 | * floatXX_maybe_silence_nan(). For qNaN inputs the specifications | |
474 | * says: "When possible, this QNaN result is one of the operand QNaN | |
475 | * values." In practice it seems that most implementations choose | |
476 | * the first operand if both operands are qNaN. In short this gives | |
477 | * the following rules: | |
478 | * 1. A if it is signaling | |
479 | * 2. B if it is signaling | |
480 | * 3. A (quiet) | |
481 | * 4. B (quiet) | |
482 | * A signaling NaN is always silenced before returning it. | |
483 | */ | |
484 | if (aIsSNaN) { | |
485 | return 0; | |
486 | } else if (bIsSNaN) { | |
487 | return 1; | |
488 | } else if (aIsQNaN) { | |
489 | return 0; | |
490 | } else { | |
491 | return 1; | |
492 | } | |
493 | } | |
b81fe822 | 494 | #elif defined(TARGET_PPC) || defined(TARGET_XTENSA) |
e024e881 AJ |
495 | static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, |
496 | flag aIsLargerSignificand) | |
497 | { | |
498 | /* PowerPC propagation rules: | |
499 | * 1. A if it sNaN or qNaN | |
500 | * 2. B if it sNaN or qNaN | |
501 | * A signaling NaN is always silenced before returning it. | |
502 | */ | |
503 | if (aIsSNaN || aIsQNaN) { | |
504 | return 0; | |
505 | } else { | |
506 | return 1; | |
507 | } | |
508 | } | |
e5b0cbe8 LV |
509 | #elif defined(TARGET_M68K) |
510 | static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, | |
511 | flag aIsLargerSignificand) | |
512 | { | |
513 | /* M68000 FAMILY PROGRAMMER'S REFERENCE MANUAL | |
514 | * 3.4 FLOATING-POINT INSTRUCTION DETAILS | |
515 | * If either operand, but not both operands, of an operation is a | |
516 | * nonsignaling NaN, then that NaN is returned as the result. If both | |
517 | * operands are nonsignaling NaNs, then the destination operand | |
518 | * nonsignaling NaN is returned as the result. | |
519 | * If either operand to an operation is a signaling NaN (SNaN), then the | |
520 | * SNaN bit is set in the FPSR EXC byte. If the SNaN exception enable bit | |
521 | * is set in the FPCR ENABLE byte, then the exception is taken and the | |
522 | * destination is not modified. If the SNaN exception enable bit is not | |
523 | * set, setting the SNaN bit in the operand to a one converts the SNaN to | |
524 | * a nonsignaling NaN. The operation then continues as described in the | |
525 | * preceding paragraph for nonsignaling NaNs. | |
526 | */ | |
527 | if (aIsQNaN || aIsSNaN) { /* a is the destination operand */ | |
528 | return 0; /* return the destination operand */ | |
529 | } else { | |
530 | return 1; /* return b */ | |
531 | } | |
532 | } | |
011da610 | 533 | #else |
354f211b PM |
534 | static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, |
535 | flag aIsLargerSignificand) | |
536 | { | |
537 | /* This implements x87 NaN propagation rules: | |
538 | * SNaN + QNaN => return the QNaN | |
539 | * two SNaNs => return the one with the larger significand, silenced | |
540 | * two QNaNs => return the one with the larger significand | |
541 | * SNaN and a non-NaN => return the SNaN, silenced | |
542 | * QNaN and a non-NaN => return the QNaN | |
543 | * | |
544 | * If we get down to comparing significands and they are the same, | |
545 | * return the NaN with the positive sign bit (if any). | |
546 | */ | |
547 | if (aIsSNaN) { | |
548 | if (bIsSNaN) { | |
549 | return aIsLargerSignificand ? 0 : 1; | |
550 | } | |
551 | return bIsQNaN ? 1 : 0; | |
a59eaea6 AM |
552 | } else if (aIsQNaN) { |
553 | if (bIsSNaN || !bIsQNaN) { | |
354f211b | 554 | return 0; |
a59eaea6 | 555 | } else { |
354f211b PM |
556 | return aIsLargerSignificand ? 0 : 1; |
557 | } | |
558 | } else { | |
559 | return 1; | |
560 | } | |
561 | } | |
011da610 | 562 | #endif |
354f211b | 563 | |
369be8f6 PM |
564 | /*---------------------------------------------------------------------------- |
565 | | Select which NaN to propagate for a three-input operation. | |
566 | | For the moment we assume that no CPU needs the 'larger significand' | |
567 | | information. | |
568 | | Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN | |
569 | *----------------------------------------------------------------------------*/ | |
570 | #if defined(TARGET_ARM) | |
571 | static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, | |
e5a41ffa PM |
572 | flag cIsQNaN, flag cIsSNaN, flag infzero, |
573 | float_status *status) | |
369be8f6 PM |
574 | { |
575 | /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns | |
576 | * the default NaN | |
577 | */ | |
578 | if (infzero && cIsQNaN) { | |
ff32e16e | 579 | float_raise(float_flag_invalid, status); |
369be8f6 PM |
580 | return 3; |
581 | } | |
582 | ||
583 | /* This looks different from the ARM ARM pseudocode, because the ARM ARM | |
584 | * puts the operands to a fused mac operation (a*b)+c in the order c,a,b. | |
585 | */ | |
586 | if (cIsSNaN) { | |
587 | return 2; | |
588 | } else if (aIsSNaN) { | |
589 | return 0; | |
590 | } else if (bIsSNaN) { | |
591 | return 1; | |
592 | } else if (cIsQNaN) { | |
593 | return 2; | |
594 | } else if (aIsQNaN) { | |
595 | return 0; | |
596 | } else { | |
597 | return 1; | |
598 | } | |
599 | } | |
bbc1dede AJ |
600 | #elif defined(TARGET_MIPS) |
601 | static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, | |
e5a41ffa PM |
602 | flag cIsQNaN, flag cIsSNaN, flag infzero, |
603 | float_status *status) | |
bbc1dede AJ |
604 | { |
605 | /* For MIPS, the (inf,zero,qnan) case sets InvalidOp and returns | |
606 | * the default NaN | |
607 | */ | |
608 | if (infzero) { | |
ff32e16e | 609 | float_raise(float_flag_invalid, status); |
bbc1dede AJ |
610 | return 3; |
611 | } | |
612 | ||
c27644f0 AM |
613 | if (status->snan_bit_is_one) { |
614 | /* Prefer sNaN over qNaN, in the a, b, c order. */ | |
615 | if (aIsSNaN) { | |
616 | return 0; | |
617 | } else if (bIsSNaN) { | |
618 | return 1; | |
619 | } else if (cIsSNaN) { | |
620 | return 2; | |
621 | } else if (aIsQNaN) { | |
622 | return 0; | |
623 | } else if (bIsQNaN) { | |
624 | return 1; | |
625 | } else { | |
626 | return 2; | |
627 | } | |
bbc1dede | 628 | } else { |
c27644f0 AM |
629 | /* Prefer sNaN over qNaN, in the c, a, b order. */ |
630 | if (cIsSNaN) { | |
631 | return 2; | |
632 | } else if (aIsSNaN) { | |
633 | return 0; | |
634 | } else if (bIsSNaN) { | |
635 | return 1; | |
636 | } else if (cIsQNaN) { | |
637 | return 2; | |
638 | } else if (aIsQNaN) { | |
639 | return 0; | |
640 | } else { | |
641 | return 1; | |
642 | } | |
bbc1dede AJ |
643 | } |
644 | } | |
369be8f6 PM |
645 | #elif defined(TARGET_PPC) |
646 | static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, | |
e5a41ffa PM |
647 | flag cIsQNaN, flag cIsSNaN, flag infzero, |
648 | float_status *status) | |
369be8f6 PM |
649 | { |
650 | /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer | |
651 | * to return an input NaN if we have one (ie c) rather than generating | |
652 | * a default NaN | |
653 | */ | |
654 | if (infzero) { | |
ff32e16e | 655 | float_raise(float_flag_invalid, status); |
369be8f6 PM |
656 | return 2; |
657 | } | |
658 | ||
659 | /* If fRA is a NaN return it; otherwise if fRB is a NaN return it; | |
660 | * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB | |
661 | */ | |
662 | if (aIsSNaN || aIsQNaN) { | |
663 | return 0; | |
664 | } else if (cIsSNaN || cIsQNaN) { | |
665 | return 2; | |
666 | } else { | |
667 | return 1; | |
668 | } | |
669 | } | |
670 | #else | |
671 | /* A default implementation: prefer a to b to c. | |
672 | * This is unlikely to actually match any real implementation. | |
673 | */ | |
674 | static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN, | |
e5a41ffa PM |
675 | flag cIsQNaN, flag cIsSNaN, flag infzero, |
676 | float_status *status) | |
369be8f6 PM |
677 | { |
678 | if (aIsSNaN || aIsQNaN) { | |
679 | return 0; | |
680 | } else if (bIsSNaN || bIsQNaN) { | |
681 | return 1; | |
682 | } else { | |
683 | return 2; | |
684 | } | |
685 | } | |
686 | #endif | |
687 | ||
158142c2 FB |
688 | /*---------------------------------------------------------------------------- |
689 | | Takes two single-precision floating-point values `a' and `b', one of which | |
690 | | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a | |
691 | | signaling NaN, the invalid exception is raised. | |
692 | *----------------------------------------------------------------------------*/ | |
693 | ||
e5a41ffa | 694 | static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status) |
158142c2 | 695 | { |
d735d695 AJ |
696 | flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; |
697 | flag aIsLargerSignificand; | |
bb98fe42 | 698 | uint32_t av, bv; |
158142c2 | 699 | |
af39bc8c AM |
700 | aIsQuietNaN = float32_is_quiet_nan(a, status); |
701 | aIsSignalingNaN = float32_is_signaling_nan(a, status); | |
702 | bIsQuietNaN = float32_is_quiet_nan(b, status); | |
703 | bIsSignalingNaN = float32_is_signaling_nan(b, status); | |
f090c9d4 PB |
704 | av = float32_val(a); |
705 | bv = float32_val(b); | |
1f398e08 | 706 | |
ff32e16e PM |
707 | if (aIsSignalingNaN | bIsSignalingNaN) { |
708 | float_raise(float_flag_invalid, status); | |
709 | } | |
354f211b | 710 | |
af39bc8c AM |
711 | if (status->default_nan_mode) { |
712 | return float32_default_nan(status); | |
713 | } | |
10201602 | 714 | |
a59eaea6 | 715 | if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) { |
354f211b | 716 | aIsLargerSignificand = 0; |
a59eaea6 | 717 | } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) { |
354f211b PM |
718 | aIsLargerSignificand = 1; |
719 | } else { | |
720 | aIsLargerSignificand = (av < bv) ? 1 : 0; | |
158142c2 | 721 | } |
354f211b | 722 | |
d735d695 | 723 | if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, |
354f211b | 724 | aIsLargerSignificand)) { |
af39bc8c | 725 | return float32_maybe_silence_nan(b, status); |
354f211b | 726 | } else { |
af39bc8c | 727 | return float32_maybe_silence_nan(a, status); |
158142c2 | 728 | } |
158142c2 FB |
729 | } |
730 | ||
369be8f6 PM |
731 | /*---------------------------------------------------------------------------- |
732 | | Takes three single-precision floating-point values `a', `b' and `c', one of | |
733 | | which is a NaN, and returns the appropriate NaN result. If any of `a', | |
734 | | `b' or `c' is a signaling NaN, the invalid exception is raised. | |
735 | | The input infzero indicates whether a*b was 0*inf or inf*0 (in which case | |
736 | | obviously c is a NaN, and whether to propagate c or some other NaN is | |
737 | | implementation defined). | |
738 | *----------------------------------------------------------------------------*/ | |
739 | ||
740 | static float32 propagateFloat32MulAddNaN(float32 a, float32 b, | |
e5a41ffa PM |
741 | float32 c, flag infzero, |
742 | float_status *status) | |
369be8f6 PM |
743 | { |
744 | flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, | |
745 | cIsQuietNaN, cIsSignalingNaN; | |
746 | int which; | |
747 | ||
af39bc8c AM |
748 | aIsQuietNaN = float32_is_quiet_nan(a, status); |
749 | aIsSignalingNaN = float32_is_signaling_nan(a, status); | |
750 | bIsQuietNaN = float32_is_quiet_nan(b, status); | |
751 | bIsSignalingNaN = float32_is_signaling_nan(b, status); | |
752 | cIsQuietNaN = float32_is_quiet_nan(c, status); | |
753 | cIsSignalingNaN = float32_is_signaling_nan(c, status); | |
369be8f6 PM |
754 | |
755 | if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { | |
ff32e16e | 756 | float_raise(float_flag_invalid, status); |
369be8f6 PM |
757 | } |
758 | ||
759 | which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, | |
760 | bIsQuietNaN, bIsSignalingNaN, | |
ff32e16e | 761 | cIsQuietNaN, cIsSignalingNaN, infzero, status); |
369be8f6 | 762 | |
a2f2d288 | 763 | if (status->default_nan_mode) { |
369be8f6 PM |
764 | /* Note that this check is after pickNaNMulAdd so that function |
765 | * has an opportunity to set the Invalid flag. | |
766 | */ | |
af39bc8c | 767 | return float32_default_nan(status); |
369be8f6 PM |
768 | } |
769 | ||
770 | switch (which) { | |
771 | case 0: | |
af39bc8c | 772 | return float32_maybe_silence_nan(a, status); |
369be8f6 | 773 | case 1: |
af39bc8c | 774 | return float32_maybe_silence_nan(b, status); |
369be8f6 | 775 | case 2: |
af39bc8c | 776 | return float32_maybe_silence_nan(c, status); |
369be8f6 PM |
777 | case 3: |
778 | default: | |
af39bc8c | 779 | return float32_default_nan(status); |
369be8f6 PM |
780 | } |
781 | } | |
782 | ||
213ff4e6 | 783 | #ifdef NO_SIGNALING_NANS |
af39bc8c | 784 | int float64_is_quiet_nan(float64 a_, float_status *status) |
213ff4e6 MF |
785 | { |
786 | return float64_is_any_nan(a_); | |
787 | } | |
788 | ||
af39bc8c | 789 | int float64_is_signaling_nan(float64 a_, float_status *status) |
213ff4e6 MF |
790 | { |
791 | return 0; | |
792 | } | |
793 | #else | |
158142c2 | 794 | /*---------------------------------------------------------------------------- |
5a6932d5 TS |
795 | | Returns 1 if the double-precision floating-point value `a' is a quiet |
796 | | NaN; otherwise returns 0. | |
158142c2 FB |
797 | *----------------------------------------------------------------------------*/ |
798 | ||
af39bc8c | 799 | int float64_is_quiet_nan(float64 a_, float_status *status) |
158142c2 | 800 | { |
bb98fe42 | 801 | uint64_t a = float64_val(a_); |
af39bc8c AM |
802 | if (status->snan_bit_is_one) { |
803 | return (((a >> 51) & 0xFFF) == 0xFFE) | |
804 | && (a & 0x0007FFFFFFFFFFFFULL); | |
805 | } else { | |
806 | return ((a << 1) >= 0xFFF0000000000000ULL); | |
807 | } | |
158142c2 FB |
808 | } |
809 | ||
810 | /*---------------------------------------------------------------------------- | |
811 | | Returns 1 if the double-precision floating-point value `a' is a signaling | |
812 | | NaN; otherwise returns 0. | |
813 | *----------------------------------------------------------------------------*/ | |
814 | ||
af39bc8c | 815 | int float64_is_signaling_nan(float64 a_, float_status *status) |
158142c2 | 816 | { |
bb98fe42 | 817 | uint64_t a = float64_val(a_); |
af39bc8c AM |
818 | if (status->snan_bit_is_one) { |
819 | return ((a << 1) >= 0xFFF0000000000000ULL); | |
820 | } else { | |
821 | return (((a >> 51) & 0xFFF) == 0xFFE) | |
822 | && (a & LIT64(0x0007FFFFFFFFFFFF)); | |
823 | } | |
158142c2 | 824 | } |
213ff4e6 | 825 | #endif |
158142c2 | 826 | |
b408dbde PM |
827 | /*---------------------------------------------------------------------------- |
828 | | Returns a quiet NaN if the double-precision floating point value `a' is a | |
829 | | signaling NaN; otherwise returns `a'. | |
830 | *----------------------------------------------------------------------------*/ | |
831 | ||
af39bc8c | 832 | float64 float64_maybe_silence_nan(float64 a_, float_status *status) |
b408dbde | 833 | { |
af39bc8c AM |
834 | if (float64_is_signaling_nan(a_, status)) { |
835 | if (status->snan_bit_is_one) { | |
005fa38d RH |
836 | #ifdef TARGET_HPPA |
837 | uint64_t a = float64_val(a_); | |
838 | a &= ~0x0008000000000000ULL; | |
839 | a |= 0x0004000000000000ULL; | |
840 | return make_float64(a); | |
841 | #else | |
af39bc8c | 842 | return float64_default_nan(status); |
005fa38d | 843 | #endif |
af39bc8c AM |
844 | } else { |
845 | uint64_t a = float64_val(a_); | |
846 | a |= LIT64(0x0008000000000000); | |
847 | return make_float64(a); | |
848 | } | |
b408dbde PM |
849 | } |
850 | return a_; | |
851 | } | |
852 | ||
158142c2 FB |
853 | /*---------------------------------------------------------------------------- |
854 | | Returns the result of converting the double-precision floating-point NaN | |
855 | | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid | |
856 | | exception is raised. | |
857 | *----------------------------------------------------------------------------*/ | |
858 | ||
e5a41ffa | 859 | static commonNaNT float64ToCommonNaN(float64 a, float_status *status) |
158142c2 FB |
860 | { |
861 | commonNaNT z; | |
862 | ||
af39bc8c | 863 | if (float64_is_signaling_nan(a, status)) { |
ff32e16e PM |
864 | float_raise(float_flag_invalid, status); |
865 | } | |
a59eaea6 | 866 | z.sign = float64_val(a) >> 63; |
158142c2 | 867 | z.low = 0; |
a59eaea6 | 868 | z.high = float64_val(a) << 12; |
158142c2 | 869 | return z; |
158142c2 FB |
870 | } |
871 | ||
872 | /*---------------------------------------------------------------------------- | |
873 | | Returns the result of converting the canonical NaN `a' to the double- | |
874 | | precision floating-point format. | |
875 | *----------------------------------------------------------------------------*/ | |
876 | ||
e5a41ffa | 877 | static float64 commonNaNToFloat64(commonNaNT a, float_status *status) |
158142c2 | 878 | { |
a59eaea6 | 879 | uint64_t mantissa = a.high >> 12; |
85016c98 | 880 | |
a2f2d288 | 881 | if (status->default_nan_mode) { |
af39bc8c | 882 | return float64_default_nan(status); |
bcd4d9af CL |
883 | } |
884 | ||
af39bc8c | 885 | if (mantissa) { |
85016c98 | 886 | return make_float64( |
a59eaea6 AM |
887 | (((uint64_t) a.sign) << 63) |
888 | | LIT64(0x7FF0000000000000) | |
889 | | (a.high >> 12)); | |
af39bc8c AM |
890 | } else { |
891 | return float64_default_nan(status); | |
892 | } | |
158142c2 FB |
893 | } |
894 | ||
895 | /*---------------------------------------------------------------------------- | |
896 | | Takes two double-precision floating-point values `a' and `b', one of which | |
897 | | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a | |
898 | | signaling NaN, the invalid exception is raised. | |
899 | *----------------------------------------------------------------------------*/ | |
900 | ||
e5a41ffa | 901 | static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status) |
158142c2 | 902 | { |
d735d695 AJ |
903 | flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; |
904 | flag aIsLargerSignificand; | |
bb98fe42 | 905 | uint64_t av, bv; |
158142c2 | 906 | |
af39bc8c AM |
907 | aIsQuietNaN = float64_is_quiet_nan(a, status); |
908 | aIsSignalingNaN = float64_is_signaling_nan(a, status); | |
909 | bIsQuietNaN = float64_is_quiet_nan(b, status); | |
910 | bIsSignalingNaN = float64_is_signaling_nan(b, status); | |
f090c9d4 PB |
911 | av = float64_val(a); |
912 | bv = float64_val(b); | |
1f398e08 | 913 | |
ff32e16e PM |
914 | if (aIsSignalingNaN | bIsSignalingNaN) { |
915 | float_raise(float_flag_invalid, status); | |
916 | } | |
354f211b | 917 | |
af39bc8c AM |
918 | if (status->default_nan_mode) { |
919 | return float64_default_nan(status); | |
920 | } | |
10201602 | 921 | |
a59eaea6 | 922 | if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) { |
354f211b | 923 | aIsLargerSignificand = 0; |
a59eaea6 | 924 | } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) { |
354f211b PM |
925 | aIsLargerSignificand = 1; |
926 | } else { | |
927 | aIsLargerSignificand = (av < bv) ? 1 : 0; | |
158142c2 | 928 | } |
354f211b | 929 | |
d735d695 | 930 | if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, |
354f211b | 931 | aIsLargerSignificand)) { |
af39bc8c | 932 | return float64_maybe_silence_nan(b, status); |
354f211b | 933 | } else { |
af39bc8c | 934 | return float64_maybe_silence_nan(a, status); |
158142c2 | 935 | } |
158142c2 FB |
936 | } |
937 | ||
369be8f6 PM |
938 | /*---------------------------------------------------------------------------- |
939 | | Takes three double-precision floating-point values `a', `b' and `c', one of | |
940 | | which is a NaN, and returns the appropriate NaN result. If any of `a', | |
941 | | `b' or `c' is a signaling NaN, the invalid exception is raised. | |
942 | | The input infzero indicates whether a*b was 0*inf or inf*0 (in which case | |
943 | | obviously c is a NaN, and whether to propagate c or some other NaN is | |
944 | | implementation defined). | |
945 | *----------------------------------------------------------------------------*/ | |
946 | ||
947 | static float64 propagateFloat64MulAddNaN(float64 a, float64 b, | |
e5a41ffa PM |
948 | float64 c, flag infzero, |
949 | float_status *status) | |
369be8f6 PM |
950 | { |
951 | flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, | |
952 | cIsQuietNaN, cIsSignalingNaN; | |
953 | int which; | |
954 | ||
af39bc8c AM |
955 | aIsQuietNaN = float64_is_quiet_nan(a, status); |
956 | aIsSignalingNaN = float64_is_signaling_nan(a, status); | |
957 | bIsQuietNaN = float64_is_quiet_nan(b, status); | |
958 | bIsSignalingNaN = float64_is_signaling_nan(b, status); | |
959 | cIsQuietNaN = float64_is_quiet_nan(c, status); | |
960 | cIsSignalingNaN = float64_is_signaling_nan(c, status); | |
369be8f6 PM |
961 | |
962 | if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) { | |
ff32e16e | 963 | float_raise(float_flag_invalid, status); |
369be8f6 PM |
964 | } |
965 | ||
966 | which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN, | |
967 | bIsQuietNaN, bIsSignalingNaN, | |
ff32e16e | 968 | cIsQuietNaN, cIsSignalingNaN, infzero, status); |
369be8f6 | 969 | |
a2f2d288 | 970 | if (status->default_nan_mode) { |
369be8f6 PM |
971 | /* Note that this check is after pickNaNMulAdd so that function |
972 | * has an opportunity to set the Invalid flag. | |
973 | */ | |
af39bc8c | 974 | return float64_default_nan(status); |
369be8f6 PM |
975 | } |
976 | ||
977 | switch (which) { | |
978 | case 0: | |
af39bc8c | 979 | return float64_maybe_silence_nan(a, status); |
369be8f6 | 980 | case 1: |
af39bc8c | 981 | return float64_maybe_silence_nan(b, status); |
369be8f6 | 982 | case 2: |
af39bc8c | 983 | return float64_maybe_silence_nan(c, status); |
369be8f6 PM |
984 | case 3: |
985 | default: | |
af39bc8c | 986 | return float64_default_nan(status); |
369be8f6 PM |
987 | } |
988 | } | |
989 | ||
213ff4e6 | 990 | #ifdef NO_SIGNALING_NANS |
af39bc8c | 991 | int floatx80_is_quiet_nan(floatx80 a_, float_status *status) |
213ff4e6 MF |
992 | { |
993 | return floatx80_is_any_nan(a_); | |
994 | } | |
995 | ||
af39bc8c | 996 | int floatx80_is_signaling_nan(floatx80 a_, float_status *status) |
213ff4e6 MF |
997 | { |
998 | return 0; | |
999 | } | |
1000 | #else | |
158142c2 FB |
1001 | /*---------------------------------------------------------------------------- |
1002 | | Returns 1 if the extended double-precision floating-point value `a' is a | |
de4af5f7 AJ |
1003 | | quiet NaN; otherwise returns 0. This slightly differs from the same |
1004 | | function for other types as floatx80 has an explicit bit. | |
158142c2 FB |
1005 | *----------------------------------------------------------------------------*/ |
1006 | ||
af39bc8c | 1007 | int floatx80_is_quiet_nan(floatx80 a, float_status *status) |
158142c2 | 1008 | { |
af39bc8c AM |
1009 | if (status->snan_bit_is_one) { |
1010 | uint64_t aLow; | |
158142c2 | 1011 | |
af39bc8c AM |
1012 | aLow = a.low & ~0x4000000000000000ULL; |
1013 | return ((a.high & 0x7FFF) == 0x7FFF) | |
1014 | && (aLow << 1) | |
1015 | && (a.low == aLow); | |
1016 | } else { | |
1017 | return ((a.high & 0x7FFF) == 0x7FFF) | |
1018 | && (LIT64(0x8000000000000000) <= ((uint64_t)(a.low << 1))); | |
1019 | } | |
158142c2 FB |
1020 | } |
1021 | ||
1022 | /*---------------------------------------------------------------------------- | |
1023 | | Returns 1 if the extended double-precision floating-point value `a' is a | |
de4af5f7 AJ |
1024 | | signaling NaN; otherwise returns 0. This slightly differs from the same |
1025 | | function for other types as floatx80 has an explicit bit. | |
158142c2 FB |
1026 | *----------------------------------------------------------------------------*/ |
1027 | ||
af39bc8c | 1028 | int floatx80_is_signaling_nan(floatx80 a, float_status *status) |
158142c2 | 1029 | { |
af39bc8c AM |
1030 | if (status->snan_bit_is_one) { |
1031 | return ((a.high & 0x7FFF) == 0x7FFF) | |
1032 | && ((a.low << 1) >= 0x8000000000000000ULL); | |
1033 | } else { | |
1034 | uint64_t aLow; | |
158142c2 | 1035 | |
af39bc8c AM |
1036 | aLow = a.low & ~LIT64(0x4000000000000000); |
1037 | return ((a.high & 0x7FFF) == 0x7FFF) | |
1038 | && (uint64_t)(aLow << 1) | |
1039 | && (a.low == aLow); | |
1040 | } | |
158142c2 | 1041 | } |
213ff4e6 | 1042 | #endif |
158142c2 | 1043 | |
f6a7d92a AJ |
1044 | /*---------------------------------------------------------------------------- |
1045 | | Returns a quiet NaN if the extended double-precision floating point value | |
1046 | | `a' is a signaling NaN; otherwise returns `a'. | |
1047 | *----------------------------------------------------------------------------*/ | |
1048 | ||
af39bc8c | 1049 | floatx80 floatx80_maybe_silence_nan(floatx80 a, float_status *status) |
f6a7d92a | 1050 | { |
af39bc8c AM |
1051 | if (floatx80_is_signaling_nan(a, status)) { |
1052 | if (status->snan_bit_is_one) { | |
1053 | a = floatx80_default_nan(status); | |
1054 | } else { | |
1055 | a.low |= LIT64(0xC000000000000000); | |
1056 | return a; | |
1057 | } | |
f6a7d92a AJ |
1058 | } |
1059 | return a; | |
1060 | } | |
1061 | ||
158142c2 FB |
1062 | /*---------------------------------------------------------------------------- |
1063 | | Returns the result of converting the extended double-precision floating- | |
1064 | | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the | |
1065 | | invalid exception is raised. | |
1066 | *----------------------------------------------------------------------------*/ | |
1067 | ||
e5a41ffa | 1068 | static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status) |
158142c2 | 1069 | { |
af39bc8c | 1070 | floatx80 dflt; |
158142c2 FB |
1071 | commonNaNT z; |
1072 | ||
af39bc8c | 1073 | if (floatx80_is_signaling_nan(a, status)) { |
ff32e16e PM |
1074 | float_raise(float_flag_invalid, status); |
1075 | } | |
a59eaea6 | 1076 | if (a.low >> 63) { |
e2f42204 AJ |
1077 | z.sign = a.high >> 15; |
1078 | z.low = 0; | |
1079 | z.high = a.low << 1; | |
1080 | } else { | |
af39bc8c AM |
1081 | dflt = floatx80_default_nan(status); |
1082 | z.sign = dflt.high >> 15; | |
e2f42204 | 1083 | z.low = 0; |
af39bc8c | 1084 | z.high = dflt.low << 1; |
e2f42204 | 1085 | } |
158142c2 | 1086 | return z; |
158142c2 FB |
1087 | } |
1088 | ||
1089 | /*---------------------------------------------------------------------------- | |
1090 | | Returns the result of converting the canonical NaN `a' to the extended | |
1091 | | double-precision floating-point format. | |
1092 | *----------------------------------------------------------------------------*/ | |
1093 | ||
e5a41ffa | 1094 | static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status) |
158142c2 FB |
1095 | { |
1096 | floatx80 z; | |
1097 | ||
a2f2d288 | 1098 | if (status->default_nan_mode) { |
af39bc8c | 1099 | return floatx80_default_nan(status); |
bcd4d9af CL |
1100 | } |
1101 | ||
e2f42204 | 1102 | if (a.high >> 1) { |
a59eaea6 AM |
1103 | z.low = LIT64(0x8000000000000000) | a.high >> 1; |
1104 | z.high = (((uint16_t)a.sign) << 15) | 0x7FFF; | |
e2f42204 | 1105 | } else { |
af39bc8c | 1106 | z = floatx80_default_nan(status); |
e2f42204 | 1107 | } |
158142c2 | 1108 | return z; |
158142c2 FB |
1109 | } |
1110 | ||
1111 | /*---------------------------------------------------------------------------- | |
1112 | | Takes two extended double-precision floating-point values `a' and `b', one | |
1113 | | of which is a NaN, and returns the appropriate NaN result. If either `a' or | |
1114 | | `b' is a signaling NaN, the invalid exception is raised. | |
1115 | *----------------------------------------------------------------------------*/ | |
1116 | ||
e5a41ffa PM |
1117 | static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b, |
1118 | float_status *status) | |
158142c2 | 1119 | { |
d735d695 AJ |
1120 | flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; |
1121 | flag aIsLargerSignificand; | |
158142c2 | 1122 | |
af39bc8c AM |
1123 | aIsQuietNaN = floatx80_is_quiet_nan(a, status); |
1124 | aIsSignalingNaN = floatx80_is_signaling_nan(a, status); | |
1125 | bIsQuietNaN = floatx80_is_quiet_nan(b, status); | |
1126 | bIsSignalingNaN = floatx80_is_signaling_nan(b, status); | |
1f398e08 | 1127 | |
ff32e16e PM |
1128 | if (aIsSignalingNaN | bIsSignalingNaN) { |
1129 | float_raise(float_flag_invalid, status); | |
1130 | } | |
354f211b | 1131 | |
a2f2d288 | 1132 | if (status->default_nan_mode) { |
af39bc8c | 1133 | return floatx80_default_nan(status); |
10201602 AJ |
1134 | } |
1135 | ||
354f211b PM |
1136 | if (a.low < b.low) { |
1137 | aIsLargerSignificand = 0; | |
1138 | } else if (b.low < a.low) { | |
1139 | aIsLargerSignificand = 1; | |
1140 | } else { | |
1141 | aIsLargerSignificand = (a.high < b.high) ? 1 : 0; | |
158142c2 | 1142 | } |
354f211b | 1143 | |
d735d695 | 1144 | if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, |
354f211b | 1145 | aIsLargerSignificand)) { |
af39bc8c | 1146 | return floatx80_maybe_silence_nan(b, status); |
354f211b | 1147 | } else { |
af39bc8c | 1148 | return floatx80_maybe_silence_nan(a, status); |
158142c2 | 1149 | } |
158142c2 FB |
1150 | } |
1151 | ||
213ff4e6 | 1152 | #ifdef NO_SIGNALING_NANS |
af39bc8c | 1153 | int float128_is_quiet_nan(float128 a_, float_status *status) |
213ff4e6 MF |
1154 | { |
1155 | return float128_is_any_nan(a_); | |
1156 | } | |
1157 | ||
af39bc8c | 1158 | int float128_is_signaling_nan(float128 a_, float_status *status) |
213ff4e6 MF |
1159 | { |
1160 | return 0; | |
1161 | } | |
1162 | #else | |
158142c2 | 1163 | /*---------------------------------------------------------------------------- |
5a6932d5 TS |
1164 | | Returns 1 if the quadruple-precision floating-point value `a' is a quiet |
1165 | | NaN; otherwise returns 0. | |
158142c2 FB |
1166 | *----------------------------------------------------------------------------*/ |
1167 | ||
af39bc8c | 1168 | int float128_is_quiet_nan(float128 a, float_status *status) |
158142c2 | 1169 | { |
af39bc8c AM |
1170 | if (status->snan_bit_is_one) { |
1171 | return (((a.high >> 47) & 0xFFFF) == 0xFFFE) | |
1172 | && (a.low || (a.high & 0x00007FFFFFFFFFFFULL)); | |
1173 | } else { | |
1174 | return ((a.high << 1) >= 0xFFFF000000000000ULL) | |
1175 | && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL)); | |
1176 | } | |
158142c2 FB |
1177 | } |
1178 | ||
1179 | /*---------------------------------------------------------------------------- | |
1180 | | Returns 1 if the quadruple-precision floating-point value `a' is a | |
1181 | | signaling NaN; otherwise returns 0. | |
1182 | *----------------------------------------------------------------------------*/ | |
1183 | ||
af39bc8c | 1184 | int float128_is_signaling_nan(float128 a, float_status *status) |
158142c2 | 1185 | { |
af39bc8c AM |
1186 | if (status->snan_bit_is_one) { |
1187 | return ((a.high << 1) >= 0xFFFF000000000000ULL) | |
1188 | && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL)); | |
1189 | } else { | |
1190 | return (((a.high >> 47) & 0xFFFF) == 0xFFFE) | |
1191 | && (a.low || (a.high & LIT64(0x00007FFFFFFFFFFF))); | |
1192 | } | |
158142c2 | 1193 | } |
213ff4e6 | 1194 | #endif |
158142c2 | 1195 | |
f6a7d92a AJ |
1196 | /*---------------------------------------------------------------------------- |
1197 | | Returns a quiet NaN if the quadruple-precision floating point value `a' is | |
1198 | | a signaling NaN; otherwise returns `a'. | |
1199 | *----------------------------------------------------------------------------*/ | |
1200 | ||
af39bc8c | 1201 | float128 float128_maybe_silence_nan(float128 a, float_status *status) |
f6a7d92a | 1202 | { |
af39bc8c AM |
1203 | if (float128_is_signaling_nan(a, status)) { |
1204 | if (status->snan_bit_is_one) { | |
1205 | a = float128_default_nan(status); | |
1206 | } else { | |
1207 | a.high |= LIT64(0x0000800000000000); | |
1208 | return a; | |
1209 | } | |
f6a7d92a AJ |
1210 | } |
1211 | return a; | |
1212 | } | |
1213 | ||
158142c2 FB |
1214 | /*---------------------------------------------------------------------------- |
1215 | | Returns the result of converting the quadruple-precision floating-point NaN | |
1216 | | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid | |
1217 | | exception is raised. | |
1218 | *----------------------------------------------------------------------------*/ | |
1219 | ||
e5a41ffa | 1220 | static commonNaNT float128ToCommonNaN(float128 a, float_status *status) |
158142c2 FB |
1221 | { |
1222 | commonNaNT z; | |
1223 | ||
af39bc8c | 1224 | if (float128_is_signaling_nan(a, status)) { |
ff32e16e PM |
1225 | float_raise(float_flag_invalid, status); |
1226 | } | |
a59eaea6 AM |
1227 | z.sign = a.high >> 63; |
1228 | shortShift128Left(a.high, a.low, 16, &z.high, &z.low); | |
158142c2 | 1229 | return z; |
158142c2 FB |
1230 | } |
1231 | ||
1232 | /*---------------------------------------------------------------------------- | |
1233 | | Returns the result of converting the canonical NaN `a' to the quadruple- | |
1234 | | precision floating-point format. | |
1235 | *----------------------------------------------------------------------------*/ | |
1236 | ||
e5a41ffa | 1237 | static float128 commonNaNToFloat128(commonNaNT a, float_status *status) |
158142c2 FB |
1238 | { |
1239 | float128 z; | |
1240 | ||
a2f2d288 | 1241 | if (status->default_nan_mode) { |
af39bc8c | 1242 | return float128_default_nan(status); |
bcd4d9af CL |
1243 | } |
1244 | ||
a59eaea6 AM |
1245 | shift128Right(a.high, a.low, 16, &z.high, &z.low); |
1246 | z.high |= (((uint64_t)a.sign) << 63) | LIT64(0x7FFF000000000000); | |
158142c2 | 1247 | return z; |
158142c2 FB |
1248 | } |
1249 | ||
1250 | /*---------------------------------------------------------------------------- | |
1251 | | Takes two quadruple-precision floating-point values `a' and `b', one of | |
1252 | | which is a NaN, and returns the appropriate NaN result. If either `a' or | |
1253 | | `b' is a signaling NaN, the invalid exception is raised. | |
1254 | *----------------------------------------------------------------------------*/ | |
1255 | ||
e5a41ffa PM |
1256 | static float128 propagateFloat128NaN(float128 a, float128 b, |
1257 | float_status *status) | |
158142c2 | 1258 | { |
d735d695 AJ |
1259 | flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN; |
1260 | flag aIsLargerSignificand; | |
158142c2 | 1261 | |
af39bc8c AM |
1262 | aIsQuietNaN = float128_is_quiet_nan(a, status); |
1263 | aIsSignalingNaN = float128_is_signaling_nan(a, status); | |
1264 | bIsQuietNaN = float128_is_quiet_nan(b, status); | |
1265 | bIsSignalingNaN = float128_is_signaling_nan(b, status); | |
1f398e08 | 1266 | |
ff32e16e PM |
1267 | if (aIsSignalingNaN | bIsSignalingNaN) { |
1268 | float_raise(float_flag_invalid, status); | |
1269 | } | |
354f211b | 1270 | |
a2f2d288 | 1271 | if (status->default_nan_mode) { |
af39bc8c | 1272 | return float128_default_nan(status); |
10201602 AJ |
1273 | } |
1274 | ||
a59eaea6 | 1275 | if (lt128(a.high << 1, a.low, b.high << 1, b.low)) { |
354f211b | 1276 | aIsLargerSignificand = 0; |
a59eaea6 | 1277 | } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) { |
354f211b PM |
1278 | aIsLargerSignificand = 1; |
1279 | } else { | |
1280 | aIsLargerSignificand = (a.high < b.high) ? 1 : 0; | |
158142c2 | 1281 | } |
354f211b | 1282 | |
d735d695 | 1283 | if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN, |
354f211b | 1284 | aIsLargerSignificand)) { |
af39bc8c | 1285 | return float128_maybe_silence_nan(b, status); |
354f211b | 1286 | } else { |
af39bc8c | 1287 | return float128_maybe_silence_nan(a, status); |
158142c2 | 1288 | } |
158142c2 | 1289 | } |