]> git.proxmox.com Git - mirror_qemu.git/blame - fpu/softfloat-specialize.h
e1000: Fix multi-descriptor packet checksum offload
[mirror_qemu.git] / fpu / softfloat-specialize.h
CommitLineData
158142c2
FB
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
158142c2
FB
33/*----------------------------------------------------------------------------
34| Raises the exceptions specified by `flags'. Floating-point traps can be
35| defined here if desired. It is currently not possible for such a trap
36| to substitute a result value. If traps are not implemented, this routine
37| should be simply `float_exception_flags |= flags;'.
38*----------------------------------------------------------------------------*/
39
40void float_raise( int8 flags STATUS_PARAM )
41{
158142c2 42 STATUS(float_exception_flags) |= flags;
158142c2
FB
43}
44
45/*----------------------------------------------------------------------------
46| Internal canonical NaN format.
47*----------------------------------------------------------------------------*/
48typedef struct {
49 flag sign;
50 bits64 high, low;
51} commonNaNT;
52
bb4d4bb3
PM
53/*----------------------------------------------------------------------------
54| Returns 1 if the half-precision floating-point value `a' is a quiet
55| NaN; otherwise returns 0.
56*----------------------------------------------------------------------------*/
57
58int float16_is_quiet_nan(float16 a_)
59{
60 uint16_t a = float16_val(a_);
61#if SNAN_BIT_IS_ONE
62 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
63#else
64 return ((a & ~0x8000) >= 0x7c80);
65#endif
66}
67
68/*----------------------------------------------------------------------------
69| Returns 1 if the half-precision floating-point value `a' is a signaling
70| NaN; otherwise returns 0.
71*----------------------------------------------------------------------------*/
72
73int float16_is_signaling_nan(float16 a_)
74{
75 uint16_t a = float16_val(a_);
76#if SNAN_BIT_IS_ONE
77 return ((a & ~0x8000) >= 0x7c80);
78#else
79 return (((a >> 9) & 0x3F) == 0x3E) && (a & 0x1FF);
80#endif
81}
82
83/*----------------------------------------------------------------------------
84| Returns a quiet NaN if the half-precision floating point value `a' is a
85| signaling NaN; otherwise returns `a'.
86*----------------------------------------------------------------------------*/
87float16 float16_maybe_silence_nan(float16 a_)
88{
89 if (float16_is_signaling_nan(a_)) {
90#if SNAN_BIT_IS_ONE
91# if defined(TARGET_MIPS) || defined(TARGET_SH4)
92 return float16_default_nan;
93# else
94# error Rules for silencing a signaling NaN are target-specific
95# endif
96#else
97 uint16_t a = float16_val(a_);
98 a |= (1 << 9);
99 return make_float16(a);
100#endif
101 }
102 return a_;
103}
104
f591e1be
PM
105/*----------------------------------------------------------------------------
106| Returns the result of converting the half-precision floating-point NaN
107| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
108| exception is raised.
109*----------------------------------------------------------------------------*/
110
111static commonNaNT float16ToCommonNaN( float16 a STATUS_PARAM )
112{
113 commonNaNT z;
114
115 if ( float16_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
116 z.sign = float16_val(a) >> 15;
117 z.low = 0;
118 z.high = ((bits64) float16_val(a))<<54;
119 return z;
120}
121
600e30d2
PM
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
158142c2 143/*----------------------------------------------------------------------------
5a6932d5
TS
144| Returns 1 if the single-precision floating-point value `a' is a quiet
145| NaN; otherwise returns 0.
158142c2
FB
146*----------------------------------------------------------------------------*/
147
18569871 148int float32_is_quiet_nan( float32 a_ )
158142c2 149{
f090c9d4 150 uint32_t a = float32_val(a_);
5a6932d5 151#if SNAN_BIT_IS_ONE
b645bb48
TS
152 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
153#else
154 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
155#endif
158142c2
FB
156}
157
158/*----------------------------------------------------------------------------
159| Returns 1 if the single-precision floating-point value `a' is a signaling
160| NaN; otherwise returns 0.
161*----------------------------------------------------------------------------*/
162
f090c9d4 163int float32_is_signaling_nan( float32 a_ )
158142c2 164{
f090c9d4 165 uint32_t a = float32_val(a_);
5a6932d5 166#if SNAN_BIT_IS_ONE
b645bb48
TS
167 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
168#else
158142c2 169 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
b645bb48 170#endif
158142c2
FB
171}
172
b408dbde
PM
173/*----------------------------------------------------------------------------
174| Returns a quiet NaN if the single-precision floating point value `a' is a
175| signaling NaN; otherwise returns `a'.
176*----------------------------------------------------------------------------*/
177
178float32 float32_maybe_silence_nan( float32 a_ )
179{
180 if (float32_is_signaling_nan(a_)) {
b408dbde 181#if SNAN_BIT_IS_ONE
e9087750 182# if defined(TARGET_MIPS) || defined(TARGET_SH4)
93ae1c6f
AJ
183 return float32_default_nan;
184# else
185# error Rules for silencing a signaling NaN are target-specific
186# endif
b408dbde 187#else
93ae1c6f 188 bits32 a = float32_val(a_);
b408dbde 189 a |= (1 << 22);
b408dbde 190 return make_float32(a);
93ae1c6f 191#endif
b408dbde
PM
192 }
193 return a_;
194}
195
158142c2
FB
196/*----------------------------------------------------------------------------
197| Returns the result of converting the single-precision floating-point NaN
198| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
199| exception is raised.
200*----------------------------------------------------------------------------*/
201
202static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
203{
204 commonNaNT z;
205
206 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
f090c9d4 207 z.sign = float32_val(a)>>31;
158142c2 208 z.low = 0;
f090c9d4 209 z.high = ( (bits64) float32_val(a) )<<41;
158142c2 210 return z;
158142c2
FB
211}
212
213/*----------------------------------------------------------------------------
214| Returns the result of converting the canonical NaN `a' to the single-
215| precision floating-point format.
216*----------------------------------------------------------------------------*/
217
bcd4d9af 218static float32 commonNaNToFloat32( commonNaNT a STATUS_PARAM)
158142c2 219{
85016c98 220 bits32 mantissa = a.high>>41;
bcd4d9af
CL
221
222 if ( STATUS(default_nan_mode) ) {
223 return float32_default_nan;
224 }
225
85016c98
TS
226 if ( mantissa )
227 return make_float32(
228 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
229 else
230 return float32_default_nan;
158142c2
FB
231}
232
354f211b
PM
233/*----------------------------------------------------------------------------
234| Select which NaN to propagate for a two-input operation.
235| IEEE754 doesn't specify all the details of this, so the
236| algorithm is target-specific.
237| The routine is passed various bits of information about the
238| two NaNs and should return 0 to select NaN a and 1 for NaN b.
239| Note that signalling NaNs are always squashed to quiet NaNs
1f398e08
AJ
240| by the caller, by calling floatXX_maybe_silence_nan() before
241| returning them.
354f211b
PM
242|
243| aIsLargerSignificand is only valid if both a and b are NaNs
244| of some kind, and is true if a has the larger significand,
245| or if both a and b have the same significand but a is
246| positive but b is negative. It is only needed for the x87
247| tie-break rule.
248*----------------------------------------------------------------------------*/
249
011da610
PM
250#if defined(TARGET_ARM)
251static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
252 flag aIsLargerSignificand)
253{
254 /* ARM mandated NaN propagation rules: take the first of:
255 * 1. A if it is signaling
256 * 2. B if it is signaling
257 * 3. A (quiet)
258 * 4. B (quiet)
259 * A signaling NaN is always quietened before returning it.
260 */
261 if (aIsSNaN) {
262 return 0;
263 } else if (bIsSNaN) {
264 return 1;
265 } else if (aIsQNaN) {
266 return 0;
267 } else {
268 return 1;
269 }
270}
084d19ba
AJ
271#elif defined(TARGET_MIPS)
272static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
273 flag aIsLargerSignificand)
274{
275 /* According to MIPS specifications, if one of the two operands is
276 * a sNaN, a new qNaN has to be generated. This is done in
277 * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
278 * says: "When possible, this QNaN result is one of the operand QNaN
279 * values." In practice it seems that most implementations choose
280 * the first operand if both operands are qNaN. In short this gives
281 * the following rules:
282 * 1. A if it is signaling
283 * 2. B if it is signaling
284 * 3. A (quiet)
285 * 4. B (quiet)
286 * A signaling NaN is always silenced before returning it.
287 */
288 if (aIsSNaN) {
289 return 0;
290 } else if (bIsSNaN) {
291 return 1;
292 } else if (aIsQNaN) {
293 return 0;
294 } else {
295 return 1;
296 }
297}
e024e881
AJ
298#elif defined(TARGET_PPC)
299static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
300 flag aIsLargerSignificand)
301{
302 /* PowerPC propagation rules:
303 * 1. A if it sNaN or qNaN
304 * 2. B if it sNaN or qNaN
305 * A signaling NaN is always silenced before returning it.
306 */
307 if (aIsSNaN || aIsQNaN) {
308 return 0;
309 } else {
310 return 1;
311 }
312}
011da610 313#else
354f211b
PM
314static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
315 flag aIsLargerSignificand)
316{
317 /* This implements x87 NaN propagation rules:
318 * SNaN + QNaN => return the QNaN
319 * two SNaNs => return the one with the larger significand, silenced
320 * two QNaNs => return the one with the larger significand
321 * SNaN and a non-NaN => return the SNaN, silenced
322 * QNaN and a non-NaN => return the QNaN
323 *
324 * If we get down to comparing significands and they are the same,
325 * return the NaN with the positive sign bit (if any).
326 */
327 if (aIsSNaN) {
328 if (bIsSNaN) {
329 return aIsLargerSignificand ? 0 : 1;
330 }
331 return bIsQNaN ? 1 : 0;
332 }
333 else if (aIsQNaN) {
334 if (bIsSNaN || !bIsQNaN)
335 return 0;
336 else {
337 return aIsLargerSignificand ? 0 : 1;
338 }
339 } else {
340 return 1;
341 }
342}
011da610 343#endif
354f211b 344
158142c2
FB
345/*----------------------------------------------------------------------------
346| Takes two single-precision floating-point values `a' and `b', one of which
347| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
348| signaling NaN, the invalid exception is raised.
349*----------------------------------------------------------------------------*/
350
351static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
352{
d735d695
AJ
353 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
354 flag aIsLargerSignificand;
1f398e08 355 bits32 av, bv;
158142c2 356
d735d695 357 aIsQuietNaN = float32_is_quiet_nan( a );
158142c2 358 aIsSignalingNaN = float32_is_signaling_nan( a );
d735d695 359 bIsQuietNaN = float32_is_quiet_nan( b );
158142c2 360 bIsSignalingNaN = float32_is_signaling_nan( b );
f090c9d4
PB
361 av = float32_val(a);
362 bv = float32_val(b);
1f398e08 363
158142c2 364 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
354f211b 365
10201602
AJ
366 if ( STATUS(default_nan_mode) )
367 return float32_default_nan;
368
354f211b
PM
369 if ((bits32)(av<<1) < (bits32)(bv<<1)) {
370 aIsLargerSignificand = 0;
371 } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
372 aIsLargerSignificand = 1;
373 } else {
374 aIsLargerSignificand = (av < bv) ? 1 : 0;
158142c2 375 }
354f211b 376
d735d695 377 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
354f211b 378 aIsLargerSignificand)) {
1f398e08 379 return float32_maybe_silence_nan(b);
354f211b 380 } else {
1f398e08 381 return float32_maybe_silence_nan(a);
158142c2 382 }
158142c2
FB
383}
384
158142c2 385/*----------------------------------------------------------------------------
5a6932d5
TS
386| Returns 1 if the double-precision floating-point value `a' is a quiet
387| NaN; otherwise returns 0.
158142c2
FB
388*----------------------------------------------------------------------------*/
389
18569871 390int float64_is_quiet_nan( float64 a_ )
158142c2 391{
f090c9d4 392 bits64 a = float64_val(a_);
5a6932d5 393#if SNAN_BIT_IS_ONE
b645bb48
TS
394 return
395 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
396 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
397#else
398 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
399#endif
158142c2
FB
400}
401
402/*----------------------------------------------------------------------------
403| Returns 1 if the double-precision floating-point value `a' is a signaling
404| NaN; otherwise returns 0.
405*----------------------------------------------------------------------------*/
406
f090c9d4 407int float64_is_signaling_nan( float64 a_ )
158142c2 408{
f090c9d4 409 bits64 a = float64_val(a_);
5a6932d5 410#if SNAN_BIT_IS_ONE
b645bb48
TS
411 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
412#else
158142c2
FB
413 return
414 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
415 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
b645bb48 416#endif
158142c2
FB
417}
418
b408dbde
PM
419/*----------------------------------------------------------------------------
420| Returns a quiet NaN if the double-precision floating point value `a' is a
421| signaling NaN; otherwise returns `a'.
422*----------------------------------------------------------------------------*/
423
424float64 float64_maybe_silence_nan( float64 a_ )
425{
426 if (float64_is_signaling_nan(a_)) {
b408dbde 427#if SNAN_BIT_IS_ONE
e9087750 428# if defined(TARGET_MIPS) || defined(TARGET_SH4)
93ae1c6f
AJ
429 return float64_default_nan;
430# else
431# error Rules for silencing a signaling NaN are target-specific
432# endif
b408dbde 433#else
93ae1c6f 434 bits64 a = float64_val(a_);
b408dbde 435 a |= LIT64( 0x0008000000000000 );
b408dbde 436 return make_float64(a);
93ae1c6f 437#endif
b408dbde
PM
438 }
439 return a_;
440}
441
158142c2
FB
442/*----------------------------------------------------------------------------
443| Returns the result of converting the double-precision floating-point NaN
444| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
445| exception is raised.
446*----------------------------------------------------------------------------*/
447
448static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
449{
450 commonNaNT z;
451
452 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
f090c9d4 453 z.sign = float64_val(a)>>63;
158142c2 454 z.low = 0;
f090c9d4 455 z.high = float64_val(a)<<12;
158142c2 456 return z;
158142c2
FB
457}
458
459/*----------------------------------------------------------------------------
460| Returns the result of converting the canonical NaN `a' to the double-
461| precision floating-point format.
462*----------------------------------------------------------------------------*/
463
bcd4d9af 464static float64 commonNaNToFloat64( commonNaNT a STATUS_PARAM)
158142c2 465{
85016c98
TS
466 bits64 mantissa = a.high>>12;
467
bcd4d9af
CL
468 if ( STATUS(default_nan_mode) ) {
469 return float64_default_nan;
470 }
471
85016c98
TS
472 if ( mantissa )
473 return make_float64(
474 ( ( (bits64) a.sign )<<63 )
475 | LIT64( 0x7FF0000000000000 )
476 | ( a.high>>12 ));
477 else
478 return float64_default_nan;
158142c2
FB
479}
480
481/*----------------------------------------------------------------------------
482| Takes two double-precision floating-point values `a' and `b', one of which
483| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
484| signaling NaN, the invalid exception is raised.
485*----------------------------------------------------------------------------*/
486
487static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
488{
d735d695
AJ
489 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
490 flag aIsLargerSignificand;
1f398e08 491 bits64 av, bv;
158142c2 492
d735d695 493 aIsQuietNaN = float64_is_quiet_nan( a );
158142c2 494 aIsSignalingNaN = float64_is_signaling_nan( a );
d735d695 495 bIsQuietNaN = float64_is_quiet_nan( b );
158142c2 496 bIsSignalingNaN = float64_is_signaling_nan( b );
f090c9d4
PB
497 av = float64_val(a);
498 bv = float64_val(b);
1f398e08 499
158142c2 500 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
354f211b 501
10201602
AJ
502 if ( STATUS(default_nan_mode) )
503 return float64_default_nan;
504
354f211b
PM
505 if ((bits64)(av<<1) < (bits64)(bv<<1)) {
506 aIsLargerSignificand = 0;
507 } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
508 aIsLargerSignificand = 1;
509 } else {
510 aIsLargerSignificand = (av < bv) ? 1 : 0;
158142c2 511 }
354f211b 512
d735d695 513 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
354f211b 514 aIsLargerSignificand)) {
1f398e08 515 return float64_maybe_silence_nan(b);
354f211b 516 } else {
1f398e08 517 return float64_maybe_silence_nan(a);
158142c2 518 }
158142c2
FB
519}
520
521#ifdef FLOATX80
522
158142c2
FB
523/*----------------------------------------------------------------------------
524| Returns 1 if the extended double-precision floating-point value `a' is a
de4af5f7
AJ
525| quiet NaN; otherwise returns 0. This slightly differs from the same
526| function for other types as floatx80 has an explicit bit.
158142c2
FB
527*----------------------------------------------------------------------------*/
528
18569871 529int floatx80_is_quiet_nan( floatx80 a )
158142c2 530{
5a6932d5
TS
531#if SNAN_BIT_IS_ONE
532 bits64 aLow;
158142c2 533
5a6932d5
TS
534 aLow = a.low & ~ LIT64( 0x4000000000000000 );
535 return
536 ( ( a.high & 0x7FFF ) == 0x7FFF )
537 && (bits64) ( aLow<<1 )
538 && ( a.low == aLow );
539#else
de4af5f7
AJ
540 return ( ( a.high & 0x7FFF ) == 0x7FFF )
541 && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
5a6932d5 542#endif
158142c2
FB
543}
544
545/*----------------------------------------------------------------------------
546| Returns 1 if the extended double-precision floating-point value `a' is a
de4af5f7
AJ
547| signaling NaN; otherwise returns 0. This slightly differs from the same
548| function for other types as floatx80 has an explicit bit.
158142c2
FB
549*----------------------------------------------------------------------------*/
550
750afe93 551int floatx80_is_signaling_nan( floatx80 a )
158142c2 552{
5a6932d5 553#if SNAN_BIT_IS_ONE
de4af5f7
AJ
554 return ( ( a.high & 0x7FFF ) == 0x7FFF )
555 && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
5a6932d5 556#else
158142c2
FB
557 bits64 aLow;
558
559 aLow = a.low & ~ LIT64( 0x4000000000000000 );
560 return
561 ( ( a.high & 0x7FFF ) == 0x7FFF )
562 && (bits64) ( aLow<<1 )
563 && ( a.low == aLow );
5a6932d5 564#endif
158142c2
FB
565}
566
f6a7d92a
AJ
567/*----------------------------------------------------------------------------
568| Returns a quiet NaN if the extended double-precision floating point value
569| `a' is a signaling NaN; otherwise returns `a'.
570*----------------------------------------------------------------------------*/
571
572floatx80 floatx80_maybe_silence_nan( floatx80 a )
573{
574 if (floatx80_is_signaling_nan(a)) {
575#if SNAN_BIT_IS_ONE
e9087750 576# if defined(TARGET_MIPS) || defined(TARGET_SH4)
f6a7d92a
AJ
577 a.low = floatx80_default_nan_low;
578 a.high = floatx80_default_nan_high;
579# else
580# error Rules for silencing a signaling NaN are target-specific
581# endif
582#else
583 a.low |= LIT64( 0xC000000000000000 );
584 return a;
585#endif
586 }
587 return a;
588}
589
158142c2
FB
590/*----------------------------------------------------------------------------
591| Returns the result of converting the extended double-precision floating-
592| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
593| invalid exception is raised.
594*----------------------------------------------------------------------------*/
595
596static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
597{
598 commonNaNT z;
599
600 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
601 z.sign = a.high>>15;
602 z.low = 0;
85016c98 603 z.high = a.low;
158142c2 604 return z;
158142c2
FB
605}
606
607/*----------------------------------------------------------------------------
608| Returns the result of converting the canonical NaN `a' to the extended
609| double-precision floating-point format.
610*----------------------------------------------------------------------------*/
611
bcd4d9af 612static floatx80 commonNaNToFloatx80( commonNaNT a STATUS_PARAM)
158142c2
FB
613{
614 floatx80 z;
615
bcd4d9af
CL
616 if ( STATUS(default_nan_mode) ) {
617 z.low = floatx80_default_nan_low;
618 z.high = floatx80_default_nan_high;
619 return z;
620 }
621
85016c98
TS
622 if (a.high)
623 z.low = a.high;
624 else
625 z.low = floatx80_default_nan_low;
158142c2
FB
626 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
627 return z;
158142c2
FB
628}
629
630/*----------------------------------------------------------------------------
631| Takes two extended double-precision floating-point values `a' and `b', one
632| of which is a NaN, and returns the appropriate NaN result. If either `a' or
633| `b' is a signaling NaN, the invalid exception is raised.
634*----------------------------------------------------------------------------*/
635
636static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
637{
d735d695
AJ
638 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
639 flag aIsLargerSignificand;
158142c2 640
d735d695 641 aIsQuietNaN = floatx80_is_quiet_nan( a );
158142c2 642 aIsSignalingNaN = floatx80_is_signaling_nan( a );
d735d695 643 bIsQuietNaN = floatx80_is_quiet_nan( b );
158142c2 644 bIsSignalingNaN = floatx80_is_signaling_nan( b );
1f398e08 645
158142c2 646 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
354f211b 647
10201602
AJ
648 if ( STATUS(default_nan_mode) ) {
649 a.low = floatx80_default_nan_low;
650 a.high = floatx80_default_nan_high;
651 return a;
652 }
653
354f211b
PM
654 if (a.low < b.low) {
655 aIsLargerSignificand = 0;
656 } else if (b.low < a.low) {
657 aIsLargerSignificand = 1;
658 } else {
659 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
158142c2 660 }
354f211b 661
d735d695 662 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
354f211b 663 aIsLargerSignificand)) {
1f398e08 664 return floatx80_maybe_silence_nan(b);
354f211b 665 } else {
1f398e08 666 return floatx80_maybe_silence_nan(a);
158142c2 667 }
158142c2
FB
668}
669
670#endif
671
672#ifdef FLOAT128
673
158142c2 674/*----------------------------------------------------------------------------
5a6932d5
TS
675| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
676| NaN; otherwise returns 0.
158142c2
FB
677*----------------------------------------------------------------------------*/
678
18569871 679int float128_is_quiet_nan( float128 a )
158142c2 680{
5a6932d5
TS
681#if SNAN_BIT_IS_ONE
682 return
683 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
684 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
685#else
158142c2
FB
686 return
687 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
688 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
5a6932d5 689#endif
158142c2
FB
690}
691
692/*----------------------------------------------------------------------------
693| Returns 1 if the quadruple-precision floating-point value `a' is a
694| signaling NaN; otherwise returns 0.
695*----------------------------------------------------------------------------*/
696
750afe93 697int float128_is_signaling_nan( float128 a )
158142c2 698{
5a6932d5
TS
699#if SNAN_BIT_IS_ONE
700 return
701 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
702 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
703#else
158142c2
FB
704 return
705 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
706 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
5a6932d5 707#endif
158142c2
FB
708}
709
f6a7d92a
AJ
710/*----------------------------------------------------------------------------
711| Returns a quiet NaN if the quadruple-precision floating point value `a' is
712| a signaling NaN; otherwise returns `a'.
713*----------------------------------------------------------------------------*/
714
715float128 float128_maybe_silence_nan( float128 a )
716{
717 if (float128_is_signaling_nan(a)) {
718#if SNAN_BIT_IS_ONE
e9087750 719# if defined(TARGET_MIPS) || defined(TARGET_SH4)
f6a7d92a
AJ
720 a.low = float128_default_nan_low;
721 a.high = float128_default_nan_high;
722# else
723# error Rules for silencing a signaling NaN are target-specific
724# endif
725#else
726 a.high |= LIT64( 0x0000800000000000 );
727 return a;
728#endif
729 }
730 return a;
731}
732
158142c2
FB
733/*----------------------------------------------------------------------------
734| Returns the result of converting the quadruple-precision floating-point NaN
735| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
736| exception is raised.
737*----------------------------------------------------------------------------*/
738
739static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
740{
741 commonNaNT z;
742
743 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
744 z.sign = a.high>>63;
745 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
746 return z;
158142c2
FB
747}
748
749/*----------------------------------------------------------------------------
750| Returns the result of converting the canonical NaN `a' to the quadruple-
751| precision floating-point format.
752*----------------------------------------------------------------------------*/
753
bcd4d9af 754static float128 commonNaNToFloat128( commonNaNT a STATUS_PARAM)
158142c2
FB
755{
756 float128 z;
757
bcd4d9af
CL
758 if ( STATUS(default_nan_mode) ) {
759 z.low = float128_default_nan_low;
760 z.high = float128_default_nan_high;
761 return z;
762 }
763
158142c2 764 shift128Right( a.high, a.low, 16, &z.high, &z.low );
85016c98 765 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
158142c2 766 return z;
158142c2
FB
767}
768
769/*----------------------------------------------------------------------------
770| Takes two quadruple-precision floating-point values `a' and `b', one of
771| which is a NaN, and returns the appropriate NaN result. If either `a' or
772| `b' is a signaling NaN, the invalid exception is raised.
773*----------------------------------------------------------------------------*/
774
775static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
776{
d735d695
AJ
777 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
778 flag aIsLargerSignificand;
158142c2 779
d735d695 780 aIsQuietNaN = float128_is_quiet_nan( a );
158142c2 781 aIsSignalingNaN = float128_is_signaling_nan( a );
d735d695 782 bIsQuietNaN = float128_is_quiet_nan( b );
158142c2 783 bIsSignalingNaN = float128_is_signaling_nan( b );
1f398e08 784
158142c2 785 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
354f211b 786
10201602
AJ
787 if ( STATUS(default_nan_mode) ) {
788 a.low = float128_default_nan_low;
789 a.high = float128_default_nan_high;
790 return a;
791 }
792
354f211b
PM
793 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
794 aIsLargerSignificand = 0;
795 } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
796 aIsLargerSignificand = 1;
797 } else {
798 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
158142c2 799 }
354f211b 800
d735d695 801 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
354f211b 802 aIsLargerSignificand)) {
1f398e08 803 return float128_maybe_silence_nan(b);
354f211b 804 } else {
1f398e08 805 return float128_maybe_silence_nan(a);
158142c2 806 }
158142c2
FB
807}
808
809#endif