]> git.proxmox.com Git - mirror_qemu.git/blame - fpu/softfloat-specialize.h
softfloat: Add float16 type and float16 NaN handling functions
[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
e9087750 33#if defined(TARGET_MIPS) || defined(TARGET_SH4)
5a6932d5
TS
34#define SNAN_BIT_IS_ONE 1
35#else
36#define SNAN_BIT_IS_ONE 0
37#endif
38
158142c2
FB
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{
158142c2 48 STATUS(float_exception_flags) |= flags;
158142c2
FB
49}
50
51/*----------------------------------------------------------------------------
52| Internal canonical NaN format.
53*----------------------------------------------------------------------------*/
54typedef struct {
55 flag sign;
56 bits64 high, low;
57} commonNaNT;
58
bb4d4bb3
PM
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
158142c2
FB
122/*----------------------------------------------------------------------------
123| The pattern for a default generated single-precision NaN.
124*----------------------------------------------------------------------------*/
85016c98
TS
125#if defined(TARGET_SPARC)
126#define float32_default_nan make_float32(0x7FFFFFFF)
e024e881 127#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
85016c98 128#define float32_default_nan make_float32(0x7FC00000)
85016c98 129#elif SNAN_BIT_IS_ONE
f090c9d4 130#define float32_default_nan make_float32(0x7FBFFFFF)
b645bb48 131#else
f090c9d4 132#define float32_default_nan make_float32(0xFFC00000)
b645bb48 133#endif
158142c2
FB
134
135/*----------------------------------------------------------------------------
5a6932d5
TS
136| Returns 1 if the single-precision floating-point value `a' is a quiet
137| NaN; otherwise returns 0.
158142c2
FB
138*----------------------------------------------------------------------------*/
139
18569871 140int float32_is_quiet_nan( float32 a_ )
158142c2 141{
f090c9d4 142 uint32_t a = float32_val(a_);
5a6932d5 143#if SNAN_BIT_IS_ONE
b645bb48
TS
144 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
145#else
146 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
147#endif
158142c2
FB
148}
149
150/*----------------------------------------------------------------------------
151| Returns 1 if the single-precision floating-point value `a' is a signaling
152| NaN; otherwise returns 0.
153*----------------------------------------------------------------------------*/
154
f090c9d4 155int float32_is_signaling_nan( float32 a_ )
158142c2 156{
f090c9d4 157 uint32_t a = float32_val(a_);
5a6932d5 158#if SNAN_BIT_IS_ONE
b645bb48
TS
159 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
160#else
158142c2 161 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
b645bb48 162#endif
158142c2
FB
163}
164
b408dbde
PM
165/*----------------------------------------------------------------------------
166| Returns a quiet NaN if the single-precision floating point value `a' is a
167| signaling NaN; otherwise returns `a'.
168*----------------------------------------------------------------------------*/
169
170float32 float32_maybe_silence_nan( float32 a_ )
171{
172 if (float32_is_signaling_nan(a_)) {
b408dbde 173#if SNAN_BIT_IS_ONE
e9087750 174# if defined(TARGET_MIPS) || defined(TARGET_SH4)
93ae1c6f
AJ
175 return float32_default_nan;
176# else
177# error Rules for silencing a signaling NaN are target-specific
178# endif
b408dbde 179#else
93ae1c6f 180 bits32 a = float32_val(a_);
b408dbde 181 a |= (1 << 22);
b408dbde 182 return make_float32(a);
93ae1c6f 183#endif
b408dbde
PM
184 }
185 return a_;
186}
187
158142c2
FB
188/*----------------------------------------------------------------------------
189| Returns the result of converting the single-precision floating-point NaN
190| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
191| exception is raised.
192*----------------------------------------------------------------------------*/
193
194static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
195{
196 commonNaNT z;
197
198 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
f090c9d4 199 z.sign = float32_val(a)>>31;
158142c2 200 z.low = 0;
f090c9d4 201 z.high = ( (bits64) float32_val(a) )<<41;
158142c2 202 return z;
158142c2
FB
203}
204
205/*----------------------------------------------------------------------------
206| Returns the result of converting the canonical NaN `a' to the single-
207| precision floating-point format.
208*----------------------------------------------------------------------------*/
209
210static float32 commonNaNToFloat32( commonNaNT a )
211{
85016c98
TS
212 bits32 mantissa = a.high>>41;
213 if ( mantissa )
214 return make_float32(
215 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
216 else
217 return float32_default_nan;
158142c2
FB
218}
219
354f211b
PM
220/*----------------------------------------------------------------------------
221| Select which NaN to propagate for a two-input operation.
222| IEEE754 doesn't specify all the details of this, so the
223| algorithm is target-specific.
224| The routine is passed various bits of information about the
225| two NaNs and should return 0 to select NaN a and 1 for NaN b.
226| Note that signalling NaNs are always squashed to quiet NaNs
1f398e08
AJ
227| by the caller, by calling floatXX_maybe_silence_nan() before
228| returning them.
354f211b
PM
229|
230| aIsLargerSignificand is only valid if both a and b are NaNs
231| of some kind, and is true if a has the larger significand,
232| or if both a and b have the same significand but a is
233| positive but b is negative. It is only needed for the x87
234| tie-break rule.
235*----------------------------------------------------------------------------*/
236
011da610
PM
237#if defined(TARGET_ARM)
238static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
239 flag aIsLargerSignificand)
240{
241 /* ARM mandated NaN propagation rules: take the first of:
242 * 1. A if it is signaling
243 * 2. B if it is signaling
244 * 3. A (quiet)
245 * 4. B (quiet)
246 * A signaling NaN is always quietened before returning it.
247 */
248 if (aIsSNaN) {
249 return 0;
250 } else if (bIsSNaN) {
251 return 1;
252 } else if (aIsQNaN) {
253 return 0;
254 } else {
255 return 1;
256 }
257}
084d19ba
AJ
258#elif defined(TARGET_MIPS)
259static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
260 flag aIsLargerSignificand)
261{
262 /* According to MIPS specifications, if one of the two operands is
263 * a sNaN, a new qNaN has to be generated. This is done in
264 * floatXX_maybe_silence_nan(). For qNaN inputs the specifications
265 * says: "When possible, this QNaN result is one of the operand QNaN
266 * values." In practice it seems that most implementations choose
267 * the first operand if both operands are qNaN. In short this gives
268 * the following rules:
269 * 1. A if it is signaling
270 * 2. B if it is signaling
271 * 3. A (quiet)
272 * 4. B (quiet)
273 * A signaling NaN is always silenced before returning it.
274 */
275 if (aIsSNaN) {
276 return 0;
277 } else if (bIsSNaN) {
278 return 1;
279 } else if (aIsQNaN) {
280 return 0;
281 } else {
282 return 1;
283 }
284}
e024e881
AJ
285#elif defined(TARGET_PPC)
286static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
287 flag aIsLargerSignificand)
288{
289 /* PowerPC propagation rules:
290 * 1. A if it sNaN or qNaN
291 * 2. B if it sNaN or qNaN
292 * A signaling NaN is always silenced before returning it.
293 */
294 if (aIsSNaN || aIsQNaN) {
295 return 0;
296 } else {
297 return 1;
298 }
299}
011da610 300#else
354f211b
PM
301static int pickNaN(flag aIsQNaN, flag aIsSNaN, flag bIsQNaN, flag bIsSNaN,
302 flag aIsLargerSignificand)
303{
304 /* This implements x87 NaN propagation rules:
305 * SNaN + QNaN => return the QNaN
306 * two SNaNs => return the one with the larger significand, silenced
307 * two QNaNs => return the one with the larger significand
308 * SNaN and a non-NaN => return the SNaN, silenced
309 * QNaN and a non-NaN => return the QNaN
310 *
311 * If we get down to comparing significands and they are the same,
312 * return the NaN with the positive sign bit (if any).
313 */
314 if (aIsSNaN) {
315 if (bIsSNaN) {
316 return aIsLargerSignificand ? 0 : 1;
317 }
318 return bIsQNaN ? 1 : 0;
319 }
320 else if (aIsQNaN) {
321 if (bIsSNaN || !bIsQNaN)
322 return 0;
323 else {
324 return aIsLargerSignificand ? 0 : 1;
325 }
326 } else {
327 return 1;
328 }
329}
011da610 330#endif
354f211b 331
158142c2
FB
332/*----------------------------------------------------------------------------
333| Takes two single-precision floating-point values `a' and `b', one of which
334| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
335| signaling NaN, the invalid exception is raised.
336*----------------------------------------------------------------------------*/
337
338static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
339{
d735d695
AJ
340 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
341 flag aIsLargerSignificand;
1f398e08 342 bits32 av, bv;
158142c2 343
d735d695 344 aIsQuietNaN = float32_is_quiet_nan( a );
158142c2 345 aIsSignalingNaN = float32_is_signaling_nan( a );
d735d695 346 bIsQuietNaN = float32_is_quiet_nan( b );
158142c2 347 bIsSignalingNaN = float32_is_signaling_nan( b );
f090c9d4
PB
348 av = float32_val(a);
349 bv = float32_val(b);
1f398e08 350
158142c2 351 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
354f211b 352
10201602
AJ
353 if ( STATUS(default_nan_mode) )
354 return float32_default_nan;
355
354f211b
PM
356 if ((bits32)(av<<1) < (bits32)(bv<<1)) {
357 aIsLargerSignificand = 0;
358 } else if ((bits32)(bv<<1) < (bits32)(av<<1)) {
359 aIsLargerSignificand = 1;
360 } else {
361 aIsLargerSignificand = (av < bv) ? 1 : 0;
158142c2 362 }
354f211b 363
d735d695 364 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
354f211b 365 aIsLargerSignificand)) {
1f398e08 366 return float32_maybe_silence_nan(b);
354f211b 367 } else {
1f398e08 368 return float32_maybe_silence_nan(a);
158142c2 369 }
158142c2
FB
370}
371
372/*----------------------------------------------------------------------------
373| The pattern for a default generated double-precision NaN.
374*----------------------------------------------------------------------------*/
85016c98
TS
375#if defined(TARGET_SPARC)
376#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
e024e881 377#elif defined(TARGET_PPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
85016c98 378#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
85016c98 379#elif SNAN_BIT_IS_ONE
f090c9d4 380#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
b645bb48 381#else
f090c9d4 382#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
b645bb48 383#endif
158142c2
FB
384
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
464static float64 commonNaNToFloat64( commonNaNT a )
465{
85016c98
TS
466 bits64 mantissa = a.high>>12;
467
468 if ( mantissa )
469 return make_float64(
470 ( ( (bits64) a.sign )<<63 )
471 | LIT64( 0x7FF0000000000000 )
472 | ( a.high>>12 ));
473 else
474 return float64_default_nan;
158142c2
FB
475}
476
477/*----------------------------------------------------------------------------
478| Takes two double-precision floating-point values `a' and `b', one of which
479| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
480| signaling NaN, the invalid exception is raised.
481*----------------------------------------------------------------------------*/
482
483static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
484{
d735d695
AJ
485 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
486 flag aIsLargerSignificand;
1f398e08 487 bits64 av, bv;
158142c2 488
d735d695 489 aIsQuietNaN = float64_is_quiet_nan( a );
158142c2 490 aIsSignalingNaN = float64_is_signaling_nan( a );
d735d695 491 bIsQuietNaN = float64_is_quiet_nan( b );
158142c2 492 bIsSignalingNaN = float64_is_signaling_nan( b );
f090c9d4
PB
493 av = float64_val(a);
494 bv = float64_val(b);
1f398e08 495
158142c2 496 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
354f211b 497
10201602
AJ
498 if ( STATUS(default_nan_mode) )
499 return float64_default_nan;
500
354f211b
PM
501 if ((bits64)(av<<1) < (bits64)(bv<<1)) {
502 aIsLargerSignificand = 0;
503 } else if ((bits64)(bv<<1) < (bits64)(av<<1)) {
504 aIsLargerSignificand = 1;
505 } else {
506 aIsLargerSignificand = (av < bv) ? 1 : 0;
158142c2 507 }
354f211b 508
d735d695 509 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
354f211b 510 aIsLargerSignificand)) {
1f398e08 511 return float64_maybe_silence_nan(b);
354f211b 512 } else {
1f398e08 513 return float64_maybe_silence_nan(a);
158142c2 514 }
158142c2
FB
515}
516
517#ifdef FLOATX80
518
519/*----------------------------------------------------------------------------
520| The pattern for a default generated extended double-precision NaN. The
521| `high' and `low' values hold the most- and least-significant bits,
522| respectively.
523*----------------------------------------------------------------------------*/
5a6932d5
TS
524#if SNAN_BIT_IS_ONE
525#define floatx80_default_nan_high 0x7FFF
526#define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
527#else
158142c2
FB
528#define floatx80_default_nan_high 0xFFFF
529#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
5a6932d5 530#endif
158142c2
FB
531
532/*----------------------------------------------------------------------------
533| Returns 1 if the extended double-precision floating-point value `a' is a
de4af5f7
AJ
534| quiet NaN; otherwise returns 0. This slightly differs from the same
535| function for other types as floatx80 has an explicit bit.
158142c2
FB
536*----------------------------------------------------------------------------*/
537
18569871 538int floatx80_is_quiet_nan( floatx80 a )
158142c2 539{
5a6932d5
TS
540#if SNAN_BIT_IS_ONE
541 bits64 aLow;
158142c2 542
5a6932d5
TS
543 aLow = a.low & ~ LIT64( 0x4000000000000000 );
544 return
545 ( ( a.high & 0x7FFF ) == 0x7FFF )
546 && (bits64) ( aLow<<1 )
547 && ( a.low == aLow );
548#else
de4af5f7
AJ
549 return ( ( a.high & 0x7FFF ) == 0x7FFF )
550 && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
5a6932d5 551#endif
158142c2
FB
552}
553
554/*----------------------------------------------------------------------------
555| Returns 1 if the extended double-precision floating-point value `a' is a
de4af5f7
AJ
556| signaling NaN; otherwise returns 0. This slightly differs from the same
557| function for other types as floatx80 has an explicit bit.
158142c2
FB
558*----------------------------------------------------------------------------*/
559
750afe93 560int floatx80_is_signaling_nan( floatx80 a )
158142c2 561{
5a6932d5 562#if SNAN_BIT_IS_ONE
de4af5f7
AJ
563 return ( ( a.high & 0x7FFF ) == 0x7FFF )
564 && (LIT64( 0x8000000000000000 ) <= ((bits64) ( a.low<<1 )));
5a6932d5 565#else
158142c2
FB
566 bits64 aLow;
567
568 aLow = a.low & ~ LIT64( 0x4000000000000000 );
569 return
570 ( ( a.high & 0x7FFF ) == 0x7FFF )
571 && (bits64) ( aLow<<1 )
572 && ( a.low == aLow );
5a6932d5 573#endif
158142c2
FB
574}
575
f6a7d92a
AJ
576/*----------------------------------------------------------------------------
577| Returns a quiet NaN if the extended double-precision floating point value
578| `a' is a signaling NaN; otherwise returns `a'.
579*----------------------------------------------------------------------------*/
580
581floatx80 floatx80_maybe_silence_nan( floatx80 a )
582{
583 if (floatx80_is_signaling_nan(a)) {
584#if SNAN_BIT_IS_ONE
e9087750 585# if defined(TARGET_MIPS) || defined(TARGET_SH4)
f6a7d92a
AJ
586 a.low = floatx80_default_nan_low;
587 a.high = floatx80_default_nan_high;
588# else
589# error Rules for silencing a signaling NaN are target-specific
590# endif
591#else
592 a.low |= LIT64( 0xC000000000000000 );
593 return a;
594#endif
595 }
596 return a;
597}
598
158142c2
FB
599/*----------------------------------------------------------------------------
600| Returns the result of converting the extended double-precision floating-
601| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
602| invalid exception is raised.
603*----------------------------------------------------------------------------*/
604
605static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
606{
607 commonNaNT z;
608
609 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
610 z.sign = a.high>>15;
611 z.low = 0;
85016c98 612 z.high = a.low;
158142c2 613 return z;
158142c2
FB
614}
615
616/*----------------------------------------------------------------------------
617| Returns the result of converting the canonical NaN `a' to the extended
618| double-precision floating-point format.
619*----------------------------------------------------------------------------*/
620
621static floatx80 commonNaNToFloatx80( commonNaNT a )
622{
623 floatx80 z;
624
85016c98
TS
625 if (a.high)
626 z.low = a.high;
627 else
628 z.low = floatx80_default_nan_low;
158142c2
FB
629 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
630 return z;
158142c2
FB
631}
632
633/*----------------------------------------------------------------------------
634| Takes two extended double-precision floating-point values `a' and `b', one
635| of which is a NaN, and returns the appropriate NaN result. If either `a' or
636| `b' is a signaling NaN, the invalid exception is raised.
637*----------------------------------------------------------------------------*/
638
639static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
640{
d735d695
AJ
641 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
642 flag aIsLargerSignificand;
158142c2 643
d735d695 644 aIsQuietNaN = floatx80_is_quiet_nan( a );
158142c2 645 aIsSignalingNaN = floatx80_is_signaling_nan( a );
d735d695 646 bIsQuietNaN = floatx80_is_quiet_nan( b );
158142c2 647 bIsSignalingNaN = floatx80_is_signaling_nan( b );
1f398e08 648
158142c2 649 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
354f211b 650
10201602
AJ
651 if ( STATUS(default_nan_mode) ) {
652 a.low = floatx80_default_nan_low;
653 a.high = floatx80_default_nan_high;
654 return a;
655 }
656
354f211b
PM
657 if (a.low < b.low) {
658 aIsLargerSignificand = 0;
659 } else if (b.low < a.low) {
660 aIsLargerSignificand = 1;
661 } else {
662 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
158142c2 663 }
354f211b 664
d735d695 665 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
354f211b 666 aIsLargerSignificand)) {
1f398e08 667 return floatx80_maybe_silence_nan(b);
354f211b 668 } else {
1f398e08 669 return floatx80_maybe_silence_nan(a);
158142c2 670 }
158142c2
FB
671}
672
673#endif
674
675#ifdef FLOAT128
676
677/*----------------------------------------------------------------------------
678| The pattern for a default generated quadruple-precision NaN. The `high' and
679| `low' values hold the most- and least-significant bits, respectively.
680*----------------------------------------------------------------------------*/
5a6932d5
TS
681#if SNAN_BIT_IS_ONE
682#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
683#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
684#else
158142c2
FB
685#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
686#define float128_default_nan_low LIT64( 0x0000000000000000 )
5a6932d5 687#endif
158142c2
FB
688
689/*----------------------------------------------------------------------------
5a6932d5
TS
690| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
691| NaN; otherwise returns 0.
158142c2
FB
692*----------------------------------------------------------------------------*/
693
18569871 694int float128_is_quiet_nan( float128 a )
158142c2 695{
5a6932d5
TS
696#if SNAN_BIT_IS_ONE
697 return
698 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
699 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
700#else
158142c2
FB
701 return
702 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
703 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
5a6932d5 704#endif
158142c2
FB
705}
706
707/*----------------------------------------------------------------------------
708| Returns 1 if the quadruple-precision floating-point value `a' is a
709| signaling NaN; otherwise returns 0.
710*----------------------------------------------------------------------------*/
711
750afe93 712int float128_is_signaling_nan( float128 a )
158142c2 713{
5a6932d5
TS
714#if SNAN_BIT_IS_ONE
715 return
716 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
717 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
718#else
158142c2
FB
719 return
720 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
721 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
5a6932d5 722#endif
158142c2
FB
723}
724
f6a7d92a
AJ
725/*----------------------------------------------------------------------------
726| Returns a quiet NaN if the quadruple-precision floating point value `a' is
727| a signaling NaN; otherwise returns `a'.
728*----------------------------------------------------------------------------*/
729
730float128 float128_maybe_silence_nan( float128 a )
731{
732 if (float128_is_signaling_nan(a)) {
733#if SNAN_BIT_IS_ONE
e9087750 734# if defined(TARGET_MIPS) || defined(TARGET_SH4)
f6a7d92a
AJ
735 a.low = float128_default_nan_low;
736 a.high = float128_default_nan_high;
737# else
738# error Rules for silencing a signaling NaN are target-specific
739# endif
740#else
741 a.high |= LIT64( 0x0000800000000000 );
742 return a;
743#endif
744 }
745 return a;
746}
747
158142c2
FB
748/*----------------------------------------------------------------------------
749| Returns the result of converting the quadruple-precision floating-point NaN
750| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
751| exception is raised.
752*----------------------------------------------------------------------------*/
753
754static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
755{
756 commonNaNT z;
757
758 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
759 z.sign = a.high>>63;
760 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
761 return z;
158142c2
FB
762}
763
764/*----------------------------------------------------------------------------
765| Returns the result of converting the canonical NaN `a' to the quadruple-
766| precision floating-point format.
767*----------------------------------------------------------------------------*/
768
769static float128 commonNaNToFloat128( commonNaNT a )
770{
771 float128 z;
772
773 shift128Right( a.high, a.low, 16, &z.high, &z.low );
85016c98 774 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
158142c2 775 return z;
158142c2
FB
776}
777
778/*----------------------------------------------------------------------------
779| Takes two quadruple-precision floating-point values `a' and `b', one of
780| which is a NaN, and returns the appropriate NaN result. If either `a' or
781| `b' is a signaling NaN, the invalid exception is raised.
782*----------------------------------------------------------------------------*/
783
784static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
785{
d735d695
AJ
786 flag aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN;
787 flag aIsLargerSignificand;
158142c2 788
d735d695 789 aIsQuietNaN = float128_is_quiet_nan( a );
158142c2 790 aIsSignalingNaN = float128_is_signaling_nan( a );
d735d695 791 bIsQuietNaN = float128_is_quiet_nan( b );
158142c2 792 bIsSignalingNaN = float128_is_signaling_nan( b );
1f398e08 793
158142c2 794 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
354f211b 795
10201602
AJ
796 if ( STATUS(default_nan_mode) ) {
797 a.low = float128_default_nan_low;
798 a.high = float128_default_nan_high;
799 return a;
800 }
801
354f211b
PM
802 if (lt128(a.high<<1, a.low, b.high<<1, b.low)) {
803 aIsLargerSignificand = 0;
804 } else if (lt128(b.high<<1, b.low, a.high<<1, a.low)) {
805 aIsLargerSignificand = 1;
806 } else {
807 aIsLargerSignificand = (a.high < b.high) ? 1 : 0;
158142c2 808 }
354f211b 809
d735d695 810 if (pickNaN(aIsQuietNaN, aIsSignalingNaN, bIsQuietNaN, bIsSignalingNaN,
354f211b 811 aIsLargerSignificand)) {
1f398e08 812 return float128_maybe_silence_nan(b);
354f211b 813 } else {
1f398e08 814 return float128_maybe_silence_nan(a);
158142c2 815 }
158142c2
FB
816}
817
818#endif