Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ 18569871

History | View | Annotate | Download (21.4 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_HPPA)
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_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
65
#define float32_default_nan make_float32(0x7FC00000)
66
#elif defined(TARGET_HPPA)
67
#define float32_default_nan make_float32(0x7FA00000)
68
#elif SNAN_BIT_IS_ONE
69
#define float32_default_nan make_float32(0x7FBFFFFF)
70
#else
71
#define float32_default_nan make_float32(0xFFC00000)
72
#endif
73

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

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

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

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

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

    
109
float32 float32_maybe_silence_nan( float32 a_ )
110
{
111
    if (float32_is_signaling_nan(a_)) {
112
        uint32_t a = float32_val(a_);
113
#if SNAN_BIT_IS_ONE
114
        a &= ~(1 << 22);
115
#else
116
        a |= (1 << 22);
117
#endif
118
        return make_float32(a);
119
    }
120
    return a_;
121
}
122

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

    
129
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
130
{
131
    commonNaNT z;
132

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

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

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

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

    
161
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
162
{
163
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
164
    bits32 av, bv, res;
165

    
166
    if ( STATUS(default_nan_mode) )
167
        return float32_default_nan;
168

    
169
    aIsNaN = float32_is_quiet_nan( a );
170
    aIsSignalingNaN = float32_is_signaling_nan( a );
171
    bIsNaN = float32_is_quiet_nan( b );
172
    bIsSignalingNaN = float32_is_signaling_nan( b );
173
    av = float32_val(a);
174
    bv = float32_val(b);
175
#if SNAN_BIT_IS_ONE
176
    av &= ~0x00400000;
177
    bv &= ~0x00400000;
178
#else
179
    av |= 0x00400000;
180
    bv |= 0x00400000;
181
#endif
182
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
183
    if ( aIsSignalingNaN ) {
184
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
185
        res = bIsNaN ? bv : av;
186
    }
187
    else if ( aIsNaN ) {
188
        if ( bIsSignalingNaN || ! bIsNaN )
189
            res = av;
190
        else {
191
 returnLargerSignificand:
192
            if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
193
                res = bv;
194
            else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
195
                res = av;
196
            else
197
                res = ( av < bv ) ? av : bv;
198
        }
199
    }
200
    else {
201
        res = bv;
202
    }
203
    return make_float32(res);
204
}
205

    
206
/*----------------------------------------------------------------------------
207
| The pattern for a default generated double-precision NaN.
208
*----------------------------------------------------------------------------*/
209
#if defined(TARGET_SPARC)
210
#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
211
#elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
212
#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
213
#elif defined(TARGET_HPPA)
214
#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
215
#elif SNAN_BIT_IS_ONE
216
#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
217
#else
218
#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
219
#endif
220

    
221
/*----------------------------------------------------------------------------
222
| Returns 1 if the double-precision floating-point value `a' is a quiet
223
| NaN; otherwise returns 0.
224
*----------------------------------------------------------------------------*/
225

    
226
int float64_is_quiet_nan( float64 a_ )
227
{
228
    bits64 a = float64_val(a_);
229
#if SNAN_BIT_IS_ONE
230
    return
231
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
232
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
233
#else
234
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
235
#endif
236
}
237

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

    
243
int float64_is_signaling_nan( float64 a_ )
244
{
245
    bits64 a = float64_val(a_);
246
#if SNAN_BIT_IS_ONE
247
    return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
248
#else
249
    return
250
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
251
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
252
#endif
253
}
254

    
255
/*----------------------------------------------------------------------------
256
| Returns a quiet NaN if the double-precision floating point value `a' is a
257
| signaling NaN; otherwise returns `a'.
258
*----------------------------------------------------------------------------*/
259

    
260
float64 float64_maybe_silence_nan( float64 a_ )
261
{
262
    if (float64_is_signaling_nan(a_)) {
263
        bits64 a = float64_val(a_);
264
#if SNAN_BIT_IS_ONE
265
        a &= ~LIT64( 0x0008000000000000 );
266
#else
267
        a |= LIT64( 0x0008000000000000 );
268
#endif
269
        return make_float64(a);
270
    }
271
    return a_;
272
}
273

    
274
/*----------------------------------------------------------------------------
275
| Returns the result of converting the double-precision floating-point NaN
276
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
277
| exception is raised.
278
*----------------------------------------------------------------------------*/
279

    
280
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
281
{
282
    commonNaNT z;
283

    
284
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
285
    z.sign = float64_val(a)>>63;
286
    z.low = 0;
287
    z.high = float64_val(a)<<12;
288
    return z;
289
}
290

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

    
296
static float64 commonNaNToFloat64( commonNaNT a )
297
{
298
    bits64 mantissa = a.high>>12;
299

    
300
    if ( mantissa )
301
        return make_float64(
302
              ( ( (bits64) a.sign )<<63 )
303
            | LIT64( 0x7FF0000000000000 )
304
            | ( a.high>>12 ));
305
    else
306
        return float64_default_nan;
307
}
308

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

    
315
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
316
{
317
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
318
    bits64 av, bv, res;
319

    
320
    if ( STATUS(default_nan_mode) )
321
        return float64_default_nan;
322

    
323
    aIsNaN = float64_is_quiet_nan( a );
324
    aIsSignalingNaN = float64_is_signaling_nan( a );
325
    bIsNaN = float64_is_quiet_nan( b );
326
    bIsSignalingNaN = float64_is_signaling_nan( b );
327
    av = float64_val(a);
328
    bv = float64_val(b);
329
#if SNAN_BIT_IS_ONE
330
    av &= ~LIT64( 0x0008000000000000 );
331
    bv &= ~LIT64( 0x0008000000000000 );
332
#else
333
    av |= LIT64( 0x0008000000000000 );
334
    bv |= LIT64( 0x0008000000000000 );
335
#endif
336
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
337
    if ( aIsSignalingNaN ) {
338
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
339
        res = bIsNaN ? bv : av;
340
    }
341
    else if ( aIsNaN ) {
342
        if ( bIsSignalingNaN || ! bIsNaN )
343
            res = av;
344
        else {
345
 returnLargerSignificand:
346
            if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
347
                res = bv;
348
            else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
349
                res = av;
350
            else
351
                res = ( av < bv ) ? av : bv;
352
        }
353
    }
354
    else {
355
        res = bv;
356
    }
357
    return make_float64(res);
358
}
359

    
360
#ifdef FLOATX80
361

    
362
/*----------------------------------------------------------------------------
363
| The pattern for a default generated extended double-precision NaN.  The
364
| `high' and `low' values hold the most- and least-significant bits,
365
| respectively.
366
*----------------------------------------------------------------------------*/
367
#if SNAN_BIT_IS_ONE
368
#define floatx80_default_nan_high 0x7FFF
369
#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
370
#else
371
#define floatx80_default_nan_high 0xFFFF
372
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
373
#endif
374

    
375
/*----------------------------------------------------------------------------
376
| Returns 1 if the extended double-precision floating-point value `a' is a
377
| quiet NaN; otherwise returns 0.
378
*----------------------------------------------------------------------------*/
379

    
380
int floatx80_is_quiet_nan( floatx80 a )
381
{
382
#if SNAN_BIT_IS_ONE
383
    bits64 aLow;
384

    
385
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
386
    return
387
           ( ( a.high & 0x7FFF ) == 0x7FFF )
388
        && (bits64) ( aLow<<1 )
389
        && ( a.low == aLow );
390
#else
391
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
392
#endif
393
}
394

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

    
400
int floatx80_is_signaling_nan( floatx80 a )
401
{
402
#if SNAN_BIT_IS_ONE
403
    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
404
#else
405
    bits64 aLow;
406

    
407
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
408
    return
409
           ( ( a.high & 0x7FFF ) == 0x7FFF )
410
        && (bits64) ( aLow<<1 )
411
        && ( a.low == aLow );
412
#endif
413
}
414

    
415
/*----------------------------------------------------------------------------
416
| Returns the result of converting the extended double-precision floating-
417
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
418
| invalid exception is raised.
419
*----------------------------------------------------------------------------*/
420

    
421
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
422
{
423
    commonNaNT z;
424

    
425
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
426
    z.sign = a.high>>15;
427
    z.low = 0;
428
    z.high = a.low;
429
    return z;
430
}
431

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

    
437
static floatx80 commonNaNToFloatx80( commonNaNT a )
438
{
439
    floatx80 z;
440

    
441
    if (a.high)
442
        z.low = a.high;
443
    else
444
        z.low = floatx80_default_nan_low;
445
    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
446
    return z;
447
}
448

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

    
455
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
456
{
457
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
458

    
459
    if ( STATUS(default_nan_mode) ) {
460
        a.low = floatx80_default_nan_low;
461
        a.high = floatx80_default_nan_high;
462
        return a;
463
    }
464

    
465
    aIsNaN = floatx80_is_quiet_nan( a );
466
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
467
    bIsNaN = floatx80_is_quiet_nan( b );
468
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
469
#if SNAN_BIT_IS_ONE
470
    a.low &= ~LIT64( 0xC000000000000000 );
471
    b.low &= ~LIT64( 0xC000000000000000 );
472
#else
473
    a.low |= LIT64( 0xC000000000000000 );
474
    b.low |= LIT64( 0xC000000000000000 );
475
#endif
476
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
477
    if ( aIsSignalingNaN ) {
478
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
479
        return bIsNaN ? b : a;
480
    }
481
    else if ( aIsNaN ) {
482
        if ( bIsSignalingNaN || ! bIsNaN ) return a;
483
 returnLargerSignificand:
484
        if ( a.low < b.low ) return b;
485
        if ( b.low < a.low ) return a;
486
        return ( a.high < b.high ) ? a : b;
487
    }
488
    else {
489
        return b;
490
    }
491
}
492

    
493
#endif
494

    
495
#ifdef FLOAT128
496

    
497
/*----------------------------------------------------------------------------
498
| The pattern for a default generated quadruple-precision NaN.  The `high' and
499
| `low' values hold the most- and least-significant bits, respectively.
500
*----------------------------------------------------------------------------*/
501
#if SNAN_BIT_IS_ONE
502
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
503
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
504
#else
505
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
506
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
507
#endif
508

    
509
/*----------------------------------------------------------------------------
510
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
511
| NaN; otherwise returns 0.
512
*----------------------------------------------------------------------------*/
513

    
514
int float128_is_quiet_nan( float128 a )
515
{
516
#if SNAN_BIT_IS_ONE
517
    return
518
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
519
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
520
#else
521
    return
522
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
523
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
524
#endif
525
}
526

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

    
532
int float128_is_signaling_nan( float128 a )
533
{
534
#if SNAN_BIT_IS_ONE
535
    return
536
           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
537
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
538
#else
539
    return
540
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
541
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
542
#endif
543
}
544

    
545
/*----------------------------------------------------------------------------
546
| Returns the result of converting the quadruple-precision floating-point NaN
547
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
548
| exception is raised.
549
*----------------------------------------------------------------------------*/
550

    
551
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
552
{
553
    commonNaNT z;
554

    
555
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
556
    z.sign = a.high>>63;
557
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
558
    return z;
559
}
560

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

    
566
static float128 commonNaNToFloat128( commonNaNT a )
567
{
568
    float128 z;
569

    
570
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
571
    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
572
    return z;
573
}
574

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

    
581
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
582
{
583
    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
584

    
585
    if ( STATUS(default_nan_mode) ) {
586
        a.low = float128_default_nan_low;
587
        a.high = float128_default_nan_high;
588
        return a;
589
    }
590

    
591
    aIsNaN = float128_is_quiet_nan( a );
592
    aIsSignalingNaN = float128_is_signaling_nan( a );
593
    bIsNaN = float128_is_quiet_nan( b );
594
    bIsSignalingNaN = float128_is_signaling_nan( b );
595
#if SNAN_BIT_IS_ONE
596
    a.high &= ~LIT64( 0x0000800000000000 );
597
    b.high &= ~LIT64( 0x0000800000000000 );
598
#else
599
    a.high |= LIT64( 0x0000800000000000 );
600
    b.high |= LIT64( 0x0000800000000000 );
601
#endif
602
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
603
    if ( aIsSignalingNaN ) {
604
        if ( bIsSignalingNaN ) goto returnLargerSignificand;
605
        return bIsNaN ? b : a;
606
    }
607
    else if ( aIsNaN ) {
608
        if ( bIsSignalingNaN || ! bIsNaN ) return a;
609
 returnLargerSignificand:
610
        if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
611
        if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
612
        return ( a.high < b.high ) ? a : b;
613
    }
614
    else {
615
        return b;
616
    }
617
}
618

    
619
#endif