Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ bb98fe42

History | View | Annotate | Download (27.1 kB)

1
/*
2
 * QEMU float support
3
 *
4
 * Derived from SoftFloat.
5
 */
6

    
7
/*============================================================================
8

9
This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
10
Arithmetic Package, Release 2b.
11

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

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

31
Derivative works are acceptable, even for commercial purposes, so long as
32
(1) the source code for the derivative work includes prominent notice that
33
the work is derivative, and (2) the source code includes prominent notice with
34
these four paragraphs for those parts of this code that are retained.
35

36
=============================================================================*/
37

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

    
45
void float_raise( int8 flags STATUS_PARAM )
46
{
47
    STATUS(float_exception_flags) |= flags;
48
}
49

    
50
/*----------------------------------------------------------------------------
51
| Internal canonical NaN format.
52
*----------------------------------------------------------------------------*/
53
typedef struct {
54
    flag sign;
55
    uint64_t high, low;
56
} commonNaNT;
57

    
58
/*----------------------------------------------------------------------------
59
| Returns 1 if the half-precision floating-point value `a' is a quiet
60
| NaN; otherwise returns 0.
61
*----------------------------------------------------------------------------*/
62

    
63
int float16_is_quiet_nan(float16 a_)
64
{
65
    uint16_t a = float16_val(a_);
66
#if SNAN_BIT_IS_ONE
67
    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
68
#else
69
    return ((a & ~0x8000) >= 0x7c80);
70
#endif
71
}
72

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

    
78
int float16_is_signaling_nan(float16 a_)
79
{
80
    uint16_t a = float16_val(a_);
81
#if SNAN_BIT_IS_ONE
82
    return ((a & ~0x8000) >= 0x7c80);
83
#else
84
    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
85
#endif
86
}
87

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

    
110
/*----------------------------------------------------------------------------
111
| Returns the result of converting the half-precision floating-point NaN
112
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
113
| exception is raised.
114
*----------------------------------------------------------------------------*/
115

    
116
static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
117
{
118
    commonNaNT z;
119

    
120
    if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
121
    z.sign = float16_val(a) >> 15;
122
    z.low = 0;
123
    z.high = ((uint64_t) float16_val(a))<<54;
124
    return z;
125
}
126

    
127
/*----------------------------------------------------------------------------
128
| Returns the result of converting the canonical NaN `a' to the half-
129
| precision floating-point format.
130
*----------------------------------------------------------------------------*/
131

    
132
static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
133
{
134
    uint16_t mantissa = a.high>>54;
135

    
136
    if (STATUS(default_nan_mode)) {
137
        return float16_default_nan;
138
    }
139

    
140
    if (mantissa) {
141
        return make_float16(((((uint16_t) a.sign) << 15)
142
                             | (0x1F << 10) | mantissa));
143
    } else {
144
        return float16_default_nan;
145
    }
146
}
147

    
148
/*----------------------------------------------------------------------------
149
| Returns 1 if the single-precision floating-point value `a' is a quiet
150
| NaN; otherwise returns 0.
151
*----------------------------------------------------------------------------*/
152

    
153
int float32_is_quiet_nan( float32 a_ )
154
{
155
    uint32_t a = float32_val(a_);
156
#if SNAN_BIT_IS_ONE
157
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
158
#else
159
    return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
160
#endif
161
}
162

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

    
168
int float32_is_signaling_nan( float32 a_ )
169
{
170
    uint32_t a = float32_val(a_);
171
#if SNAN_BIT_IS_ONE
172
    return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
173
#else
174
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
175
#endif
176
}
177

    
178
/*----------------------------------------------------------------------------
179
| Returns a quiet NaN if the single-precision floating point value `a' is a
180
| signaling NaN; otherwise returns `a'.
181
*----------------------------------------------------------------------------*/
182

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

    
201
/*----------------------------------------------------------------------------
202
| Returns the result of converting the single-precision floating-point NaN
203
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
204
| exception is raised.
205
*----------------------------------------------------------------------------*/
206

    
207
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
208
{
209
    commonNaNT z;
210

    
211
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
212
    z.sign = float32_val(a)>>31;
213
    z.low = 0;
214
    z.high = ( (uint64_t) float32_val(a) )<<41;
215
    return z;
216
}
217

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

    
223
static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
224
{
225
    uint32_t mantissa = a.high>>41;
226

    
227
    if ( STATUS(default_nan_mode) ) {
228
        return float32_default_nan;
229
    }
230

    
231
    if ( mantissa )
232
        return make_float32(
233
            ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
234
    else
235
        return float32_default_nan;
236
}
237

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

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

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

    
356
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
357
{
358
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
359
    flag aIsLargerSignificand;
360
    uint32_t av, bv;
361

    
362
    aIsQuietNaN = float32_is_quiet_nan( a );
363
    aIsSignalingNaN = float32_is_signaling_nan( a );
364
    bIsQuietNaN = float32_is_quiet_nan( b );
365
    bIsSignalingNaN = float32_is_signaling_nan( b );
366
    av = float32_val(a);
367
    bv = float32_val(b);
368

    
369
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
370

    
371
    if ( STATUS(default_nan_mode) )
372
        return float32_default_nan;
373

    
374
    if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) {
375
        aIsLargerSignificand = 0;
376
    } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) {
377
        aIsLargerSignificand = 1;
378
    } else {
379
        aIsLargerSignificand = (av < bv) ? 1 : 0;
380
    }
381

    
382
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
383
                aIsLargerSignificand)) {
384
        return float32_maybe_silence_nan(b);
385
    } else {
386
        return float32_maybe_silence_nan(a);
387
    }
388
}
389

    
390
/*----------------------------------------------------------------------------
391
| Returns 1 if the double-precision floating-point value `a' is a quiet
392
| NaN; otherwise returns 0.
393
*----------------------------------------------------------------------------*/
394

    
395
int float64_is_quiet_nan( float64 a_ )
396
{
397
    uint64_t a = float64_val(a_);
398
#if SNAN_BIT_IS_ONE
399
    return
400
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
401
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
402
#else
403
    return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
404
#endif
405
}
406

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

    
412
int float64_is_signaling_nan( float64 a_ )
413
{
414
    uint64_t a = float64_val(a_);
415
#if SNAN_BIT_IS_ONE
416
    return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
417
#else
418
    return
419
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
420
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
421
#endif
422
}
423

    
424
/*----------------------------------------------------------------------------
425
| Returns a quiet NaN if the double-precision floating point value `a' is a
426
| signaling NaN; otherwise returns `a'.
427
*----------------------------------------------------------------------------*/
428

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

    
447
/*----------------------------------------------------------------------------
448
| Returns the result of converting the double-precision floating-point NaN
449
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
450
| exception is raised.
451
*----------------------------------------------------------------------------*/
452

    
453
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
454
{
455
    commonNaNT z;
456

    
457
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
458
    z.sign = float64_val(a)>>63;
459
    z.low = 0;
460
    z.high = float64_val(a)<<12;
461
    return z;
462
}
463

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

    
469
static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
470
{
471
    uint64_t mantissa = a.high>>12;
472

    
473
    if ( STATUS(default_nan_mode) ) {
474
        return float64_default_nan;
475
    }
476

    
477
    if ( mantissa )
478
        return make_float64(
479
              ( ( (uint64_t) a.sign )<<63 )
480
            | LIT64( 0x7FF0000000000000 )
481
            | ( a.high>>12 ));
482
    else
483
        return float64_default_nan;
484
}
485

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

    
492
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
493
{
494
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
495
    flag aIsLargerSignificand;
496
    uint64_t av, bv;
497

    
498
    aIsQuietNaN = float64_is_quiet_nan( a );
499
    aIsSignalingNaN = float64_is_signaling_nan( a );
500
    bIsQuietNaN = float64_is_quiet_nan( b );
501
    bIsSignalingNaN = float64_is_signaling_nan( b );
502
    av = float64_val(a);
503
    bv = float64_val(b);
504

    
505
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
506

    
507
    if ( STATUS(default_nan_mode) )
508
        return float64_default_nan;
509

    
510
    if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) {
511
        aIsLargerSignificand = 0;
512
    } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) {
513
        aIsLargerSignificand = 1;
514
    } else {
515
        aIsLargerSignificand = (av < bv) ? 1 : 0;
516
    }
517

    
518
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
519
                aIsLargerSignificand)) {
520
        return float64_maybe_silence_nan(b);
521
    } else {
522
        return float64_maybe_silence_nan(a);
523
    }
524
}
525

    
526
#ifdef FLOATX80
527

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

    
534
int floatx80_is_quiet_nan( floatx80 a )
535
{
536
#if SNAN_BIT_IS_ONE
537
    uint64_t aLow;
538

    
539
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
540
    return
541
           ( ( a.high & 0x7FFF ) == 0x7FFF )
542
        && (uint64_t) ( aLow<<1 )
543
        && ( a.low == aLow );
544
#else
545
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
546
        && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
547
#endif
548
}
549

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

    
556
int floatx80_is_signaling_nan( floatx80 a )
557
{
558
#if SNAN_BIT_IS_ONE
559
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
560
        && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
561
#else
562
    uint64_t aLow;
563

    
564
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
565
    return
566
           ( ( a.high & 0x7FFF ) == 0x7FFF )
567
        && (uint64_t) ( aLow<<1 )
568
        && ( a.low == aLow );
569
#endif
570
}
571

    
572
/*----------------------------------------------------------------------------
573
| Returns a quiet NaN if the extended double-precision floating point value
574
| `a' is a signaling NaN; otherwise returns `a'.
575
*----------------------------------------------------------------------------*/
576

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

    
595
/*----------------------------------------------------------------------------
596
| Returns the result of converting the extended double-precision floating-
597
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
598
| invalid exception is raised.
599
*----------------------------------------------------------------------------*/
600

    
601
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
602
{
603
    commonNaNT z;
604

    
605
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
606
    z.sign = a.high>>15;
607
    z.low = 0;
608
    z.high = a.low;
609
    return z;
610
}
611

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

    
617
static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
618
{
619
    floatx80 z;
620

    
621
    if ( STATUS(default_nan_mode) ) {
622
        z.low = floatx80_default_nan_low;
623
        z.high = floatx80_default_nan_high;
624
        return z;
625
    }
626

    
627
    if (a.high)
628
        z.low = a.high;
629
    else
630
        z.low = floatx80_default_nan_low;
631
    z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
632
    return z;
633
}
634

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

    
641
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
642
{
643
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
644
    flag aIsLargerSignificand;
645

    
646
    aIsQuietNaN = floatx80_is_quiet_nan( a );
647
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
648
    bIsQuietNaN = floatx80_is_quiet_nan( b );
649
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
650

    
651
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
652

    
653
    if ( STATUS(default_nan_mode) ) {
654
        a.low = floatx80_default_nan_low;
655
        a.high = floatx80_default_nan_high;
656
        return a;
657
    }
658

    
659
    if (a.low < b.low) {
660
        aIsLargerSignificand = 0;
661
    } else if (b.low < a.low) {
662
        aIsLargerSignificand = 1;
663
    } else {
664
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
665
    }
666

    
667
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
668
                aIsLargerSignificand)) {
669
        return floatx80_maybe_silence_nan(b);
670
    } else {
671
        return floatx80_maybe_silence_nan(a);
672
    }
673
}
674

    
675
#endif
676

    
677
#ifdef FLOAT128
678

    
679
/*----------------------------------------------------------------------------
680
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
681
| NaN; otherwise returns 0.
682
*----------------------------------------------------------------------------*/
683

    
684
int float128_is_quiet_nan( float128 a )
685
{
686
#if SNAN_BIT_IS_ONE
687
    return
688
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
689
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
690
#else
691
    return
692
           ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
693
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
694
#endif
695
}
696

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

    
702
int float128_is_signaling_nan( float128 a )
703
{
704
#if SNAN_BIT_IS_ONE
705
    return
706
           ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
707
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
708
#else
709
    return
710
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
711
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
712
#endif
713
}
714

    
715
/*----------------------------------------------------------------------------
716
| Returns a quiet NaN if the quadruple-precision floating point value `a' is
717
| a signaling NaN; otherwise returns `a'.
718
*----------------------------------------------------------------------------*/
719

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

    
738
/*----------------------------------------------------------------------------
739
| Returns the result of converting the quadruple-precision floating-point NaN
740
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
741
| exception is raised.
742
*----------------------------------------------------------------------------*/
743

    
744
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
745
{
746
    commonNaNT z;
747

    
748
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
749
    z.sign = a.high>>63;
750
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
751
    return z;
752
}
753

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

    
759
static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
760
{
761
    float128 z;
762

    
763
    if ( STATUS(default_nan_mode) ) {
764
        z.low = float128_default_nan_low;
765
        z.high = float128_default_nan_high;
766
        return z;
767
    }
768

    
769
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
770
    z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
771
    return z;
772
}
773

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

    
780
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
781
{
782
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
783
    flag aIsLargerSignificand;
784

    
785
    aIsQuietNaN = float128_is_quiet_nan( a );
786
    aIsSignalingNaN = float128_is_signaling_nan( a );
787
    bIsQuietNaN = float128_is_quiet_nan( b );
788
    bIsSignalingNaN = float128_is_signaling_nan( b );
789

    
790
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
791

    
792
    if ( STATUS(default_nan_mode) ) {
793
        a.low = float128_default_nan_low;
794
        a.high = float128_default_nan_high;
795
        return a;
796
    }
797

    
798
    if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
799
        aIsLargerSignificand = 0;
800
    } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
801
        aIsLargerSignificand = 1;
802
    } else {
803
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
804
    }
805

    
806
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
807
                aIsLargerSignificand)) {
808
        return float128_maybe_silence_nan(b);
809
    } else {
810
        return float128_maybe_silence_nan(a);
811
    }
812
}
813

    
814
#endif