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