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