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