]> Git Repo - qemu.git/blob - fpu/softfloat-specialize.h
target-mips: Implement correct NaN propagation rules
[qemu.git] / fpu / softfloat-specialize.h
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)
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 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)
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 #else
223 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
224                     flag aIsLargerSignificand)
225 {
226     /* This implements x87 NaN propagation rules:
227      * SNaN + QNaN => return the QNaN
228      * two SNaNs => return the one with the larger significand, silenced
229      * two QNaNs => return the one with the larger significand
230      * SNaN and a non-NaN => return the SNaN, silenced
231      * QNaN and a non-NaN => return the QNaN
232      *
233      * If we get down to comparing significands and they are the same,
234      * return the NaN with the positive sign bit (if any).
235      */
236     if (aIsSNaN) {
237         if (bIsSNaN) {
238             return aIsLargerSignificand ? 0 : 1;
239         }
240         return bIsQNaN ? 1 : 0;
241     }
242     else if (aIsQNaN) {
243         if (bIsSNaN || !bIsQNaN)
244             return 0;
245         else {
246             return aIsLargerSignificand ? 0 : 1;
247         }
248     } else {
249         return 1;
250     }
251 }
252 #endif
253
254 /*----------------------------------------------------------------------------
255 | Takes two single-precision floating-point values `a' and `b', one of which
256 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
257 | signaling NaN, the invalid exception is raised.
258 *----------------------------------------------------------------------------*/
259
260 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
261 {
262     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
263     flag aIsLargerSignificand;
264     bits32 av, bv;
265
266     if ( STATUS(default_nan_mode) )
267         return float32_default_nan;
268
269     aIsQuietNaN = float32_is_quiet_nan( a );
270     aIsSignalingNaN = float32_is_signaling_nan( a );
271     bIsQuietNaN = float32_is_quiet_nan( b );
272     bIsSignalingNaN = float32_is_signaling_nan( b );
273     av = float32_val(a);
274     bv = float32_val(b);
275
276     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
277
278     if ((bits32)(av<<1) < (bits32)(bv<<1)) {
279         aIsLargerSignificand = 0;
280     } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
281         aIsLargerSignificand = 1;
282     } else {
283         aIsLargerSignificand = (av < bv) ? 1 : 0;
284     }
285
286     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
287                 aIsLargerSignificand)) {
288         return float32_maybe_silence_nan(b);
289     } else {
290         return float32_maybe_silence_nan(a);
291     }
292 }
293
294 /*----------------------------------------------------------------------------
295 | The pattern for a default generated double-precision NaN.
296 *----------------------------------------------------------------------------*/
297 #if defined(TARGET_SPARC)
298 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
299 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
300 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
301 #elif SNAN_BIT_IS_ONE
302 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
303 #else
304 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
305 #endif
306
307 /*----------------------------------------------------------------------------
308 | Returns 1 if the double-precision floating-point value `a' is a quiet
309 | NaN; otherwise returns 0.
310 *----------------------------------------------------------------------------*/
311
312 int float64_is_quiet_nan( float64 a_ )
313 {
314     bits64 a = float64_val(a_);
315 #if SNAN_BIT_IS_ONE
316     return
317            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
318         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
319 #else
320     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
321 #endif
322 }
323
324 /*----------------------------------------------------------------------------
325 | Returns 1 if the double-precision floating-point value `a' is a signaling
326 | NaN; otherwise returns 0.
327 *----------------------------------------------------------------------------*/
328
329 int float64_is_signaling_nan( float64 a_ )
330 {
331     bits64 a = float64_val(a_);
332 #if SNAN_BIT_IS_ONE
333     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
334 #else
335     return
336            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
337         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
338 #endif
339 }
340
341 /*----------------------------------------------------------------------------
342 | Returns a quiet NaN if the double-precision floating point value `a' is a
343 | signaling NaN; otherwise returns `a'.
344 *----------------------------------------------------------------------------*/
345
346 float64 float64_maybe_silence_nan( float64 a_ )
347 {
348     if (float64_is_signaling_nan(a_)) {
349 #if SNAN_BIT_IS_ONE
350 #  if defined(TARGET_MIPS)
351         return float64_default_nan;
352 #  else
353 #    error Rules for silencing a signaling NaN are target-specific
354 #  endif
355 #else
356         bits64 a = float64_val(a_);
357         a |= LIT64( 0x0008000000000000 );
358         return make_float64(a);
359 #endif
360     }
361     return a_;
362 }
363
364 /*----------------------------------------------------------------------------
365 | Returns the result of converting the double-precision floating-point NaN
366 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
367 | exception is raised.
368 *----------------------------------------------------------------------------*/
369
370 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
371 {
372     commonNaNT z;
373
374     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
375     z.sign = float64_val(a)>>63;
376     z.low = 0;
377     z.high = float64_val(a)<<12;
378     return z;
379 }
380
381 /*----------------------------------------------------------------------------
382 | Returns the result of converting the canonical NaN `a' to the double-
383 | precision floating-point format.
384 *----------------------------------------------------------------------------*/
385
386 static float64 commonNaNToFloat64( commonNaNT a )
387 {
388     bits64 mantissa = a.high>>12;
389
390     if ( mantissa )
391         return make_float64(
392               ( ( (bits64) a.sign )<<63 )
393             | LIT64( 0x7FF0000000000000 )
394             | ( a.high>>12 ));
395     else
396         return float64_default_nan;
397 }
398
399 /*----------------------------------------------------------------------------
400 | Takes two double-precision floating-point values `a' and `b', one of which
401 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
402 | signaling NaN, the invalid exception is raised.
403 *----------------------------------------------------------------------------*/
404
405 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
406 {
407     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
408     flag aIsLargerSignificand;
409     bits64 av, bv;
410
411     if ( STATUS(default_nan_mode) )
412         return float64_default_nan;
413
414     aIsQuietNaN = float64_is_quiet_nan( a );
415     aIsSignalingNaN = float64_is_signaling_nan( a );
416     bIsQuietNaN = float64_is_quiet_nan( b );
417     bIsSignalingNaN = float64_is_signaling_nan( b );
418     av = float64_val(a);
419     bv = float64_val(b);
420
421     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
422
423     if ((bits64)(av<<1) < (bits64)(bv<<1)) {
424         aIsLargerSignificand = 0;
425     } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
426         aIsLargerSignificand = 1;
427     } else {
428         aIsLargerSignificand = (av < bv) ? 1 : 0;
429     }
430
431     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
432                 aIsLargerSignificand)) {
433         return float64_maybe_silence_nan(b);
434     } else {
435         return float64_maybe_silence_nan(a);
436     }
437 }
438
439 #ifdef FLOATX80
440
441 /*----------------------------------------------------------------------------
442 | The pattern for a default generated extended double-precision NaN.  The
443 | `high' and `low' values hold the most- and least-significant bits,
444 | respectively.
445 *----------------------------------------------------------------------------*/
446 #if SNAN_BIT_IS_ONE
447 #define floatx80_default_nan_high 0x7FFF
448 #define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
449 #else
450 #define floatx80_default_nan_high 0xFFFF
451 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
452 #endif
453
454 /*----------------------------------------------------------------------------
455 | Returns 1 if the extended double-precision floating-point value `a' is a
456 | quiet NaN; otherwise returns 0.
457 *----------------------------------------------------------------------------*/
458
459 int floatx80_is_quiet_nan( floatx80 a )
460 {
461 #if SNAN_BIT_IS_ONE
462     bits64 aLow;
463
464     aLow = a.low & ~ LIT64( 0x4000000000000000 );
465     return
466            ( ( a.high & 0x7FFF ) == 0x7FFF )
467         && (bits64) ( aLow<<1 )
468         && ( a.low == aLow );
469 #else
470     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
471 #endif
472 }
473
474 /*----------------------------------------------------------------------------
475 | Returns 1 if the extended double-precision floating-point value `a' is a
476 | signaling NaN; otherwise returns 0.
477 *----------------------------------------------------------------------------*/
478
479 int floatx80_is_signaling_nan( floatx80 a )
480 {
481 #if SNAN_BIT_IS_ONE
482     return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
483 #else
484     bits64 aLow;
485
486     aLow = a.low & ~ LIT64( 0x4000000000000000 );
487     return
488            ( ( a.high & 0x7FFF ) == 0x7FFF )
489         && (bits64) ( aLow<<1 )
490         && ( a.low == aLow );
491 #endif
492 }
493
494 /*----------------------------------------------------------------------------
495 | Returns a quiet NaN if the extended double-precision floating point value
496 | `a' is a signaling NaN; otherwise returns `a'.
497 *----------------------------------------------------------------------------*/
498
499 floatx80 floatx80_maybe_silence_nan( floatx80 a )
500 {
501     if (floatx80_is_signaling_nan(a)) {
502 #if SNAN_BIT_IS_ONE
503 #  if defined(TARGET_MIPS)
504         a.low = floatx80_default_nan_low;
505         a.high = floatx80_default_nan_high;
506 #  else
507 #    error Rules for silencing a signaling NaN are target-specific
508 #  endif
509 #else
510         a.low |= LIT64( 0xC000000000000000 );
511         return a;
512 #endif
513     }
514     return a;
515 }
516
517 /*----------------------------------------------------------------------------
518 | Returns the result of converting the extended double-precision floating-
519 | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
520 | invalid exception is raised.
521 *----------------------------------------------------------------------------*/
522
523 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
524 {
525     commonNaNT z;
526
527     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
528     z.sign = a.high>>15;
529     z.low = 0;
530     z.high = a.low;
531     return z;
532 }
533
534 /*----------------------------------------------------------------------------
535 | Returns the result of converting the canonical NaN `a' to the extended
536 | double-precision floating-point format.
537 *----------------------------------------------------------------------------*/
538
539 static floatx80 commonNaNToFloatx80( commonNaNT a )
540 {
541     floatx80 z;
542
543     if (a.high)
544         z.low = a.high;
545     else
546         z.low = floatx80_default_nan_low;
547     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
548     return z;
549 }
550
551 /*----------------------------------------------------------------------------
552 | Takes two extended double-precision floating-point values `a' and `b', one
553 | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
554 | `b' is a signaling NaN, the invalid exception is raised.
555 *----------------------------------------------------------------------------*/
556
557 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
558 {
559     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
560     flag aIsLargerSignificand;
561
562     if ( STATUS(default_nan_mode) ) {
563         a.low = floatx80_default_nan_low;
564         a.high = floatx80_default_nan_high;
565         return a;
566     }
567
568     aIsQuietNaN = floatx80_is_quiet_nan( a );
569     aIsSignalingNaN = floatx80_is_signaling_nan( a );
570     bIsQuietNaN = floatx80_is_quiet_nan( b );
571     bIsSignalingNaN = floatx80_is_signaling_nan( b );
572
573     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
574
575     if (a.low < b.low) {
576         aIsLargerSignificand = 0;
577     } else if (b.low < a.low) {
578         aIsLargerSignificand = 1;
579     } else {
580         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
581     }
582
583     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
584                 aIsLargerSignificand)) {
585         return floatx80_maybe_silence_nan(b);
586     } else {
587         return floatx80_maybe_silence_nan(a);
588     }
589 }
590
591 #endif
592
593 #ifdef FLOAT128
594
595 /*----------------------------------------------------------------------------
596 | The pattern for a default generated quadruple-precision NaN.  The `high' and
597 | `low' values hold the most- and least-significant bits, respectively.
598 *----------------------------------------------------------------------------*/
599 #if SNAN_BIT_IS_ONE
600 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
601 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
602 #else
603 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
604 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
605 #endif
606
607 /*----------------------------------------------------------------------------
608 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
609 | NaN; otherwise returns 0.
610 *----------------------------------------------------------------------------*/
611
612 int float128_is_quiet_nan( float128 a )
613 {
614 #if SNAN_BIT_IS_ONE
615     return
616            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
617         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
618 #else
619     return
620            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
621         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
622 #endif
623 }
624
625 /*----------------------------------------------------------------------------
626 | Returns 1 if the quadruple-precision floating-point value `a' is a
627 | signaling NaN; otherwise returns 0.
628 *----------------------------------------------------------------------------*/
629
630 int float128_is_signaling_nan( float128 a )
631 {
632 #if SNAN_BIT_IS_ONE
633     return
634            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
635         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
636 #else
637     return
638            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
639         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
640 #endif
641 }
642
643 /*----------------------------------------------------------------------------
644 | Returns a quiet NaN if the quadruple-precision floating point value `a' is
645 | a signaling NaN; otherwise returns `a'.
646 *----------------------------------------------------------------------------*/
647
648 float128 float128_maybe_silence_nan( float128 a )
649 {
650     if (float128_is_signaling_nan(a)) {
651 #if SNAN_BIT_IS_ONE
652 #  if defined(TARGET_MIPS)
653         a.low = float128_default_nan_low;
654         a.high = float128_default_nan_high;
655 #  else
656 #    error Rules for silencing a signaling NaN are target-specific
657 #  endif
658 #else
659         a.high |= LIT64( 0x0000800000000000 );
660         return a;
661 #endif
662     }
663     return a;
664 }
665
666 /*----------------------------------------------------------------------------
667 | Returns the result of converting the quadruple-precision floating-point NaN
668 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
669 | exception is raised.
670 *----------------------------------------------------------------------------*/
671
672 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
673 {
674     commonNaNT z;
675
676     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
677     z.sign = a.high>>63;
678     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
679     return z;
680 }
681
682 /*----------------------------------------------------------------------------
683 | Returns the result of converting the canonical NaN `a' to the quadruple-
684 | precision floating-point format.
685 *----------------------------------------------------------------------------*/
686
687 static float128 commonNaNToFloat128( commonNaNT a )
688 {
689     float128 z;
690
691     shift128Right( a.high, a.low, 16, &z.high, &z.low );
692     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
693     return z;
694 }
695
696 /*----------------------------------------------------------------------------
697 | Takes two quadruple-precision floating-point values `a' and `b', one of
698 | which is a NaN, and returns the appropriate NaN result.  If either `a' or
699 | `b' is a signaling NaN, the invalid exception is raised.
700 *----------------------------------------------------------------------------*/
701
702 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
703 {
704     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
705     flag aIsLargerSignificand;
706
707     if ( STATUS(default_nan_mode) ) {
708         a.low = float128_default_nan_low;
709         a.high = float128_default_nan_high;
710         return a;
711     }
712
713     aIsQuietNaN = float128_is_quiet_nan( a );
714     aIsSignalingNaN = float128_is_signaling_nan( a );
715     bIsQuietNaN = float128_is_quiet_nan( b );
716     bIsSignalingNaN = float128_is_signaling_nan( b );
717
718     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
719
720     if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
721         aIsLargerSignificand = 0;
722     } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
723         aIsLargerSignificand = 1;
724     } else {
725         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
726     }
727
728     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
729                 aIsLargerSignificand)) {
730         return float128_maybe_silence_nan(b);
731     } else {
732         return float128_maybe_silence_nan(a);
733     }
734 }
735
736 #endif
This page took 0.064287 seconds and 4 git commands to generate.