1/* THIS FILE HAS BEEN MODIFIED FOR USE WITH THE HERCULES PROJECT */
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
33/*----------------------------------------------------------------------------
34| Underflow tininess-detection mode, statically initialized to default value.
35| (The declaration in `softfloat.h' must match the `int8' type here.)
36*----------------------------------------------------------------------------*/
37int8 float_detect_tininess = float_tininess_before_rounding;
38
39/*----------------------------------------------------------------------------
40| Sets the floating-point rounding mode.
41*----------------------------------------------------------------------------*/
42
43void float_set_rounding_mode( int8 mode )
44{
45
46    float_rounding_mode = mode;
47
48}
49
50/*----------------------------------------------------------------------------
51| Gets the floating-point exception flags.
52*----------------------------------------------------------------------------*/
53
54int8 float_get_exception_flags()
55{
56
57    return float_exception_flags;
58
59}
60
61/*----------------------------------------------------------------------------
62| Clears the floating-point exception flags.
63*----------------------------------------------------------------------------*/
64
65void float_clear_exception_flags()
66{
67
68    float_exception_flags = 0;
69
70}
71
72/*----------------------------------------------------------------------------
73| Raises the exceptions specified by `flags'.  Floating-point traps can be
74| defined here if desired.  It is currently not possible for such a trap to
75| substitute a result value.  If traps are not implemented, this routine
76| should be simply `float_exception_flags |= flags;'.
77*----------------------------------------------------------------------------*/
78
79void float_raise( int8 flags )
80{
81
82    float_exception_flags |= flags;
83
84}
85
86/*----------------------------------------------------------------------------
87| Internal canonical NaN format.
88*----------------------------------------------------------------------------*/
89typedef struct {
90    flag sign;
91    bits64 high, low;
92} commonNaNT;
93
94/*----------------------------------------------------------------------------
95| Returns 1 if the single-precision floating-point value `a' is infinity;
96| otherwise returns 0.
97*----------------------------------------------------------------------------*/
98
99flag float32_is_inf( float32 a )
100{
101
102    return ( 0xFF000000 == (bits32) ( a<<1 ) );
103
104}
105
106/*----------------------------------------------------------------------------
107| Returns 1 if the single-precision floating-point value `a' is a NaN;
108| otherwise returns 0.
109*----------------------------------------------------------------------------*/
110
111flag float32_is_nan( float32 a )
112{
113
114    return ( 0xFF000000 < (bits32) ( a<<1 ) );
115
116}
117
118/*----------------------------------------------------------------------------
119| Returns 1 if the single-precision floating-point value `a' is negative;
120| otherwise returns 0.
121*----------------------------------------------------------------------------*/
122
123flag float32_is_neg( float32 a )
124{
125
126    return ( a>>31 );
127
128}
129
130/*----------------------------------------------------------------------------
131| Returns 1 if the single-precision floating-point value `a' is a signaling
132| NaN; otherwise returns 0.
133*----------------------------------------------------------------------------*/
134
135flag float32_is_signaling_nan( float32 a )
136{
137
138    return ( ( ( a>>22 ) & 0x1FF ) == 0x1FE ) && ( a & 0x003FFFFF );
139
140}
141
142/*----------------------------------------------------------------------------
143| Returns 1 if the single-precision floating-point value `a' is subnormal;
144| otherwise returns 0.
145*----------------------------------------------------------------------------*/
146
147flag float32_is_subnormal( float32 a )
148{
149
150    return ( ( ( a>>23 ) & 0xFF ) == 0 )
151        && ( a & 0x007FFFFF );
152
153}
154
155/*----------------------------------------------------------------------------
156| Returns 1 if the single-precision floating-point value `a' is zero;
157| otherwise returns 0.
158*----------------------------------------------------------------------------*/
159
160flag float32_is_zero( float32 a )
161{
162
163    return ( ( a & 0x7FFFFFFF ) == 0);
164
165}
166
167/*----------------------------------------------------------------------------
168| Returns the single-precision floating-point value `a' with positive sign.
169*----------------------------------------------------------------------------*/
170
171float32 float32_pos( float32 a )
172{
173
174    return ( a & 0x7FFFFFFF );
175
176}
177
178/*----------------------------------------------------------------------------
179| Returns the single-precision floating-point value `a' with negative sign.
180*----------------------------------------------------------------------------*/
181
182float32 float32_neg( float32 a )
183{
184
185    return ( a | 0x80000000 );
186
187}
188
189/*----------------------------------------------------------------------------
190| Returns the result of converting the single-precision floating-point
191| signaling NaN `a' to a quiet NaN.
192*----------------------------------------------------------------------------*/
193float32 float32_snan_to_qnan( float32 a )
194{
195
196    return ( a | 0x00400000 );
197
198}
199
200/*----------------------------------------------------------------------------
201| Builds a single-precision floating-point value.
202*----------------------------------------------------------------------------*/
203
204float32 float32_build( int sign, int exp, bits32 fract )
205{
206
207    return ( (bits32) ( sign ? 0x80000000 : 0 ) )
208        | ( (bits32) ( exp & 0xFF ) << 23 )
209        | ( fract & 0x007FFFFF );
210
211}
212
213/*----------------------------------------------------------------------------
214| Returns the exponent of single-precision floating-point value `a'.
215*----------------------------------------------------------------------------*/
216
217bits16 float32_exp( float32 a )
218{
219
220    return (( a>>23 ) & 0xFF );
221
222}
223
224/*----------------------------------------------------------------------------
225| Returns the fraction of single-precision floating-point value `a'.
226*----------------------------------------------------------------------------*/
227
228bits32 float32_fract( float32 a )
229{
230
231    return ( a & 0x007FFFFF );
232
233}
234
235/*----------------------------------------------------------------------------
236| Returns the result of converting the single-precision floating-point NaN
237| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
238| exception is raised.
239*----------------------------------------------------------------------------*/
240
241static commonNaNT float32ToCommonNaN( float32 a )
242{
243    commonNaNT z;
244
245    if ( float32_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
246    z.sign = a>>31;
247    z.low = 0;
248    z.high = ( (bits64) a )<<41;
249    return z;
250
251}
252
253/*----------------------------------------------------------------------------
254| Returns the result of converting the canonical NaN `a' to the single-
255| precision floating-point format.
256*----------------------------------------------------------------------------*/
257
258static float32 commonNaNToFloat32( commonNaNT a )
259{
260
261    return ( ( (bits32) a.sign )<<31 ) | 0x7FC00000 | ( a.high>>41 );
262
263}
264
265/*----------------------------------------------------------------------------
266| Takes two single-precision floating-point values `a' and `b', one of which
267| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
268| signaling NaN, the invalid exception is raised.
269*----------------------------------------------------------------------------*/
270
271static float32 propagateFloat32NaN( float32 a, float32 b )
272{
273    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
274
275    aIsNaN = float32_is_nan( a );
276    aIsSignalingNaN = float32_is_signaling_nan( a );
277    bIsNaN = float32_is_nan( b );
278    bIsSignalingNaN = float32_is_signaling_nan( b );
279    a |= 0x00400000;
280    b |= 0x00400000;
281    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
282    if ( aIsNaN ) {
283        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
284    }
285    else {
286        return b;
287    }
288
289}
290
291/*----------------------------------------------------------------------------
292| Returns 1 if the double-precision floating-point value `a' is infinity;
293| otherwise returns 0.
294*----------------------------------------------------------------------------*/
295
296flag float64_is_inf( float64 a )
297{
298
299    return ( LIT64( 0xFFE0000000000000 ) == (bits64) ( a<<1 ) );
300
301}
302
303/*----------------------------------------------------------------------------
304| Returns 1 if the double-precision floating-point value `a' is a NaN;
305| otherwise returns 0.
306*----------------------------------------------------------------------------*/
307
308flag float64_is_nan( float64 a )
309{
310
311    return ( LIT64( 0xFFE0000000000000 ) < (bits64) ( a<<1 ) );
312
313}
314
315/*----------------------------------------------------------------------------
316| Returns 1 if the double-precision floating-point value `a' is negative;
317| otherwise returns 0.
318*----------------------------------------------------------------------------*/
319
320flag float64_is_neg( float64 a )
321{
322
323    return ( a>>63 );
324
325}
326
327/*----------------------------------------------------------------------------
328| Returns 1 if the double-precision floating-point value `a' is a signaling
329| NaN; otherwise returns 0.
330*----------------------------------------------------------------------------*/
331
332flag float64_is_signaling_nan( float64 a )
333{
334
335    return
336           ( ( ( a>>51 ) & 0xFFF ) == 0xFFE )
337        && ( a & LIT64( 0x0007FFFFFFFFFFFF ) );
338
339}
340
341/*----------------------------------------------------------------------------
342| Returns 1 if the double-precision floating-point value `a' is subnormal;
343| otherwise returns 0.
344*----------------------------------------------------------------------------*/
345
346flag float64_is_subnormal( float64 a )
347{
348
349    return ( ( ( a>>52 ) & 0x7FF ) == 0 )
350        && ( a & LIT64( 0x000FFFFFFFFFFFFF ) );
351
352}
353
354/*----------------------------------------------------------------------------
355| Returns 1 if the double-precision floating-point value `a' is zero;
356| otherwise returns 0.
357*----------------------------------------------------------------------------*/
358
359flag float64_is_zero( float64 a )
360{
361
362    return ( ( a & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0);
363
364}
365
366/*----------------------------------------------------------------------------
367| Returns the double-precision floating-point value `a' with positive sign.
368*----------------------------------------------------------------------------*/
369
370float64 float64_pos( float64 a )
371{
372
373    return ( a & LIT64( 0x7FFFFFFFFFFFFFFF ) );
374
375}
376
377/*----------------------------------------------------------------------------
378| Returns the double-precision floating-point value `a' with negative sign.
379*----------------------------------------------------------------------------*/
380
381float64 float64_neg( float64 a )
382{
383
384    return ( a | LIT64( 0x8000000000000000 ) );
385
386}
387
388/*----------------------------------------------------------------------------
389| Returns the result of converting the double-precision floating-point
390| signaling NaN `a' to a quiet NaN.
391*----------------------------------------------------------------------------*/
392float64 float64_snan_to_qnan( float64 a )
393{
394
395    return ( a | LIT64( 0x0008000000000000 ) );
396
397}
398
399/*----------------------------------------------------------------------------
400| Builds a double-precision floating-point value.
401*----------------------------------------------------------------------------*/
402
403float64 float64_build( int sign, int exp, bits64 fract )
404{
405
406    return ( (bits64) ( sign ? LIT64( 0x8000000000000000 ) : 0 )
407        | ( (bits64) ( exp & 0x7FF ) << 52 )
408        | ( fract & LIT64( 0x000FFFFFFFFFFFFF ) ) );
409
410}
411
412/*----------------------------------------------------------------------------
413| Returns the exponent of double-precision floating-point value `a'.
414*----------------------------------------------------------------------------*/
415
416bits16 float64_exp( float64 a )
417{
418
419    return (( a>>52 ) & 0x7FF );
420
421}
422
423/*----------------------------------------------------------------------------
424| Returns the fraction of double-precision floating-point value `a'.
425*----------------------------------------------------------------------------*/
426
427bits64 float64_fract( float64 a )
428{
429
430    return ( a & LIT64( 0x000FFFFFFFFFFFFF ) );
431
432}
433
434/*----------------------------------------------------------------------------
435| Returns the result of converting the double-precision floating-point NaN
436| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
437| exception is raised.
438*----------------------------------------------------------------------------*/
439
440static commonNaNT float64ToCommonNaN( float64 a )
441{
442    commonNaNT z;
443
444    if ( float64_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
445    z.sign = a>>63;
446    z.low = 0;
447    z.high = a<<12;
448    return z;
449
450}
451
452/*----------------------------------------------------------------------------
453| Returns the result of converting the canonical NaN `a' to the double-
454| precision floating-point format.
455*----------------------------------------------------------------------------*/
456
457static float64 commonNaNToFloat64( commonNaNT a )
458{
459
460    return
461          ( ( (bits64) a.sign )<<63 )
462        | LIT64( 0x7FF8000000000000 )
463        | ( a.high>>12 );
464
465}
466
467/*----------------------------------------------------------------------------
468| Takes two double-precision floating-point values `a' and `b', one of which
469| is a NaN, and returns the appropriate NaN result.  If either `a' or `b' is a
470| signaling NaN, the invalid exception is raised.
471*----------------------------------------------------------------------------*/
472
473static float64 propagateFloat64NaN( float64 a, float64 b )
474{
475    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
476
477    aIsNaN = float64_is_nan( a );
478    aIsSignalingNaN = float64_is_signaling_nan( a );
479    bIsNaN = float64_is_nan( b );
480    bIsSignalingNaN = float64_is_signaling_nan( b );
481    a |= LIT64( 0x0008000000000000 );
482    b |= LIT64( 0x0008000000000000 );
483    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
484    if ( aIsNaN ) {
485        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
486    }
487    else {
488        return b;
489    }
490
491}
492
493#ifdef FLOATX80
494
495/*----------------------------------------------------------------------------
496| The pattern for a default generated extended double-precision NaN.  The
497| `high' and `low' values hold the most- and least-significant bits,
498| respectively.
499*----------------------------------------------------------------------------*/
500#define floatx80_default_nan_high 0xFFFF
501#define floatx80_default_nan_low  LIT64( 0xFFFFFFFFFFFFFFFF )
502
503/*----------------------------------------------------------------------------
504| Returns 1 if the extended double-precision floating-point value `a' is a
505| NaN; otherwise returns 0.
506*----------------------------------------------------------------------------*/
507
508flag floatx80_is_nan( floatx80 a )
509{
510
511    return ( ( a.high & 0x7FFF ) == 0x7FFF ) && (bits64) ( a.low<<1 );
512
513}
514
515/*----------------------------------------------------------------------------
516| Returns 1 if the extended double-precision floating-point value `a' is a
517| signaling NaN; otherwise returns 0.
518*----------------------------------------------------------------------------*/
519
520flag floatx80_is_signaling_nan( floatx80 a )
521{
522    bits64 aLow;
523
524    aLow = a.low & ~ LIT64( 0x4000000000000000 );
525    return
526           ( ( a.high & 0x7FFF ) == 0x7FFF )
527        && (bits64) ( aLow<<1 )
528        && ( a.low == aLow );
529
530}
531
532/*----------------------------------------------------------------------------
533| Returns the result of converting the extended double-precision floating-
534| point NaN `a' to the canonical NaN format.  If `a' is a signaling NaN, the
535| invalid exception is raised.
536*----------------------------------------------------------------------------*/
537
538static commonNaNT floatx80ToCommonNaN( floatx80 a )
539{
540    commonNaNT z;
541
542    if ( floatx80_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
543    z.sign = a.high>>15;
544    z.low = 0;
545    z.high = a.low<<1;
546    return z;
547
548}
549
550/*----------------------------------------------------------------------------
551| Returns the result of converting the canonical NaN `a' to the extended
552| double-precision floating-point format.
553*----------------------------------------------------------------------------*/
554
555static floatx80 commonNaNToFloatx80( commonNaNT a )
556{
557    floatx80 z;
558
559    z.low = LIT64( 0xC000000000000000 ) | ( a.high>>1 );
560    z.high = ( ( (bits16) a.sign )<<15 ) | 0x7FFF;
561    return z;
562
563}
564
565/*----------------------------------------------------------------------------
566| Takes two extended double-precision floating-point values `a' and `b', one
567| of which is a NaN, and returns the appropriate NaN result.  If either `a' or
568| `b' is a signaling NaN, the invalid exception is raised.
569*----------------------------------------------------------------------------*/
570
571static floatx80 propagateFloatx80NaN( floatx80 a, floatx80 b )
572{
573    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
574
575    aIsNaN = floatx80_is_nan( a );
576    aIsSignalingNaN = floatx80_is_signaling_nan( a );
577    bIsNaN = floatx80_is_nan( b );
578    bIsSignalingNaN = floatx80_is_signaling_nan( b );
579    a.low |= LIT64( 0xC000000000000000 );
580    b.low |= LIT64( 0xC000000000000000 );
581    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
582    if ( aIsNaN ) {
583        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
584    }
585    else {
586        return b;
587    }
588
589}
590
591#endif
592
593#ifdef FLOAT128
594
595/*----------------------------------------------------------------------------
596| Returns 1 if the quadruple-precision floating-point value `a' is infinity;
597| otherwise returns 0.
598*----------------------------------------------------------------------------*/
599
600flag float128_is_inf( float128 a )
601{
602
603    return ( a.low == 0
604        && ( (bits64) ( a.high<<1 ) == LIT64( 0xFFFE000000000000 ) ) );
605
606}
607
608/*----------------------------------------------------------------------------
609| Returns 1 if the quadruple-precision floating-point value `a' is a NaN;
610| otherwise returns 0.
611*----------------------------------------------------------------------------*/
612
613flag float128_is_nan( float128 a )
614{
615
616    return
617           ( LIT64( 0xFFFE000000000000 ) <= (bits64) ( a.high<<1 ) )
618        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
619
620}
621
622/*----------------------------------------------------------------------------
623| Returns 1 if the quadruple-precision floating-point value `a' is negative;
624| otherwise returns 0.
625*----------------------------------------------------------------------------*/
626
627flag float128_is_neg( float128 a )
628{
629
630    return ( a.high>>63 );
631
632}
633
634/*----------------------------------------------------------------------------
635| Returns 1 if the quadruple-precision floating-point value `a' is a
636| signaling NaN; otherwise returns 0.
637*----------------------------------------------------------------------------*/
638
639flag float128_is_signaling_nan( float128 a )
640{
641
642    return
643           ( ( ( a.high>>47 ) & 0xFFFF ) == 0xFFFE )
644        && ( a.low || ( a.high & LIT64( 0x00007FFFFFFFFFFF ) ) );
645
646}
647
648/*----------------------------------------------------------------------------
649| Returns 1 if the quadruple-precision floating-point value `a' is subnormal;
650| otherwise returns 0.
651*----------------------------------------------------------------------------*/
652
653flag float128_is_subnormal( float128 a )
654{
655
656    return ( ( ( a.high>>48 ) & 0x7FFF ) == 0 )
657        && ( a.low || ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
658
659}
660
661/*----------------------------------------------------------------------------
662| Returns 1 if the quadruple-precision floating-point value `a' is zero;
663| otherwise returns 0.
664*----------------------------------------------------------------------------*/
665
666flag float128_is_zero( float128 a )
667{
668
669    return ( a.low == 0 && ( a.high & LIT64( 0x7FFFFFFFFFFFFFFF ) ) == 0 );
670
671}
672
673/*----------------------------------------------------------------------------
674| Returns the quadruple-precision floating-point value `a' with positive sign.
675*----------------------------------------------------------------------------*/
676
677float128 float128_pos( float128 a )
678{
679    float128 result;
680
681    result.high = ( a.high & LIT64( 0x7FFFFFFFFFFFFFFF ) );
682    result.low = a.low;
683    return result;
684
685}
686
687/*----------------------------------------------------------------------------
688| Returns the quadruple-precision floating-point value `a' with negative sign.
689*----------------------------------------------------------------------------*/
690
691float128 float128_neg( float128 a )
692{
693    float128 result;
694
695    result.high = ( a.high | LIT64( 0x8000000000000000 ) );
696    result.low = a.low;
697    return result;
698
699}
700
701/*----------------------------------------------------------------------------
702| Returns the result of converting the quadruple-precision floating-point
703| signaling NaN `a' to a quiet NaN.
704*----------------------------------------------------------------------------*/
705float128 float128_snan_to_qnan( float128 a )
706{
707    float128 result;
708
709    result.high = ( a.high | LIT64( 0x0000800000000000 ) );
710    result.low = a.low;
711    return result;
712
713}
714
715/*----------------------------------------------------------------------------
716| Builds a quadruple-precision floating-point value.
717*----------------------------------------------------------------------------*/
718
719float128 float128_build( int sign, int exp, bits64 fract_high, bits64 fract_low )
720{
721    float128 result;
722
723    result.high = ( (bits64) ( sign ? LIT64( 0x8000000000000000 ) : 0 )
724        | ( (bits64) ( exp & 0x7FFF ) << 48 )
725        | ( fract_high & LIT64( 0x0000FFFFFFFFFFFF ) ) );
726    result.low = fract_low;
727    return result;
728
729}
730
731/*----------------------------------------------------------------------------
732| Returns the exponent of quadruple-precision floating-point value `a'.
733*----------------------------------------------------------------------------*/
734
735bits16 float128_exp( float128 a )
736{
737
738    return (( a.high>>48 ) & 0x7FFF );
739
740}
741
742/*----------------------------------------------------------------------------
743| Returns the high-order 48 bits of the fraction of quadruple-precision
744| floating-point value `a'.
745*----------------------------------------------------------------------------*/
746
747bits64 float128_fract_high( float128 a )
748{
749
750    return ( a.high & LIT64( 0x0000FFFFFFFFFFFF ) );
751
752}
753
754/*----------------------------------------------------------------------------
755| Returns the low-order 64 bits of the fraction of quadruple-precision
756| floating-point value `a'.
757*----------------------------------------------------------------------------*/
758
759bits64 float128_fract_low( float128 a )
760{
761
762    return ( a.low );
763
764}
765
766/*----------------------------------------------------------------------------
767| Returns the result of converting the quadruple-precision floating-point NaN
768| `a' to the canonical NaN format.  If `a' is a signaling NaN, the invalid
769| exception is raised.
770*----------------------------------------------------------------------------*/
771
772static commonNaNT float128ToCommonNaN( float128 a )
773{
774    commonNaNT z;
775
776    if ( float128_is_signaling_nan( a ) ) float_raise( float_flag_invalid );
777    z.sign = a.high>>63;
778    shortShift128Left( a.high, a.low, 16, &z.high, &z.low );
779    return z;
780
781}
782
783/*----------------------------------------------------------------------------
784| Returns the result of converting the canonical NaN `a' to the quadruple-
785| precision floating-point format.
786*----------------------------------------------------------------------------*/
787
788static float128 commonNaNToFloat128( commonNaNT a )
789{
790    float128 z;
791
792    shift128Right( a.high, a.low, 16, &z.high, &z.low );
793    z.high |= ( ( (bits64) a.sign )<<63 ) | LIT64( 0x7FFF800000000000 );
794    return z;
795
796}
797
798/*----------------------------------------------------------------------------
799| Takes two quadruple-precision floating-point values `a' and `b', one of
800| which is a NaN, and returns the appropriate NaN result.  If either `a' or
801| `b' is a signaling NaN, the invalid exception is raised.
802*----------------------------------------------------------------------------*/
803
804static float128 propagateFloat128NaN( float128 a, float128 b )
805{
806    flag aIsNaN, aIsSignalingNaN, bIsNaN, bIsSignalingNaN;
807
808    aIsNaN = float128_is_nan( a );
809    aIsSignalingNaN = float128_is_signaling_nan( a );
810    bIsNaN = float128_is_nan( b );
811    bIsSignalingNaN = float128_is_signaling_nan( b );
812    a.high |= LIT64( 0x0000800000000000 );
813    b.high |= LIT64( 0x0000800000000000 );
814    if ( aIsSignalingNaN | bIsSignalingNaN ) float_raise( float_flag_invalid );
815    if ( aIsNaN ) {
816        return ( aIsSignalingNaN & bIsNaN ) ? b : a;
817    }
818    else {
819        return b;
820    }
821
822}
823
824#endif
825
826