]> git.proxmox.com Git - qemu.git/blame - fpu/softfloat-specialize.h
TCG: Improve tb_phys_hash_func()
[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
5a6932d5
TS
33#if defined(TARGET_MIPS) || defined(TARGET_HPPA)
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
TS
65#define float32_default_nan make_float32(0x7FC00000)
66#elif defined(TARGET_HPPA)
67#define float32_default_nan make_float32(0x7FA00000)
68#elif SNAN_BIT_IS_ONE
f090c9d4 69#define float32_default_nan make_float32(0x7FBFFFFF)
b645bb48 70#else
f090c9d4 71#define float32_default_nan make_float32(0xFFC00000)
b645bb48 72#endif
158142c2
FB
73
74/*----------------------------------------------------------------------------
5a6932d5
TS
75| Returns 1 if the single-precision floating-point value `a' is a quiet
76| NaN; otherwise returns 0.
158142c2
FB
77*----------------------------------------------------------------------------*/
78
f090c9d4 79int float32_is_nan( float32 a_ )
158142c2 80{
f090c9d4 81 uint32_t a = float32_val(a_);
5a6932d5 82#if SNAN_BIT_IS_ONE
b645bb48
TS
83 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
84#else
85 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
86#endif
158142c2
FB
87}
88
89/*----------------------------------------------------------------------------
90| Returns 1 if the single-precision floating-point value `a' is a signaling
91| NaN; otherwise returns 0.
92*----------------------------------------------------------------------------*/
93
f090c9d4 94int float32_is_signaling_nan( float32 a_ )
158142c2 95{
f090c9d4 96 uint32_t a = float32_val(a_);
5a6932d5 97#if SNAN_BIT_IS_ONE
b645bb48
TS
98 return ( 0xFF800000 <= (bits32) ( a<<1 ) );
99#else
158142c2 100 return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
b645bb48 101#endif
158142c2
FB
102}
103
b408dbde
PM
104/*----------------------------------------------------------------------------
105| Returns a quiet NaN if the single-precision floating point value `a' is a
106| signaling NaN; otherwise returns `a'.
107*----------------------------------------------------------------------------*/
108
109float32 float32_maybe_silence_nan( float32 a_ )
110{
111 if (float32_is_signaling_nan(a_)) {
112 uint32_t a = float32_val(a_);
113#if SNAN_BIT_IS_ONE
114 a &= ~(1 << 22);
115#else
116 a |= (1 << 22);
117#endif
118 return make_float32(a);
119 }
120 return a_;
121}
122
158142c2
FB
123/*----------------------------------------------------------------------------
124| Returns the result of converting the single-precision floating-point NaN
125| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
126| exception is raised.
127*----------------------------------------------------------------------------*/
128
129static commonNaNT float32ToCommonNaN( float32 a STATUS_PARAM )
130{
131 commonNaNT z;
132
133 if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR );
f090c9d4 134 z.sign = float32_val(a)>>31;
158142c2 135 z.low = 0;
f090c9d4 136 z.high = ( (bits64) float32_val(a) )<<41;
158142c2 137 return z;
158142c2
FB
138}
139
140/*----------------------------------------------------------------------------
141| Returns the result of converting the canonical NaN `a' to the single-
142| precision floating-point format.
143*----------------------------------------------------------------------------*/
144
145static float32 commonNaNToFloat32( commonNaNT a )
146{
85016c98
TS
147 bits32 mantissa = a.high>>41;
148 if ( mantissa )
149 return make_float32(
150 ( ( (bits32) a.sign )<<31 ) | 0x7F800000 | ( a.high>>41 ) );
151 else
152 return float32_default_nan;
158142c2
FB
153}
154
155/*----------------------------------------------------------------------------
156| Takes two single-precision floating-point values `a' and `b', one of which
157| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
158| signaling NaN, the invalid exception is raised.
159*----------------------------------------------------------------------------*/
160
161static float32 propagateFloat32NaN( float32 a, float32 b STATUS_PARAM)
162{
163 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
f090c9d4 164 bits32 av, bv, res;
158142c2 165
5c7908ed
PB
166 if ( STATUS(default_nan_mode) )
167 return float32_default_nan;
168
158142c2
FB
169 aIsNaN = float32_is_nan( a );
170 aIsSignalingNaN = float32_is_signaling_nan( a );
171 bIsNaN = float32_is_nan( b );
172 bIsSignalingNaN = float32_is_signaling_nan( b );
f090c9d4
PB
173 av = float32_val(a);
174 bv = float32_val(b);
5a6932d5 175#if SNAN_BIT_IS_ONE
f090c9d4
PB
176 av &= ~0x00400000;
177 bv &= ~0x00400000;
b645bb48 178#else
f090c9d4
PB
179 av |= 0x00400000;
180 bv |= 0x00400000;
b645bb48 181#endif
158142c2
FB
182 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
183 if ( aIsSignalingNaN ) {
184 if ( bIsSignalingNaN ) goto returnLargerSignificand;
f090c9d4 185 res = bIsNaN ? bv : av;
158142c2
FB
186 }
187 else if ( aIsNaN ) {
70c14705 188 if ( bIsSignalingNaN || ! bIsNaN )
f090c9d4
PB
189 res = av;
190 else {
158142c2 191 returnLargerSignificand:
f090c9d4
PB
192 if ( (bits32) ( av<<1 ) < (bits32) ( bv<<1 ) )
193 res = bv;
194 else if ( (bits32) ( bv<<1 ) < (bits32) ( av<<1 ) )
195 res = av;
196 else
197 res = ( av < bv ) ? av : bv;
198 }
158142c2
FB
199 }
200 else {
f090c9d4 201 res = bv;
158142c2 202 }
f090c9d4 203 return make_float32(res);
158142c2
FB
204}
205
206/*----------------------------------------------------------------------------
207| The pattern for a default generated double-precision NaN.
208*----------------------------------------------------------------------------*/
85016c98
TS
209#if defined(TARGET_SPARC)
210#define float64_default_nan make_float64(LIT64( 0x7FFFFFFFFFFFFFFF ))
990b3e19 211#elif defined(TARGET_POWERPC) || defined(TARGET_ARM) || defined(TARGET_ALPHA)
85016c98
TS
212#define float64_default_nan make_float64(LIT64( 0x7FF8000000000000 ))
213#elif defined(TARGET_HPPA)
214#define float64_default_nan make_float64(LIT64( 0x7FF4000000000000 ))
215#elif SNAN_BIT_IS_ONE
f090c9d4 216#define float64_default_nan make_float64(LIT64( 0x7FF7FFFFFFFFFFFF ))
b645bb48 217#else
f090c9d4 218#define float64_default_nan make_float64(LIT64( 0xFFF8000000000000 ))
b645bb48 219#endif
158142c2
FB
220
221/*----------------------------------------------------------------------------
5a6932d5
TS
222| Returns 1 if the double-precision floating-point value `a' is a quiet
223| NaN; otherwise returns 0.
158142c2
FB
224*----------------------------------------------------------------------------*/
225
f090c9d4 226int float64_is_nan( float64 a_ )
158142c2 227{
f090c9d4 228 bits64 a = float64_val(a_);
5a6932d5 229#if SNAN_BIT_IS_ONE
b645bb48
TS
230 return
231 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
232 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
233#else
234 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
235#endif
158142c2
FB
236}
237
238/*----------------------------------------------------------------------------
239| Returns 1 if the double-precision floating-point value `a' is a signaling
240| NaN; otherwise returns 0.
241*----------------------------------------------------------------------------*/
242
f090c9d4 243int float64_is_signaling_nan( float64 a_ )
158142c2 244{
f090c9d4 245 bits64 a = float64_val(a_);
5a6932d5 246#if SNAN_BIT_IS_ONE
b645bb48
TS
247 return ( LIT64( 0xFFF0000000000000 ) <= (bits64) ( a<<1 ) );
248#else
158142c2
FB
249 return
250 ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
251 && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
b645bb48 252#endif
158142c2
FB
253}
254
b408dbde
PM
255/*----------------------------------------------------------------------------
256| Returns a quiet NaN if the double-precision floating point value `a' is a
257| signaling NaN; otherwise returns `a'.
258*----------------------------------------------------------------------------*/
259
260float64 float64_maybe_silence_nan( float64 a_ )
261{
262 if (float64_is_signaling_nan(a_)) {
263 bits64 a = float64_val(a_);
264#if SNAN_BIT_IS_ONE
265 a &= ~LIT64( 0x0008000000000000 );
266#else
267 a |= LIT64( 0x0008000000000000 );
268#endif
269 return make_float64(a);
270 }
271 return a_;
272}
273
158142c2
FB
274/*----------------------------------------------------------------------------
275| Returns the result of converting the double-precision floating-point NaN
276| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
277| exception is raised.
278*----------------------------------------------------------------------------*/
279
280static commonNaNT float64ToCommonNaN( float64 a STATUS_PARAM)
281{
282 commonNaNT z;
283
284 if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
f090c9d4 285 z.sign = float64_val(a)>>63;
158142c2 286 z.low = 0;
f090c9d4 287 z.high = float64_val(a)<<12;
158142c2 288 return z;
158142c2
FB
289}
290
291/*----------------------------------------------------------------------------
292| Returns the result of converting the canonical NaN `a' to the double-
293| precision floating-point format.
294*----------------------------------------------------------------------------*/
295
296static float64 commonNaNToFloat64( commonNaNT a )
297{
85016c98
TS
298 bits64 mantissa = a.high>>12;
299
300 if ( mantissa )
301 return make_float64(
302 ( ( (bits64) a.sign )<<63 )
303 | LIT64( 0x7FF0000000000000 )
304 | ( a.high>>12 ));
305 else
306 return float64_default_nan;
158142c2
FB
307}
308
309/*----------------------------------------------------------------------------
310| Takes two double-precision floating-point values `a' and `b', one of which
311| is a NaN, and returns the appropriate NaN result. If either `a' or `b' is a
312| signaling NaN, the invalid exception is raised.
313*----------------------------------------------------------------------------*/
314
315static float64 propagateFloat64NaN( float64 a, float64 b STATUS_PARAM)
316{
317 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
f090c9d4 318 bits64 av, bv, res;
158142c2 319
5c7908ed
PB
320 if ( STATUS(default_nan_mode) )
321 return float64_default_nan;
322
158142c2
FB
323 aIsNaN = float64_is_nan( a );
324 aIsSignalingNaN = float64_is_signaling_nan( a );
325 bIsNaN = float64_is_nan( b );
326 bIsSignalingNaN = float64_is_signaling_nan( b );
f090c9d4
PB
327 av = float64_val(a);
328 bv = float64_val(b);
5a6932d5 329#if SNAN_BIT_IS_ONE
f090c9d4
PB
330 av &= ~LIT64( 0x0008000000000000 );
331 bv &= ~LIT64( 0x0008000000000000 );
b645bb48 332#else
f090c9d4
PB
333 av |= LIT64( 0x0008000000000000 );
334 bv |= LIT64( 0x0008000000000000 );
b645bb48 335#endif
158142c2
FB
336 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
337 if ( aIsSignalingNaN ) {
338 if ( bIsSignalingNaN ) goto returnLargerSignificand;
f090c9d4 339 res = bIsNaN ? bv : av;
158142c2
FB
340 }
341 else if ( aIsNaN ) {
70c14705 342 if ( bIsSignalingNaN || ! bIsNaN )
f090c9d4
PB
343 res = av;
344 else {
158142c2 345 returnLargerSignificand:
f090c9d4
PB
346 if ( (bits64) ( av<<1 ) < (bits64) ( bv<<1 ) )
347 res = bv;
348 else if ( (bits64) ( bv<<1 ) < (bits64) ( av<<1 ) )
349 res = av;
350 else
351 res = ( av < bv ) ? av : bv;
352 }
158142c2
FB
353 }
354 else {
f090c9d4 355 res = bv;
158142c2 356 }
f090c9d4 357 return make_float64(res);
158142c2
FB
358}
359
360#ifdef FLOATX80
361
362/*----------------------------------------------------------------------------
363| The pattern for a default generated extended double-precision NaN. The
364| `high' and `low' values hold the most- and least-significant bits,
365| respectively.
366*----------------------------------------------------------------------------*/
5a6932d5
TS
367#if SNAN_BIT_IS_ONE
368#define floatx80_default_nan_high 0x7FFF
369#define floatx80_default_nan_low LIT64( 0xBFFFFFFFFFFFFFFF )
370#else
158142c2
FB
371#define floatx80_default_nan_high 0xFFFF
372#define floatx80_default_nan_low LIT64( 0xC000000000000000 )
5a6932d5 373#endif
158142c2
FB
374
375/*----------------------------------------------------------------------------
376| Returns 1 if the extended double-precision floating-point value `a' is a
5a6932d5 377| quiet NaN; otherwise returns 0.
158142c2
FB
378*----------------------------------------------------------------------------*/
379
750afe93 380int floatx80_is_nan( floatx80 a )
158142c2 381{
5a6932d5
TS
382#if SNAN_BIT_IS_ONE
383 bits64 aLow;
158142c2 384
5a6932d5
TS
385 aLow = a.low & ~ LIT64( 0x4000000000000000 );
386 return
387 ( ( a.high & 0x7FFF ) == 0x7FFF )
388 && (bits64) ( aLow<<1 )
389 && ( a.low == aLow );
390#else
158142c2 391 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
5a6932d5 392#endif
158142c2
FB
393}
394
395/*----------------------------------------------------------------------------
396| Returns 1 if the extended double-precision floating-point value `a' is a
397| signaling NaN; otherwise returns 0.
398*----------------------------------------------------------------------------*/
399
750afe93 400int floatx80_is_signaling_nan( floatx80 a )
158142c2 401{
5a6932d5
TS
402#if SNAN_BIT_IS_ONE
403 return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
404#else
158142c2
FB
405 bits64 aLow;
406
407 aLow = a.low & ~ LIT64( 0x4000000000000000 );
408 return
409 ( ( a.high & 0x7FFF ) == 0x7FFF )
410 && (bits64) ( aLow<<1 )
411 && ( a.low == aLow );
5a6932d5 412#endif
158142c2
FB
413}
414
415/*----------------------------------------------------------------------------
416| Returns the result of converting the extended double-precision floating-
417| point NaN `a' to the canonical NaN format. If `a' is a signaling NaN, the
418| invalid exception is raised.
419*----------------------------------------------------------------------------*/
420
421static commonNaNT floatx80ToCommonNaN( floatx80 a STATUS_PARAM)
422{
423 commonNaNT z;
424
425 if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
426 z.sign = a.high>>15;
427 z.low = 0;
85016c98 428 z.high = a.low;
158142c2 429 return z;
158142c2
FB
430}
431
432/*----------------------------------------------------------------------------
433| Returns the result of converting the canonical NaN `a' to the extended
434| double-precision floating-point format.
435*----------------------------------------------------------------------------*/
436
437static floatx80 commonNaNToFloatx80( commonNaNT a )
438{
439 floatx80 z;
440
85016c98
TS
441 if (a.high)
442 z.low = a.high;
443 else
444 z.low = floatx80_default_nan_low;
158142c2
FB
445 z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
446 return z;
158142c2
FB
447}
448
449/*----------------------------------------------------------------------------
450| Takes two extended double-precision floating-point values `a' and `b', one
451| of which is a NaN, and returns the appropriate NaN result. If either `a' or
452| `b' is a signaling NaN, the invalid exception is raised.
453*----------------------------------------------------------------------------*/
454
455static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b STATUS_PARAM)
456{
457 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
458
5c7908ed
PB
459 if ( STATUS(default_nan_mode) ) {
460 a.low = floatx80_default_nan_low;
461 a.high = floatx80_default_nan_high;
462 return a;
463 }
464
158142c2
FB
465 aIsNaN = floatx80_is_nan( a );
466 aIsSignalingNaN = floatx80_is_signaling_nan( a );
467 bIsNaN = floatx80_is_nan( b );
468 bIsSignalingNaN = floatx80_is_signaling_nan( b );
5a6932d5
TS
469#if SNAN_BIT_IS_ONE
470 a.low &= ~LIT64( 0xC000000000000000 );
471 b.low &= ~LIT64( 0xC000000000000000 );
472#else
158142c2
FB
473 a.low |= LIT64( 0xC000000000000000 );
474 b.low |= LIT64( 0xC000000000000000 );
5a6932d5 475#endif
158142c2
FB
476 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
477 if ( aIsSignalingNaN ) {
478 if ( bIsSignalingNaN ) goto returnLargerSignificand;
479 return bIsNaN ? b : a;
480 }
481 else if ( aIsNaN ) {
70c14705 482 if ( bIsSignalingNaN || ! bIsNaN ) return a;
158142c2
FB
483 returnLargerSignificand:
484 if ( a.low < b.low ) return b;
485 if ( b.low < a.low ) return a;
486 return ( a.high < b.high ) ? a : b;
487 }
488 else {
489 return b;
490 }
158142c2
FB
491}
492
493#endif
494
495#ifdef FLOAT128
496
497/*----------------------------------------------------------------------------
498| The pattern for a default generated quadruple-precision NaN. The `high' and
499| `low' values hold the most- and least-significant bits, respectively.
500*----------------------------------------------------------------------------*/
5a6932d5
TS
501#if SNAN_BIT_IS_ONE
502#define float128_default_nan_high LIT64( 0x7FFF7FFFFFFFFFFF )
503#define float128_default_nan_low LIT64( 0xFFFFFFFFFFFFFFFF )
504#else
158142c2
FB
505#define float128_default_nan_high LIT64( 0xFFFF800000000000 )
506#define float128_default_nan_low LIT64( 0x0000000000000000 )
5a6932d5 507#endif
158142c2
FB
508
509/*----------------------------------------------------------------------------
5a6932d5
TS
510| Returns 1 if the quadruple-precision floating-point value `a' is a quiet
511| NaN; otherwise returns 0.
158142c2
FB
512*----------------------------------------------------------------------------*/
513
750afe93 514int float128_is_nan( float128 a )
158142c2 515{
5a6932d5
TS
516#if SNAN_BIT_IS_ONE
517 return
518 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
519 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
520#else
158142c2
FB
521 return
522 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
523 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
5a6932d5 524#endif
158142c2
FB
525}
526
527/*----------------------------------------------------------------------------
528| Returns 1 if the quadruple-precision floating-point value `a' is a
529| signaling NaN; otherwise returns 0.
530*----------------------------------------------------------------------------*/
531
750afe93 532int float128_is_signaling_nan( float128 a )
158142c2 533{
5a6932d5
TS
534#if SNAN_BIT_IS_ONE
535 return
536 ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
537 && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
538#else
158142c2
FB
539 return
540 ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
541 && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
5a6932d5 542#endif
158142c2
FB
543}
544
545/*----------------------------------------------------------------------------
546| Returns the result of converting the quadruple-precision floating-point NaN
547| `a' to the canonical NaN format. If `a' is a signaling NaN, the invalid
548| exception is raised.
549*----------------------------------------------------------------------------*/
550
551static commonNaNT float128ToCommonNaN( float128 a STATUS_PARAM)
552{
553 commonNaNT z;
554
555 if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid STATUS_VAR);
556 z.sign = a.high>>63;
557 shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
558 return z;
158142c2
FB
559}
560
561/*----------------------------------------------------------------------------
562| Returns the result of converting the canonical NaN `a' to the quadruple-
563| precision floating-point format.
564*----------------------------------------------------------------------------*/
565
566static float128 commonNaNToFloat128( commonNaNT a )
567{
568 float128 z;
569
570 shift128Right( a.high, a.low, 16, &z.high, &z.low );
85016c98 571 z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF000000000000 );
158142c2 572 return z;
158142c2
FB
573}
574
575/*----------------------------------------------------------------------------
576| Takes two quadruple-precision floating-point values `a' and `b', one of
577| which is a NaN, and returns the appropriate NaN result. If either `a' or
578| `b' is a signaling NaN, the invalid exception is raised.
579*----------------------------------------------------------------------------*/
580
581static float128 propagateFloat128NaN( float128 a, float128 b STATUS_PARAM)
582{
583 flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
584
5c7908ed
PB
585 if ( STATUS(default_nan_mode) ) {
586 a.low = float128_default_nan_low;
587 a.high = float128_default_nan_high;
588 return a;
589 }
590
158142c2
FB
591 aIsNaN = float128_is_nan( a );
592 aIsSignalingNaN = float128_is_signaling_nan( a );
593 bIsNaN = float128_is_nan( b );
594 bIsSignalingNaN = float128_is_signaling_nan( b );
5a6932d5
TS
595#if SNAN_BIT_IS_ONE
596 a.high &= ~LIT64( 0x0000800000000000 );
597 b.high &= ~LIT64( 0x0000800000000000 );
598#else
158142c2
FB
599 a.high |= LIT64( 0x0000800000000000 );
600 b.high |= LIT64( 0x0000800000000000 );
5a6932d5 601#endif
158142c2
FB
602 if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid STATUS_VAR);
603 if ( aIsSignalingNaN ) {
604 if ( bIsSignalingNaN ) goto returnLargerSignificand;
605 return bIsNaN ? b : a;
606 }
607 else if ( aIsNaN ) {
70c14705 608 if ( bIsSignalingNaN || ! bIsNaN ) return a;
158142c2
FB
609 returnLargerSignificand:
610 if ( lt128( a.high<<1, a.low, b.high<<1, b.low ) ) return b;
611 if ( lt128( b.high<<1, b.low, a.high<<1, a.low ) ) return a;
612 return ( a.high < b.high ) ? a : b;
613 }
614 else {
615 return b;
616 }
158142c2
FB
617}
618
619#endif