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