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