]> git.proxmox.com Git - qemu.git/blob - fpu/softfloat-specialize.h
softfloat: always enable floatx80 and float128 support
[qemu.git] / fpu / softfloat-specialize.h
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
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
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
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 *----------------------------------------------------------------------------*/
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
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
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
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
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
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
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
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)
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)
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)
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
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
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
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
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
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
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
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
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 /*----------------------------------------------------------------------------
527 | Returns 1 if the extended double-precision floating-point value `a' is a
528 | quiet NaN; otherwise returns 0. This slightly differs from the same
529 | function for other types as floatx80 has an explicit bit.
530 *----------------------------------------------------------------------------*/
531
532 int floatx80_is_quiet_nan( floatx80 a )
533 {
534 #if SNAN_BIT_IS_ONE
535 uint64_t aLow;
536
537 aLow = a.low & ~ LIT64( 0x4000000000000000 );
538 return
539 ( ( a.high & 0x7FFF ) == 0x7FFF )
540 && (uint64_t) ( aLow<<1 )
541 && ( a.low == aLow );
542 #else
543 return ( ( a.high & 0x7FFF ) == 0x7FFF )
544 && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
545 #endif
546 }
547
548 /*----------------------------------------------------------------------------
549 | Returns 1 if the extended double-precision floating-point value `a' is a
550 | signaling NaN; otherwise returns 0. This slightly differs from the same
551 | function for other types as floatx80 has an explicit bit.
552 *----------------------------------------------------------------------------*/
553
554 int floatx80_is_signaling_nan( floatx80 a )
555 {
556 #if SNAN_BIT_IS_ONE
557 return ( ( a.high & 0x7FFF ) == 0x7FFF )
558 && (LIT64( 0x8000000000000000 ) <= ((uint64_t) ( a.low<<1 )));
559 #else
560 uint64_t aLow;
561
562 aLow = a.low & ~ LIT64( 0x4000000000000000 );
563 return
564 ( ( a.high & 0x7FFF ) == 0x7FFF )
565 && (uint64_t) ( aLow<<1 )
566 && ( a.low == aLow );
567 #endif
568 }
569
570 /*----------------------------------------------------------------------------
571 | Returns a quiet NaN if the extended double-precision floating point value
572 | `a' is a signaling NaN; otherwise returns `a'.
573 *----------------------------------------------------------------------------*/
574
575 floatx80 floatx80_maybe_silence_nan( floatx80 a )
576 {
577 if (floatx80_is_signaling_nan(a)) {
578 #if SNAN_BIT_IS_ONE
579 # if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
580 a.low = floatx80_default_nan_low;
581 a.high = floatx80_default_nan_high;
582 # else
583 # error Rules for silencing a signaling NaN are target-specific
584 # endif
585 #else
586 a.low |= LIT64( 0xC000000000000000 );
587 return a;
588 #endif
589 }
590 return a;
591 }
592
593 /*----------------------------------------------------------------------------
594 | Returns the result of converting the extended double-precision floating-
595 | point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
596 | invalid exception is raised.
597 *----------------------------------------------------------------------------*/
598
599 static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
600 {
601 commonNaNT z;
602
603 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
604 if ( a.low >> 63 ) {
605 z.sign = a.high >> 15;
606 z.low = 0;
607 z.high = a.low << 1;
608 } else {
609 z.sign = floatx80_default_nan_high >> 15;
610 z.low = 0;
611 z.high = floatx80_default_nan_low << 1;
612 }
613 return z;
614 }
615
616 /*----------------------------------------------------------------------------
617 | Returns the result of converting the canonical NaN `a' to the extended
618 | double-precision floating-point format.
619 *----------------------------------------------------------------------------*/
620
621 static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
622 {
623 floatx80 z;
624
625 if ( STATUS(default_nan_mode) ) {
626 z.low = floatx80_default_nan_low;
627 z.high = floatx80_default_nan_high;
628 return z;
629 }
630
631 if (a.high >> 1) {
632 z.low = LIT64( 0x8000000000000000 ) | a.high >> 1;
633 z.high = ( ( (uint16_t) a.sign )<<15 ) | 0x7FFF;
634 } else {
635 z.low = floatx80_default_nan_low;
636 z.high = floatx80_default_nan_high;
637 }
638
639 return z;
640 }
641
642 /*----------------------------------------------------------------------------
643 | Takes two extended double-precision floating-point values `a' and `b', one
644 | of which is a NaN, and returns the appropriate NaN result. If either `a' or
645 | `b' is a signaling NaN, the invalid exception is raised.
646 *----------------------------------------------------------------------------*/
647
648 static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
649 {
650 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
651 flag aIsLargerSignificand;
652
653 aIsQuietNaN = floatx80_is_quiet_nan( a );
654 aIsSignalingNaN = floatx80_is_signaling_nan( a );
655 bIsQuietNaN = floatx80_is_quiet_nan( b );
656 bIsSignalingNaN = floatx80_is_signaling_nan( b );
657
658 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
659
660 if ( STATUS(default_nan_mode) ) {
661 a.low = floatx80_default_nan_low;
662 a.high = floatx80_default_nan_high;
663 return a;
664 }
665
666 if (a.low < b.low) {
667 aIsLargerSignificand = 0;
668 } else if (b.low < a.low) {
669 aIsLargerSignificand = 1;
670 } else {
671 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
672 }
673
674 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
675 aIsLargerSignificand)) {
676 return floatx80_maybe_silence_nan(b);
677 } else {
678 return floatx80_maybe_silence_nan(a);
679 }
680 }
681
682 /*----------------------------------------------------------------------------
683 | Returns 1 if the quadruple-precision floating-point value `a' is a quiet
684 | NaN; otherwise returns 0.
685 *----------------------------------------------------------------------------*/
686
687 int float128_is_quiet_nan( float128 a )
688 {
689 #if SNAN_BIT_IS_ONE
690 return
691 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
692 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
693 #else
694 return
695 ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
696 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
697 #endif
698 }
699
700 /*----------------------------------------------------------------------------
701 | Returns 1 if the quadruple-precision floating-point value `a' is a
702 | signaling NaN; otherwise returns 0.
703 *----------------------------------------------------------------------------*/
704
705 int float128_is_signaling_nan( float128 a )
706 {
707 #if SNAN_BIT_IS_ONE
708 return
709 ( LIT64( 0xFFFE000000000000 ) <= (uint64_t) ( a.high<<1 ) )
710 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
711 #else
712 return
713 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
714 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
715 #endif
716 }
717
718 /*----------------------------------------------------------------------------
719 | Returns a quiet NaN if the quadruple-precision floating point value `a' is
720 | a signaling NaN; otherwise returns `a'.
721 *----------------------------------------------------------------------------*/
722
723 float128 float128_maybe_silence_nan( float128 a )
724 {
725 if (float128_is_signaling_nan(a)) {
726 #if SNAN_BIT_IS_ONE
727 # if defined(TARGET_MIPS) || defined(TARGET_SH4) || defined(TARGET_UNICORE32)
728 a.low = float128_default_nan_low;
729 a.high = float128_default_nan_high;
730 # else
731 # error Rules for silencing a signaling NaN are target-specific
732 # endif
733 #else
734 a.high |= LIT64( 0x0000800000000000 );
735 return a;
736 #endif
737 }
738 return a;
739 }
740
741 /*----------------------------------------------------------------------------
742 | Returns the result of converting the quadruple-precision floating-point NaN
743 | `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
744 | exception is raised.
745 *----------------------------------------------------------------------------*/
746
747 static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
748 {
749 commonNaNT z;
750
751 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
752 z.sign = a.high>>63;
753 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
754 return z;
755 }
756
757 /*----------------------------------------------------------------------------
758 | Returns the result of converting the canonical NaN `a' to the quadruple-
759 | precision floating-point format.
760 *----------------------------------------------------------------------------*/
761
762 static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
763 {
764 float128 z;
765
766 if ( STATUS(default_nan_mode) ) {
767 z.low = float128_default_nan_low;
768 z.high = float128_default_nan_high;
769 return z;
770 }
771
772 shift128Right( a.high, a.low, 16, &z.high, &z.low );
773 z.high |= ( ( (uint64_t) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
774 return z;
775 }
776
777 /*----------------------------------------------------------------------------
778 | Takes two quadruple-precision floating-point values `a' and `b', one of
779 | which is a NaN, and returns the appropriate NaN result. If either `a' or
780 | `b' is a signaling NaN, the invalid exception is raised.
781 *----------------------------------------------------------------------------*/
782
783 static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
784 {
785 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
786 flag aIsLargerSignificand;
787
788 aIsQuietNaN = float128_is_quiet_nan( a );
789 aIsSignalingNaN = float128_is_signaling_nan( a );
790 bIsQuietNaN = float128_is_quiet_nan( b );
791 bIsSignalingNaN = float128_is_signaling_nan( b );
792
793 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
794
795 if ( STATUS(default_nan_mode) ) {
796 a.low = float128_default_nan_low;
797 a.high = float128_default_nan_high;
798 return a;
799 }
800
801 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
802 aIsLargerSignificand = 0;
803 } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
804 aIsLargerSignificand = 1;
805 } else {
806 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
807 }
808
809 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
810 aIsLargerSignificand)) {
811 return float128_maybe_silence_nan(b);
812 } else {
813 return float128_maybe_silence_nan(a);
814 }
815 }
816