Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ b55c22c6

History | View | Annotate | Download (26.9 kB)

1

    
2
/*============================================================================
3

4
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5
Arithmetic Package, Release 2b.
6

7
Written by John R. Hauser.  This work was made possible in part by the
8
International Computer Science Institute, located at Suite 600, 1947 Center
9
Street, Berkeley, California 94704.  Funding was partially provided by the
10
National Science Foundation under grant MIP-9311980.  The original version
11
of this code was written as part of a project to build a fixed-point vector
12
processor in collaboration with the University of California at Berkeley,
13
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
14
is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15
arithmetic/SoftFloat.html'.
16

17
THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
18
been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19
RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20
AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21
COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22
EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23
INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24
OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25

26
Derivative works are acceptable, even for commercial purposes, so long as
27
(1) the source code for the derivative work includes prominent notice that
28
the work is derivative, and (2) the source code includes prominent notice with
29
these four paragraphs for those parts of this code that are retained.
30

31
=============================================================================*/
32

    
33
/*----------------------------------------------------------------------------
34
| Raises the exceptions specified by `flags'.  Floating-point traps can be
35
| defined here if desired.  It is currently not possible for such a trap
36
| to substitute a result value.  If traps are not implemented, this routine
37
| should be simply `float_exception_flags |= flags;'.
38
*----------------------------------------------------------------------------*/
39

    
40
void float_raise( int8 flags STATUS_PARAM )
41
{
42
    STATUS(float_exception_flags) |= flags;
43
}
44

    
45
/*----------------------------------------------------------------------------
46
| Internal canonical NaN format.
47
*----------------------------------------------------------------------------*/
48
typedef struct {
49
    flag sign;
50
    bits64 high, low;
51
} commonNaNT;
52

    
53
/*----------------------------------------------------------------------------
54
| Returns 1 if the half-precision floating-point value `a' is a quiet
55
| NaN; otherwise returns 0.
56
*----------------------------------------------------------------------------*/
57

    
58
int float16_is_quiet_nan(float16 a_)
59
{
60
    uint16_t a = float16_val(a_);
61
#if SNAN_BIT_IS_ONE
62
    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
63
#else
64
    return ((a & ~0x8000) >= 0x7c80);
65
#endif
66
}
67

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

    
73
int float16_is_signaling_nan(float16 a_)
74
{
75
    uint16_t a = float16_val(a_);
76
#if SNAN_BIT_IS_ONE
77
    return ((a & ~0x8000) >= 0x7c80);
78
#else
79
    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
80
#endif
81
}
82

    
83
/*----------------------------------------------------------------------------
84
| Returns a quiet NaN if the half-precision floating point value `a' is a
85
| signaling NaN; otherwise returns `a'.
86
*----------------------------------------------------------------------------*/
87
float16 float16_maybe_silence_nan(float16 a_)
88
{
89
    if (float16_is_signaling_nan(a_)) {
90
#if SNAN_BIT_IS_ONE
91
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
92
        return float16_default_nan;
93
#  else
94
#    error Rules for silencing a signaling NaN are target-specific
95
#  endif
96
#else
97
        uint16_t a = float16_val(a_);
98
        a |= (1 << 9);
99
        return make_float16(a);
100
#endif
101
    }
102
    return a_;
103
}
104

    
105
/*----------------------------------------------------------------------------
106
| Returns the result of converting the half-precision floating-point NaN
107
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
108
| exception is raised.
109
*----------------------------------------------------------------------------*/
110

    
111
static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
112
{
113
    commonNaNT z;
114

    
115
    if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
116
    z.sign = float16_val(a) >> 15;
117
    z.low = 0;
118
    z.high = ((bits64) float16_val(a))<<54;
119
    return z;
120
}
121

    
122
/*----------------------------------------------------------------------------
123
| Returns the result of converting the canonical NaN `a' to the half-
124
| precision floating-point format.
125
*----------------------------------------------------------------------------*/
126

    
127
static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
128
{
129
    uint16_t mantissa = a.high>>54;
130

    
131
    if (STATUS(default_nan_mode)) {
132
        return float16_default_nan;
133
    }
134

    
135
    if (mantissa) {
136
        return make_float16(((((uint16_t) a.sign) << 15)
137
                             | (0x1F << 10) | mantissa));
138
    } else {
139
        return float16_default_nan;
140
    }
141
}
142

    
143
/*----------------------------------------------------------------------------
144
| Returns 1 if the single-precision floating-point value `a' is a quiet
145
| NaN; otherwise returns 0.
146
*----------------------------------------------------------------------------*/
147

    
148
int float32_is_quiet_nan( float32 a_ )
149
{
150
    uint32_t a = float32_val(a_);
151
#if SNAN_BIT_IS_ONE
152
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
153
#else
154
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
155
#endif
156
}
157

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

    
163
int float32_is_signaling_nan( float32 a_ )
164
{
165
    uint32_t a = float32_val(a_);
166
#if SNAN_BIT_IS_ONE
167
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
168
#else
169
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
170
#endif
171
}
172

    
173
/*----------------------------------------------------------------------------
174
| Returns a quiet NaN if the single-precision floating point value `a' is a
175
| signaling NaN; otherwise returns `a'.
176
*----------------------------------------------------------------------------*/
177

    
178
float32 float32_maybe_silence_nan( float32 a_ )
179
{
180
    if (float32_is_signaling_nan(a_)) {
181
#if SNAN_BIT_IS_ONE
182
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
183
        return float32_default_nan;
184
#  else
185
#    error Rules for silencing a signaling NaN are target-specific
186
#  endif
187
#else
188
        bits32 a = float32_val(a_);
189
        a |= (1 << 22);
190
        return make_float32(a);
191
#endif
192
    }
193
    return a_;
194
}
195

    
196
/*----------------------------------------------------------------------------
197
| Returns the result of converting the single-precision floating-point NaN
198
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
199
| exception is raised.
200
*----------------------------------------------------------------------------*/
201

    
202
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
203
{
204
    commonNaNT z;
205

    
206
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
207
    z.sign = float32_val(a)>>31;
208
    z.low = 0;
209
    z.high = ( (bits64) float32_val(a) )<<41;
210
    return z;
211
}
212

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

    
218
static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
219
{
220
    bits32 mantissa = a.high>>41;
221

    
222
    if ( STATUS(default_nan_mode) ) {
223
        return float32_default_nan;
224
    }
225

    
226
    if ( mantissa )
227
        return make_float32(
228
            ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
229
    else
230
        return float32_default_nan;
231
}
232

    
233
/*----------------------------------------------------------------------------
234
| Select which NaN to propagate for a two-input operation.
235
| IEEE754 doesn't specify all the details of this, so the
236
| algorithm is target-specific.
237
| The routine is passed various bits of information about the
238
| two NaNs and should return 0 to select NaN a and 1 for NaN b.
239
| Note that signalling NaNs are always squashed to quiet NaNs
240
| by the caller, by calling floatXX_maybe_silence_nan() before
241
| returning them.
242
|
243
| aIsLargerSignificand is only valid if both a and b are NaNs
244
| of some kind, and is true if a has the larger significand,
245
| or if both a and b have the same significand but a is
246
| positive but b is negative. It is only needed for the x87
247
| tie-break rule.
248
*----------------------------------------------------------------------------*/
249

    
250
#if defined(TARGET_ARM)
251
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
252
                    flag aIsLargerSignificand)
253
{
254
    /* ARM mandated NaN propagation rules: take the first of:
255
     *  1. A if it is signaling
256
     *  2. B if it is signaling
257
     *  3. A (quiet)
258
     *  4. B (quiet)
259
     * A signaling NaN is always quietened before returning it.
260
     */
261
    if (aIsSNaN) {
262
        return 0;
263
    } else if (bIsSNaN) {
264
        return 1;
265
    } else if (aIsQNaN) {
266
        return 0;
267
    } else {
268
        return 1;
269
    }
270
}
271
#elif defined(TARGET_MIPS)
272
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
273
                    flag aIsLargerSignificand)
274
{
275
    /* According to MIPS specifications, if one of the two operands is
276
     * a sNaN, a new qNaN has to be generated. This is done in
277
     * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
278
     * says: "When possible, this QNaN result is one of the operand QNaN
279
     * values." In practice it seems that most implementations choose
280
     * the first operand if both operands are qNaN. In short this gives
281
     * the following rules:
282
     *  1. A if it is signaling
283
     *  2. B if it is signaling
284
     *  3. A (quiet)
285
     *  4. B (quiet)
286
     * A signaling NaN is always silenced before returning it.
287
     */
288
    if (aIsSNaN) {
289
        return 0;
290
    } else if (bIsSNaN) {
291
        return 1;
292
    } else if (aIsQNaN) {
293
        return 0;
294
    } else {
295
        return 1;
296
    }
297
}
298
#elif defined(TARGET_PPC)
299
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
300
                   flag aIsLargerSignificand)
301
{
302
    /* PowerPC propagation rules:
303
     *  1. A if it sNaN or qNaN
304
     *  2. B if it sNaN or qNaN
305
     * A signaling NaN is always silenced before returning it.
306
     */
307
    if (aIsSNaN || aIsQNaN) {
308
        return 0;
309
    } else {
310
        return 1;
311
    }
312
}
313
#else
314
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
315
                    flag aIsLargerSignificand)
316
{
317
    /* This implements x87 NaN propagation rules:
318
     * SNaN + QNaN => return the QNaN
319
     * two SNaNs => return the one with the larger significand, silenced
320
     * two QNaNs => return the one with the larger significand
321
     * SNaN and a non-NaN => return the SNaN, silenced
322
     * QNaN and a non-NaN => return the QNaN
323
     *
324
     * If we get down to comparing significands and they are the same,
325
     * return the NaN with the positive sign bit (if any).
326
     */
327
    if (aIsSNaN) {
328
        if (bIsSNaN) {
329
            return aIsLargerSignificand ? 0 : 1;
330
        }
331
        return bIsQNaN ? 1 : 0;
332
    }
333
    else if (aIsQNaN) {
334
        if (bIsSNaN || !bIsQNaN)
335
            return 0;
336
        else {
337
            return aIsLargerSignificand ? 0 : 1;
338
        }
339
    } else {
340
        return 1;
341
    }
342
}
343
#endif
344

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

    
351
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
352
{
353
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
354
    flag aIsLargerSignificand;
355
    bits32 av, bv;
356

    
357
    aIsQuietNaN = float32_is_quiet_nan( a );
358
    aIsSignalingNaN = float32_is_signaling_nan( a );
359
    bIsQuietNaN = float32_is_quiet_nan( b );
360
    bIsSignalingNaN = float32_is_signaling_nan( b );
361
    av = float32_val(a);
362
    bv = float32_val(b);
363

    
364
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
365

    
366
    if ( STATUS(default_nan_mode) )
367
        return float32_default_nan;
368

    
369
    if ((bits32)(av<<1) < (bits32)(bv<<1)) {
370
        aIsLargerSignificand = 0;
371
    } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
372
        aIsLargerSignificand = 1;
373
    } else {
374
        aIsLargerSignificand = (av < bv) ? 1 : 0;
375
    }
376

    
377
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
378
                aIsLargerSignificand)) {
379
        return float32_maybe_silence_nan(b);
380
    } else {
381
        return float32_maybe_silence_nan(a);
382
    }
383
}
384

    
385
/*----------------------------------------------------------------------------
386
| Returns 1 if the double-precision floating-point value `a' is a quiet
387
| NaN; otherwise returns 0.
388
*----------------------------------------------------------------------------*/
389

    
390
int float64_is_quiet_nan( float64 a_ )
391
{
392
    bits64 a = float64_val(a_);
393
#if SNAN_BIT_IS_ONE
394
    return
395
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
396
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
397
#else
398
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
399
#endif
400
}
401

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

    
407
int float64_is_signaling_nan( float64 a_ )
408
{
409
    bits64 a = float64_val(a_);
410
#if SNAN_BIT_IS_ONE
411
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
412
#else
413
    return
414
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
415
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
416
#endif
417
}
418

    
419
/*----------------------------------------------------------------------------
420
| Returns a quiet NaN if the double-precision floating point value `a' is a
421
| signaling NaN; otherwise returns `a'.
422
*----------------------------------------------------------------------------*/
423

    
424
float64 float64_maybe_silence_nan( float64 a_ )
425
{
426
    if (float64_is_signaling_nan(a_)) {
427
#if SNAN_BIT_IS_ONE
428
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
429
        return float64_default_nan;
430
#  else
431
#    error Rules for silencing a signaling NaN are target-specific
432
#  endif
433
#else
434
        bits64 a = float64_val(a_);
435
        a |= LIT64( 0x0008000000000000 );
436
        return make_float64(a);
437
#endif
438
    }
439
    return a_;
440
}
441

    
442
/*----------------------------------------------------------------------------
443
| Returns the result of converting the double-precision floating-point NaN
444
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
445
| exception is raised.
446
*----------------------------------------------------------------------------*/
447

    
448
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
449
{
450
    commonNaNT z;
451

    
452
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
453
    z.sign = float64_val(a)>>63;
454
    z.low = 0;
455
    z.high = float64_val(a)<<12;
456
    return z;
457
}
458

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

    
464
static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
465
{
466
    bits64 mantissa = a.high>>12;
467

    
468
    if ( STATUS(default_nan_mode) ) {
469
        return float64_default_nan;
470
    }
471

    
472
    if ( mantissa )
473
        return make_float64(
474
              ( ( (bits64) a.sign )<<63 )
475
            | LIT64( 0x7FF0000000000000 )
476
            | ( a.high>>12 ));
477
    else
478
        return float64_default_nan;
479
}
480

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

    
487
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
488
{
489
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
490
    flag aIsLargerSignificand;
491
    bits64 av, bv;
492

    
493
    aIsQuietNaN = float64_is_quiet_nan( a );
494
    aIsSignalingNaN = float64_is_signaling_nan( a );
495
    bIsQuietNaN = float64_is_quiet_nan( b );
496
    bIsSignalingNaN = float64_is_signaling_nan( b );
497
    av = float64_val(a);
498
    bv = float64_val(b);
499

    
500
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
501

    
502
    if ( STATUS(default_nan_mode) )
503
        return float64_default_nan;
504

    
505
    if ((bits64)(av<<1) < (bits64)(bv<<1)) {
506
        aIsLargerSignificand = 0;
507
    } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
508
        aIsLargerSignificand = 1;
509
    } else {
510
        aIsLargerSignificand = (av < bv) ? 1 : 0;
511
    }
512

    
513
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
514
                aIsLargerSignificand)) {
515
        return float64_maybe_silence_nan(b);
516
    } else {
517
        return float64_maybe_silence_nan(a);
518
    }
519
}
520

    
521
#ifdef FLOATX80
522

    
523
/*----------------------------------------------------------------------------
524
| Returns 1 if the extended double-precision floating-point value `a' is a
525
| quiet NaN; otherwise returns 0. This slightly differs from the same
526
| function for other types as floatx80 has an explicit bit.
527
*----------------------------------------------------------------------------*/
528

    
529
int floatx80_is_quiet_nan( floatx80 a )
530
{
531
#if SNAN_BIT_IS_ONE
532
    bits64 aLow;
533

    
534
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
535
    return
536
           ( ( a.high & 0x7FFF ) == 0x7FFF )
537
        && (bits64) ( aLow<<1 )
538
        && ( a.low == aLow );
539
#else
540
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
541
        && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
542
#endif
543
}
544

    
545
/*----------------------------------------------------------------------------
546
| Returns 1 if the extended double-precision floating-point value `a' is a
547
| signaling NaN; otherwise returns 0. This slightly differs from the same
548
| function for other types as floatx80 has an explicit bit.
549
*----------------------------------------------------------------------------*/
550

    
551
int floatx80_is_signaling_nan( floatx80 a )
552
{
553
#if SNAN_BIT_IS_ONE
554
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
555
        && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
556
#else
557
    bits64 aLow;
558

    
559
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
560
    return
561
           ( ( a.high & 0x7FFF ) == 0x7FFF )
562
        && (bits64) ( aLow<<1 )
563
        && ( a.low == aLow );
564
#endif
565
}
566

    
567
/*----------------------------------------------------------------------------
568
| Returns a quiet NaN if the extended double-precision floating point value
569
| `a' is a signaling NaN; otherwise returns `a'.
570
*----------------------------------------------------------------------------*/
571

    
572
floatx80 floatx80_maybe_silence_nan( floatx80 a )
573
{
574
    if (floatx80_is_signaling_nan(a)) {
575
#if SNAN_BIT_IS_ONE
576
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
577
        a.low = floatx80_default_nan_low;
578
        a.high = floatx80_default_nan_high;
579
#  else
580
#    error Rules for silencing a signaling NaN are target-specific
581
#  endif
582
#else
583
        a.low |= LIT64( 0xC000000000000000 );
584
        return a;
585
#endif
586
    }
587
    return a;
588
}
589

    
590
/*----------------------------------------------------------------------------
591
| Returns the result of converting the extended double-precision floating-
592
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
593
| invalid exception is raised.
594
*----------------------------------------------------------------------------*/
595

    
596
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
597
{
598
    commonNaNT z;
599

    
600
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
601
    z.sign = a.high>>15;
602
    z.low = 0;
603
    z.high = a.low;
604
    return z;
605
}
606

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

    
612
static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
613
{
614
    floatx80 z;
615

    
616
    if ( STATUS(default_nan_mode) ) {
617
        z.low = floatx80_default_nan_low;
618
        z.high = floatx80_default_nan_high;
619
        return z;
620
    }
621

    
622
    if (a.high)
623
        z.low = a.high;
624
    else
625
        z.low = floatx80_default_nan_low;
626
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
627
    return z;
628
}
629

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

    
636
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
637
{
638
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
639
    flag aIsLargerSignificand;
640

    
641
    aIsQuietNaN = floatx80_is_quiet_nan( a );
642
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
643
    bIsQuietNaN = floatx80_is_quiet_nan( b );
644
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
645

    
646
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
647

    
648
    if ( STATUS(default_nan_mode) ) {
649
        a.low = floatx80_default_nan_low;
650
        a.high = floatx80_default_nan_high;
651
        return a;
652
    }
653

    
654
    if (a.low < b.low) {
655
        aIsLargerSignificand = 0;
656
    } else if (b.low < a.low) {
657
        aIsLargerSignificand = 1;
658
    } else {
659
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
660
    }
661

    
662
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
663
                aIsLargerSignificand)) {
664
        return floatx80_maybe_silence_nan(b);
665
    } else {
666
        return floatx80_maybe_silence_nan(a);
667
    }
668
}
669

    
670
#endif
671

    
672
#ifdef FLOAT128
673

    
674
/*----------------------------------------------------------------------------
675
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
676
| NaN; otherwise returns 0.
677
*----------------------------------------------------------------------------*/
678

    
679
int float128_is_quiet_nan( float128 a )
680
{
681
#if SNAN_BIT_IS_ONE
682
    return
683
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
684
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
685
#else
686
    return
687
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
688
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
689
#endif
690
}
691

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

    
697
int float128_is_signaling_nan( float128 a )
698
{
699
#if SNAN_BIT_IS_ONE
700
    return
701
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
702
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
703
#else
704
    return
705
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
706
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
707
#endif
708
}
709

    
710
/*----------------------------------------------------------------------------
711
| Returns a quiet NaN if the quadruple-precision floating point value `a' is
712
| a signaling NaN; otherwise returns `a'.
713
*----------------------------------------------------------------------------*/
714

    
715
float128 float128_maybe_silence_nan( float128 a )
716
{
717
    if (float128_is_signaling_nan(a)) {
718
#if SNAN_BIT_IS_ONE
719
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
720
        a.low = float128_default_nan_low;
721
        a.high = float128_default_nan_high;
722
#  else
723
#    error Rules for silencing a signaling NaN are target-specific
724
#  endif
725
#else
726
        a.high |= LIT64( 0x0000800000000000 );
727
        return a;
728
#endif
729
    }
730
    return a;
731
}
732

    
733
/*----------------------------------------------------------------------------
734
| Returns the result of converting the quadruple-precision floating-point NaN
735
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
736
| exception is raised.
737
*----------------------------------------------------------------------------*/
738

    
739
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
740
{
741
    commonNaNT z;
742

    
743
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
744
    z.sign = a.high>>63;
745
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
746
    return z;
747
}
748

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

    
754
static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
755
{
756
    float128 z;
757

    
758
    if ( STATUS(default_nan_mode) ) {
759
        z.low = float128_default_nan_low;
760
        z.high = float128_default_nan_high;
761
        return z;
762
    }
763

    
764
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
765
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
766
    return z;
767
}
768

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

    
775
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
776
{
777
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
778
    flag aIsLargerSignificand;
779

    
780
    aIsQuietNaN = float128_is_quiet_nan( a );
781
    aIsSignalingNaN = float128_is_signaling_nan( a );
782
    bIsQuietNaN = float128_is_quiet_nan( b );
783
    bIsSignalingNaN = float128_is_signaling_nan( b );
784

    
785
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
786

    
787
    if ( STATUS(default_nan_mode) ) {
788
        a.low = float128_default_nan_low;
789
        a.high = float128_default_nan_high;
790
        return a;
791
    }
792

    
793
    if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
794
        aIsLargerSignificand = 0;
795
    } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
796
        aIsLargerSignificand = 1;
797
    } else {
798
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
799
    }
800

    
801
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
802
                aIsLargerSignificand)) {
803
        return float128_maybe_silence_nan(b);
804
    } else {
805
        return float128_maybe_silence_nan(a);
806
    }
807
}
808

    
809
#endif