Statistics
| Branch: | Revision:

root / fpu / softfloat-specialize.h @ 3bf7e40a

History | View | Annotate | Download (36.5 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
#if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
39
#define SNAN_BIT_IS_ONE                1
40
#else
41
#define SNAN_BIT_IS_ONE                0
42
#endif
43

    
44
/*----------------------------------------------------------------------------
45
| The pattern for a default generated half-precision NaN.
46
*----------------------------------------------------------------------------*/
47
#if defined(TARGET_ARM)
48
const float16 float16_default_nan = const_float16(0x7E00);
49
#elif SNAN_BIT_IS_ONE
50
const float16 float16_default_nan = const_float16(0x7DFF);
51
#else
52
const float16 float16_default_nan = const_float16(0xFE00);
53
#endif
54

    
55
/*----------------------------------------------------------------------------
56
| The pattern for a default generated single-precision NaN.
57
*----------------------------------------------------------------------------*/
58
#if defined(TARGET_SPARC)
59
const float32 float32_default_nan = const_float32(0x7FFFFFFF);
60
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
61
const float32 float32_default_nan = const_float32(0x7FC00000);
62
#elif SNAN_BIT_IS_ONE
63
const float32 float32_default_nan = const_float32(0x7FBFFFFF);
64
#else
65
const float32 float32_default_nan = const_float32(0xFFC00000);
66
#endif
67

    
68
/*----------------------------------------------------------------------------
69
| The pattern for a default generated double-precision NaN.
70
*----------------------------------------------------------------------------*/
71
#if defined(TARGET_SPARC)
72
const float64 float64_default_nan = const_float64(LIT64( 0x7FFFFFFFFFFFFFFF ));
73
#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
74
const float64 float64_default_nan = const_float64(LIT64( 0x7FF8000000000000 ));
75
#elif SNAN_BIT_IS_ONE
76
const float64 float64_default_nan = const_float64(LIT64( 0x7FF7FFFFFFFFFFFF ));
77
#else
78
const float64 float64_default_nan = const_float64(LIT64( 0xFFF8000000000000 ));
79
#endif
80

    
81
/*----------------------------------------------------------------------------
82
| The pattern for a default generated extended double-precision NaN.
83
*----------------------------------------------------------------------------*/
84
#if SNAN_BIT_IS_ONE
85
#define floatx80_default_nan_high 0x7FFF
86
#define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
87
#else
88
#define floatx80_default_nan_high 0xFFFF
89
#define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
90
#endif
91

    
92
const floatx80 floatx80_default_nan
93
    = make_floatx80_init(floatx80_default_nan_high, floatx80_default_nan_low);
94

    
95
/*----------------------------------------------------------------------------
96
| The pattern for a default generated quadruple-precision NaN.  The `high' and
97
| `low' values hold the most- and least-significant bits, respectively.
98
*----------------------------------------------------------------------------*/
99
#if SNAN_BIT_IS_ONE
100
#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
101
#define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
102
#else
103
#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
104
#define float128_default_nan_low  LIT64( 0x0000000000000000 )
105
#endif
106

    
107
const float128 float128_default_nan
108
    = make_float128_init(float128_default_nan_high, float128_default_nan_low);
109

    
110
/*----------------------------------------------------------------------------
111
| Raises the exceptions specified by `flags'.  Floating-point traps can be
112
| defined here if desired.  It is currently not possible for such a trap
113
| to substitute a result value.  If traps are not implemented, this routine
114
| should be simply `float_exception_flags |= flags;'.
115
*----------------------------------------------------------------------------*/
116

    
117
void float_raise( int8 flags STATUS_PARAM )
118
{
119
    STATUS(float_exception_flags) |= flags;
120
}
121

    
122
/*----------------------------------------------------------------------------
123
| Internal canonical NaN format.
124
*----------------------------------------------------------------------------*/
125
typedef struct {
126
    flag sign;
127
    uint64_t high, low;
128
} commonNaNT;
129

    
130
/*----------------------------------------------------------------------------
131
| Returns 1 if the half-precision floating-point value `a' is a quiet
132
| NaN; otherwise returns 0.
133
*----------------------------------------------------------------------------*/
134

    
135
int float16_is_quiet_nan(float16 a_)
136
{
137
    uint16_t a = float16_val(a_);
138
#if SNAN_BIT_IS_ONE
139
    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
140
#else
141
    return ((a & ~0x8000) >= 0x7c80);
142
#endif
143
}
144

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

    
150
int float16_is_signaling_nan(float16 a_)
151
{
152
    uint16_t a = float16_val(a_);
153
#if SNAN_BIT_IS_ONE
154
    return ((a & ~0x8000) >= 0x7c80);
155
#else
156
    return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
157
#endif
158
}
159

    
160
/*----------------------------------------------------------------------------
161
| Returns a quiet NaN if the half-precision floating point value `a' is a
162
| signaling NaN; otherwise returns `a'.
163
*----------------------------------------------------------------------------*/
164
float16 float16_maybe_silence_nan(float16 a_)
165
{
166
    if (float16_is_signaling_nan(a_)) {
167
#if SNAN_BIT_IS_ONE
168
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
169
        return float16_default_nan;
170
#  else
171
#    error Rules for silencing a signaling NaN are target-specific
172
#  endif
173
#else
174
        uint16_t a = float16_val(a_);
175
        a |= (1 << 9);
176
        return make_float16(a);
177
#endif
178
    }
179
    return a_;
180
}
181

    
182
/*----------------------------------------------------------------------------
183
| Returns the result of converting the half-precision floating-point NaN
184
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
185
| exception is raised.
186
*----------------------------------------------------------------------------*/
187

    
188
static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
189
{
190
    commonNaNT z;
191

    
192
    if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
193
    z.sign = float16_val(a) >> 15;
194
    z.low = 0;
195
    z.high = ((uint64_t) float16_val(a))<<54;
196
    return z;
197
}
198

    
199
/*----------------------------------------------------------------------------
200
| Returns the result of converting the canonical NaN `a' to the half-
201
| precision floating-point format.
202
*----------------------------------------------------------------------------*/
203

    
204
static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
205
{
206
    uint16_t mantissa = a.high>>54;
207

    
208
    if (STATUS(default_nan_mode)) {
209
        return float16_default_nan;
210
    }
211

    
212
    if (mantissa) {
213
        return make_float16(((((uint16_t) a.sign) << 15)
214
                             | (0x1F << 10) | mantissa));
215
    } else {
216
        return float16_default_nan;
217
    }
218
}
219

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

    
225
int float32_is_quiet_nan( float32 a_ )
226
{
227
    uint32_t a = float32_val(a_);
228
#if SNAN_BIT_IS_ONE
229
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
230
#else
231
    return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
232
#endif
233
}
234

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

    
240
int float32_is_signaling_nan( float32 a_ )
241
{
242
    uint32_t a = float32_val(a_);
243
#if SNAN_BIT_IS_ONE
244
    return ( 0xFF800000 <= (uint32_t) ( a<<1 ) );
245
#else
246
    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
247
#endif
248
}
249

    
250
/*----------------------------------------------------------------------------
251
| Returns a quiet NaN if the single-precision floating point value `a' is a
252
| signaling NaN; otherwise returns `a'.
253
*----------------------------------------------------------------------------*/
254

    
255
float32 float32_maybe_silence_nan( float32 a_ )
256
{
257
    if (float32_is_signaling_nan(a_)) {
258
#if SNAN_BIT_IS_ONE
259
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
260
        return float32_default_nan;
261
#  else
262
#    error Rules for silencing a signaling NaN are target-specific
263
#  endif
264
#else
265
        uint32_t a = float32_val(a_);
266
        a |= (1 << 22);
267
        return make_float32(a);
268
#endif
269
    }
270
    return a_;
271
}
272

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

    
279
static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
280
{
281
    commonNaNT z;
282

    
283
    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
284
    z.sign = float32_val(a)>>31;
285
    z.low = 0;
286
    z.high = ( (uint64_t) float32_val(a) )<<41;
287
    return z;
288
}
289

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

    
295
static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
296
{
297
    uint32_t mantissa = a.high>>41;
298

    
299
    if ( STATUS(default_nan_mode) ) {
300
        return float32_default_nan;
301
    }
302

    
303
    if ( mantissa )
304
        return make_float32(
305
            ( ( (uint32_t) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
306
    else
307
        return float32_default_nan;
308
}
309

    
310
/*----------------------------------------------------------------------------
311
| Select which NaN to propagate for a two-input operation.
312
| IEEE754 doesn't specify all the details of this, so the
313
| algorithm is target-specific.
314
| The routine is passed various bits of information about the
315
| two NaNs and should return 0 to select NaN a and 1 for NaN b.
316
| Note that signalling NaNs are always squashed to quiet NaNs
317
| by the caller, by calling floatXX_maybe_silence_nan() before
318
| returning them.
319
|
320
| aIsLargerSignificand is only valid if both a and b are NaNs
321
| of some kind, and is true if a has the larger significand,
322
| or if both a and b have the same significand but a is
323
| positive but b is negative. It is only needed for the x87
324
| tie-break rule.
325
*----------------------------------------------------------------------------*/
326

    
327
#if defined(TARGET_ARM)
328
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
329
                    flag aIsLargerSignificand)
330
{
331
    /* ARM mandated NaN propagation rules: take the first of:
332
     *  1. A if it is signaling
333
     *  2. B if it is signaling
334
     *  3. A (quiet)
335
     *  4. B (quiet)
336
     * A signaling NaN is always quietened before returning it.
337
     */
338
    if (aIsSNaN) {
339
        return 0;
340
    } else if (bIsSNaN) {
341
        return 1;
342
    } else if (aIsQNaN) {
343
        return 0;
344
    } else {
345
        return 1;
346
    }
347
}
348
#elif defined(TARGET_MIPS)
349
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
350
                    flag aIsLargerSignificand)
351
{
352
    /* According to MIPS specifications, if one of the two operands is
353
     * a sNaN, a new qNaN has to be generated. This is done in
354
     * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
355
     * says: "When possible, this QNaN result is one of the operand QNaN
356
     * values." In practice it seems that most implementations choose
357
     * the first operand if both operands are qNaN. In short this gives
358
     * the following rules:
359
     *  1. A if it is signaling
360
     *  2. B if it is signaling
361
     *  3. A (quiet)
362
     *  4. B (quiet)
363
     * A signaling NaN is always silenced before returning it.
364
     */
365
    if (aIsSNaN) {
366
        return 0;
367
    } else if (bIsSNaN) {
368
        return 1;
369
    } else if (aIsQNaN) {
370
        return 0;
371
    } else {
372
        return 1;
373
    }
374
}
375
#elif defined(TARGET_PPC)
376
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
377
                   flag aIsLargerSignificand)
378
{
379
    /* PowerPC propagation rules:
380
     *  1. A if it sNaN or qNaN
381
     *  2. B if it sNaN or qNaN
382
     * A signaling NaN is always silenced before returning it.
383
     */
384
    if (aIsSNaN || aIsQNaN) {
385
        return 0;
386
    } else {
387
        return 1;
388
    }
389
}
390
#else
391
static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
392
                    flag aIsLargerSignificand)
393
{
394
    /* This implements x87 NaN propagation rules:
395
     * SNaN + QNaN => return the QNaN
396
     * two SNaNs => return the one with the larger significand, silenced
397
     * two QNaNs => return the one with the larger significand
398
     * SNaN and a non-NaN => return the SNaN, silenced
399
     * QNaN and a non-NaN => return the QNaN
400
     *
401
     * If we get down to comparing significands and they are the same,
402
     * return the NaN with the positive sign bit (if any).
403
     */
404
    if (aIsSNaN) {
405
        if (bIsSNaN) {
406
            return aIsLargerSignificand ? 0 : 1;
407
        }
408
        return bIsQNaN ? 1 : 0;
409
    }
410
    else if (aIsQNaN) {
411
        if (bIsSNaN || !bIsQNaN)
412
            return 0;
413
        else {
414
            return aIsLargerSignificand ? 0 : 1;
415
        }
416
    } else {
417
        return 1;
418
    }
419
}
420
#endif
421

    
422
/*----------------------------------------------------------------------------
423
| Select which NaN to propagate for a three-input operation.
424
| For the moment we assume that no CPU needs the 'larger significand'
425
| information.
426
| Return values : 0 : a; 1 : b; 2 : c; 3 : default-NaN
427
*----------------------------------------------------------------------------*/
428
#if defined(TARGET_ARM)
429
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
430
                         flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
431
{
432
    /* For ARM, the (inf,zero,qnan) case sets InvalidOp and returns
433
     * the default NaN
434
     */
435
    if (infzero && cIsQNaN) {
436
        float_raise(float_flag_invalid STATUS_VAR);
437
        return 3;
438
    }
439

    
440
    /* This looks different from the ARM ARM pseudocode, because the ARM ARM
441
     * puts the operands to a fused mac operation (a*b)+c in the order c,a,b.
442
     */
443
    if (cIsSNaN) {
444
        return 2;
445
    } else if (aIsSNaN) {
446
        return 0;
447
    } else if (bIsSNaN) {
448
        return 1;
449
    } else if (cIsQNaN) {
450
        return 2;
451
    } else if (aIsQNaN) {
452
        return 0;
453
    } else {
454
        return 1;
455
    }
456
}
457
#elif defined(TARGET_PPC)
458
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
459
                         flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
460
{
461
    /* For PPC, the (inf,zero,qnan) case sets InvalidOp, but we prefer
462
     * to return an input NaN if we have one (ie c) rather than generating
463
     * a default NaN
464
     */
465
    if (infzero) {
466
        float_raise(float_flag_invalid STATUS_VAR);
467
        return 2;
468
    }
469

    
470
    /* If fRA is a NaN return it; otherwise if fRB is a NaN return it;
471
     * otherwise return fRC. Note that muladd on PPC is (fRA * fRC) + frB
472
     */
473
    if (aIsSNaN || aIsQNaN) {
474
        return 0;
475
    } else if (cIsSNaN || cIsQNaN) {
476
        return 2;
477
    } else {
478
        return 1;
479
    }
480
}
481
#else
482
/* A default implementation: prefer a to b to c.
483
 * This is unlikely to actually match any real implementation.
484
 */
485
static int pickNaNMulAdd(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
486
                         flag cIsQNaN, flag cIsSNaN, flag infzero STATUS_PARAM)
487
{
488
    if (aIsSNaN || aIsQNaN) {
489
        return 0;
490
    } else if (bIsSNaN || bIsQNaN) {
491
        return 1;
492
    } else {
493
        return 2;
494
    }
495
}
496
#endif
497

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

    
504
static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
505
{
506
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
507
    flag aIsLargerSignificand;
508
    uint32_t av, bv;
509

    
510
    aIsQuietNaN = float32_is_quiet_nan( a );
511
    aIsSignalingNaN = float32_is_signaling_nan( a );
512
    bIsQuietNaN = float32_is_quiet_nan( b );
513
    bIsSignalingNaN = float32_is_signaling_nan( b );
514
    av = float32_val(a);
515
    bv = float32_val(b);
516

    
517
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
518

    
519
    if ( STATUS(default_nan_mode) )
520
        return float32_default_nan;
521

    
522
    if ((uint32_t)(av<<1) < (uint32_t)(bv<<1)) {
523
        aIsLargerSignificand = 0;
524
    } else if ((uint32_t)(bv<<1) < (uint32_t)(av<<1)) {
525
        aIsLargerSignificand = 1;
526
    } else {
527
        aIsLargerSignificand = (av < bv) ? 1 : 0;
528
    }
529

    
530
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
531
                aIsLargerSignificand)) {
532
        return float32_maybe_silence_nan(b);
533
    } else {
534
        return float32_maybe_silence_nan(a);
535
    }
536
}
537

    
538
/*----------------------------------------------------------------------------
539
| Takes three single-precision floating-point values `a', `b' and `c', one of
540
| which is a NaN, and returns the appropriate NaN result.  If any of  `a',
541
| `b' or `c' is a signaling NaN, the invalid exception is raised.
542
| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
543
| obviously c is a NaN, and whether to propagate c or some other NaN is
544
| implementation defined).
545
*----------------------------------------------------------------------------*/
546

    
547
static float32 propagateFloat32MulAddNaN(float32 a, float32 b,
548
                                         float32 c, flag infzero STATUS_PARAM)
549
{
550
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
551
        cIsQuietNaN, cIsSignalingNaN;
552
    int which;
553

    
554
    aIsQuietNaN = float32_is_quiet_nan(a);
555
    aIsSignalingNaN = float32_is_signaling_nan(a);
556
    bIsQuietNaN = float32_is_quiet_nan(b);
557
    bIsSignalingNaN = float32_is_signaling_nan(b);
558
    cIsQuietNaN = float32_is_quiet_nan(c);
559
    cIsSignalingNaN = float32_is_signaling_nan(c);
560

    
561
    if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
562
        float_raise(float_flag_invalid STATUS_VAR);
563
    }
564

    
565
    which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
566
                          bIsQuietNaN, bIsSignalingNaN,
567
                          cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR);
568

    
569
    if (STATUS(default_nan_mode)) {
570
        /* Note that this check is after pickNaNMulAdd so that function
571
         * has an opportunity to set the Invalid flag.
572
         */
573
        return float32_default_nan;
574
    }
575

    
576
    switch (which) {
577
    case 0:
578
        return float32_maybe_silence_nan(a);
579
    case 1:
580
        return float32_maybe_silence_nan(b);
581
    case 2:
582
        return float32_maybe_silence_nan(c);
583
    case 3:
584
    default:
585
        return float32_default_nan;
586
    }
587
}
588

    
589
/*----------------------------------------------------------------------------
590
| Returns 1 if the double-precision floating-point value `a' is a quiet
591
| NaN; otherwise returns 0.
592
*----------------------------------------------------------------------------*/
593

    
594
int float64_is_quiet_nan( float64 a_ )
595
{
596
    uint64_t a = float64_val(a_);
597
#if SNAN_BIT_IS_ONE
598
    return
599
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
600
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
601
#else
602
    return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
603
#endif
604
}
605

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

    
611
int float64_is_signaling_nan( float64 a_ )
612
{
613
    uint64_t a = float64_val(a_);
614
#if SNAN_BIT_IS_ONE
615
    return ( LIT64( 0xFFF0000000000000 ) <= (uint64_t) ( a<<1 ) );
616
#else
617
    return
618
           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
619
        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
620
#endif
621
}
622

    
623
/*----------------------------------------------------------------------------
624
| Returns a quiet NaN if the double-precision floating point value `a' is a
625
| signaling NaN; otherwise returns `a'.
626
*----------------------------------------------------------------------------*/
627

    
628
float64 float64_maybe_silence_nan( float64 a_ )
629
{
630
    if (float64_is_signaling_nan(a_)) {
631
#if SNAN_BIT_IS_ONE
632
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
633
        return float64_default_nan;
634
#  else
635
#    error Rules for silencing a signaling NaN are target-specific
636
#  endif
637
#else
638
        uint64_t a = float64_val(a_);
639
        a |= LIT64( 0x0008000000000000 );
640
        return make_float64(a);
641
#endif
642
    }
643
    return a_;
644
}
645

    
646
/*----------------------------------------------------------------------------
647
| Returns the result of converting the double-precision floating-point NaN
648
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
649
| exception is raised.
650
*----------------------------------------------------------------------------*/
651

    
652
static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
653
{
654
    commonNaNT z;
655

    
656
    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
657
    z.sign = float64_val(a)>>63;
658
    z.low = 0;
659
    z.high = float64_val(a)<<12;
660
    return z;
661
}
662

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

    
668
static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
669
{
670
    uint64_t mantissa = a.high>>12;
671

    
672
    if ( STATUS(default_nan_mode) ) {
673
        return float64_default_nan;
674
    }
675

    
676
    if ( mantissa )
677
        return make_float64(
678
              ( ( (uint64_t) a.sign )<<63 )
679
            | LIT64( 0x7FF0000000000000 )
680
            | ( a.high>>12 ));
681
    else
682
        return float64_default_nan;
683
}
684

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

    
691
static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
692
{
693
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
694
    flag aIsLargerSignificand;
695
    uint64_t av, bv;
696

    
697
    aIsQuietNaN = float64_is_quiet_nan( a );
698
    aIsSignalingNaN = float64_is_signaling_nan( a );
699
    bIsQuietNaN = float64_is_quiet_nan( b );
700
    bIsSignalingNaN = float64_is_signaling_nan( b );
701
    av = float64_val(a);
702
    bv = float64_val(b);
703

    
704
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
705

    
706
    if ( STATUS(default_nan_mode) )
707
        return float64_default_nan;
708

    
709
    if ((uint64_t)(av<<1) < (uint64_t)(bv<<1)) {
710
        aIsLargerSignificand = 0;
711
    } else if ((uint64_t)(bv<<1) < (uint64_t)(av<<1)) {
712
        aIsLargerSignificand = 1;
713
    } else {
714
        aIsLargerSignificand = (av < bv) ? 1 : 0;
715
    }
716

    
717
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
718
                aIsLargerSignificand)) {
719
        return float64_maybe_silence_nan(b);
720
    } else {
721
        return float64_maybe_silence_nan(a);
722
    }
723
}
724

    
725
/*----------------------------------------------------------------------------
726
| Takes three double-precision floating-point values `a', `b' and `c', one of
727
| which is a NaN, and returns the appropriate NaN result.  If any of  `a',
728
| `b' or `c' is a signaling NaN, the invalid exception is raised.
729
| The input infzero indicates whether a*b was 0*inf or inf*0 (in which case
730
| obviously c is a NaN, and whether to propagate c or some other NaN is
731
| implementation defined).
732
*----------------------------------------------------------------------------*/
733

    
734
static float64 propagateFloat64MulAddNaN(float64 a, float64 b,
735
                                         float64 c, flag infzero STATUS_PARAM)
736
{
737
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
738
        cIsQuietNaN, cIsSignalingNaN;
739
    int which;
740

    
741
    aIsQuietNaN = float64_is_quiet_nan(a);
742
    aIsSignalingNaN = float64_is_signaling_nan(a);
743
    bIsQuietNaN = float64_is_quiet_nan(b);
744
    bIsSignalingNaN = float64_is_signaling_nan(b);
745
    cIsQuietNaN = float64_is_quiet_nan(c);
746
    cIsSignalingNaN = float64_is_signaling_nan(c);
747

    
748
    if (aIsSignalingNaN | bIsSignalingNaN | cIsSignalingNaN) {
749
        float_raise(float_flag_invalid STATUS_VAR);
750
    }
751

    
752
    which = pickNaNMulAdd(aIsQuietNaN, aIsSignalingNaN,
753
                          bIsQuietNaN, bIsSignalingNaN,
754
                          cIsQuietNaN, cIsSignalingNaN, infzero STATUS_VAR);
755

    
756
    if (STATUS(default_nan_mode)) {
757
        /* Note that this check is after pickNaNMulAdd so that function
758
         * has an opportunity to set the Invalid flag.
759
         */
760
        return float64_default_nan;
761
    }
762

    
763
    switch (which) {
764
    case 0:
765
        return float64_maybe_silence_nan(a);
766
    case 1:
767
        return float64_maybe_silence_nan(b);
768
    case 2:
769
        return float64_maybe_silence_nan(c);
770
    case 3:
771
    default:
772
        return float64_default_nan;
773
    }
774
}
775

    
776
/*----------------------------------------------------------------------------
777
| Returns 1 if the extended double-precision floating-point value `a' is a
778
| quiet NaN; otherwise returns 0. This slightly differs from the same
779
| function for other types as floatx80 has an explicit bit.
780
*----------------------------------------------------------------------------*/
781

    
782
int floatx80_is_quiet_nan( floatx80 a )
783
{
784
#if SNAN_BIT_IS_ONE
785
    uint64_t aLow;
786

    
787
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
788
    return
789
           ( ( a.high & 0x7FFF ) == 0x7FFF )
790
        && (uint64_t) ( aLow<<1 )
791
        && ( a.low == aLow );
792
#else
793
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
794
        && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
795
#endif
796
}
797

    
798
/*----------------------------------------------------------------------------
799
| Returns 1 if the extended double-precision floating-point value `a' is a
800
| signaling NaN; otherwise returns 0. This slightly differs from the same
801
| function for other types as floatx80 has an explicit bit.
802
*----------------------------------------------------------------------------*/
803

    
804
int floatx80_is_signaling_nan( floatx80 a )
805
{
806
#if SNAN_BIT_IS_ONE
807
    return ( ( a.high & 0x7FFF ) == 0x7FFF )
808
        && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
809
#else
810
    uint64_t aLow;
811

    
812
    aLow = a.low & ~ LIT64( 0x4000000000000000 );
813
    return
814
           ( ( a.high & 0x7FFF ) == 0x7FFF )
815
        && (uint64_t) ( aLow<<1 )
816
        && ( a.low == aLow );
817
#endif
818
}
819

    
820
/*----------------------------------------------------------------------------
821
| Returns a quiet NaN if the extended double-precision floating point value
822
| `a' is a signaling NaN; otherwise returns `a'.
823
*----------------------------------------------------------------------------*/
824

    
825
floatx80 floatx80_maybe_silence_nan( floatx80 a )
826
{
827
    if (floatx80_is_signaling_nan(a)) {
828
#if SNAN_BIT_IS_ONE
829
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
830
        a.low = floatx80_default_nan_low;
831
        a.high = floatx80_default_nan_high;
832
#  else
833
#    error Rules for silencing a signaling NaN are target-specific
834
#  endif
835
#else
836
        a.low |= LIT64( 0xC000000000000000 );
837
        return a;
838
#endif
839
    }
840
    return a;
841
}
842

    
843
/*----------------------------------------------------------------------------
844
| Returns the result of converting the extended double-precision floating-
845
| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
846
| invalid exception is raised.
847
*----------------------------------------------------------------------------*/
848

    
849
static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
850
{
851
    commonNaNT z;
852

    
853
    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
854
    if ( a.low >> 63 ) {
855
        z.sign = a.high >> 15;
856
        z.low = 0;
857
        z.high = a.low << 1;
858
    } else {
859
        z.sign = floatx80_default_nan_high >> 15;
860
        z.low = 0;
861
        z.high = floatx80_default_nan_low << 1;
862
    }
863
    return z;
864
}
865

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

    
871
static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
872
{
873
    floatx80 z;
874

    
875
    if ( STATUS(default_nan_mode) ) {
876
        z.low = floatx80_default_nan_low;
877
        z.high = floatx80_default_nan_high;
878
        return z;
879
    }
880

    
881
    if (a.high >> 1) {
882
        z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
883
        z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
884
    } else {
885
        z.low = floatx80_default_nan_low;
886
        z.high = floatx80_default_nan_high;
887
    }
888

    
889
    return z;
890
}
891

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

    
898
static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
899
{
900
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
901
    flag aIsLargerSignificand;
902

    
903
    aIsQuietNaN = floatx80_is_quiet_nan( a );
904
    aIsSignalingNaN = floatx80_is_signaling_nan( a );
905
    bIsQuietNaN = floatx80_is_quiet_nan( b );
906
    bIsSignalingNaN = floatx80_is_signaling_nan( b );
907

    
908
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
909

    
910
    if ( STATUS(default_nan_mode) ) {
911
        a.low = floatx80_default_nan_low;
912
        a.high = floatx80_default_nan_high;
913
        return a;
914
    }
915

    
916
    if (a.low < b.low) {
917
        aIsLargerSignificand = 0;
918
    } else if (b.low < a.low) {
919
        aIsLargerSignificand = 1;
920
    } else {
921
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
922
    }
923

    
924
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
925
                aIsLargerSignificand)) {
926
        return floatx80_maybe_silence_nan(b);
927
    } else {
928
        return floatx80_maybe_silence_nan(a);
929
    }
930
}
931

    
932
/*----------------------------------------------------------------------------
933
| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
934
| NaN; otherwise returns 0.
935
*----------------------------------------------------------------------------*/
936

    
937
int float128_is_quiet_nan( float128 a )
938
{
939
#if SNAN_BIT_IS_ONE
940
    return
941
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
942
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
943
#else
944
    return
945
           ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
946
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
947
#endif
948
}
949

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

    
955
int float128_is_signaling_nan( float128 a )
956
{
957
#if SNAN_BIT_IS_ONE
958
    return
959
           ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
960
        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
961
#else
962
    return
963
           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
964
        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
965
#endif
966
}
967

    
968
/*----------------------------------------------------------------------------
969
| Returns a quiet NaN if the quadruple-precision floating point value `a' is
970
| a signaling NaN; otherwise returns `a'.
971
*----------------------------------------------------------------------------*/
972

    
973
float128 float128_maybe_silence_nan( float128 a )
974
{
975
    if (float128_is_signaling_nan(a)) {
976
#if SNAN_BIT_IS_ONE
977
#  if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
978
        a.low = float128_default_nan_low;
979
        a.high = float128_default_nan_high;
980
#  else
981
#    error Rules for silencing a signaling NaN are target-specific
982
#  endif
983
#else
984
        a.high |= LIT64( 0x0000800000000000 );
985
        return a;
986
#endif
987
    }
988
    return a;
989
}
990

    
991
/*----------------------------------------------------------------------------
992
| Returns the result of converting the quadruple-precision floating-point NaN
993
| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
994
| exception is raised.
995
*----------------------------------------------------------------------------*/
996

    
997
static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
998
{
999
    commonNaNT z;
1000

    
1001
    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
1002
    z.sign = a.high>>63;
1003
    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
1004
    return z;
1005
}
1006

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

    
1012
static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
1013
{
1014
    float128 z;
1015

    
1016
    if ( STATUS(default_nan_mode) ) {
1017
        z.low = float128_default_nan_low;
1018
        z.high = float128_default_nan_high;
1019
        return z;
1020
    }
1021

    
1022
    shift128Right( a.high, a.low, 16, &z.high, &z.low );
1023
    z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
1024
    return z;
1025
}
1026

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

    
1033
static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
1034
{
1035
    flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
1036
    flag aIsLargerSignificand;
1037

    
1038
    aIsQuietNaN = float128_is_quiet_nan( a );
1039
    aIsSignalingNaN = float128_is_signaling_nan( a );
1040
    bIsQuietNaN = float128_is_quiet_nan( b );
1041
    bIsSignalingNaN = float128_is_signaling_nan( b );
1042

    
1043
    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
1044

    
1045
    if ( STATUS(default_nan_mode) ) {
1046
        a.low = float128_default_nan_low;
1047
        a.high = float128_default_nan_high;
1048
        return a;
1049
    }
1050

    
1051
    if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
1052
        aIsLargerSignificand = 0;
1053
    } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
1054
        aIsLargerSignificand = 1;
1055
    } else {
1056
        aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
1057
    }
1058

    
1059
    if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
1060
                aIsLargerSignificand)) {
1061
        return float128_maybe_silence_nan(b);
1062
    } else {
1063
        return float128_maybe_silence_nan(a);
1064
    }
1065
}
1066