Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ de4af5f7

History | View | Annotate | Download (26 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
#if defined(TARGET_MIPS) || defined(TARGET_SH4)
34
#define SNAN_BIT_IS_ONE                1
35
#else
36
#define SNAN_BIT_IS_ONE                0
37
#endif
38

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

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

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

    
59
/*----------------------------------------------------------------------------
60
| The pattern for a default generated single-precision NaN.
61
*----------------------------------------------------------------------------*/
62
#if defined(TARGET_SPARC)
63
#define float32_default_nan make_float32(0x7FFFFFFF)
64
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
65
#define float32_default_nan make_float32(0x7FC00000)
66
#elif SNAN_BIT_IS_ONE
67
#define float32_default_nan make_float32(0x7FBFFFFF)
68
#else
69
#define float32_default_nan make_float32(0xFFC00000)
70
#endif
71

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

    
77
int float32_is_quiet_nan( float32 a_ )
78
{
79
    uint32_t a = float32_val(a_);
80
#if SNAN_BIT_IS_ONE
81
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
82
#else
83
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
84
#endif
85
}
86

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

    
92
int float32_is_signaling_nan( float32 a_ )
93
{
94
    uint32_t a = float32_val(a_);
95
#if SNAN_BIT_IS_ONE
96
    return ( 0xFF800000 <= (bits32) ( a<<1 ) );
97
#else
98
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
99
#endif
100
}
101

    
102
/*----------------------------------------------------------------------------
103
| Returns a quiet NaN if the single-precision floating point value `a' is a
104
| signaling NaN; otherwise returns `a'.
105
*----------------------------------------------------------------------------*/
106

    
107
float32 float32_maybe_silence_nan( float32 a_ )
108
{
109
    if (float32_is_signaling_nan(a_)) {
110
#if SNAN_BIT_IS_ONE
111
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
112
        return float32_default_nan;
113
#  else
114
#    error Rules for silencing a signaling NaN are target-specific
115
#  endif
116
#else
117
        bits32 a = float32_val(a_);
118
        a |= (1 << 22);
119
        return make_float32(a);
120
#endif
121
    }
122
    return a_;
123
}
124

    
125
/*----------------------------------------------------------------------------
126
| Returns the result of converting the single-precision floating-point NaN
127
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
128
| exception is raised.
129
*----------------------------------------------------------------------------*/
130

    
131
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
132
{
133
    commonNaNT z;
134

    
135
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
136
    z.sign = float32_val(a)>>31;
137
    z.low = 0;
138
    z.high = ( (bits64) float32_val(a) )<<41;
139
    return z;
140
}
141

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

    
147
static float32 commonNaNToFloat32( commonNaNT a )
148
{
149
    bits32 mantissa = a.high>>41;
150
    if ( mantissa )
151
        return make_float32(
152
            ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
153
    else
154
        return float32_default_nan;
155
}
156

    
157
/*----------------------------------------------------------------------------
158
| Select which NaN to propagate for a two-input operation.
159
| IEEE754 doesn't specify all the details of this, so the
160
| algorithm is target-specific.
161
| The routine is passed various bits of information about the
162
| two NaNs and should return 0 to select NaN a and 1 for NaN b.
163
| Note that signalling NaNs are always squashed to quiet NaNs
164
| by the caller, by calling floatXX_maybe_silence_nan() before
165
| returning them.
166
|
167
| aIsLargerSignificand is only valid if both a and b are NaNs
168
| of some kind, and is true if a has the larger significand,
169
| or if both a and b have the same significand but a is
170
| positive but b is negative. It is only needed for the x87
171
| tie-break rule.
172
*----------------------------------------------------------------------------*/
173

    
174
#if defined(TARGET_ARM)
175
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
176
                    flag aIsLargerSignificand)
177
{
178
    /* ARM mandated NaN propagation rules: take the first of:
179
     *  1. A if it is signaling
180
     *  2. B if it is signaling
181
     *  3. A (quiet)
182
     *  4. B (quiet)
183
     * A signaling NaN is always quietened before returning it.
184
     */
185
    if (aIsSNaN) {
186
        return 0;
187
    } else if (bIsSNaN) {
188
        return 1;
189
    } else if (aIsQNaN) {
190
        return 0;
191
    } else {
192
        return 1;
193
    }
194
}
195
#elif defined(TARGET_MIPS)
196
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
197
                    flag aIsLargerSignificand)
198
{
199
    /* According to MIPS specifications, if one of the two operands is
200
     * a sNaN, a new qNaN has to be generated. This is done in
201
     * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
202
     * says: "When possible, this QNaN result is one of the operand QNaN
203
     * values." In practice it seems that most implementations choose
204
     * the first operand if both operands are qNaN. In short this gives
205
     * the following rules:
206
     *  1. A if it is signaling
207
     *  2. B if it is signaling
208
     *  3. A (quiet)
209
     *  4. B (quiet)
210
     * A signaling NaN is always silenced before returning it.
211
     */
212
    if (aIsSNaN) {
213
        return 0;
214
    } else if (bIsSNaN) {
215
        return 1;
216
    } else if (aIsQNaN) {
217
        return 0;
218
    } else {
219
        return 1;
220
    }
221
}
222
#elif defined(TARGET_PPC)
223
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
224
                   flag aIsLargerSignificand)
225
{
226
    /* PowerPC propagation rules:
227
     *  1. A if it sNaN or qNaN
228
     *  2. B if it sNaN or qNaN
229
     * A signaling NaN is always silenced before returning it.
230
     */
231
    if (aIsSNaN || aIsQNaN) {
232
        return 0;
233
    } else {
234
        return 1;
235
    }
236
}
237
#else
238
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
239
                    flag aIsLargerSignificand)
240
{
241
    /* This implements x87 NaN propagation rules:
242
     * SNaN + QNaN => return the QNaN
243
     * two SNaNs => return the one with the larger significand, silenced
244
     * two QNaNs => return the one with the larger significand
245
     * SNaN and a non-NaN => return the SNaN, silenced
246
     * QNaN and a non-NaN => return the QNaN
247
     *
248
     * If we get down to comparing significands and they are the same,
249
     * return the NaN with the positive sign bit (if any).
250
     */
251
    if (aIsSNaN) {
252
        if (bIsSNaN) {
253
            return aIsLargerSignificand ? 0 : 1;
254
        }
255
        return bIsQNaN ? 1 : 0;
256
    }
257
    else if (aIsQNaN) {
258
        if (bIsSNaN || !bIsQNaN)
259
            return 0;
260
        else {
261
            return aIsLargerSignificand ? 0 : 1;
262
        }
263
    } else {
264
        return 1;
265
    }
266
}
267
#endif
268

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

    
275
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
276
{
277
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
278
    flag aIsLargerSignificand;
279
    bits32 av, bv;
280

    
281
    aIsQuietNaN = float32_is_quiet_nan( a );
282
    aIsSignalingNaN = float32_is_signaling_nan( a );
283
    bIsQuietNaN = float32_is_quiet_nan( b );
284
    bIsSignalingNaN = float32_is_signaling_nan( b );
285
    av = float32_val(a);
286
    bv = float32_val(b);
287

    
288
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
289

    
290
    if ( STATUS(default_nan_mode) )
291
        return float32_default_nan;
292

    
293
    if ((bits32)(av<<1) < (bits32)(bv<<1)) {
294
        aIsLargerSignificand = 0;
295
    } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
296
        aIsLargerSignificand = 1;
297
    } else {
298
        aIsLargerSignificand = (av < bv) ? 1 : 0;
299
    }
300

    
301
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
302
                aIsLargerSignificand)) {
303
        return float32_maybe_silence_nan(b);
304
    } else {
305
        return float32_maybe_silence_nan(a);
306
    }
307
}
308

    
309
/*----------------------------------------------------------------------------
310
| The pattern for a default generated double-precision NaN.
311
*----------------------------------------------------------------------------*/
312
#if defined(TARGET_SPARC)
313
#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
314
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
315
#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
316
#elif SNAN_BIT_IS_ONE
317
#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
318
#else
319
#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
320
#endif
321

    
322
/*----------------------------------------------------------------------------
323
| Returns 1 if the double-precision floating-point value `a' is a quiet
324
| NaN; otherwise returns 0.
325
*----------------------------------------------------------------------------*/
326

    
327
int float64_is_quiet_nan( float64 a_ )
328
{
329
    bits64 a = float64_val(a_);
330
#if SNAN_BIT_IS_ONE
331
    return
332
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
333
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
334
#else
335
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
336
#endif
337
}
338

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

    
344
int float64_is_signaling_nan( float64 a_ )
345
{
346
    bits64 a = float64_val(a_);
347
#if SNAN_BIT_IS_ONE
348
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
349
#else
350
    return
351
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
352
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
353
#endif
354
}
355

    
356
/*----------------------------------------------------------------------------
357
| Returns a quiet NaN if the double-precision floating point value `a' is a
358
| signaling NaN; otherwise returns `a'.
359
*----------------------------------------------------------------------------*/
360

    
361
float64 float64_maybe_silence_nan( float64 a_ )
362
{
363
    if (float64_is_signaling_nan(a_)) {
364
#if SNAN_BIT_IS_ONE
365
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
366
        return float64_default_nan;
367
#  else
368
#    error Rules for silencing a signaling NaN are target-specific
369
#  endif
370
#else
371
        bits64 a = float64_val(a_);
372
        a |= LIT64( 0x0008000000000000 );
373
        return make_float64(a);
374
#endif
375
    }
376
    return a_;
377
}
378

    
379
/*----------------------------------------------------------------------------
380
| Returns the result of converting the double-precision floating-point NaN
381
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
382
| exception is raised.
383
*----------------------------------------------------------------------------*/
384

    
385
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
386
{
387
    commonNaNT z;
388

    
389
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
390
    z.sign = float64_val(a)>>63;
391
    z.low = 0;
392
    z.high = float64_val(a)<<12;
393
    return z;
394
}
395

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

    
401
static float64 commonNaNToFloat64( commonNaNT a )
402
{
403
    bits64 mantissa = a.high>>12;
404

    
405
    if ( mantissa )
406
        return make_float64(
407
              ( ( (bits64) a.sign )<<63 )
408
            | LIT64( 0x7FF0000000000000 )
409
            | ( a.high>>12 ));
410
    else
411
        return float64_default_nan;
412
}
413

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

    
420
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
421
{
422
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
423
    flag aIsLargerSignificand;
424
    bits64 av, bv;
425

    
426
    aIsQuietNaN = float64_is_quiet_nan( a );
427
    aIsSignalingNaN = float64_is_signaling_nan( a );
428
    bIsQuietNaN = float64_is_quiet_nan( b );
429
    bIsSignalingNaN = float64_is_signaling_nan( b );
430
    av = float64_val(a);
431
    bv = float64_val(b);
432

    
433
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
434

    
435
    if ( STATUS(default_nan_mode) )
436
        return float64_default_nan;
437

    
438
    if ((bits64)(av<<1) < (bits64)(bv<<1)) {
439
        aIsLargerSignificand = 0;
440
    } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
441
        aIsLargerSignificand = 1;
442
    } else {
443
        aIsLargerSignificand = (av < bv) ? 1 : 0;
444
    }
445

    
446
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
447
                aIsLargerSignificand)) {
448
        return float64_maybe_silence_nan(b);
449
    } else {
450
        return float64_maybe_silence_nan(a);
451
    }
452
}
453

    
454
#ifdef FLOATX80
455

    
456
/*----------------------------------------------------------------------------
457
| The pattern for a default generated extended double-precision NaN.  The
458
| `high' and `low' values hold the most- and least-significant bits,
459
| respectively.
460
*----------------------------------------------------------------------------*/
461
#if SNAN_BIT_IS_ONE
462
#define floatx80_default_nan_high 0x7FFF
463
#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
464
#else
465
#define floatx80_default_nan_high 0xFFFF
466
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
467
#endif
468

    
469
/*----------------------------------------------------------------------------
470
| Returns 1 if the extended double-precision floating-point value `a' is a
471
| quiet NaN; otherwise returns 0. This slightly differs from the same
472
| function for other types as floatx80 has an explicit bit.
473
*----------------------------------------------------------------------------*/
474

    
475
int floatx80_is_quiet_nan( floatx80 a )
476
{
477
#if SNAN_BIT_IS_ONE
478
    bits64 aLow;
479

    
480
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
481
    return
482
           ( ( a.high & 0x7FFF ) == 0x7FFF )
483
        && (bits64) ( aLow<<1 )
484
        && ( a.low == aLow );
485
#else
486
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
487
        && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
488
#endif
489
}
490

    
491
/*----------------------------------------------------------------------------
492
| Returns 1 if the extended double-precision floating-point value `a' is a
493
| signaling NaN; otherwise returns 0. This slightly differs from the same
494
| function for other types as floatx80 has an explicit bit.
495
*----------------------------------------------------------------------------*/
496

    
497
int floatx80_is_signaling_nan( floatx80 a )
498
{
499
#if SNAN_BIT_IS_ONE
500
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
501
        && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
502
#else
503
    bits64 aLow;
504

    
505
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
506
    return
507
           ( ( a.high & 0x7FFF ) == 0x7FFF )
508
        && (bits64) ( aLow<<1 )
509
        && ( a.low == aLow );
510
#endif
511
}
512

    
513
/*----------------------------------------------------------------------------
514
| Returns a quiet NaN if the extended double-precision floating point value
515
| `a' is a signaling NaN; otherwise returns `a'.
516
*----------------------------------------------------------------------------*/
517

    
518
floatx80 floatx80_maybe_silence_nan( floatx80 a )
519
{
520
    if (floatx80_is_signaling_nan(a)) {
521
#if SNAN_BIT_IS_ONE
522
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
523
        a.low = floatx80_default_nan_low;
524
        a.high = floatx80_default_nan_high;
525
#  else
526
#    error Rules for silencing a signaling NaN are target-specific
527
#  endif
528
#else
529
        a.low |= LIT64( 0xC000000000000000 );
530
        return a;
531
#endif
532
    }
533
    return a;
534
}
535

    
536
/*----------------------------------------------------------------------------
537
| Returns the result of converting the extended double-precision floating-
538
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
539
| invalid exception is raised.
540
*----------------------------------------------------------------------------*/
541

    
542
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
543
{
544
    commonNaNT z;
545

    
546
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
547
    z.sign = a.high>>15;
548
    z.low = 0;
549
    z.high = a.low;
550
    return z;
551
}
552

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

    
558
static floatx80 commonNaNToFloatx80( commonNaNT a )
559
{
560
    floatx80 z;
561

    
562
    if (a.high)
563
        z.low = a.high;
564
    else
565
        z.low = floatx80_default_nan_low;
566
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
567
    return z;
568
}
569

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

    
576
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
577
{
578
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
579
    flag aIsLargerSignificand;
580

    
581
    aIsQuietNaN = floatx80_is_quiet_nan( a );
582
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
583
    bIsQuietNaN = floatx80_is_quiet_nan( b );
584
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
585

    
586
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
587

    
588
    if ( STATUS(default_nan_mode) ) {
589
        a.low = floatx80_default_nan_low;
590
        a.high = floatx80_default_nan_high;
591
        return a;
592
    }
593

    
594
    if (a.low < b.low) {
595
        aIsLargerSignificand = 0;
596
    } else if (b.low < a.low) {
597
        aIsLargerSignificand = 1;
598
    } else {
599
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
600
    }
601

    
602
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
603
                aIsLargerSignificand)) {
604
        return floatx80_maybe_silence_nan(b);
605
    } else {
606
        return floatx80_maybe_silence_nan(a);
607
    }
608
}
609

    
610
#endif
611

    
612
#ifdef FLOAT128
613

    
614
/*----------------------------------------------------------------------------
615
| The pattern for a default generated quadruple-precision NaN.  The `high' and
616
| `low' values hold the most- and least-significant bits, respectively.
617
*----------------------------------------------------------------------------*/
618
#if SNAN_BIT_IS_ONE
619
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
620
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
621
#else
622
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
623
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
624
#endif
625

    
626
/*----------------------------------------------------------------------------
627
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
628
| NaN; otherwise returns 0.
629
*----------------------------------------------------------------------------*/
630

    
631
int float128_is_quiet_nan( float128 a )
632
{
633
#if SNAN_BIT_IS_ONE
634
    return
635
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
636
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
637
#else
638
    return
639
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
640
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
641
#endif
642
}
643

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

    
649
int float128_is_signaling_nan( float128 a )
650
{
651
#if SNAN_BIT_IS_ONE
652
    return
653
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
654
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
655
#else
656
    return
657
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
658
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
659
#endif
660
}
661

    
662
/*----------------------------------------------------------------------------
663
| Returns a quiet NaN if the quadruple-precision floating point value `a' is
664
| a signaling NaN; otherwise returns `a'.
665
*----------------------------------------------------------------------------*/
666

    
667
float128 float128_maybe_silence_nan( float128 a )
668
{
669
    if (float128_is_signaling_nan(a)) {
670
#if SNAN_BIT_IS_ONE
671
#  if defined(TARGET_MIPS) || defined(TARGET_SH4)
672
        a.low = float128_default_nan_low;
673
        a.high = float128_default_nan_high;
674
#  else
675
#    error Rules for silencing a signaling NaN are target-specific
676
#  endif
677
#else
678
        a.high |= LIT64( 0x0000800000000000 );
679
        return a;
680
#endif
681
    }
682
    return a;
683
}
684

    
685
/*----------------------------------------------------------------------------
686
| Returns the result of converting the quadruple-precision floating-point NaN
687
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
688
| exception is raised.
689
*----------------------------------------------------------------------------*/
690

    
691
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
692
{
693
    commonNaNT z;
694

    
695
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
696
    z.sign = a.high>>63;
697
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
698
    return z;
699
}
700

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

    
706
static float128 commonNaNToFloat128( commonNaNT a )
707
{
708
    float128 z;
709

    
710
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
711
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
712
    return z;
713
}
714

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

    
721
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
722
{
723
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
724
    flag aIsLargerSignificand;
725

    
726
    aIsQuietNaN = float128_is_quiet_nan( a );
727
    aIsSignalingNaN = float128_is_signaling_nan( a );
728
    bIsQuietNaN = float128_is_quiet_nan( b );
729
    bIsSignalingNaN = float128_is_signaling_nan( b );
730

    
731
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
732

    
733
    if ( STATUS(default_nan_mode) ) {
734
        a.low = float128_default_nan_low;
735
        a.high = float128_default_nan_high;
736
        return a;
737
    }
738

    
739
    if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
740
        aIsLargerSignificand = 0;
741
    } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
742
        aIsLargerSignificand = 1;
743
    } else {
744
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
745
    }
746

    
747
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
748
                aIsLargerSignificand)) {
749
        return float128_maybe_silence_nan(b);
750
    } else {
751
        return float128_maybe_silence_nan(a);
752
    }
753
}
754

    
755
#endif