]> git.proxmox.com Git - qemu.git/blob - fpu/softfloat-specialize.h
3ce5bb53bf5641b7b888a1062412ec73f973473a
[qemu.git] / fpu / softfloat-specialize.h
1
2 /*============================================================================
3
4 This C source fragment is part of the SoftFloat IEC/IEEE Floating-point
5 Arithmetic Package, Release 2b.
6
7 Written by John R. Hauser. This work was made possible in part by the
8 International Computer Science Institute, located at Suite 600, 1947 Center
9 Street, Berkeley, California 94704. Funding was partially provided by the
10 National Science Foundation under grant MIP-9311980. The original version
11 of this code was written as part of a project to build a fixed-point vector
12 processor in collaboration with the University of California at Berkeley,
13 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
14 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
15 arithmetic/SoftFloat.html'.
16
17 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort has
18 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
19 RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
20 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
21 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
22 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
23 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
24 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
25
26 Derivative works are acceptable, even for commercial purposes, so long as
27 (1) the source code for the derivative work includes prominent notice that
28 the work is derivative, and (2) the source code includes prominent notice with
29 these four paragraphs for those parts of this code that are retained.
30
31 =============================================================================*/
32
33 #if defined(TARGET_MIPS)
34 #define SNAN_BIT_IS_ONE 1
35 #else
36 #define SNAN_BIT_IS_ONE 0
37 #endif
38
39 /*----------------------------------------------------------------------------
40 | Raises the exceptions specified by `flags'. Floating-point traps can be
41 | defined here if desired. It is currently not possible for such a trap
42 | to substitute a result value. If traps are not implemented, this routine
43 | should be simply `float_exception_flags |= flags;'.
44 *----------------------------------------------------------------------------*/
45
46 void float_raise( int8 flags STATUS_PARAM )
47 {
48 STATUS(float_exception_flags) |= flags;
49 }
50
51 /*----------------------------------------------------------------------------
52 | Internal canonical NaN format.
53 *----------------------------------------------------------------------------*/
54 typedef struct {
55 flag sign;
56 bits64 high, low;
57 } commonNaNT;
58
59 /*----------------------------------------------------------------------------
60 | The pattern for a default generated single-precision NaN.
61 *----------------------------------------------------------------------------*/
62 #if defined(TARGET_SPARC)
63 #define float32_default_nan make_float32(0x7FFFFFFF)
64 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
65 #define float32_default_nan make_float32(0x7FC00000)
66 #elif SNAN_BIT_IS_ONE
67 #define float32_default_nan make_float32(0x7FBFFFFF)
68 #else
69 #define float32_default_nan make_float32(0xFFC00000)
70 #endif
71
72 /*----------------------------------------------------------------------------
73 | Returns 1 if the single-precision floating-point value `a' is a quiet
74 | NaN; otherwise returns 0.
75 *----------------------------------------------------------------------------*/
76
77 int float32_is_quiet_nan( float32 a_ )
78 {
79 uint32_t a = float32_val(a_);
80 #if SNAN_BIT_IS_ONE
81 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
82 #else
83 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
84 #endif
85 }
86
87 /*----------------------------------------------------------------------------
88 | Returns 1 if the single-precision floating-point value `a' is a signaling
89 | NaN; otherwise returns 0.
90 *----------------------------------------------------------------------------*/
91
92 int float32_is_signaling_nan( float32 a_ )
93 {
94 uint32_t a = float32_val(a_);
95 #if SNAN_BIT_IS_ONE
96 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
97 #else
98 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
99 #endif
100 }
101
102 /*----------------------------------------------------------------------------
103 | Returns a quiet NaN if the single-precision floating point value `a' is a
104 | signaling NaN; otherwise returns `a'.
105 *----------------------------------------------------------------------------*/
106
107 float32 float32_maybe_silence_nan( float32 a_ )
108 {
109 if (float32_is_signaling_nan(a_)) {
110 #if SNAN_BIT_IS_ONE
111 # if defined(TARGET_MIPS)
112 return float32_default_nan;
113 # else
114 # error Rules for silencing a signaling NaN are target-specific
115 # endif
116 #else
117 bits32 a = float32_val(a_);
118 a |= (1 << 22);
119 return make_float32(a);
120 #endif
121 }
122 return a_;
123 }
124
125 /*----------------------------------------------------------------------------
126 | Returns the result of converting the single-precision floating-point NaN
127 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
128 | exception is raised.
129 *----------------------------------------------------------------------------*/
130
131 static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
132 {
133 commonNaNT z;
134
135 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
136 z.sign = float32_val(a)>>31;
137 z.low = 0;
138 z.high = ( (bits64) float32_val(a) )<<41;
139 return z;
140 }
141
142 /*----------------------------------------------------------------------------
143 | Returns the result of converting the canonical NaN `a' to the single-
144 | precision floating-point format.
145 *----------------------------------------------------------------------------*/
146
147 static float32 commonNaNToFloat32( commonNaNT a )
148 {
149 bits32 mantissa = a.high>>41;
150 if ( mantissa )
151 return make_float32(
152 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
153 else
154 return float32_default_nan;
155 }
156
157 /*----------------------------------------------------------------------------
158 | Select which NaN to propagate for a two-input operation.
159 | IEEE754 doesn't specify all the details of this, so the
160 | algorithm is target-specific.
161 | The routine is passed various bits of information about the
162 | two NaNs and should return 0 to select NaN a and 1 for NaN b.
163 | Note that signalling NaNs are always squashed to quiet NaNs
164 | by the caller, by calling floatXX_maybe_silence_nan() before
165 | returning them.
166 |
167 | aIsLargerSignificand is only valid if both a and b are NaNs
168 | of some kind, and is true if a has the larger significand,
169 | or if both a and b have the same significand but a is
170 | positive but b is negative. It is only needed for the x87
171 | tie-break rule.
172 *----------------------------------------------------------------------------*/
173
174 #if defined(TARGET_ARM)
175 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
176 flag aIsLargerSignificand)
177 {
178 /* ARM mandated NaN propagation rules: take the first of:
179 * 1. A if it is signaling
180 * 2. B if it is signaling
181 * 3. A (quiet)
182 * 4. B (quiet)
183 * A signaling NaN is always quietened before returning it.
184 */
185 if (aIsSNaN) {
186 return 0;
187 } else if (bIsSNaN) {
188 return 1;
189 } else if (aIsQNaN) {
190 return 0;
191 } else {
192 return 1;
193 }
194 }
195 #else
196 static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
197 flag aIsLargerSignificand)
198 {
199 /* This implements x87 NaN propagation rules:
200 * SNaN + QNaN => return the QNaN
201 * two SNaNs => return the one with the larger significand, silenced
202 * two QNaNs => return the one with the larger significand
203 * SNaN and a non-NaN => return the SNaN, silenced
204 * QNaN and a non-NaN => return the QNaN
205 *
206 * If we get down to comparing significands and they are the same,
207 * return the NaN with the positive sign bit (if any).
208 */
209 if (aIsSNaN) {
210 if (bIsSNaN) {
211 return aIsLargerSignificand ? 0 : 1;
212 }
213 return bIsQNaN ? 1 : 0;
214 }
215 else if (aIsQNaN) {
216 if (bIsSNaN || !bIsQNaN)
217 return 0;
218 else {
219 return aIsLargerSignificand ? 0 : 1;
220 }
221 } else {
222 return 1;
223 }
224 }
225 #endif
226
227 /*----------------------------------------------------------------------------
228 | Takes two single-precision floating-point values `a' and `b', one of which
229 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
230 | signaling NaN, the invalid exception is raised.
231 *----------------------------------------------------------------------------*/
232
233 static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
234 {
235 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
236 flag aIsLargerSignificand;
237 bits32 av, bv;
238
239 if ( STATUS(default_nan_mode) )
240 return float32_default_nan;
241
242 aIsQuietNaN = float32_is_quiet_nan( a );
243 aIsSignalingNaN = float32_is_signaling_nan( a );
244 bIsQuietNaN = float32_is_quiet_nan( b );
245 bIsSignalingNaN = float32_is_signaling_nan( b );
246 av = float32_val(a);
247 bv = float32_val(b);
248
249 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
250
251 if ((bits32)(av<<1) < (bits32)(bv<<1)) {
252 aIsLargerSignificand = 0;
253 } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
254 aIsLargerSignificand = 1;
255 } else {
256 aIsLargerSignificand = (av < bv) ? 1 : 0;
257 }
258
259 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
260 aIsLargerSignificand)) {
261 return float32_maybe_silence_nan(b);
262 } else {
263 return float32_maybe_silence_nan(a);
264 }
265 }
266
267 /*----------------------------------------------------------------------------
268 | The pattern for a default generated double-precision NaN.
269 *----------------------------------------------------------------------------*/
270 #if defined(TARGET_SPARC)
271 #define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
272 #elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
273 #define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
274 #elif SNAN_BIT_IS_ONE
275 #define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
276 #else
277 #define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
278 #endif
279
280 /*----------------------------------------------------------------------------
281 | Returns 1 if the double-precision floating-point value `a' is a quiet
282 | NaN; otherwise returns 0.
283 *----------------------------------------------------------------------------*/
284
285 int float64_is_quiet_nan( float64 a_ )
286 {
287 bits64 a = float64_val(a_);
288 #if SNAN_BIT_IS_ONE
289 return
290 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
291 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
292 #else
293 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
294 #endif
295 }
296
297 /*----------------------------------------------------------------------------
298 | Returns 1 if the double-precision floating-point value `a' is a signaling
299 | NaN; otherwise returns 0.
300 *----------------------------------------------------------------------------*/
301
302 int float64_is_signaling_nan( float64 a_ )
303 {
304 bits64 a = float64_val(a_);
305 #if SNAN_BIT_IS_ONE
306 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
307 #else
308 return
309 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
310 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
311 #endif
312 }
313
314 /*----------------------------------------------------------------------------
315 | Returns a quiet NaN if the double-precision floating point value `a' is a
316 | signaling NaN; otherwise returns `a'.
317 *----------------------------------------------------------------------------*/
318
319 float64 float64_maybe_silence_nan( float64 a_ )
320 {
321 if (float64_is_signaling_nan(a_)) {
322 #if SNAN_BIT_IS_ONE
323 # if defined(TARGET_MIPS)
324 return float64_default_nan;
325 # else
326 # error Rules for silencing a signaling NaN are target-specific
327 # endif
328 #else
329 bits64 a = float64_val(a_);
330 a |= LIT64( 0x0008000000000000 );
331 return make_float64(a);
332 #endif
333 }
334 return a_;
335 }
336
337 /*----------------------------------------------------------------------------
338 | Returns the result of converting the double-precision floating-point NaN
339 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
340 | exception is raised.
341 *----------------------------------------------------------------------------*/
342
343 static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
344 {
345 commonNaNT z;
346
347 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
348 z.sign = float64_val(a)>>63;
349 z.low = 0;
350 z.high = float64_val(a)<<12;
351 return z;
352 }
353
354 /*----------------------------------------------------------------------------
355 | Returns the result of converting the canonical NaN `a' to the double-
356 | precision floating-point format.
357 *----------------------------------------------------------------------------*/
358
359 static float64 commonNaNToFloat64( commonNaNT a )
360 {
361 bits64 mantissa = a.high>>12;
362
363 if ( mantissa )
364 return make_float64(
365 ( ( (bits64) a.sign )<<63 )
366 | LIT64( 0x7FF0000000000000 )
367 | ( a.high>>12 ));
368 else
369 return float64_default_nan;
370 }
371
372 /*----------------------------------------------------------------------------
373 | Takes two double-precision floating-point values `a' and `b', one of which
374 | is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
375 | signaling NaN, the invalid exception is raised.
376 *----------------------------------------------------------------------------*/
377
378 static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
379 {
380 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
381 flag aIsLargerSignificand;
382 bits64 av, bv;
383
384 if ( STATUS(default_nan_mode) )
385 return float64_default_nan;
386
387 aIsQuietNaN = float64_is_quiet_nan( a );
388 aIsSignalingNaN = float64_is_signaling_nan( a );
389 bIsQuietNaN = float64_is_quiet_nan( b );
390 bIsSignalingNaN = float64_is_signaling_nan( b );
391 av = float64_val(a);
392 bv = float64_val(b);
393
394 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
395
396 if ((bits64)(av<<1) < (bits64)(bv<<1)) {
397 aIsLargerSignificand = 0;
398 } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
399 aIsLargerSignificand = 1;
400 } else {
401 aIsLargerSignificand = (av < bv) ? 1 : 0;
402 }
403
404 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
405 aIsLargerSignificand)) {
406 return float64_maybe_silence_nan(b);
407 } else {
408 return float64_maybe_silence_nan(a);
409 }
410 }
411
412 #ifdef FLOATX80
413
414 /*----------------------------------------------------------------------------
415 | The pattern for a default generated extended double-precision NaN. The
416 | `high' and `low' values hold the most- and least-significant bits,
417 | respectively.
418 *----------------------------------------------------------------------------*/
419 #if SNAN_BIT_IS_ONE
420 #define floatx80_default_nan_high 0x7FFF
421 #define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
422 #else
423 #define floatx80_default_nan_high 0xFFFF
424 #define floatx80_default_nan_low LIT64( 0xC000000000000000 )
425 #endif
426
427 /*----------------------------------------------------------------------------
428 | Returns 1 if the extended double-precision floating-point value `a' is a
429 | quiet NaN; otherwise returns 0.
430 *----------------------------------------------------------------------------*/
431
432 int floatx80_is_quiet_nan( floatx80 a )
433 {
434 #if SNAN_BIT_IS_ONE
435 bits64 aLow;
436
437 aLow = a.low & ~ LIT64( 0x4000000000000000 );
438 return
439 ( ( a.high & 0x7FFF ) == 0x7FFF )
440 && (bits64) ( aLow<<1 )
441 && ( a.low == aLow );
442 #else
443 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
444 #endif
445 }
446
447 /*----------------------------------------------------------------------------
448 | Returns 1 if the extended double-precision floating-point value `a' is a
449 | signaling NaN; otherwise returns 0.
450 *----------------------------------------------------------------------------*/
451
452 int floatx80_is_signaling_nan( floatx80 a )
453 {
454 #if SNAN_BIT_IS_ONE
455 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
456 #else
457 bits64 aLow;
458
459 aLow = a.low & ~ LIT64( 0x4000000000000000 );
460 return
461 ( ( a.high & 0x7FFF ) == 0x7FFF )
462 && (bits64) ( aLow<<1 )
463 && ( a.low == aLow );
464 #endif
465 }
466
467 /*----------------------------------------------------------------------------
468 | Returns a quiet NaN if the extended double-precision floating point value
469 | `a' is a signaling NaN; otherwise returns `a'.
470 *----------------------------------------------------------------------------*/
471
472 floatx80 floatx80_maybe_silence_nan( floatx80 a )
473 {
474 if (floatx80_is_signaling_nan(a)) {
475 #if SNAN_BIT_IS_ONE
476 # if defined(TARGET_MIPS)
477 a.low = floatx80_default_nan_low;
478 a.high = floatx80_default_nan_high;
479 # else
480 # error Rules for silencing a signaling NaN are target-specific
481 # endif
482 #else
483 a.low |= LIT64( 0xC000000000000000 );
484 return a;
485 #endif
486 }
487 return a;
488 }
489
490 /*----------------------------------------------------------------------------
491 | Returns the result of converting the extended double-precision floating-
492 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
493 | invalid exception is raised.
494 *----------------------------------------------------------------------------*/
495
496 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
497 {
498 commonNaNT z;
499
500 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
501 z.sign = a.high>>15;
502 z.low = 0;
503 z.high = a.low;
504 return z;
505 }
506
507 /*----------------------------------------------------------------------------
508 | Returns the result of converting the canonical NaN `a' to the extended
509 | double-precision floating-point format.
510 *----------------------------------------------------------------------------*/
511
512 static floatx80 commonNaNToFloatx80( commonNaNT a )
513 {
514 floatx80 z;
515
516 if (a.high)
517 z.low = a.high;
518 else
519 z.low = floatx80_default_nan_low;
520 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
521 return z;
522 }
523
524 /*----------------------------------------------------------------------------
525 | Takes two extended double-precision floating-point values `a' and `b', one
526 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
527 | `b' is a signaling NaN, the invalid exception is raised.
528 *----------------------------------------------------------------------------*/
529
530 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
531 {
532 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
533 flag aIsLargerSignificand;
534
535 if ( STATUS(default_nan_mode) ) {
536 a.low = floatx80_default_nan_low;
537 a.high = floatx80_default_nan_high;
538 return a;
539 }
540
541 aIsQuietNaN = floatx80_is_quiet_nan( a );
542 aIsSignalingNaN = floatx80_is_signaling_nan( a );
543 bIsQuietNaN = floatx80_is_quiet_nan( b );
544 bIsSignalingNaN = floatx80_is_signaling_nan( b );
545
546 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
547
548 if (a.low < b.low) {
549 aIsLargerSignificand = 0;
550 } else if (b.low < a.low) {
551 aIsLargerSignificand = 1;
552 } else {
553 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
554 }
555
556 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
557 aIsLargerSignificand)) {
558 return floatx80_maybe_silence_nan(b);
559 } else {
560 return floatx80_maybe_silence_nan(a);
561 }
562 }
563
564 #endif
565
566 #ifdef FLOAT128
567
568 /*----------------------------------------------------------------------------
569 | The pattern for a default generated quadruple-precision NaN. The `high' and
570 | `low' values hold the most- and least-significant bits, respectively.
571 *----------------------------------------------------------------------------*/
572 #if SNAN_BIT_IS_ONE
573 #define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
574 #define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
575 #else
576 #define float128_default_nan_high LIT64( 0xFFFF800000000000 )
577 #define float128_default_nan_low LIT64( 0x0000000000000000 )
578 #endif
579
580 /*----------------------------------------------------------------------------
581 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
582 | NaN; otherwise returns 0.
583 *----------------------------------------------------------------------------*/
584
585 int float128_is_quiet_nan( float128 a )
586 {
587 #if SNAN_BIT_IS_ONE
588 return
589 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
590 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
591 #else
592 return
593 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
594 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
595 #endif
596 }
597
598 /*----------------------------------------------------------------------------
599 | Returns 1 if the quadruple-precision floating-point value `a' is a
600 | signaling NaN; otherwise returns 0.
601 *----------------------------------------------------------------------------*/
602
603 int float128_is_signaling_nan( float128 a )
604 {
605 #if SNAN_BIT_IS_ONE
606 return
607 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
608 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
609 #else
610 return
611 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
612 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
613 #endif
614 }
615
616 /*----------------------------------------------------------------------------
617 | Returns a quiet NaN if the quadruple-precision floating point value `a' is
618 | a signaling NaN; otherwise returns `a'.
619 *----------------------------------------------------------------------------*/
620
621 float128 float128_maybe_silence_nan( float128 a )
622 {
623 if (float128_is_signaling_nan(a)) {
624 #if SNAN_BIT_IS_ONE
625 # if defined(TARGET_MIPS)
626 a.low = float128_default_nan_low;
627 a.high = float128_default_nan_high;
628 # else
629 # error Rules for silencing a signaling NaN are target-specific
630 # endif
631 #else
632 a.high |= LIT64( 0x0000800000000000 );
633 return a;
634 #endif
635 }
636 return a;
637 }
638
639 /*----------------------------------------------------------------------------
640 | Returns the result of converting the quadruple-precision floating-point NaN
641 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
642 | exception is raised.
643 *----------------------------------------------------------------------------*/
644
645 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
646 {
647 commonNaNT z;
648
649 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
650 z.sign = a.high>>63;
651 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
652 return z;
653 }
654
655 /*----------------------------------------------------------------------------
656 | Returns the result of converting the canonical NaN `a' to the quadruple-
657 | precision floating-point format.
658 *----------------------------------------------------------------------------*/
659
660 static float128 commonNaNToFloat128( commonNaNT a )
661 {
662 float128 z;
663
664 shift128Right( a.high, a.low, 16, &z.high, &z.low );
665 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
666 return z;
667 }
668
669 /*----------------------------------------------------------------------------
670 | Takes two quadruple-precision floating-point values `a' and `b', one of
671 | 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 float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
676 {
677 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
678 flag aIsLargerSignificand;
679
680 if ( STATUS(default_nan_mode) ) {
681 a.low = float128_default_nan_low;
682 a.high = float128_default_nan_high;
683 return a;
684 }
685
686 aIsQuietNaN = float128_is_quiet_nan( a );
687 aIsSignalingNaN = float128_is_signaling_nan( a );
688 bIsQuietNaN = float128_is_quiet_nan( b );
689 bIsSignalingNaN = float128_is_signaling_nan( b );
690
691 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
692
693 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
694 aIsLargerSignificand = 0;
695 } else if (lt128(b.high<<1, b.low, a.high<<1, 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 float128_maybe_silence_nan(b);
704 } else {
705 return float128_maybe_silence_nan(a);
706 }
707 }
708
709 #endif