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