]> Git Repo - qemu.git/blob - fpu/softfloat-specialize.h
softfloat: Fix single-to-half precision float conversions
[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) || defined(TARGET_SH4)
34 #define SNAN_BIT_IS_ONE         1
35 #else
36 #define SNAN_BIT_IS_ONE         0
37 #endif
38
39 /*----------------------------------------------------------------------------
40 | Raises the exceptions specified by `flags'.  Floating-point traps can be
41 | defined here if desired.  It is currently not possible for such a trap
42 | to substitute a result value.  If traps are not implemented, this routine
43 | should be simply `float_exception_flags |= flags;'.
44 *----------------------------------------------------------------------------*/
45
46 void float_raise( int8 flags STATUS_PARAM )
47 {
48     STATUS(float_exception_flags) |= flags;
49 }
50
51 /*----------------------------------------------------------------------------
52 | Internal canonical NaN format.
53 *----------------------------------------------------------------------------*/
54 typedef struct {
55     flag sign;
56     bits64 high, low;
57 } commonNaNT;
58
59 /*----------------------------------------------------------------------------
60 | The pattern for a default generated half-precision NaN.
61 *----------------------------------------------------------------------------*/
62 #if defined(TARGET_ARM)
63 #define float16_default_nan make_float16(0x7E00)
64 #elif SNAN_BIT_IS_ONE
65 #define float16_default_nan make_float16(0x7DFF)
66 #else
67 #define float16_default_nan make_float16(0xFE00)
68 #endif
69
70 /*----------------------------------------------------------------------------
71 | Returns 1 if the half-precision floating-point value `a' is a quiet
72 | NaN; otherwise returns 0.
73 *----------------------------------------------------------------------------*/
74
75 int float16_is_quiet_nan(float16 a_)
76 {
77     uint16_t a = float16_val(a_);
78 #if SNAN_BIT_IS_ONE
79     return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
80 #else
81     return ((a & ~0x8000) >= 0x7c80);
82 #endif
83 }
84
85 /*----------------------------------------------------------------------------
86 | Returns 1 if the half-precision floating-point value `a' is a signaling
87 | NaN; otherwise returns 0.
88 *----------------------------------------------------------------------------*/
89
90 int float16_is_signaling_nan(float16 a_)
91 {
92     uint16_t a = float16_val(a_);
93 #if SNAN_BIT_IS_ONE
94     return ((a & ~0x8000) >= 0x7c80);
95 #else
96     return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
97 #endif
98 }
99
100 /*----------------------------------------------------------------------------
101 | Returns a quiet NaN if the half-precision floating point value `a' is a
102 | signaling NaN; otherwise returns `a'.
103 *----------------------------------------------------------------------------*/
104 float16 float16_maybe_silence_nan(float16 a_)
105 {
106     if (float16_is_signaling_nan(a_)) {
107 #if SNAN_BIT_IS_ONE
108 #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
109         return float16_default_nan;
110 #  else
111 #    error Rules for silencing a signaling NaN are target-specific
112 #  endif
113 #else
114         uint16_t a = float16_val(a_);
115         a |= (1 << 9);
116         return make_float16(a);
117 #endif
118     }
119     return a_;
120 }
121
122 /*----------------------------------------------------------------------------
123 | Returns the result of converting the canonical NaN `a' to the half-
124 | precision floating-point format.
125 *----------------------------------------------------------------------------*/
126
127 static float16 commonNaNToFloat16(commonNaNT a STATUS_PARAM)
128 {
129     uint16_t mantissa = a.high>>54;
130
131     if (STATUS(default_nan_mode)) {
132         return float16_default_nan;
133     }
134
135     if (mantissa) {
136         return make_float16(((((uint16_t) a.sign) << 15)
137                              | (0x1F << 10) | mantissa));
138     } else {
139         return float16_default_nan;
140     }
141 }
142
143 /*----------------------------------------------------------------------------
144 | The pattern for a default generated single-precision NaN.
145 *----------------------------------------------------------------------------*/
146 #if defined(TARGET_SPARC)
147 #define float32_default_nan make_float32(0x7FFFFFFF)
148 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
149 #define float32_default_nan make_float32(0x7FC00000)
150 #elif SNAN_BIT_IS_ONE
151 #define float32_default_nan make_float32(0x7FBFFFFF)
152 #else
153 #define float32_default_nan make_float32(0xFFC00000)
154 #endif
155
156 /*----------------------------------------------------------------------------
157 | Returns 1 if the single-precision floating-point value `a' is a quiet
158 | NaN; otherwise returns 0.
159 *----------------------------------------------------------------------------*/
160
161 int float32_is_quiet_nan( float32 a_ )
162 {
163     uint32_t a = float32_val(a_);
164 #if SNAN_BIT_IS_ONE
165     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
166 #else
167     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
168 #endif
169 }
170
171 /*----------------------------------------------------------------------------
172 | Returns 1 if the single-precision floating-point value `a' is a signaling
173 | NaN; otherwise returns 0.
174 *----------------------------------------------------------------------------*/
175
176 int float32_is_signaling_nan( float32 a_ )
177 {
178     uint32_t a = float32_val(a_);
179 #if SNAN_BIT_IS_ONE
180     return ( 0xFF800000 <= (bits32) ( a<<1 ) );
181 #else
182     return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
183 #endif
184 }
185
186 /*----------------------------------------------------------------------------
187 | Returns a quiet NaN if the single-precision floating point value `a' is a
188 | signaling NaN; otherwise returns `a'.
189 *----------------------------------------------------------------------------*/
190
191 float32 float32_maybe_silence_nan( float32 a_ )
192 {
193     if (float32_is_signaling_nan(a_)) {
194 #if SNAN_BIT_IS_ONE
195 #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
196         return float32_default_nan;
197 #  else
198 #    error Rules for silencing a signaling NaN are target-specific
199 #  endif
200 #else
201         bits32 a = float32_val(a_);
202         a |= (1 << 22);
203         return make_float32(a);
204 #endif
205     }
206     return a_;
207 }
208
209 /*----------------------------------------------------------------------------
210 | Returns the result of converting the single-precision floating-point NaN
211 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
212 | exception is raised.
213 *----------------------------------------------------------------------------*/
214
215 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
216 {
217     commonNaNT z;
218
219     if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
220     z.sign = float32_val(a)>>31;
221     z.low = 0;
222     z.high = ( (bits64) float32_val(a) )<<41;
223     return z;
224 }
225
226 /*----------------------------------------------------------------------------
227 | Returns the result of converting the canonical NaN `a' to the single-
228 | precision floating-point format.
229 *----------------------------------------------------------------------------*/
230
231 static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
232 {
233     bits32 mantissa = a.high>>41;
234
235     if ( STATUS(default_nan_mode) ) {
236         return float32_default_nan;
237     }
238
239     if ( mantissa )
240         return make_float32(
241             ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
242     else
243         return float32_default_nan;
244 }
245
246 /*----------------------------------------------------------------------------
247 | Select which NaN to propagate for a two-input operation.
248 | IEEE754 doesn't specify all the details of this, so the
249 | algorithm is target-specific.
250 | The routine is passed various bits of information about the
251 | two NaNs and should return 0 to select NaN a and 1 for NaN b.
252 | Note that signalling NaNs are always squashed to quiet NaNs
253 | by the caller, by calling floatXX_maybe_silence_nan() before
254 | returning them.
255 |
256 | aIsLargerSignificand is only valid if both a and b are NaNs
257 | of some kind, and is true if a has the larger significand,
258 | or if both a and b have the same significand but a is
259 | positive but b is negative. It is only needed for the x87
260 | tie-break rule.
261 *----------------------------------------------------------------------------*/
262
263 #if defined(TARGET_ARM)
264 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
265                     flag aIsLargerSignificand)
266 {
267     /* ARM mandated NaN propagation rules: take the first of:
268      *  1. A if it is signaling
269      *  2. B if it is signaling
270      *  3. A (quiet)
271      *  4. B (quiet)
272      * A signaling NaN is always quietened before returning it.
273      */
274     if (aIsSNaN) {
275         return 0;
276     } else if (bIsSNaN) {
277         return 1;
278     } else if (aIsQNaN) {
279         return 0;
280     } else {
281         return 1;
282     }
283 }
284 #elif defined(TARGET_MIPS)
285 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
286                     flag aIsLargerSignificand)
287 {
288     /* According to MIPS specifications, if one of the two operands is
289      * a sNaN, a new qNaN has to be generated. This is done in
290      * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
291      * says: "When possible, this QNaN result is one of the operand QNaN
292      * values." In practice it seems that most implementations choose
293      * the first operand if both operands are qNaN. In short this gives
294      * the following rules:
295      *  1. A if it is signaling
296      *  2. B if it is signaling
297      *  3. A (quiet)
298      *  4. B (quiet)
299      * A signaling NaN is always silenced before returning it.
300      */
301     if (aIsSNaN) {
302         return 0;
303     } else if (bIsSNaN) {
304         return 1;
305     } else if (aIsQNaN) {
306         return 0;
307     } else {
308         return 1;
309     }
310 }
311 #elif defined(TARGET_PPC)
312 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
313                    flag aIsLargerSignificand)
314 {
315     /* PowerPC propagation rules:
316      *  1. A if it sNaN or qNaN
317      *  2. B if it sNaN or qNaN
318      * A signaling NaN is always silenced before returning it.
319      */
320     if (aIsSNaN || aIsQNaN) {
321         return 0;
322     } else {
323         return 1;
324     }
325 }
326 #else
327 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
328                     flag aIsLargerSignificand)
329 {
330     /* This implements x87 NaN propagation rules:
331      * SNaN + QNaN => return the QNaN
332      * two SNaNs => return the one with the larger significand, silenced
333      * two QNaNs => return the one with the larger significand
334      * SNaN and a non-NaN => return the SNaN, silenced
335      * QNaN and a non-NaN => return the QNaN
336      *
337      * If we get down to comparing significands and they are the same,
338      * return the NaN with the positive sign bit (if any).
339      */
340     if (aIsSNaN) {
341         if (bIsSNaN) {
342             return aIsLargerSignificand ? 0 : 1;
343         }
344         return bIsQNaN ? 1 : 0;
345     }
346     else if (aIsQNaN) {
347         if (bIsSNaN || !bIsQNaN)
348             return 0;
349         else {
350             return aIsLargerSignificand ? 0 : 1;
351         }
352     } else {
353         return 1;
354     }
355 }
356 #endif
357
358 /*----------------------------------------------------------------------------
359 | Takes two single-precision floating-point values `a' and `b', one of which
360 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
361 | signaling NaN, the invalid exception is raised.
362 *----------------------------------------------------------------------------*/
363
364 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
365 {
366     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
367     flag aIsLargerSignificand;
368     bits32 av, bv;
369
370     aIsQuietNaN = float32_is_quiet_nan( a );
371     aIsSignalingNaN = float32_is_signaling_nan( a );
372     bIsQuietNaN = float32_is_quiet_nan( b );
373     bIsSignalingNaN = float32_is_signaling_nan( b );
374     av = float32_val(a);
375     bv = float32_val(b);
376
377     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
378
379     if ( STATUS(default_nan_mode) )
380         return float32_default_nan;
381
382     if ((bits32)(av<<1) < (bits32)(bv<<1)) {
383         aIsLargerSignificand = 0;
384     } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
385         aIsLargerSignificand = 1;
386     } else {
387         aIsLargerSignificand = (av < bv) ? 1 : 0;
388     }
389
390     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
391                 aIsLargerSignificand)) {
392         return float32_maybe_silence_nan(b);
393     } else {
394         return float32_maybe_silence_nan(a);
395     }
396 }
397
398 /*----------------------------------------------------------------------------
399 | The pattern for a default generated double-precision NaN.
400 *----------------------------------------------------------------------------*/
401 #if defined(TARGET_SPARC)
402 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
403 #elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
404 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
405 #elif SNAN_BIT_IS_ONE
406 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
407 #else
408 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
409 #endif
410
411 /*----------------------------------------------------------------------------
412 | Returns 1 if the double-precision floating-point value `a' is a quiet
413 | NaN; otherwise returns 0.
414 *----------------------------------------------------------------------------*/
415
416 int float64_is_quiet_nan( float64 a_ )
417 {
418     bits64 a = float64_val(a_);
419 #if SNAN_BIT_IS_ONE
420     return
421            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
422         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
423 #else
424     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
425 #endif
426 }
427
428 /*----------------------------------------------------------------------------
429 | Returns 1 if the double-precision floating-point value `a' is a signaling
430 | NaN; otherwise returns 0.
431 *----------------------------------------------------------------------------*/
432
433 int float64_is_signaling_nan( float64 a_ )
434 {
435     bits64 a = float64_val(a_);
436 #if SNAN_BIT_IS_ONE
437     return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
438 #else
439     return
440            ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
441         && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
442 #endif
443 }
444
445 /*----------------------------------------------------------------------------
446 | Returns a quiet NaN if the double-precision floating point value `a' is a
447 | signaling NaN; otherwise returns `a'.
448 *----------------------------------------------------------------------------*/
449
450 float64 float64_maybe_silence_nan( float64 a_ )
451 {
452     if (float64_is_signaling_nan(a_)) {
453 #if SNAN_BIT_IS_ONE
454 #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
455         return float64_default_nan;
456 #  else
457 #    error Rules for silencing a signaling NaN are target-specific
458 #  endif
459 #else
460         bits64 a = float64_val(a_);
461         a |= LIT64( 0x0008000000000000 );
462         return make_float64(a);
463 #endif
464     }
465     return a_;
466 }
467
468 /*----------------------------------------------------------------------------
469 | Returns the result of converting the double-precision floating-point NaN
470 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
471 | exception is raised.
472 *----------------------------------------------------------------------------*/
473
474 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
475 {
476     commonNaNT z;
477
478     if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
479     z.sign = float64_val(a)>>63;
480     z.low = 0;
481     z.high = float64_val(a)<<12;
482     return z;
483 }
484
485 /*----------------------------------------------------------------------------
486 | Returns the result of converting the canonical NaN `a' to the double-
487 | precision floating-point format.
488 *----------------------------------------------------------------------------*/
489
490 static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
491 {
492     bits64 mantissa = a.high>>12;
493
494     if ( STATUS(default_nan_mode) ) {
495         return float64_default_nan;
496     }
497
498     if ( mantissa )
499         return make_float64(
500               ( ( (bits64) a.sign )<<63 )
501             | LIT64( 0x7FF0000000000000 )
502             | ( a.high>>12 ));
503     else
504         return float64_default_nan;
505 }
506
507 /*----------------------------------------------------------------------------
508 | Takes two double-precision floating-point values `a' and `b', one of which
509 | is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
510 | signaling NaN, the invalid exception is raised.
511 *----------------------------------------------------------------------------*/
512
513 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
514 {
515     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
516     flag aIsLargerSignificand;
517     bits64 av, bv;
518
519     aIsQuietNaN = float64_is_quiet_nan( a );
520     aIsSignalingNaN = float64_is_signaling_nan( a );
521     bIsQuietNaN = float64_is_quiet_nan( b );
522     bIsSignalingNaN = float64_is_signaling_nan( b );
523     av = float64_val(a);
524     bv = float64_val(b);
525
526     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
527
528     if ( STATUS(default_nan_mode) )
529         return float64_default_nan;
530
531     if ((bits64)(av<<1) < (bits64)(bv<<1)) {
532         aIsLargerSignificand = 0;
533     } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
534         aIsLargerSignificand = 1;
535     } else {
536         aIsLargerSignificand = (av < bv) ? 1 : 0;
537     }
538
539     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
540                 aIsLargerSignificand)) {
541         return float64_maybe_silence_nan(b);
542     } else {
543         return float64_maybe_silence_nan(a);
544     }
545 }
546
547 #ifdef FLOATX80
548
549 /*----------------------------------------------------------------------------
550 | The pattern for a default generated extended double-precision NaN.  The
551 | `high' and `low' values hold the most- and least-significant bits,
552 | respectively.
553 *----------------------------------------------------------------------------*/
554 #if SNAN_BIT_IS_ONE
555 #define floatx80_default_nan_high 0x7FFF
556 #define floatx80_default_nan_low  LIT64( 0xBFFFFFFFFFFFFFFF )
557 #else
558 #define floatx80_default_nan_high 0xFFFF
559 #define floatx80_default_nan_low  LIT64( 0xC000000000000000 )
560 #endif
561
562 /*----------------------------------------------------------------------------
563 | Returns 1 if the extended double-precision floating-point value `a' is a
564 | quiet NaN; otherwise returns 0. This slightly differs from the same
565 | function for other types as floatx80 has an explicit bit.
566 *----------------------------------------------------------------------------*/
567
568 int floatx80_is_quiet_nan( floatx80 a )
569 {
570 #if SNAN_BIT_IS_ONE
571     bits64 aLow;
572
573     aLow = a.low & ~ LIT64( 0x4000000000000000 );
574     return
575            ( ( a.high & 0x7FFF ) == 0x7FFF )
576         && (bits64) ( aLow<<1 )
577         && ( a.low == aLow );
578 #else
579     return ( ( a.high & 0x7FFF ) == 0x7FFF )
580         && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
581 #endif
582 }
583
584 /*----------------------------------------------------------------------------
585 | Returns 1 if the extended double-precision floating-point value `a' is a
586 | signaling NaN; otherwise returns 0. This slightly differs from the same
587 | function for other types as floatx80 has an explicit bit.
588 *----------------------------------------------------------------------------*/
589
590 int floatx80_is_signaling_nan( floatx80 a )
591 {
592 #if SNAN_BIT_IS_ONE
593     return ( ( a.high & 0x7FFF ) == 0x7FFF )
594         && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
595 #else
596     bits64 aLow;
597
598     aLow = a.low & ~ LIT64( 0x4000000000000000 );
599     return
600            ( ( a.high & 0x7FFF ) == 0x7FFF )
601         && (bits64) ( aLow<<1 )
602         && ( a.low == aLow );
603 #endif
604 }
605
606 /*----------------------------------------------------------------------------
607 | Returns a quiet NaN if the extended double-precision floating point value
608 | `a' is a signaling NaN; otherwise returns `a'.
609 *----------------------------------------------------------------------------*/
610
611 floatx80 floatx80_maybe_silence_nan( floatx80 a )
612 {
613     if (floatx80_is_signaling_nan(a)) {
614 #if SNAN_BIT_IS_ONE
615 #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
616         a.low = floatx80_default_nan_low;
617         a.high = floatx80_default_nan_high;
618 #  else
619 #    error Rules for silencing a signaling NaN are target-specific
620 #  endif
621 #else
622         a.low |= LIT64( 0xC000000000000000 );
623         return a;
624 #endif
625     }
626     return a;
627 }
628
629 /*----------------------------------------------------------------------------
630 | Returns the result of converting the extended double-precision floating-
631 | point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
632 | invalid exception is raised.
633 *----------------------------------------------------------------------------*/
634
635 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
636 {
637     commonNaNT z;
638
639     if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
640     z.sign = a.high>>15;
641     z.low = 0;
642     z.high = a.low;
643     return z;
644 }
645
646 /*----------------------------------------------------------------------------
647 | Returns the result of converting the canonical NaN `a' to the extended
648 | double-precision floating-point format.
649 *----------------------------------------------------------------------------*/
650
651 static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
652 {
653     floatx80 z;
654
655     if ( STATUS(default_nan_mode) ) {
656         z.low = floatx80_default_nan_low;
657         z.high = floatx80_default_nan_high;
658         return z;
659     }
660
661     if (a.high)
662         z.low = a.high;
663     else
664         z.low = floatx80_default_nan_low;
665     z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
666     return z;
667 }
668
669 /*----------------------------------------------------------------------------
670 | Takes two extended double-precision floating-point values `a' and `b', one
671 | of which is a NaN, and returns the appropriate NaN result.  If either `a' or
672 | `b' is a signaling NaN, the invalid exception is raised.
673 *----------------------------------------------------------------------------*/
674
675 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
676 {
677     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
678     flag aIsLargerSignificand;
679
680     aIsQuietNaN = floatx80_is_quiet_nan( a );
681     aIsSignalingNaN = floatx80_is_signaling_nan( a );
682     bIsQuietNaN = floatx80_is_quiet_nan( b );
683     bIsSignalingNaN = floatx80_is_signaling_nan( b );
684
685     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
686
687     if ( STATUS(default_nan_mode) ) {
688         a.low = floatx80_default_nan_low;
689         a.high = floatx80_default_nan_high;
690         return a;
691     }
692
693     if (a.low < b.low) {
694         aIsLargerSignificand = 0;
695     } else if (b.low < a.low) {
696         aIsLargerSignificand = 1;
697     } else {
698         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
699     }
700
701     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
702                 aIsLargerSignificand)) {
703         return floatx80_maybe_silence_nan(b);
704     } else {
705         return floatx80_maybe_silence_nan(a);
706     }
707 }
708
709 #endif
710
711 #ifdef FLOAT128
712
713 /*----------------------------------------------------------------------------
714 | The pattern for a default generated quadruple-precision NaN.  The `high' and
715 | `low' values hold the most- and least-significant bits, respectively.
716 *----------------------------------------------------------------------------*/
717 #if SNAN_BIT_IS_ONE
718 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
719 #define float128_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
720 #else
721 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
722 #define float128_default_nan_low  LIT64( 0x0000000000000000 )
723 #endif
724
725 /*----------------------------------------------------------------------------
726 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
727 | NaN; otherwise returns 0.
728 *----------------------------------------------------------------------------*/
729
730 int float128_is_quiet_nan( float128 a )
731 {
732 #if SNAN_BIT_IS_ONE
733     return
734            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
735         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
736 #else
737     return
738            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
739         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
740 #endif
741 }
742
743 /*----------------------------------------------------------------------------
744 | Returns 1 if the quadruple-precision floating-point value `a' is a
745 | signaling NaN; otherwise returns 0.
746 *----------------------------------------------------------------------------*/
747
748 int float128_is_signaling_nan( float128 a )
749 {
750 #if SNAN_BIT_IS_ONE
751     return
752            ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
753         && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
754 #else
755     return
756            ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
757         && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
758 #endif
759 }
760
761 /*----------------------------------------------------------------------------
762 | Returns a quiet NaN if the quadruple-precision floating point value `a' is
763 | a signaling NaN; otherwise returns `a'.
764 *----------------------------------------------------------------------------*/
765
766 float128 float128_maybe_silence_nan( float128 a )
767 {
768     if (float128_is_signaling_nan(a)) {
769 #if SNAN_BIT_IS_ONE
770 #  if defined(TARGET_MIPS) || defined(TARGET_SH4)
771         a.low = float128_default_nan_low;
772         a.high = float128_default_nan_high;
773 #  else
774 #    error Rules for silencing a signaling NaN are target-specific
775 #  endif
776 #else
777         a.high |= LIT64( 0x0000800000000000 );
778         return a;
779 #endif
780     }
781     return a;
782 }
783
784 /*----------------------------------------------------------------------------
785 | Returns the result of converting the quadruple-precision floating-point NaN
786 | `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
787 | exception is raised.
788 *----------------------------------------------------------------------------*/
789
790 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
791 {
792     commonNaNT z;
793
794     if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
795     z.sign = a.high>>63;
796     shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
797     return z;
798 }
799
800 /*----------------------------------------------------------------------------
801 | Returns the result of converting the canonical NaN `a' to the quadruple-
802 | precision floating-point format.
803 *----------------------------------------------------------------------------*/
804
805 static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
806 {
807     float128 z;
808
809     if ( STATUS(default_nan_mode) ) {
810         z.low = float128_default_nan_low;
811         z.high = float128_default_nan_high;
812         return z;
813     }
814
815     shift128Right( a.high, a.low, 16, &z.high, &z.low );
816     z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
817     return z;
818 }
819
820 /*----------------------------------------------------------------------------
821 | Takes two quadruple-precision floating-point values `a' and `b', one of
822 | which is a NaN, and returns the appropriate NaN result.  If either `a' or
823 | `b' is a signaling NaN, the invalid exception is raised.
824 *----------------------------------------------------------------------------*/
825
826 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
827 {
828     flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
829     flag aIsLargerSignificand;
830
831     aIsQuietNaN = float128_is_quiet_nan( a );
832     aIsSignalingNaN = float128_is_signaling_nan( a );
833     bIsQuietNaN = float128_is_quiet_nan( b );
834     bIsSignalingNaN = float128_is_signaling_nan( b );
835
836     if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
837
838     if ( STATUS(default_nan_mode) ) {
839         a.low = float128_default_nan_low;
840         a.high = float128_default_nan_high;
841         return a;
842     }
843
844     if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
845         aIsLargerSignificand = 0;
846     } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
847         aIsLargerSignificand = 1;
848     } else {
849         aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
850     }
851
852     if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
853                 aIsLargerSignificand)) {
854         return float128_maybe_silence_nan(b);
855     } else {
856         return float128_maybe_silence_nan(a);
857     }
858 }
859
860 #endif
This page took 0.073553 seconds and 4 git commands to generate.