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