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