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