softfloat-specialize.h 42 KB
Newer Older
1 2 3
/*
 * QEMU float support
 *
4 5 6 7 8 9 10 11 12 13 14 15
 * The code in this source file is derived from release 2a of the SoftFloat
 * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
 * some later contributions) are provided under that license, as detailed below.
 * It has subsequently been modified by contributors to the QEMU Project,
 * so some portions are provided under:
 *  the SoftFloat-2a license
 *  the BSD license
 *  GPL-v2-or-later
 *
 * Any future contributions to this file after December 1st 2014 will be
 * taken to be licensed under the Softfloat-2a license unless specifically
 * indicated otherwise.
16
 */
bellard's avatar
bellard committed
17

18 19
/*
===============================================================================
bellard's avatar
bellard committed
20
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
21
Arithmetic Package, Release 2a.
bellard's avatar
bellard committed
22 23 24 25 26 27 28 29

Written by John R. Hauser.  This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704.  Funding was partially provided by the
National Science Foundation under grant MIP-9311980.  The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
30
is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
bellard's avatar
bellard committed
31 32
arithmetic/SoftFloat.html'.

33 34 35 36 37
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
bellard's avatar
bellard committed
38 39

Derivative works are acceptable, even for commercial purposes, so long as
40 41 42
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.
bellard's avatar
bellard committed
43

44 45
===============================================================================
*/
bellard's avatar
bellard committed
46

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
/* BSD licensing:
 * Copyright (c) 2006, Fabrice Bellard
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors
 * may be used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

/* Portions of this work are licensed under the terms of the GNU GPL,
 * version 2 or later. See the COPYING file in the top-level directory.
 */

82 83 84 85 86 87 88
#if defined(TARGET_XTENSA)
/* Define for architectures which deviate from IEEE in not supporting
 * signaling NaNs (so all NaNs are treated as quiet).
 */
#define NO_SIGNALING_NANS 1
#endif

89 90 91
/*----------------------------------------------------------------------------
| The pattern for a default generated half-precision NaN.
*----------------------------------------------------------------------------*/
92 93
float16 float16_default_nan(float_status *status)
{
94
#if defined(TARGET_ARM)
95
    return const_float16(0x7E00);
96
#else
97 98 99
    if (status->snan_bit_is_one) {
        return const_float16(0x7DFF);
    } else {
100 101 102
#if defined(TARGET_MIPS)
        return const_float16(0x7E00);
#else
103
        return const_float16(0xFE00);
104
#endif
105
    }
106
#endif
107
}
108 109 110 111

/*----------------------------------------------------------------------------
| The pattern for a default generated single-precision NaN.
*----------------------------------------------------------------------------*/
112 113
float32 float32_default_nan(float_status *status)
{
114
#if defined(TARGET_SPARC)
115
    return const_float32(0x7FFFFFFF);
116
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
117
      defined(TARGET_XTENSA) || defined(TARGET_S390X) || defined(TARGET_TRICORE)
118
    return const_float32(0x7FC00000);
119 120
#elif defined(TARGET_HPPA)
    return const_float32(0x7FA00000);
121
#else
122 123 124
    if (status->snan_bit_is_one) {
        return const_float32(0x7FBFFFFF);
    } else {
125 126 127
#if defined(TARGET_MIPS)
        return const_float32(0x7FC00000);
#else
128
        return const_float32(0xFFC00000);
129
#endif
130
    }
131
#endif
132
}
133 134 135 136

/*----------------------------------------------------------------------------
| The pattern for a default generated double-precision NaN.
*----------------------------------------------------------------------------*/
137 138
float64 float64_default_nan(float_status *status)
{
139
#if defined(TARGET_SPARC)
140
    return const_float64(LIT64(0x7FFFFFFFFFFFFFFF));
141 142
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA) || \
      defined(TARGET_S390X)
143
    return const_float64(LIT64(0x7FF8000000000000));
144 145
#elif defined(TARGET_HPPA)
    return const_float64(LIT64(0x7FF4000000000000));
146
#else
147 148 149
    if (status->snan_bit_is_one) {
        return const_float64(LIT64(0x7FF7FFFFFFFFFFFF));
    } else {
150 151 152
#if defined(TARGET_MIPS)
        return const_float64(LIT64(0x7FF8000000000000));
#else
153
        return const_float64(LIT64(0xFFF8000000000000));
154
#endif
155
    }
156
#endif
157
}
158 159 160 161

/*----------------------------------------------------------------------------
| The pattern for a default generated extended double-precision NaN.
*----------------------------------------------------------------------------*/
162 163 164
floatx80 floatx80_default_nan(float_status *status)
{
    floatx80 r;
165

166 167 168 169 170 171 172 173 174
    if (status->snan_bit_is_one) {
        r.low = LIT64(0xBFFFFFFFFFFFFFFF);
        r.high = 0x7FFF;
    } else {
        r.low = LIT64(0xC000000000000000);
        r.high = 0xFFFF;
    }
    return r;
}
175 176

/*----------------------------------------------------------------------------
177
| The pattern for a default generated quadruple-precision NaN.
178
*----------------------------------------------------------------------------*/
179 180 181 182 183 184 185 186 187
float128 float128_default_nan(float_status *status)
{
    float128 r;

    if (status->snan_bit_is_one) {
        r.low = LIT64(0xFFFFFFFFFFFFFFFF);
        r.high = LIT64(0x7FFF7FFFFFFFFFFF);
    } else {
        r.low = LIT64(0x0000000000000000);
188
#if defined(TARGET_S390X) || defined(TARGET_PPC)
189
        r.high = LIT64(0x7FFF800000000000);
190
#else
191
        r.high = LIT64(0xFFFF800000000000);
192
#endif
193 194 195
    }
    return r;
}
196

bellard's avatar
bellard committed
197 198 199 200 201 202 203
/*----------------------------------------------------------------------------
| Raises the exceptions specified by `flags'.  Floating-point traps can be
| defined here if desired.  It is currently not possible for such a trap
| to substitute a result value.  If traps are not implemented, this routine
| should be simply `float_exception_flags |= flags;'.
*----------------------------------------------------------------------------*/

204
void float_raise(uint8_t flags, float_status *status)
bellard's avatar
bellard committed
205
{
206
    status->float_exception_flags |= flags;
bellard's avatar
bellard committed
207 208 209 210 211 212 213
}

/*----------------------------------------------------------------------------
| Internal canonical NaN format.
*----------------------------------------------------------------------------*/
typedef struct {
    flag sign;
214
    uint64_t high, low;
bellard's avatar
bellard committed
215 216
} commonNaNT;

217
#ifdef NO_SIGNALING_NANS
218
int float16_is_quiet_nan(float16 a_, float_status *status)
219 220 221 222
{
    return float16_is_any_nan(a_);
}

223
int float16_is_signaling_nan(float16 a_, float_status *status)
224 225 226 227
{
    return 0;
}
#else
228 229 230 231 232
/*----------------------------------------------------------------------------
| Returns 1 if the half-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/

233
int float16_is_quiet_nan(float16 a_, float_status *status)
234 235
{
    uint16_t a = float16_val(a_);
236 237 238 239 240
    if (status->snan_bit_is_one) {
        return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
    } else {
        return ((a & ~0x8000) >= 0x7C80);
    }
241 242 243 244 245 246 247
}

/*----------------------------------------------------------------------------
| Returns 1 if the half-precision floating-point value `a' is a signaling
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/

248
int float16_is_signaling_nan(float16 a_, float_status *status)
249 250
{
    uint16_t a = float16_val(a_);
251 252 253 254 255
    if (status->snan_bit_is_one) {
        return ((a & ~0x8000) >= 0x7C80);
    } else {
        return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
    }
256
}
257
#endif
258 259 260 261 262

/*----------------------------------------------------------------------------
| Returns a quiet NaN if the half-precision floating point value `a' is a
| signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/
263
float16 float16_maybe_silence_nan(float16 a_, float_status *status)
264
{
265 266 267 268 269 270 271 272
    if (float16_is_signaling_nan(a_, status)) {
        if (status->snan_bit_is_one) {
            return float16_default_nan(status);
        } else {
            uint16_t a = float16_val(a_);
            a |= (1 << 9);
            return make_float16(a);
        }
273 274 275 276
    }
    return a_;
}

277 278 279 280 281 282
/*----------------------------------------------------------------------------
| Returns the result of converting the half-precision floating-point NaN
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/

283
static commonNaNT float16ToCommonNaN(float16 a, float_status *status)
284 285 286
{
    commonNaNT z;

287
    if (float16_is_signaling_nan(a, status)) {
288 289
        float_raise(float_flag_invalid, status);
    }
290 291
    z.sign = float16_val(a) >> 15;
    z.low = 0;
292
    z.high = ((uint64_t) float16_val(a)) << 54;
293 294 295
    return z;
}

296 297 298 299 300
/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the half-
| precision floating-point format.
*----------------------------------------------------------------------------*/

301
static float16 commonNaNToFloat16(commonNaNT a, float_status *status)
302
{
303
    uint16_t mantissa = a.high >> 54;
304

305
    if (status->default_nan_mode) {
306
        return float16_default_nan(status);
307 308 309 310 311 312
    }

    if (mantissa) {
        return make_float16(((((uint16_t) a.sign) << 15)
                             | (0x1F << 10) | mantissa));
    } else {
313
        return float16_default_nan(status);
314 315 316
    }
}

317
#ifdef NO_SIGNALING_NANS
318
int float32_is_quiet_nan(float32 a_, float_status *status)
319 320 321 322
{
    return float32_is_any_nan(a_);
}

323
int float32_is_signaling_nan(float32 a_, float_status *status)
324 325 326 327
{
    return 0;
}
#else
bellard's avatar
bellard committed
328
/*----------------------------------------------------------------------------
329 330
| Returns 1 if the single-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
bellard's avatar
bellard committed
331 332
*----------------------------------------------------------------------------*/

333
int float32_is_quiet_nan(float32 a_, float_status *status)
bellard's avatar
bellard committed
334
{
335
    uint32_t a = float32_val(a_);
336 337 338 339 340
    if (status->snan_bit_is_one) {
        return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
    } else {
        return ((uint32_t)(a << 1) >= 0xFF800000);
    }
bellard's avatar
bellard committed
341 342 343 344 345 346 347
}

/*----------------------------------------------------------------------------
| Returns 1 if the single-precision floating-point value `a' is a signaling
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/

348
int float32_is_signaling_nan(float32 a_, float_status *status)
bellard's avatar
bellard committed
349
{
350
    uint32_t a = float32_val(a_);
351 352 353 354 355
    if (status->snan_bit_is_one) {
        return ((uint32_t)(a << 1) >= 0xFF800000);
    } else {
        return (((a >> 22) & 0x1FF) == 0x1FE) && (a & 0x003FFFFF);
    }
bellard's avatar
bellard committed
356
}
357
#endif
bellard's avatar
bellard committed
358

359 360 361 362 363
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the single-precision floating point value `a' is a
| signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/

364
float32 float32_maybe_silence_nan(float32 a_, float_status *status)
365
{
366 367
    if (float32_is_signaling_nan(a_, status)) {
        if (status->snan_bit_is_one) {
368 369 370 371 372 373
#ifdef TARGET_HPPA
            uint32_t a = float32_val(a_);
            a &= ~0x00400000;
            a |=  0x00200000;
            return make_float32(a);
#else
374
            return float32_default_nan(status);
375
#endif
376 377 378 379 380
        } else {
            uint32_t a = float32_val(a_);
            a |= (1 << 22);
            return make_float32(a);
        }
381 382 383 384
    }
    return a_;
}

bellard's avatar
bellard committed
385 386 387 388 389 390
/*----------------------------------------------------------------------------
| Returns the result of converting the single-precision floating-point NaN
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/

391
static commonNaNT float32ToCommonNaN(float32 a, float_status *status)
bellard's avatar
bellard committed
392 393 394
{
    commonNaNT z;

395
    if (float32_is_signaling_nan(a, status)) {
396 397
        float_raise(float_flag_invalid, status);
    }
398
    z.sign = float32_val(a) >> 31;
bellard's avatar
bellard committed
399
    z.low = 0;
400
    z.high = ((uint64_t)float32_val(a)) << 41;
bellard's avatar
bellard committed
401 402 403 404 405 406 407 408
    return z;
}

/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the single-
| precision floating-point format.
*----------------------------------------------------------------------------*/

409
static float32 commonNaNToFloat32(commonNaNT a, float_status *status)
bellard's avatar
bellard committed
410
{
411
    uint32_t mantissa = a.high >> 41;
412

413
    if (status->default_nan_mode) {
414
        return float32_default_nan(status);
415 416
    }

417
    if (mantissa) {
418
        return make_float32(
419
            (((uint32_t)a.sign) << 31) | 0x7F800000 | (a.high >> 41));
420 421 422
    } else {
        return float32_default_nan(status);
    }
bellard's avatar
bellard committed
423 424
}

425 426 427 428 429 430 431
/*----------------------------------------------------------------------------
| Select which NaN to propagate for a two-input operation.
| IEEE754 doesn't specify all the details of this, so the
| algorithm is target-specific.
| The routine is passed various bits of information about the
| two NaNs and should return 0 to select NaN a and 1 for NaN b.
| Note that signalling NaNs are always squashed to quiet NaNs
432 433
| by the caller, by calling floatXX_maybe_silence_nan() before
| returning them.
434 435 436 437 438 439 440 441
|
| aIsLargerSignificand is only valid if both a and b are NaNs
| of some kind, and is true if a has the larger significand,
| or if both a and b have the same significand but a is
| positive but b is negative. It is only needed for the x87
| tie-break rule.
*----------------------------------------------------------------------------*/

442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462
#if defined(TARGET_ARM)
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    flag aIsLargerSignificand)
{
    /* ARM mandated NaN propagation rules: take the first of:
     *  1. A if it is signaling
     *  2. B if it is signaling
     *  3. A (quiet)
     *  4. B (quiet)
     * A signaling NaN is always quietened before returning it.
     */
    if (aIsSNaN) {
        return 0;
    } else if (bIsSNaN) {
        return 1;
    } else if (aIsQNaN) {
        return 0;
    } else {
        return 1;
    }
}
463
#elif defined(TARGET_MIPS) || defined(TARGET_HPPA)
464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    flag aIsLargerSignificand)
{
    /* According to MIPS specifications, if one of the two operands is
     * a sNaN, a new qNaN has to be generated. This is done in
     * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
     * says: "When possible, this QNaN result is one of the operand QNaN
     * values." In practice it seems that most implementations choose
     * the first operand if both operands are qNaN. In short this gives
     * the following rules:
     *  1. A if it is signaling
     *  2. B if it is signaling
     *  3. A (quiet)
     *  4. B (quiet)
     * A signaling NaN is always silenced before returning it.
     */
    if (aIsSNaN) {
        return 0;
    } else if (bIsSNaN) {
        return 1;
    } else if (aIsQNaN) {
        return 0;
    } else {
        return 1;
    }
}
490
#elif defined(TARGET_PPC) || defined(TARGET_XTENSA)
491 492 493 494 495 496 497 498 499 500 501 502 503 504
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                   flag aIsLargerSignificand)
{
    /* PowerPC propagation rules:
     *  1. A if it sNaN or qNaN
     *  2. B if it sNaN or qNaN
     * A signaling NaN is always silenced before returning it.
     */
    if (aIsSNaN || aIsQNaN) {
        return 0;
    } else {
        return 1;
    }
}
505
#else
506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
                    flag aIsLargerSignificand)
{
    /* This implements x87 NaN propagation rules:
     * SNaN + QNaN => return the QNaN
     * two SNaNs => return the one with the larger significand, silenced
     * two QNaNs => return the one with the larger significand
     * SNaN and a non-NaN => return the SNaN, silenced
     * QNaN and a non-NaN => return the QNaN
     *
     * If we get down to comparing significands and they are the same,
     * return the NaN with the positive sign bit (if any).
     */
    if (aIsSNaN) {
        if (bIsSNaN) {
            return aIsLargerSignificand ? 0 : 1;
        }
        return bIsQNaN ? 1 : 0;
524 525
    } else if (aIsQNaN) {
        if (bIsSNaN || !bIsQNaN) {
526
            return 0;
527
        } else {
528 529 530 531 532 533
            return aIsLargerSignificand ? 0 : 1;
        }
    } else {
        return 1;
    }
}
534
#endif
535

536 537 538 539 540 541 542 543
/*----------------------------------------------------------------------------
| Select which NaN to propagate for a three-input operation.
| For the moment we assume that no CPU needs the 'larger significand'
| information.
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
*----------------------------------------------------------------------------*/
#if defined(TARGET_ARM)
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
544 545
                         flag cIsQNaN, flag cIsSNaN, flag infzero,
                         float_status *status)
546 547 548 549 550
{
    /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
     * the default NaN
     */
    if (infzero && cIsQNaN) {
551
        float_raise(float_flag_invalid, status);
552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571
        return 3;
    }

    /* This looks different from the ARM ARM pseudocode, because the ARM ARM
     * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
     */
    if (cIsSNaN) {
        return 2;
    } else if (aIsSNaN) {
        return 0;
    } else if (bIsSNaN) {
        return 1;
    } else if (cIsQNaN) {
        return 2;
    } else if (aIsQNaN) {
        return 0;
    } else {
        return 1;
    }
}
572 573
#elif defined(TARGET_MIPS)
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
574 575
                         flag cIsQNaN, flag cIsSNaN, flag infzero,
                         float_status *status)
576 577 578 579 580
{
    /* For MIPS, the (inf,zero,qnan) case sets InvalidOp and returns
     * the default NaN
     */
    if (infzero) {
581
        float_raise(float_flag_invalid, status);
582 583 584
        return 3;
    }

585 586 587 588 589 590 591 592 593 594 595 596 597 598 599
    if (status->snan_bit_is_one) {
        /* Prefer sNaN over qNaN, in the a, b, c order. */
        if (aIsSNaN) {
            return 0;
        } else if (bIsSNaN) {
            return 1;
        } else if (cIsSNaN) {
            return 2;
        } else if (aIsQNaN) {
            return 0;
        } else if (bIsQNaN) {
            return 1;
        } else {
            return 2;
        }
600
    } else {
601 602 603 604 605 606 607 608 609 610 611 612 613 614
        /* Prefer sNaN over qNaN, in the c, a, b order. */
        if (cIsSNaN) {
            return 2;
        } else if (aIsSNaN) {
            return 0;
        } else if (bIsSNaN) {
            return 1;
        } else if (cIsQNaN) {
            return 2;
        } else if (aIsQNaN) {
            return 0;
        } else {
            return 1;
        }
615 616
    }
}
617 618
#elif defined(TARGET_PPC)
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
619 620
                         flag cIsQNaN, flag cIsSNaN, flag infzero,
                         float_status *status)
621 622 623 624 625 626
{
    /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
     * to return an input NaN if we have one (ie c) rather than generating
     * a default NaN
     */
    if (infzero) {
627
        float_raise(float_flag_invalid, status);
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646
        return 2;
    }

    /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
     * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
     */
    if (aIsSNaN || aIsQNaN) {
        return 0;
    } else if (cIsSNaN || cIsQNaN) {
        return 2;
    } else {
        return 1;
    }
}
#else
/* A default implementation: prefer a to b to c.
 * This is unlikely to actually match any real implementation.
 */
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
647 648
                         flag cIsQNaN, flag cIsSNaN, flag infzero,
                         float_status *status)
649 650 651 652 653 654 655 656 657 658 659
{
    if (aIsSNaN || aIsQNaN) {
        return 0;
    } else if (bIsSNaN || bIsQNaN) {
        return 1;
    } else {
        return 2;
    }
}
#endif

bellard's avatar
bellard committed
660 661 662 663 664 665
/*----------------------------------------------------------------------------
| Takes two single-precision floating-point values `a' and `b', one of which
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/

666
static float32 propagateFloat32NaN(float32 a, float32 b, float_status *status)
bellard's avatar
bellard committed
667
{
668 669
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
    flag aIsLargerSignificand;
670
    uint32_t av, bv;
bellard's avatar
bellard committed
671

672 673 674 675
    aIsQuietNaN = float32_is_quiet_nan(a, status);
    aIsSignalingNaN = float32_is_signaling_nan(a, status);
    bIsQuietNaN = float32_is_quiet_nan(b, status);
    bIsSignalingNaN = float32_is_signaling_nan(b, status);
676 677
    av = float32_val(a);
    bv = float32_val(b);
678

679 680 681
    if (aIsSignalingNaN | bIsSignalingNaN) {
        float_raise(float_flag_invalid, status);
    }
682

683 684 685
    if (status->default_nan_mode) {
        return float32_default_nan(status);
    }
686

687
    if ((uint32_t)(av << 1) < (uint32_t)(bv << 1)) {
688
        aIsLargerSignificand = 0;
689
    } else if ((uint32_t)(bv << 1) < (uint32_t)(av << 1)) {
690 691 692
        aIsLargerSignificand = 1;
    } else {
        aIsLargerSignificand = (av < bv) ? 1 : 0;
bellard's avatar
bellard committed
693
    }
694

695
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
696
                aIsLargerSignificand)) {
697
        return float32_maybe_silence_nan(b, status);
698
    } else {
699
        return float32_maybe_silence_nan(a, status);
bellard's avatar
bellard committed
700 701 702
    }
}

703 704 705 706 707 708 709 710 711 712
/*----------------------------------------------------------------------------
| Takes three single-precision floating-point values `a', `b' and `c', one of
| which is a NaN, and returns the appropriate NaN result.  If any of  `a',
| `b' or `c' is a signaling NaN, the invalid exception is raised.
| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
| obviously c is a NaN, and whether to propagate c or some other NaN is
| implementation defined).
*----------------------------------------------------------------------------*/

static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
713 714
                                         float32 c, flag infzero,
                                         float_status *status)
715 716 717 718 719
{
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
        cIsQuietNaN, cIsSignalingNaN;
    int which;

720 721 722 723 724 725
    aIsQuietNaN = float32_is_quiet_nan(a, status);
    aIsSignalingNaN = float32_is_signaling_nan(a, status);
    bIsQuietNaN = float32_is_quiet_nan(b, status);
    bIsSignalingNaN = float32_is_signaling_nan(b, status);
    cIsQuietNaN = float32_is_quiet_nan(c, status);
    cIsSignalingNaN = float32_is_signaling_nan(c, status);
726 727

    if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
728
        float_raise(float_flag_invalid, status);
729 730 731 732
    }

    which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
                          bIsQuietNaN, bIsSignalingNaN,
733
                          cIsQuietNaN, cIsSignalingNaN, infzero, status);
734

735
    if (status->default_nan_mode) {
736 737 738
        /* Note that this check is after pickNaNMulAdd so that function
         * has an opportunity to set the Invalid flag.
         */
739
        return float32_default_nan(status);
740 741 742 743
    }

    switch (which) {
    case 0:
744
        return float32_maybe_silence_nan(a, status);
745
    case 1:
746
        return float32_maybe_silence_nan(b, status);
747
    case 2:
748
        return float32_maybe_silence_nan(c, status);
749 750
    case 3:
    default:
751
        return float32_default_nan(status);
752 753 754
    }
}

755
#ifdef NO_SIGNALING_NANS
756
int float64_is_quiet_nan(float64 a_, float_status *status)
757 758 759 760
{
    return float64_is_any_nan(a_);
}

761
int float64_is_signaling_nan(float64 a_, float_status *status)
762 763 764 765
{
    return 0;
}
#else
bellard's avatar
bellard committed
766
/*----------------------------------------------------------------------------
767 768
| Returns 1 if the double-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
bellard's avatar
bellard committed
769 770
*----------------------------------------------------------------------------*/

771
int float64_is_quiet_nan(float64 a_, float_status *status)
bellard's avatar
bellard committed
772
{
773
    uint64_t a = float64_val(a_);
774 775 776 777 778 779
    if (status->snan_bit_is_one) {
        return (((a >> 51) & 0xFFF) == 0xFFE)
            && (a & 0x0007FFFFFFFFFFFFULL);
    } else {
        return ((a << 1) >= 0xFFF0000000000000ULL);
    }
bellard's avatar
bellard committed
780 781 782 783 784 785 786
}

/*----------------------------------------------------------------------------
| Returns 1 if the double-precision floating-point value `a' is a signaling
| NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/

787
int float64_is_signaling_nan(float64 a_, float_status *status)
bellard's avatar
bellard committed
788
{
789
    uint64_t a = float64_val(a_);
790 791 792 793 794 795
    if (status->snan_bit_is_one) {
        return ((a << 1) >= 0xFFF0000000000000ULL);
    } else {
        return (((a >> 51) & 0xFFF) == 0xFFE)
            && (a & LIT64(0x0007FFFFFFFFFFFF));
    }
bellard's avatar
bellard committed
796
}
797
#endif
bellard's avatar
bellard committed
798

799 800 801 802 803
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the double-precision floating point value `a' is a
| signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/

804
float64 float64_maybe_silence_nan(float64 a_, float_status *status)
805
{
806 807
    if (float64_is_signaling_nan(a_, status)) {
        if (status->snan_bit_is_one) {
808 809 810 811 812 813
#ifdef TARGET_HPPA
            uint64_t a = float64_val(a_);
            a &= ~0x0008000000000000ULL;
            a |=  0x0004000000000000ULL;
            return make_float64(a);
#else
814
            return float64_default_nan(status);
815
#endif
816 817 818 819 820
        } else {
            uint64_t a = float64_val(a_);
            a |= LIT64(0x0008000000000000);
            return make_float64(a);
        }
821 822 823 824
    }
    return a_;
}

bellard's avatar
bellard committed
825 826 827 828 829 830
/*----------------------------------------------------------------------------
| Returns the result of converting the double-precision floating-point NaN
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/

831
static commonNaNT float64ToCommonNaN(float64 a, float_status *status)
bellard's avatar
bellard committed
832 833 834
{
    commonNaNT z;

835
    if (float64_is_signaling_nan(a, status)) {
836 837
        float_raise(float_flag_invalid, status);
    }
838
    z.sign = float64_val(a) >> 63;
bellard's avatar
bellard committed
839
    z.low = 0;
840
    z.high = float64_val(a) << 12;
bellard's avatar
bellard committed
841 842 843 844 845 846 847 848
    return z;
}

/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the double-
| precision floating-point format.
*----------------------------------------------------------------------------*/

849
static float64 commonNaNToFloat64(commonNaNT a, float_status *status)
bellard's avatar
bellard committed
850
{
851
    uint64_t mantissa = a.high >> 12;
852

853
    if (status->default_nan_mode) {
854
        return float64_default_nan(status);
855 856
    }

857
    if (mantissa) {
858
        return make_float64(
859 860 861
              (((uint64_t) a.sign) << 63)
            | LIT64(0x7FF0000000000000)
            | (a.high >> 12));
862 863 864
    } else {
        return float64_default_nan(status);
    }
bellard's avatar
bellard committed
865 866 867 868 869 870 871 872
}

/*----------------------------------------------------------------------------
| Takes two double-precision floating-point values `a' and `b', one of which
| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/

873
static float64 propagateFloat64NaN(float64 a, float64 b, float_status *status)
bellard's avatar
bellard committed
874
{
875 876
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
    flag aIsLargerSignificand;
877
    uint64_t av, bv;
bellard's avatar
bellard committed
878

879 880 881 882
    aIsQuietNaN = float64_is_quiet_nan(a, status);
    aIsSignalingNaN = float64_is_signaling_nan(a, status);
    bIsQuietNaN = float64_is_quiet_nan(b, status);
    bIsSignalingNaN = float64_is_signaling_nan(b, status);
883 884
    av = float64_val(a);
    bv = float64_val(b);
885

886 887 888
    if (aIsSignalingNaN | bIsSignalingNaN) {
        float_raise(float_flag_invalid, status);
    }
889

890 891 892
    if (status->default_nan_mode) {
        return float64_default_nan(status);
    }
893

894
    if ((uint64_t)(av << 1) < (uint64_t)(bv << 1)) {
895
        aIsLargerSignificand = 0;
896
    } else if ((uint64_t)(bv << 1) < (uint64_t)(av << 1)) {
897 898 899
        aIsLargerSignificand = 1;
    } else {
        aIsLargerSignificand = (av < bv) ? 1 : 0;
bellard's avatar
bellard committed
900
    }
901

902
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
903
                aIsLargerSignificand)) {
904
        return float64_maybe_silence_nan(b, status);
905
    } else {
906
        return float64_maybe_silence_nan(a, status);
bellard's avatar
bellard committed
907 908 909
    }
}

910 911 912 913 914 915 916 917 918 919
/*----------------------------------------------------------------------------
| Takes three double-precision floating-point values `a', `b' and `c', one of
| which is a NaN, and returns the appropriate NaN result.  If any of  `a',
| `b' or `c' is a signaling NaN, the invalid exception is raised.
| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
| obviously c is a NaN, and whether to propagate c or some other NaN is
| implementation defined).
*----------------------------------------------------------------------------*/

static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
920 921
                                         float64 c, flag infzero,
                                         float_status *status)
922 923 924 925 926
{
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
        cIsQuietNaN, cIsSignalingNaN;
    int which;

927 928 929 930 931 932
    aIsQuietNaN = float64_is_quiet_nan(a, status);
    aIsSignalingNaN = float64_is_signaling_nan(a, status);
    bIsQuietNaN = float64_is_quiet_nan(b, status);
    bIsSignalingNaN = float64_is_signaling_nan(b, status);
    cIsQuietNaN = float64_is_quiet_nan(c, status);
    cIsSignalingNaN = float64_is_signaling_nan(c, status);
933 934

    if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
935
        float_raise(float_flag_invalid, status);
936 937 938 939
    }

    which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
                          bIsQuietNaN, bIsSignalingNaN,
940
                          cIsQuietNaN, cIsSignalingNaN, infzero, status);
941

942
    if (status->default_nan_mode) {
943 944 945
        /* Note that this check is after pickNaNMulAdd so that function
         * has an opportunity to set the Invalid flag.
         */
946
        return float64_default_nan(status);
947 948 949 950
    }

    switch (which) {
    case 0:
951
        return float64_maybe_silence_nan(a, status);
952
    case 1:
953
        return float64_maybe_silence_nan(b, status);
954
    case 2:
955
        return float64_maybe_silence_nan(c, status);
956 957
    case 3:
    default:
958
        return float64_default_nan(status);
959 960 961
    }
}

962
#ifdef NO_SIGNALING_NANS
963
int floatx80_is_quiet_nan(floatx80 a_, float_status *status)
964 965 966 967
{
    return floatx80_is_any_nan(a_);
}

968
int floatx80_is_signaling_nan(floatx80 a_, float_status *status)
969 970 971 972
{
    return 0;
}
#else
bellard's avatar
bellard committed
973 974
/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is a
975 976
| quiet NaN; otherwise returns 0. This slightly differs from the same
| function for other types as floatx80 has an explicit bit.
bellard's avatar
bellard committed
977 978
*----------------------------------------------------------------------------*/

979
int floatx80_is_quiet_nan(floatx80 a, float_status *status)
bellard's avatar
bellard committed
980
{
981 982
    if (status->snan_bit_is_one) {
        uint64_t aLow;
bellard's avatar
bellard committed
983

984 985 986 987 988 989 990 991
        aLow = a.low & ~0x4000000000000000ULL;
        return ((a.high & 0x7FFF) == 0x7FFF)
            && (aLow << 1)
            && (a.low == aLow);
    } else {
        return ((a.high & 0x7FFF) == 0x7FFF)
            && (LIT64(0x8000000000000000) <= ((uint64_t)(a.low << 1)));
    }
bellard's avatar
bellard committed
992 993 994 995
}

/*----------------------------------------------------------------------------
| Returns 1 if the extended double-precision floating-point value `a' is a
996 997
| signaling NaN; otherwise returns 0. This slightly differs from the same
| function for other types as floatx80 has an explicit bit.
bellard's avatar
bellard committed
998 999
*----------------------------------------------------------------------------*/

1000
int floatx80_is_signaling_nan(floatx80 a, float_status *status)
bellard's avatar
bellard committed
1001
{
1002 1003 1004 1005 1006
    if (status->snan_bit_is_one) {
        return ((a.high & 0x7FFF) == 0x7FFF)
            && ((a.low << 1) >= 0x8000000000000000ULL);
    } else {
        uint64_t aLow;
bellard's avatar
bellard committed
1007

1008 1009 1010 1011 1012
        aLow = a.low & ~LIT64(0x4000000000000000);
        return ((a.high & 0x7FFF) == 0x7FFF)
            && (uint64_t)(aLow << 1)
            && (a.low == aLow);
    }
bellard's avatar
bellard committed
1013
}
1014
#endif
bellard's avatar
bellard committed
1015

1016 1017 1018 1019 1020
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the extended double-precision floating point value
| `a' is a signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/

1021
floatx80 floatx80_maybe_silence_nan(floatx80 a, float_status *status)
1022
{
1023 1024 1025 1026 1027 1028 1029
    if (floatx80_is_signaling_nan(a, status)) {
        if (status->snan_bit_is_one) {
            a = floatx80_default_nan(status);
        } else {
            a.low |= LIT64(0xC000000000000000);
            return a;
        }
1030 1031 1032 1033
    }
    return a;
}

bellard's avatar
bellard committed
1034 1035 1036 1037 1038 1039
/*----------------------------------------------------------------------------
| Returns the result of converting the extended double-precision floating-
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
| invalid exception is raised.
*----------------------------------------------------------------------------*/

1040
static commonNaNT floatx80ToCommonNaN(floatx80 a, float_status *status)
bellard's avatar
bellard committed
1041
{
1042
    floatx80 dflt;
bellard's avatar
bellard committed
1043 1044
    commonNaNT z;

1045
    if (floatx80_is_signaling_nan(a, status)) {
1046 1047
        float_raise(float_flag_invalid, status);
    }
1048
    if (a.low >> 63) {
1049 1050 1051 1052
        z.sign = a.high >> 15;
        z.low = 0;
        z.high = a.low << 1;
    } else {
1053 1054
        dflt = floatx80_default_nan(status);
        z.sign = dflt.high >> 15;
1055
        z.low = 0;
1056
        z.high = dflt.low << 1;
1057
    }
bellard's avatar
bellard committed
1058 1059 1060 1061 1062 1063 1064 1065
    return z;
}

/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the extended
| double-precision floating-point format.
*----------------------------------------------------------------------------*/

1066
static floatx80 commonNaNToFloatx80(commonNaNT a, float_status *status)
bellard's avatar
bellard committed
1067 1068 1069
{
    floatx80 z;

1070
    if (status->default_nan_mode) {
1071
        return floatx80_default_nan(status);
1072 1073
    }

1074
    if (a.high >> 1) {
1075 1076
        z.low = LIT64(0x8000000000000000) | a.high >> 1;
        z.high = (((uint16_t)a.sign) << 15) | 0x7FFF;
1077
    } else {
1078
        z = floatx80_default_nan(status);
1079
    }
bellard's avatar
bellard committed
1080 1081 1082 1083 1084 1085 1086 1087 1088
    return z;
}

/*----------------------------------------------------------------------------
| Takes two extended double-precision floating-point values `a' and `b', one
| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
| `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/

1089 1090
static floatx80 propagateFloatx80NaN(floatx80 a, floatx80 b,
                                     float_status *status)
bellard's avatar
bellard committed
1091
{
1092 1093
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
    flag aIsLargerSignificand;
bellard's avatar
bellard committed
1094

1095 1096 1097 1098
    aIsQuietNaN = floatx80_is_quiet_nan(a, status);
    aIsSignalingNaN = floatx80_is_signaling_nan(a, status);
    bIsQuietNaN = floatx80_is_quiet_nan(b, status);
    bIsSignalingNaN = floatx80_is_signaling_nan(b, status);
1099

1100 1101 1102
    if (aIsSignalingNaN | bIsSignalingNaN) {
        float_raise(float_flag_invalid, status);
    }
1103

1104
    if (status->default_nan_mode) {
1105
        return floatx80_default_nan(status);
1106 1107
    }

1108 1109 1110 1111 1112 1113
    if (a.low < b.low) {
        aIsLargerSignificand = 0;
    } else if (b.low < a.low) {
        aIsLargerSignificand = 1;
    } else {
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
bellard's avatar
bellard committed
1114
    }
1115

1116
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
1117
                aIsLargerSignificand)) {
1118
        return floatx80_maybe_silence_nan(b, status);
1119
    } else {
1120
        return floatx80_maybe_silence_nan(a, status);
bellard's avatar
bellard committed
1121 1122 1123
    }
}

1124
#ifdef NO_SIGNALING_NANS
1125
int float128_is_quiet_nan(float128 a_, float_status *status)
1126 1127 1128 1129
{
    return float128_is_any_nan(a_);
}

1130
int float128_is_signaling_nan(float128 a_, float_status *status)
1131 1132 1133 1134
{
    return 0;
}
#else
bellard's avatar
bellard committed
1135
/*----------------------------------------------------------------------------
1136 1137
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
| NaN; otherwise returns 0.
bellard's avatar
bellard committed
1138 1139
*----------------------------------------------------------------------------*/

1140
int float128_is_quiet_nan(float128 a, float_status *status)
bellard's avatar
bellard committed
1141
{
1142 1143 1144 1145 1146 1147 1148
    if (status->snan_bit_is_one) {
        return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
            && (a.low || (a.high & 0x00007FFFFFFFFFFFULL));
    } else {
        return ((a.high << 1) >= 0xFFFF000000000000ULL)
            && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
    }
bellard's avatar
bellard committed
1149 1150 1151 1152 1153 1154 1155
}

/*----------------------------------------------------------------------------
| Returns 1 if the quadruple-precision floating-point value `a' is a
| signaling NaN; otherwise returns 0.
*----------------------------------------------------------------------------*/

1156
int float128_is_signaling_nan(float128 a, float_status *status)
bellard's avatar
bellard committed
1157
{
1158 1159 1160 1161 1162 1163 1164
    if (status->snan_bit_is_one) {
        return ((a.high << 1) >= 0xFFFF000000000000ULL)
            && (a.low || (a.high & 0x0000FFFFFFFFFFFFULL));
    } else {
        return (((a.high >> 47) & 0xFFFF) == 0xFFFE)
            && (a.low || (a.high & LIT64(0x00007FFFFFFFFFFF)));
    }
bellard's avatar
bellard committed
1165
}
1166
#endif
bellard's avatar
bellard committed
1167

1168 1169 1170 1171 1172
/*----------------------------------------------------------------------------
| Returns a quiet NaN if the quadruple-precision floating point value `a' is
| a signaling NaN; otherwise returns `a'.
*----------------------------------------------------------------------------*/

1173
float128 float128_maybe_silence_nan(float128 a, float_status *status)
1174
{
1175 1176 1177 1178 1179 1180 1181
    if (float128_is_signaling_nan(a, status)) {
        if (status->snan_bit_is_one) {
            a = float128_default_nan(status);
        } else {
            a.high |= LIT64(0x0000800000000000);
            return a;
        }
1182 1183 1184 1185
    }
    return a;
}

bellard's avatar
bellard committed
1186 1187 1188 1189 1190 1191
/*----------------------------------------------------------------------------
| Returns the result of converting the quadruple-precision floating-point NaN
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/

1192
static commonNaNT float128ToCommonNaN(float128 a, float_status *status)
bellard's avatar
bellard committed
1193 1194 1195
{
    commonNaNT z;

1196
    if (float128_is_signaling_nan(a, status)) {
1197 1198
        float_raise(float_flag_invalid, status);
    }
1199 1200
    z.sign = a.high >> 63;
    shortShift128Left(a.high, a.low, 16, &z.high, &z.low);
bellard's avatar
bellard committed
1201 1202 1203 1204 1205 1206 1207 1208
    return z;
}

/*----------------------------------------------------------------------------
| Returns the result of converting the canonical NaN `a' to the quadruple-
| precision floating-point format.
*----------------------------------------------------------------------------*/

1209
static float128 commonNaNToFloat128(commonNaNT a, float_status *status)
bellard's avatar
bellard committed
1210 1211 1212
{
    float128 z;

1213
    if (status->default_nan_mode) {
1214
        return float128_default_nan(status);
1215 1216
    }

1217 1218
    shift128Right(a.high, a.low, 16, &z.high, &z.low);
    z.high |= (((uint64_t)a.sign) << 63) | LIT64(0x7FFF000000000000);
bellard's avatar
bellard committed
1219 1220 1221 1222 1223 1224 1225 1226 1227
    return z;
}

/*----------------------------------------------------------------------------
| Takes two quadruple-precision floating-point values `a' and `b', one of
| which is a NaN, and returns the appropriate NaN result.  If either `a' or
| `b' is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/

1228 1229
static float128 propagateFloat128NaN(float128 a, float128 b,
                                     float_status *status)
bellard's avatar
bellard committed
1230
{
1231 1232
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
    flag aIsLargerSignificand;
bellard's avatar
bellard committed
1233

1234 1235 1236 1237
    aIsQuietNaN = float128_is_quiet_nan(a, status);
    aIsSignalingNaN = float128_is_signaling_nan(a, status);
    bIsQuietNaN = float128_is_quiet_nan(b, status);
    bIsSignalingNaN = float128_is_signaling_nan(b, status);
1238

1239 1240 1241
    if (aIsSignalingNaN | bIsSignalingNaN) {
        float_raise(float_flag_invalid, status);
    }
1242

1243
    if (status->default_nan_mode) {
1244
        return float128_default_nan(status);
1245 1246
    }

1247
    if (lt128(a.high << 1, a.low, b.high << 1, b.low)) {
1248
        aIsLargerSignificand = 0;
1249
    } else if (lt128(b.high << 1, b.low, a.high << 1, a.low)) {
1250 1251 1252
        aIsLargerSignificand = 1;
    } else {
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
bellard's avatar
bellard committed
1253
    }
1254

1255
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
1256
                aIsLargerSignificand)) {
1257
        return float128_maybe_silence_nan(b, status);
1258
    } else {
1259
        return float128_maybe_silence_nan(a, status);
bellard's avatar
bellard committed
1260 1261
    }
}