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