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