xref: /openbmc/qemu/fpu/softfloat.c (revision e1fe50dc)
1 /*
2  * QEMU float support
3  *
4  * Derived from SoftFloat.
5  */
6 
7 /*============================================================================
8 
9 This C source file is part of the SoftFloat IEC/IEEE Floating-point Arithmetic
10 Package, Release 2b.
11 
12 Written by John R. Hauser.  This work was made possible in part by the
13 International Computer Science Institute, located at Suite 600, 1947 Center
14 Street, Berkeley, California 94704.  Funding was partially provided by the
15 National Science Foundation under grant MIP-9311980.  The original version
16 of this code was written as part of a project to build a fixed-point vector
17 processor in collaboration with the University of California at Berkeley,
18 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
19 is available through the Web page `http://www.cs.berkeley.edu/~jhauser/
20 arithmetic/SoftFloat.html'.
21 
22 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort has
23 been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT TIMES
24 RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO PERSONS
25 AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ALL LOSSES,
26 COSTS, OR OTHER PROBLEMS THEY INCUR DUE TO THE SOFTWARE, AND WHO FURTHERMORE
27 EFFECTIVELY INDEMNIFY JOHN HAUSER AND THE INTERNATIONAL COMPUTER SCIENCE
28 INSTITUTE (possibly via similar legal warning) AGAINST ALL LOSSES, COSTS, OR
29 OTHER PROBLEMS INCURRED BY THEIR CUSTOMERS AND CLIENTS DUE TO THE SOFTWARE.
30 
31 Derivative works are acceptable, even for commercial purposes, so long as
32 (1) the source code for the derivative work includes prominent notice that
33 the work is derivative, and (2) the source code includes prominent notice with
34 these four paragraphs for those parts of this code that are retained.
35 
36 =============================================================================*/
37 
38 /* softfloat (and in particular the code in softfloat-specialize.h) is
39  * target-dependent and needs the TARGET_* macros.
40  */
41 #include "config.h"
42 
43 #include "fpu/softfloat.h"
44 
45 /*----------------------------------------------------------------------------
46 | Primitive arithmetic functions, including multi-word arithmetic, and
47 | division and square root approximations.  (Can be specialized to target if
48 | desired.)
49 *----------------------------------------------------------------------------*/
50 #include "softfloat-macros.h"
51 
52 /*----------------------------------------------------------------------------
53 | Functions and definitions to determine:  (1) whether tininess for underflow
54 | is detected before or after rounding by default, (2) what (if anything)
55 | happens when exceptions are raised, (3) how signaling NaNs are distinguished
56 | from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
57 | are propagated from function inputs to output.  These details are target-
58 | specific.
59 *----------------------------------------------------------------------------*/
60 #include "softfloat-specialize.h"
61 
62 void set_float_rounding_mode(int val STATUS_PARAM)
63 {
64     STATUS(float_rounding_mode) = val;
65 }
66 
67 void set_float_exception_flags(int val STATUS_PARAM)
68 {
69     STATUS(float_exception_flags) = val;
70 }
71 
72 void set_floatx80_rounding_precision(int val STATUS_PARAM)
73 {
74     STATUS(floatx80_rounding_precision) = val;
75 }
76 
77 /*----------------------------------------------------------------------------
78 | Returns the fraction bits of the half-precision floating-point value `a'.
79 *----------------------------------------------------------------------------*/
80 
81 INLINE uint32_t extractFloat16Frac(float16 a)
82 {
83     return float16_val(a) & 0x3ff;
84 }
85 
86 /*----------------------------------------------------------------------------
87 | Returns the exponent bits of the half-precision floating-point value `a'.
88 *----------------------------------------------------------------------------*/
89 
90 INLINE int_fast16_t extractFloat16Exp(float16 a)
91 {
92     return (float16_val(a) >> 10) & 0x1f;
93 }
94 
95 /*----------------------------------------------------------------------------
96 | Returns the sign bit of the single-precision floating-point value `a'.
97 *----------------------------------------------------------------------------*/
98 
99 INLINE flag extractFloat16Sign(float16 a)
100 {
101     return float16_val(a)>>15;
102 }
103 
104 /*----------------------------------------------------------------------------
105 | Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
106 | and 7, and returns the properly rounded 32-bit integer corresponding to the
107 | input.  If `zSign' is 1, the input is negated before being converted to an
108 | integer.  Bit 63 of `absZ' must be zero.  Ordinarily, the fixed-point input
109 | is simply rounded to an integer, with the inexact exception raised if the
110 | input cannot be represented exactly as an integer.  However, if the fixed-
111 | point input is too large, the invalid exception is raised and the largest
112 | positive or negative integer is returned.
113 *----------------------------------------------------------------------------*/
114 
115 static int32 roundAndPackInt32( flag zSign, uint64_t absZ STATUS_PARAM)
116 {
117     int8 roundingMode;
118     flag roundNearestEven;
119     int8 roundIncrement, roundBits;
120     int32_t z;
121 
122     roundingMode = STATUS(float_rounding_mode);
123     roundNearestEven = ( roundingMode == float_round_nearest_even );
124     roundIncrement = 0x40;
125     if ( ! roundNearestEven ) {
126         if ( roundingMode == float_round_to_zero ) {
127             roundIncrement = 0;
128         }
129         else {
130             roundIncrement = 0x7F;
131             if ( zSign ) {
132                 if ( roundingMode == float_round_up ) roundIncrement = 0;
133             }
134             else {
135                 if ( roundingMode == float_round_down ) roundIncrement = 0;
136             }
137         }
138     }
139     roundBits = absZ & 0x7F;
140     absZ = ( absZ + roundIncrement )>>7;
141     absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
142     z = absZ;
143     if ( zSign ) z = - z;
144     if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
145         float_raise( float_flag_invalid STATUS_VAR);
146         return zSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
147     }
148     if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
149     return z;
150 
151 }
152 
153 /*----------------------------------------------------------------------------
154 | Takes the 128-bit fixed-point value formed by concatenating `absZ0' and
155 | `absZ1', with binary point between bits 63 and 64 (between the input words),
156 | and returns the properly rounded 64-bit integer corresponding to the input.
157 | If `zSign' is 1, the input is negated before being converted to an integer.
158 | Ordinarily, the fixed-point input is simply rounded to an integer, with
159 | the inexact exception raised if the input cannot be represented exactly as
160 | an integer.  However, if the fixed-point input is too large, the invalid
161 | exception is raised and the largest positive or negative integer is
162 | returned.
163 *----------------------------------------------------------------------------*/
164 
165 static int64 roundAndPackInt64( flag zSign, uint64_t absZ0, uint64_t absZ1 STATUS_PARAM)
166 {
167     int8 roundingMode;
168     flag roundNearestEven, increment;
169     int64_t z;
170 
171     roundingMode = STATUS(float_rounding_mode);
172     roundNearestEven = ( roundingMode == float_round_nearest_even );
173     increment = ( (int64_t) absZ1 < 0 );
174     if ( ! roundNearestEven ) {
175         if ( roundingMode == float_round_to_zero ) {
176             increment = 0;
177         }
178         else {
179             if ( zSign ) {
180                 increment = ( roundingMode == float_round_down ) && absZ1;
181             }
182             else {
183                 increment = ( roundingMode == float_round_up ) && absZ1;
184             }
185         }
186     }
187     if ( increment ) {
188         ++absZ0;
189         if ( absZ0 == 0 ) goto overflow;
190         absZ0 &= ~ ( ( (uint64_t) ( absZ1<<1 ) == 0 ) & roundNearestEven );
191     }
192     z = absZ0;
193     if ( zSign ) z = - z;
194     if ( z && ( ( z < 0 ) ^ zSign ) ) {
195  overflow:
196         float_raise( float_flag_invalid STATUS_VAR);
197         return
198               zSign ? (int64_t) LIT64( 0x8000000000000000 )
199             : LIT64( 0x7FFFFFFFFFFFFFFF );
200     }
201     if ( absZ1 ) STATUS(float_exception_flags) |= float_flag_inexact;
202     return z;
203 
204 }
205 
206 /*----------------------------------------------------------------------------
207 | Returns the fraction bits of the single-precision floating-point value `a'.
208 *----------------------------------------------------------------------------*/
209 
210 INLINE uint32_t extractFloat32Frac( float32 a )
211 {
212 
213     return float32_val(a) & 0x007FFFFF;
214 
215 }
216 
217 /*----------------------------------------------------------------------------
218 | Returns the exponent bits of the single-precision floating-point value `a'.
219 *----------------------------------------------------------------------------*/
220 
221 INLINE int_fast16_t extractFloat32Exp(float32 a)
222 {
223 
224     return ( float32_val(a)>>23 ) & 0xFF;
225 
226 }
227 
228 /*----------------------------------------------------------------------------
229 | Returns the sign bit of the single-precision floating-point value `a'.
230 *----------------------------------------------------------------------------*/
231 
232 INLINE flag extractFloat32Sign( float32 a )
233 {
234 
235     return float32_val(a)>>31;
236 
237 }
238 
239 /*----------------------------------------------------------------------------
240 | If `a' is denormal and we are in flush-to-zero mode then set the
241 | input-denormal exception and return zero. Otherwise just return the value.
242 *----------------------------------------------------------------------------*/
243 static float32 float32_squash_input_denormal(float32 a STATUS_PARAM)
244 {
245     if (STATUS(flush_inputs_to_zero)) {
246         if (extractFloat32Exp(a) == 0 && extractFloat32Frac(a) != 0) {
247             float_raise(float_flag_input_denormal STATUS_VAR);
248             return make_float32(float32_val(a) & 0x80000000);
249         }
250     }
251     return a;
252 }
253 
254 /*----------------------------------------------------------------------------
255 | Normalizes the subnormal single-precision floating-point value represented
256 | by the denormalized significand `aSig'.  The normalized exponent and
257 | significand are stored at the locations pointed to by `zExpPtr' and
258 | `zSigPtr', respectively.
259 *----------------------------------------------------------------------------*/
260 
261 static void
262  normalizeFloat32Subnormal(uint32_t aSig, int_fast16_t *zExpPtr, uint32_t *zSigPtr)
263 {
264     int8 shiftCount;
265 
266     shiftCount = countLeadingZeros32( aSig ) - 8;
267     *zSigPtr = aSig<<shiftCount;
268     *zExpPtr = 1 - shiftCount;
269 
270 }
271 
272 /*----------------------------------------------------------------------------
273 | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
274 | single-precision floating-point value, returning the result.  After being
275 | shifted into the proper positions, the three fields are simply added
276 | together to form the result.  This means that any integer portion of `zSig'
277 | will be added into the exponent.  Since a properly normalized significand
278 | will have an integer portion equal to 1, the `zExp' input should be 1 less
279 | than the desired result exponent whenever `zSig' is a complete, normalized
280 | significand.
281 *----------------------------------------------------------------------------*/
282 
283 INLINE float32 packFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig)
284 {
285 
286     return make_float32(
287           ( ( (uint32_t) zSign )<<31 ) + ( ( (uint32_t) zExp )<<23 ) + zSig);
288 
289 }
290 
291 /*----------------------------------------------------------------------------
292 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
293 | and significand `zSig', and returns the proper single-precision floating-
294 | point value corresponding to the abstract input.  Ordinarily, the abstract
295 | value is simply rounded and packed into the single-precision format, with
296 | the inexact exception raised if the abstract input cannot be represented
297 | exactly.  However, if the abstract value is too large, the overflow and
298 | inexact exceptions are raised and an infinity or maximal finite value is
299 | returned.  If the abstract value is too small, the input value is rounded to
300 | a subnormal number, and the underflow and inexact exceptions are raised if
301 | the abstract input cannot be represented exactly as a subnormal single-
302 | precision floating-point number.
303 |     The input significand `zSig' has its binary point between bits 30
304 | and 29, which is 7 bits to the left of the usual location.  This shifted
305 | significand must be normalized or smaller.  If `zSig' is not normalized,
306 | `zExp' must be 0; in that case, the result returned is a subnormal number,
307 | and it must not require rounding.  In the usual case that `zSig' is
308 | normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
309 | The handling of underflow and overflow follows the IEC/IEEE Standard for
310 | Binary Floating-Point Arithmetic.
311 *----------------------------------------------------------------------------*/
312 
313 static float32 roundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig STATUS_PARAM)
314 {
315     int8 roundingMode;
316     flag roundNearestEven;
317     int8 roundIncrement, roundBits;
318     flag isTiny;
319 
320     roundingMode = STATUS(float_rounding_mode);
321     roundNearestEven = ( roundingMode == float_round_nearest_even );
322     roundIncrement = 0x40;
323     if ( ! roundNearestEven ) {
324         if ( roundingMode == float_round_to_zero ) {
325             roundIncrement = 0;
326         }
327         else {
328             roundIncrement = 0x7F;
329             if ( zSign ) {
330                 if ( roundingMode == float_round_up ) roundIncrement = 0;
331             }
332             else {
333                 if ( roundingMode == float_round_down ) roundIncrement = 0;
334             }
335         }
336     }
337     roundBits = zSig & 0x7F;
338     if ( 0xFD <= (uint16_t) zExp ) {
339         if (    ( 0xFD < zExp )
340              || (    ( zExp == 0xFD )
341                   && ( (int32_t) ( zSig + roundIncrement ) < 0 ) )
342            ) {
343             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
344             return packFloat32( zSign, 0xFF, - ( roundIncrement == 0 ));
345         }
346         if ( zExp < 0 ) {
347             if (STATUS(flush_to_zero)) {
348                 float_raise(float_flag_output_denormal STATUS_VAR);
349                 return packFloat32(zSign, 0, 0);
350             }
351             isTiny =
352                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
353                 || ( zExp < -1 )
354                 || ( zSig + roundIncrement < 0x80000000 );
355             shift32RightJamming( zSig, - zExp, &zSig );
356             zExp = 0;
357             roundBits = zSig & 0x7F;
358             if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
359         }
360     }
361     if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
362     zSig = ( zSig + roundIncrement )>>7;
363     zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
364     if ( zSig == 0 ) zExp = 0;
365     return packFloat32( zSign, zExp, zSig );
366 
367 }
368 
369 /*----------------------------------------------------------------------------
370 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
371 | and significand `zSig', and returns the proper single-precision floating-
372 | point value corresponding to the abstract input.  This routine is just like
373 | `roundAndPackFloat32' except that `zSig' does not have to be normalized.
374 | Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
375 | floating-point exponent.
376 *----------------------------------------------------------------------------*/
377 
378 static float32
379  normalizeRoundAndPackFloat32(flag zSign, int_fast16_t zExp, uint32_t zSig STATUS_PARAM)
380 {
381     int8 shiftCount;
382 
383     shiftCount = countLeadingZeros32( zSig ) - 1;
384     return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
385 
386 }
387 
388 /*----------------------------------------------------------------------------
389 | Returns the fraction bits of the double-precision floating-point value `a'.
390 *----------------------------------------------------------------------------*/
391 
392 INLINE uint64_t extractFloat64Frac( float64 a )
393 {
394 
395     return float64_val(a) & LIT64( 0x000FFFFFFFFFFFFF );
396 
397 }
398 
399 /*----------------------------------------------------------------------------
400 | Returns the exponent bits of the double-precision floating-point value `a'.
401 *----------------------------------------------------------------------------*/
402 
403 INLINE int_fast16_t extractFloat64Exp(float64 a)
404 {
405 
406     return ( float64_val(a)>>52 ) & 0x7FF;
407 
408 }
409 
410 /*----------------------------------------------------------------------------
411 | Returns the sign bit of the double-precision floating-point value `a'.
412 *----------------------------------------------------------------------------*/
413 
414 INLINE flag extractFloat64Sign( float64 a )
415 {
416 
417     return float64_val(a)>>63;
418 
419 }
420 
421 /*----------------------------------------------------------------------------
422 | If `a' is denormal and we are in flush-to-zero mode then set the
423 | input-denormal exception and return zero. Otherwise just return the value.
424 *----------------------------------------------------------------------------*/
425 static float64 float64_squash_input_denormal(float64 a STATUS_PARAM)
426 {
427     if (STATUS(flush_inputs_to_zero)) {
428         if (extractFloat64Exp(a) == 0 && extractFloat64Frac(a) != 0) {
429             float_raise(float_flag_input_denormal STATUS_VAR);
430             return make_float64(float64_val(a) & (1ULL << 63));
431         }
432     }
433     return a;
434 }
435 
436 /*----------------------------------------------------------------------------
437 | Normalizes the subnormal double-precision floating-point value represented
438 | by the denormalized significand `aSig'.  The normalized exponent and
439 | significand are stored at the locations pointed to by `zExpPtr' and
440 | `zSigPtr', respectively.
441 *----------------------------------------------------------------------------*/
442 
443 static void
444  normalizeFloat64Subnormal(uint64_t aSig, int_fast16_t *zExpPtr, uint64_t *zSigPtr)
445 {
446     int8 shiftCount;
447 
448     shiftCount = countLeadingZeros64( aSig ) - 11;
449     *zSigPtr = aSig<<shiftCount;
450     *zExpPtr = 1 - shiftCount;
451 
452 }
453 
454 /*----------------------------------------------------------------------------
455 | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
456 | double-precision floating-point value, returning the result.  After being
457 | shifted into the proper positions, the three fields are simply added
458 | together to form the result.  This means that any integer portion of `zSig'
459 | will be added into the exponent.  Since a properly normalized significand
460 | will have an integer portion equal to 1, the `zExp' input should be 1 less
461 | than the desired result exponent whenever `zSig' is a complete, normalized
462 | significand.
463 *----------------------------------------------------------------------------*/
464 
465 INLINE float64 packFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig)
466 {
467 
468     return make_float64(
469         ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<52 ) + zSig);
470 
471 }
472 
473 /*----------------------------------------------------------------------------
474 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
475 | and significand `zSig', and returns the proper double-precision floating-
476 | point value corresponding to the abstract input.  Ordinarily, the abstract
477 | value is simply rounded and packed into the double-precision format, with
478 | the inexact exception raised if the abstract input cannot be represented
479 | exactly.  However, if the abstract value is too large, the overflow and
480 | inexact exceptions are raised and an infinity or maximal finite value is
481 | returned.  If the abstract value is too small, the input value is rounded
482 | to a subnormal number, and the underflow and inexact exceptions are raised
483 | if the abstract input cannot be represented exactly as a subnormal double-
484 | precision floating-point number.
485 |     The input significand `zSig' has its binary point between bits 62
486 | and 61, which is 10 bits to the left of the usual location.  This shifted
487 | significand must be normalized or smaller.  If `zSig' is not normalized,
488 | `zExp' must be 0; in that case, the result returned is a subnormal number,
489 | and it must not require rounding.  In the usual case that `zSig' is
490 | normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
491 | The handling of underflow and overflow follows the IEC/IEEE Standard for
492 | Binary Floating-Point Arithmetic.
493 *----------------------------------------------------------------------------*/
494 
495 static float64 roundAndPackFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig STATUS_PARAM)
496 {
497     int8 roundingMode;
498     flag roundNearestEven;
499     int_fast16_t roundIncrement, roundBits;
500     flag isTiny;
501 
502     roundingMode = STATUS(float_rounding_mode);
503     roundNearestEven = ( roundingMode == float_round_nearest_even );
504     roundIncrement = 0x200;
505     if ( ! roundNearestEven ) {
506         if ( roundingMode == float_round_to_zero ) {
507             roundIncrement = 0;
508         }
509         else {
510             roundIncrement = 0x3FF;
511             if ( zSign ) {
512                 if ( roundingMode == float_round_up ) roundIncrement = 0;
513             }
514             else {
515                 if ( roundingMode == float_round_down ) roundIncrement = 0;
516             }
517         }
518     }
519     roundBits = zSig & 0x3FF;
520     if ( 0x7FD <= (uint16_t) zExp ) {
521         if (    ( 0x7FD < zExp )
522              || (    ( zExp == 0x7FD )
523                   && ( (int64_t) ( zSig + roundIncrement ) < 0 ) )
524            ) {
525             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
526             return packFloat64( zSign, 0x7FF, - ( roundIncrement == 0 ));
527         }
528         if ( zExp < 0 ) {
529             if (STATUS(flush_to_zero)) {
530                 float_raise(float_flag_output_denormal STATUS_VAR);
531                 return packFloat64(zSign, 0, 0);
532             }
533             isTiny =
534                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
535                 || ( zExp < -1 )
536                 || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
537             shift64RightJamming( zSig, - zExp, &zSig );
538             zExp = 0;
539             roundBits = zSig & 0x3FF;
540             if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
541         }
542     }
543     if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
544     zSig = ( zSig + roundIncrement )>>10;
545     zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
546     if ( zSig == 0 ) zExp = 0;
547     return packFloat64( zSign, zExp, zSig );
548 
549 }
550 
551 /*----------------------------------------------------------------------------
552 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
553 | and significand `zSig', and returns the proper double-precision floating-
554 | point value corresponding to the abstract input.  This routine is just like
555 | `roundAndPackFloat64' except that `zSig' does not have to be normalized.
556 | Bit 63 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
557 | floating-point exponent.
558 *----------------------------------------------------------------------------*/
559 
560 static float64
561  normalizeRoundAndPackFloat64(flag zSign, int_fast16_t zExp, uint64_t zSig STATUS_PARAM)
562 {
563     int8 shiftCount;
564 
565     shiftCount = countLeadingZeros64( zSig ) - 1;
566     return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount STATUS_VAR);
567 
568 }
569 
570 /*----------------------------------------------------------------------------
571 | Returns the fraction bits of the extended double-precision floating-point
572 | value `a'.
573 *----------------------------------------------------------------------------*/
574 
575 INLINE uint64_t extractFloatx80Frac( floatx80 a )
576 {
577 
578     return a.low;
579 
580 }
581 
582 /*----------------------------------------------------------------------------
583 | Returns the exponent bits of the extended double-precision floating-point
584 | value `a'.
585 *----------------------------------------------------------------------------*/
586 
587 INLINE int32 extractFloatx80Exp( floatx80 a )
588 {
589 
590     return a.high & 0x7FFF;
591 
592 }
593 
594 /*----------------------------------------------------------------------------
595 | Returns the sign bit of the extended double-precision floating-point value
596 | `a'.
597 *----------------------------------------------------------------------------*/
598 
599 INLINE flag extractFloatx80Sign( floatx80 a )
600 {
601 
602     return a.high>>15;
603 
604 }
605 
606 /*----------------------------------------------------------------------------
607 | Normalizes the subnormal extended double-precision floating-point value
608 | represented by the denormalized significand `aSig'.  The normalized exponent
609 | and significand are stored at the locations pointed to by `zExpPtr' and
610 | `zSigPtr', respectively.
611 *----------------------------------------------------------------------------*/
612 
613 static void
614  normalizeFloatx80Subnormal( uint64_t aSig, int32 *zExpPtr, uint64_t *zSigPtr )
615 {
616     int8 shiftCount;
617 
618     shiftCount = countLeadingZeros64( aSig );
619     *zSigPtr = aSig<<shiftCount;
620     *zExpPtr = 1 - shiftCount;
621 
622 }
623 
624 /*----------------------------------------------------------------------------
625 | Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
626 | extended double-precision floating-point value, returning the result.
627 *----------------------------------------------------------------------------*/
628 
629 INLINE floatx80 packFloatx80( flag zSign, int32 zExp, uint64_t zSig )
630 {
631     floatx80 z;
632 
633     z.low = zSig;
634     z.high = ( ( (uint16_t) zSign )<<15 ) + zExp;
635     return z;
636 
637 }
638 
639 /*----------------------------------------------------------------------------
640 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
641 | and extended significand formed by the concatenation of `zSig0' and `zSig1',
642 | and returns the proper extended double-precision floating-point value
643 | corresponding to the abstract input.  Ordinarily, the abstract value is
644 | rounded and packed into the extended double-precision format, with the
645 | inexact exception raised if the abstract input cannot be represented
646 | exactly.  However, if the abstract value is too large, the overflow and
647 | inexact exceptions are raised and an infinity or maximal finite value is
648 | returned.  If the abstract value is too small, the input value is rounded to
649 | a subnormal number, and the underflow and inexact exceptions are raised if
650 | the abstract input cannot be represented exactly as a subnormal extended
651 | double-precision floating-point number.
652 |     If `roundingPrecision' is 32 or 64, the result is rounded to the same
653 | number of bits as single or double precision, respectively.  Otherwise, the
654 | result is rounded to the full precision of the extended double-precision
655 | format.
656 |     The input significand must be normalized or smaller.  If the input
657 | significand is not normalized, `zExp' must be 0; in that case, the result
658 | returned is a subnormal number, and it must not require rounding.  The
659 | handling of underflow and overflow follows the IEC/IEEE Standard for Binary
660 | Floating-Point Arithmetic.
661 *----------------------------------------------------------------------------*/
662 
663 static floatx80
664  roundAndPackFloatx80(
665      int8 roundingPrecision, flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1
666  STATUS_PARAM)
667 {
668     int8 roundingMode;
669     flag roundNearestEven, increment, isTiny;
670     int64 roundIncrement, roundMask, roundBits;
671 
672     roundingMode = STATUS(float_rounding_mode);
673     roundNearestEven = ( roundingMode == float_round_nearest_even );
674     if ( roundingPrecision == 80 ) goto precision80;
675     if ( roundingPrecision == 64 ) {
676         roundIncrement = LIT64( 0x0000000000000400 );
677         roundMask = LIT64( 0x00000000000007FF );
678     }
679     else if ( roundingPrecision == 32 ) {
680         roundIncrement = LIT64( 0x0000008000000000 );
681         roundMask = LIT64( 0x000000FFFFFFFFFF );
682     }
683     else {
684         goto precision80;
685     }
686     zSig0 |= ( zSig1 != 0 );
687     if ( ! roundNearestEven ) {
688         if ( roundingMode == float_round_to_zero ) {
689             roundIncrement = 0;
690         }
691         else {
692             roundIncrement = roundMask;
693             if ( zSign ) {
694                 if ( roundingMode == float_round_up ) roundIncrement = 0;
695             }
696             else {
697                 if ( roundingMode == float_round_down ) roundIncrement = 0;
698             }
699         }
700     }
701     roundBits = zSig0 & roundMask;
702     if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
703         if (    ( 0x7FFE < zExp )
704              || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
705            ) {
706             goto overflow;
707         }
708         if ( zExp <= 0 ) {
709             if (STATUS(flush_to_zero)) {
710                 float_raise(float_flag_output_denormal STATUS_VAR);
711                 return packFloatx80(zSign, 0, 0);
712             }
713             isTiny =
714                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
715                 || ( zExp < 0 )
716                 || ( zSig0 <= zSig0 + roundIncrement );
717             shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
718             zExp = 0;
719             roundBits = zSig0 & roundMask;
720             if ( isTiny && roundBits ) float_raise( float_flag_underflow STATUS_VAR);
721             if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
722             zSig0 += roundIncrement;
723             if ( (int64_t) zSig0 < 0 ) zExp = 1;
724             roundIncrement = roundMask + 1;
725             if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
726                 roundMask |= roundIncrement;
727             }
728             zSig0 &= ~ roundMask;
729             return packFloatx80( zSign, zExp, zSig0 );
730         }
731     }
732     if ( roundBits ) STATUS(float_exception_flags) |= float_flag_inexact;
733     zSig0 += roundIncrement;
734     if ( zSig0 < roundIncrement ) {
735         ++zExp;
736         zSig0 = LIT64( 0x8000000000000000 );
737     }
738     roundIncrement = roundMask + 1;
739     if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
740         roundMask |= roundIncrement;
741     }
742     zSig0 &= ~ roundMask;
743     if ( zSig0 == 0 ) zExp = 0;
744     return packFloatx80( zSign, zExp, zSig0 );
745  precision80:
746     increment = ( (int64_t) zSig1 < 0 );
747     if ( ! roundNearestEven ) {
748         if ( roundingMode == float_round_to_zero ) {
749             increment = 0;
750         }
751         else {
752             if ( zSign ) {
753                 increment = ( roundingMode == float_round_down ) && zSig1;
754             }
755             else {
756                 increment = ( roundingMode == float_round_up ) && zSig1;
757             }
758         }
759     }
760     if ( 0x7FFD <= (uint32_t) ( zExp - 1 ) ) {
761         if (    ( 0x7FFE < zExp )
762              || (    ( zExp == 0x7FFE )
763                   && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
764                   && increment
765                 )
766            ) {
767             roundMask = 0;
768  overflow:
769             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
770             if (    ( roundingMode == float_round_to_zero )
771                  || ( zSign && ( roundingMode == float_round_up ) )
772                  || ( ! zSign && ( roundingMode == float_round_down ) )
773                ) {
774                 return packFloatx80( zSign, 0x7FFE, ~ roundMask );
775             }
776             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
777         }
778         if ( zExp <= 0 ) {
779             isTiny =
780                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
781                 || ( zExp < 0 )
782                 || ! increment
783                 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
784             shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
785             zExp = 0;
786             if ( isTiny && zSig1 ) float_raise( float_flag_underflow STATUS_VAR);
787             if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
788             if ( roundNearestEven ) {
789                 increment = ( (int64_t) zSig1 < 0 );
790             }
791             else {
792                 if ( zSign ) {
793                     increment = ( roundingMode == float_round_down ) && zSig1;
794                 }
795                 else {
796                     increment = ( roundingMode == float_round_up ) && zSig1;
797                 }
798             }
799             if ( increment ) {
800                 ++zSig0;
801                 zSig0 &=
802                     ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
803                 if ( (int64_t) zSig0 < 0 ) zExp = 1;
804             }
805             return packFloatx80( zSign, zExp, zSig0 );
806         }
807     }
808     if ( zSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
809     if ( increment ) {
810         ++zSig0;
811         if ( zSig0 == 0 ) {
812             ++zExp;
813             zSig0 = LIT64( 0x8000000000000000 );
814         }
815         else {
816             zSig0 &= ~ ( ( (uint64_t) ( zSig1<<1 ) == 0 ) & roundNearestEven );
817         }
818     }
819     else {
820         if ( zSig0 == 0 ) zExp = 0;
821     }
822     return packFloatx80( zSign, zExp, zSig0 );
823 
824 }
825 
826 /*----------------------------------------------------------------------------
827 | Takes an abstract floating-point value having sign `zSign', exponent
828 | `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
829 | and returns the proper extended double-precision floating-point value
830 | corresponding to the abstract input.  This routine is just like
831 | `roundAndPackFloatx80' except that the input significand does not have to be
832 | normalized.
833 *----------------------------------------------------------------------------*/
834 
835 static floatx80
836  normalizeRoundAndPackFloatx80(
837      int8 roundingPrecision, flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1
838  STATUS_PARAM)
839 {
840     int8 shiftCount;
841 
842     if ( zSig0 == 0 ) {
843         zSig0 = zSig1;
844         zSig1 = 0;
845         zExp -= 64;
846     }
847     shiftCount = countLeadingZeros64( zSig0 );
848     shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
849     zExp -= shiftCount;
850     return
851         roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1 STATUS_VAR);
852 
853 }
854 
855 /*----------------------------------------------------------------------------
856 | Returns the least-significant 64 fraction bits of the quadruple-precision
857 | floating-point value `a'.
858 *----------------------------------------------------------------------------*/
859 
860 INLINE uint64_t extractFloat128Frac1( float128 a )
861 {
862 
863     return a.low;
864 
865 }
866 
867 /*----------------------------------------------------------------------------
868 | Returns the most-significant 48 fraction bits of the quadruple-precision
869 | floating-point value `a'.
870 *----------------------------------------------------------------------------*/
871 
872 INLINE uint64_t extractFloat128Frac0( float128 a )
873 {
874 
875     return a.high & LIT64( 0x0000FFFFFFFFFFFF );
876 
877 }
878 
879 /*----------------------------------------------------------------------------
880 | Returns the exponent bits of the quadruple-precision floating-point value
881 | `a'.
882 *----------------------------------------------------------------------------*/
883 
884 INLINE int32 extractFloat128Exp( float128 a )
885 {
886 
887     return ( a.high>>48 ) & 0x7FFF;
888 
889 }
890 
891 /*----------------------------------------------------------------------------
892 | Returns the sign bit of the quadruple-precision floating-point value `a'.
893 *----------------------------------------------------------------------------*/
894 
895 INLINE flag extractFloat128Sign( float128 a )
896 {
897 
898     return a.high>>63;
899 
900 }
901 
902 /*----------------------------------------------------------------------------
903 | Normalizes the subnormal quadruple-precision floating-point value
904 | represented by the denormalized significand formed by the concatenation of
905 | `aSig0' and `aSig1'.  The normalized exponent is stored at the location
906 | pointed to by `zExpPtr'.  The most significant 49 bits of the normalized
907 | significand are stored at the location pointed to by `zSig0Ptr', and the
908 | least significant 64 bits of the normalized significand are stored at the
909 | location pointed to by `zSig1Ptr'.
910 *----------------------------------------------------------------------------*/
911 
912 static void
913  normalizeFloat128Subnormal(
914      uint64_t aSig0,
915      uint64_t aSig1,
916      int32 *zExpPtr,
917      uint64_t *zSig0Ptr,
918      uint64_t *zSig1Ptr
919  )
920 {
921     int8 shiftCount;
922 
923     if ( aSig0 == 0 ) {
924         shiftCount = countLeadingZeros64( aSig1 ) - 15;
925         if ( shiftCount < 0 ) {
926             *zSig0Ptr = aSig1>>( - shiftCount );
927             *zSig1Ptr = aSig1<<( shiftCount & 63 );
928         }
929         else {
930             *zSig0Ptr = aSig1<<shiftCount;
931             *zSig1Ptr = 0;
932         }
933         *zExpPtr = - shiftCount - 63;
934     }
935     else {
936         shiftCount = countLeadingZeros64( aSig0 ) - 15;
937         shortShift128Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
938         *zExpPtr = 1 - shiftCount;
939     }
940 
941 }
942 
943 /*----------------------------------------------------------------------------
944 | Packs the sign `zSign', the exponent `zExp', and the significand formed
945 | by the concatenation of `zSig0' and `zSig1' into a quadruple-precision
946 | floating-point value, returning the result.  After being shifted into the
947 | proper positions, the three fields `zSign', `zExp', and `zSig0' are simply
948 | added together to form the most significant 32 bits of the result.  This
949 | means that any integer portion of `zSig0' will be added into the exponent.
950 | Since a properly normalized significand will have an integer portion equal
951 | to 1, the `zExp' input should be 1 less than the desired result exponent
952 | whenever `zSig0' and `zSig1' concatenated form a complete, normalized
953 | significand.
954 *----------------------------------------------------------------------------*/
955 
956 INLINE float128
957  packFloat128( flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 )
958 {
959     float128 z;
960 
961     z.low = zSig1;
962     z.high = ( ( (uint64_t) zSign )<<63 ) + ( ( (uint64_t) zExp )<<48 ) + zSig0;
963     return z;
964 
965 }
966 
967 /*----------------------------------------------------------------------------
968 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
969 | and extended significand formed by the concatenation of `zSig0', `zSig1',
970 | and `zSig2', and returns the proper quadruple-precision floating-point value
971 | corresponding to the abstract input.  Ordinarily, the abstract value is
972 | simply rounded and packed into the quadruple-precision format, with the
973 | inexact exception raised if the abstract input cannot be represented
974 | exactly.  However, if the abstract value is too large, the overflow and
975 | inexact exceptions are raised and an infinity or maximal finite value is
976 | returned.  If the abstract value is too small, the input value is rounded to
977 | a subnormal number, and the underflow and inexact exceptions are raised if
978 | the abstract input cannot be represented exactly as a subnormal quadruple-
979 | precision floating-point number.
980 |     The input significand must be normalized or smaller.  If the input
981 | significand is not normalized, `zExp' must be 0; in that case, the result
982 | returned is a subnormal number, and it must not require rounding.  In the
983 | usual case that the input significand is normalized, `zExp' must be 1 less
984 | than the ``true'' floating-point exponent.  The handling of underflow and
985 | overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
986 *----------------------------------------------------------------------------*/
987 
988 static float128
989  roundAndPackFloat128(
990      flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1, uint64_t zSig2 STATUS_PARAM)
991 {
992     int8 roundingMode;
993     flag roundNearestEven, increment, isTiny;
994 
995     roundingMode = STATUS(float_rounding_mode);
996     roundNearestEven = ( roundingMode == float_round_nearest_even );
997     increment = ( (int64_t) zSig2 < 0 );
998     if ( ! roundNearestEven ) {
999         if ( roundingMode == float_round_to_zero ) {
1000             increment = 0;
1001         }
1002         else {
1003             if ( zSign ) {
1004                 increment = ( roundingMode == float_round_down ) && zSig2;
1005             }
1006             else {
1007                 increment = ( roundingMode == float_round_up ) && zSig2;
1008             }
1009         }
1010     }
1011     if ( 0x7FFD <= (uint32_t) zExp ) {
1012         if (    ( 0x7FFD < zExp )
1013              || (    ( zExp == 0x7FFD )
1014                   && eq128(
1015                          LIT64( 0x0001FFFFFFFFFFFF ),
1016                          LIT64( 0xFFFFFFFFFFFFFFFF ),
1017                          zSig0,
1018                          zSig1
1019                      )
1020                   && increment
1021                 )
1022            ) {
1023             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
1024             if (    ( roundingMode == float_round_to_zero )
1025                  || ( zSign && ( roundingMode == float_round_up ) )
1026                  || ( ! zSign && ( roundingMode == float_round_down ) )
1027                ) {
1028                 return
1029                     packFloat128(
1030                         zSign,
1031                         0x7FFE,
1032                         LIT64( 0x0000FFFFFFFFFFFF ),
1033                         LIT64( 0xFFFFFFFFFFFFFFFF )
1034                     );
1035             }
1036             return packFloat128( zSign, 0x7FFF, 0, 0 );
1037         }
1038         if ( zExp < 0 ) {
1039             if (STATUS(flush_to_zero)) {
1040                 float_raise(float_flag_output_denormal STATUS_VAR);
1041                 return packFloat128(zSign, 0, 0, 0);
1042             }
1043             isTiny =
1044                    ( STATUS(float_detect_tininess) == float_tininess_before_rounding )
1045                 || ( zExp < -1 )
1046                 || ! increment
1047                 || lt128(
1048                        zSig0,
1049                        zSig1,
1050                        LIT64( 0x0001FFFFFFFFFFFF ),
1051                        LIT64( 0xFFFFFFFFFFFFFFFF )
1052                    );
1053             shift128ExtraRightJamming(
1054                 zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
1055             zExp = 0;
1056             if ( isTiny && zSig2 ) float_raise( float_flag_underflow STATUS_VAR);
1057             if ( roundNearestEven ) {
1058                 increment = ( (int64_t) zSig2 < 0 );
1059             }
1060             else {
1061                 if ( zSign ) {
1062                     increment = ( roundingMode == float_round_down ) && zSig2;
1063                 }
1064                 else {
1065                     increment = ( roundingMode == float_round_up ) && zSig2;
1066                 }
1067             }
1068         }
1069     }
1070     if ( zSig2 ) STATUS(float_exception_flags) |= float_flag_inexact;
1071     if ( increment ) {
1072         add128( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
1073         zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
1074     }
1075     else {
1076         if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
1077     }
1078     return packFloat128( zSign, zExp, zSig0, zSig1 );
1079 
1080 }
1081 
1082 /*----------------------------------------------------------------------------
1083 | Takes an abstract floating-point value having sign `zSign', exponent `zExp',
1084 | and significand formed by the concatenation of `zSig0' and `zSig1', and
1085 | returns the proper quadruple-precision floating-point value corresponding
1086 | to the abstract input.  This routine is just like `roundAndPackFloat128'
1087 | except that the input significand has fewer bits and does not have to be
1088 | normalized.  In all cases, `zExp' must be 1 less than the ``true'' floating-
1089 | point exponent.
1090 *----------------------------------------------------------------------------*/
1091 
1092 static float128
1093  normalizeRoundAndPackFloat128(
1094      flag zSign, int32 zExp, uint64_t zSig0, uint64_t zSig1 STATUS_PARAM)
1095 {
1096     int8 shiftCount;
1097     uint64_t zSig2;
1098 
1099     if ( zSig0 == 0 ) {
1100         zSig0 = zSig1;
1101         zSig1 = 0;
1102         zExp -= 64;
1103     }
1104     shiftCount = countLeadingZeros64( zSig0 ) - 15;
1105     if ( 0 <= shiftCount ) {
1106         zSig2 = 0;
1107         shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
1108     }
1109     else {
1110         shift128ExtraRightJamming(
1111             zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
1112     }
1113     zExp -= shiftCount;
1114     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR);
1115 
1116 }
1117 
1118 /*----------------------------------------------------------------------------
1119 | Returns the result of converting the 32-bit two's complement integer `a'
1120 | to the single-precision floating-point format.  The conversion is performed
1121 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1122 *----------------------------------------------------------------------------*/
1123 
1124 float32 int32_to_float32( int32 a STATUS_PARAM )
1125 {
1126     flag zSign;
1127 
1128     if ( a == 0 ) return float32_zero;
1129     if ( a == (int32_t) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
1130     zSign = ( a < 0 );
1131     return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a STATUS_VAR );
1132 
1133 }
1134 
1135 /*----------------------------------------------------------------------------
1136 | Returns the result of converting the 32-bit two's complement integer `a'
1137 | to the double-precision floating-point format.  The conversion is performed
1138 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1139 *----------------------------------------------------------------------------*/
1140 
1141 float64 int32_to_float64( int32 a STATUS_PARAM )
1142 {
1143     flag zSign;
1144     uint32 absA;
1145     int8 shiftCount;
1146     uint64_t zSig;
1147 
1148     if ( a == 0 ) return float64_zero;
1149     zSign = ( a < 0 );
1150     absA = zSign ? - a : a;
1151     shiftCount = countLeadingZeros32( absA ) + 21;
1152     zSig = absA;
1153     return packFloat64( zSign, 0x432 - shiftCount, zSig<<shiftCount );
1154 
1155 }
1156 
1157 /*----------------------------------------------------------------------------
1158 | Returns the result of converting the 32-bit two's complement integer `a'
1159 | to the extended double-precision floating-point format.  The conversion
1160 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
1161 | Arithmetic.
1162 *----------------------------------------------------------------------------*/
1163 
1164 floatx80 int32_to_floatx80( int32 a STATUS_PARAM )
1165 {
1166     flag zSign;
1167     uint32 absA;
1168     int8 shiftCount;
1169     uint64_t zSig;
1170 
1171     if ( a == 0 ) return packFloatx80( 0, 0, 0 );
1172     zSign = ( a < 0 );
1173     absA = zSign ? - a : a;
1174     shiftCount = countLeadingZeros32( absA ) + 32;
1175     zSig = absA;
1176     return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
1177 
1178 }
1179 
1180 /*----------------------------------------------------------------------------
1181 | Returns the result of converting the 32-bit two's complement integer `a' to
1182 | the quadruple-precision floating-point format.  The conversion is performed
1183 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1184 *----------------------------------------------------------------------------*/
1185 
1186 float128 int32_to_float128( int32 a STATUS_PARAM )
1187 {
1188     flag zSign;
1189     uint32 absA;
1190     int8 shiftCount;
1191     uint64_t zSig0;
1192 
1193     if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
1194     zSign = ( a < 0 );
1195     absA = zSign ? - a : a;
1196     shiftCount = countLeadingZeros32( absA ) + 17;
1197     zSig0 = absA;
1198     return packFloat128( zSign, 0x402E - shiftCount, zSig0<<shiftCount, 0 );
1199 
1200 }
1201 
1202 /*----------------------------------------------------------------------------
1203 | Returns the result of converting the 64-bit two's complement integer `a'
1204 | to the single-precision floating-point format.  The conversion is performed
1205 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1206 *----------------------------------------------------------------------------*/
1207 
1208 float32 int64_to_float32( int64 a STATUS_PARAM )
1209 {
1210     flag zSign;
1211     uint64 absA;
1212     int8 shiftCount;
1213 
1214     if ( a == 0 ) return float32_zero;
1215     zSign = ( a < 0 );
1216     absA = zSign ? - a : a;
1217     shiftCount = countLeadingZeros64( absA ) - 40;
1218     if ( 0 <= shiftCount ) {
1219         return packFloat32( zSign, 0x95 - shiftCount, absA<<shiftCount );
1220     }
1221     else {
1222         shiftCount += 7;
1223         if ( shiftCount < 0 ) {
1224             shift64RightJamming( absA, - shiftCount, &absA );
1225         }
1226         else {
1227             absA <<= shiftCount;
1228         }
1229         return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA STATUS_VAR );
1230     }
1231 
1232 }
1233 
1234 float32 uint64_to_float32( uint64 a STATUS_PARAM )
1235 {
1236     int8 shiftCount;
1237 
1238     if ( a == 0 ) return float32_zero;
1239     shiftCount = countLeadingZeros64( a ) - 40;
1240     if ( 0 <= shiftCount ) {
1241         return packFloat32(0, 0x95 - shiftCount, a<<shiftCount);
1242     }
1243     else {
1244         shiftCount += 7;
1245         if ( shiftCount < 0 ) {
1246             shift64RightJamming( a, - shiftCount, &a );
1247         }
1248         else {
1249             a <<= shiftCount;
1250         }
1251         return roundAndPackFloat32(0, 0x9C - shiftCount, a STATUS_VAR);
1252     }
1253 }
1254 
1255 /*----------------------------------------------------------------------------
1256 | Returns the result of converting the 64-bit two's complement integer `a'
1257 | to the double-precision floating-point format.  The conversion is performed
1258 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1259 *----------------------------------------------------------------------------*/
1260 
1261 float64 int64_to_float64( int64 a STATUS_PARAM )
1262 {
1263     flag zSign;
1264 
1265     if ( a == 0 ) return float64_zero;
1266     if ( a == (int64_t) LIT64( 0x8000000000000000 ) ) {
1267         return packFloat64( 1, 0x43E, 0 );
1268     }
1269     zSign = ( a < 0 );
1270     return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a STATUS_VAR );
1271 
1272 }
1273 
1274 float64 uint64_to_float64(uint64 a STATUS_PARAM)
1275 {
1276     int exp =  0x43C;
1277 
1278     if (a == 0) {
1279         return float64_zero;
1280     }
1281     if ((int64_t)a < 0) {
1282         shift64RightJamming(a, 1, &a);
1283         exp += 1;
1284     }
1285     return normalizeRoundAndPackFloat64(0, exp, a STATUS_VAR);
1286 }
1287 
1288 /*----------------------------------------------------------------------------
1289 | Returns the result of converting the 64-bit two's complement integer `a'
1290 | to the extended double-precision floating-point format.  The conversion
1291 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
1292 | Arithmetic.
1293 *----------------------------------------------------------------------------*/
1294 
1295 floatx80 int64_to_floatx80( int64 a STATUS_PARAM )
1296 {
1297     flag zSign;
1298     uint64 absA;
1299     int8 shiftCount;
1300 
1301     if ( a == 0 ) return packFloatx80( 0, 0, 0 );
1302     zSign = ( a < 0 );
1303     absA = zSign ? - a : a;
1304     shiftCount = countLeadingZeros64( absA );
1305     return packFloatx80( zSign, 0x403E - shiftCount, absA<<shiftCount );
1306 
1307 }
1308 
1309 /*----------------------------------------------------------------------------
1310 | Returns the result of converting the 64-bit two's complement integer `a' to
1311 | the quadruple-precision floating-point format.  The conversion is performed
1312 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1313 *----------------------------------------------------------------------------*/
1314 
1315 float128 int64_to_float128( int64 a STATUS_PARAM )
1316 {
1317     flag zSign;
1318     uint64 absA;
1319     int8 shiftCount;
1320     int32 zExp;
1321     uint64_t zSig0, zSig1;
1322 
1323     if ( a == 0 ) return packFloat128( 0, 0, 0, 0 );
1324     zSign = ( a < 0 );
1325     absA = zSign ? - a : a;
1326     shiftCount = countLeadingZeros64( absA ) + 49;
1327     zExp = 0x406E - shiftCount;
1328     if ( 64 <= shiftCount ) {
1329         zSig1 = 0;
1330         zSig0 = absA;
1331         shiftCount -= 64;
1332     }
1333     else {
1334         zSig1 = absA;
1335         zSig0 = 0;
1336     }
1337     shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
1338     return packFloat128( zSign, zExp, zSig0, zSig1 );
1339 
1340 }
1341 
1342 float128 uint64_to_float128(uint64 a STATUS_PARAM)
1343 {
1344     if (a == 0) {
1345         return float128_zero;
1346     }
1347     return normalizeRoundAndPackFloat128(0, 0x406E, a, 0 STATUS_VAR);
1348 }
1349 
1350 /*----------------------------------------------------------------------------
1351 | Returns the result of converting the single-precision floating-point value
1352 | `a' to the 32-bit two's complement integer format.  The conversion is
1353 | performed according to the IEC/IEEE Standard for Binary Floating-Point
1354 | Arithmetic---which means in particular that the conversion is rounded
1355 | according to the current rounding mode.  If `a' is a NaN, the largest
1356 | positive integer is returned.  Otherwise, if the conversion overflows, the
1357 | largest integer with the same sign as `a' is returned.
1358 *----------------------------------------------------------------------------*/
1359 
1360 int32 float32_to_int32( float32 a STATUS_PARAM )
1361 {
1362     flag aSign;
1363     int_fast16_t aExp, shiftCount;
1364     uint32_t aSig;
1365     uint64_t aSig64;
1366 
1367     a = float32_squash_input_denormal(a STATUS_VAR);
1368     aSig = extractFloat32Frac( a );
1369     aExp = extractFloat32Exp( a );
1370     aSign = extractFloat32Sign( a );
1371     if ( ( aExp == 0xFF ) && aSig ) aSign = 0;
1372     if ( aExp ) aSig |= 0x00800000;
1373     shiftCount = 0xAF - aExp;
1374     aSig64 = aSig;
1375     aSig64 <<= 32;
1376     if ( 0 < shiftCount ) shift64RightJamming( aSig64, shiftCount, &aSig64 );
1377     return roundAndPackInt32( aSign, aSig64 STATUS_VAR );
1378 
1379 }
1380 
1381 /*----------------------------------------------------------------------------
1382 | Returns the result of converting the single-precision floating-point value
1383 | `a' to the 32-bit two's complement integer format.  The conversion is
1384 | performed according to the IEC/IEEE Standard for Binary Floating-Point
1385 | Arithmetic, except that the conversion is always rounded toward zero.
1386 | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
1387 | the conversion overflows, the largest integer with the same sign as `a' is
1388 | returned.
1389 *----------------------------------------------------------------------------*/
1390 
1391 int32 float32_to_int32_round_to_zero( float32 a STATUS_PARAM )
1392 {
1393     flag aSign;
1394     int_fast16_t aExp, shiftCount;
1395     uint32_t aSig;
1396     int32_t z;
1397     a = float32_squash_input_denormal(a STATUS_VAR);
1398 
1399     aSig = extractFloat32Frac( a );
1400     aExp = extractFloat32Exp( a );
1401     aSign = extractFloat32Sign( a );
1402     shiftCount = aExp - 0x9E;
1403     if ( 0 <= shiftCount ) {
1404         if ( float32_val(a) != 0xCF000000 ) {
1405             float_raise( float_flag_invalid STATUS_VAR);
1406             if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
1407         }
1408         return (int32_t) 0x80000000;
1409     }
1410     else if ( aExp <= 0x7E ) {
1411         if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
1412         return 0;
1413     }
1414     aSig = ( aSig | 0x00800000 )<<8;
1415     z = aSig>>( - shiftCount );
1416     if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) {
1417         STATUS(float_exception_flags) |= float_flag_inexact;
1418     }
1419     if ( aSign ) z = - z;
1420     return z;
1421 
1422 }
1423 
1424 /*----------------------------------------------------------------------------
1425 | Returns the result of converting the single-precision floating-point value
1426 | `a' to the 16-bit two's complement integer format.  The conversion is
1427 | performed according to the IEC/IEEE Standard for Binary Floating-Point
1428 | Arithmetic, except that the conversion is always rounded toward zero.
1429 | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
1430 | the conversion overflows, the largest integer with the same sign as `a' is
1431 | returned.
1432 *----------------------------------------------------------------------------*/
1433 
1434 int_fast16_t float32_to_int16_round_to_zero(float32 a STATUS_PARAM)
1435 {
1436     flag aSign;
1437     int_fast16_t aExp, shiftCount;
1438     uint32_t aSig;
1439     int32 z;
1440 
1441     aSig = extractFloat32Frac( a );
1442     aExp = extractFloat32Exp( a );
1443     aSign = extractFloat32Sign( a );
1444     shiftCount = aExp - 0x8E;
1445     if ( 0 <= shiftCount ) {
1446         if ( float32_val(a) != 0xC7000000 ) {
1447             float_raise( float_flag_invalid STATUS_VAR);
1448             if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
1449                 return 0x7FFF;
1450             }
1451         }
1452         return (int32_t) 0xffff8000;
1453     }
1454     else if ( aExp <= 0x7E ) {
1455         if ( aExp | aSig ) {
1456             STATUS(float_exception_flags) |= float_flag_inexact;
1457         }
1458         return 0;
1459     }
1460     shiftCount -= 0x10;
1461     aSig = ( aSig | 0x00800000 )<<8;
1462     z = aSig>>( - shiftCount );
1463     if ( (uint32_t) ( aSig<<( shiftCount & 31 ) ) ) {
1464         STATUS(float_exception_flags) |= float_flag_inexact;
1465     }
1466     if ( aSign ) {
1467         z = - z;
1468     }
1469     return z;
1470 
1471 }
1472 
1473 /*----------------------------------------------------------------------------
1474 | Returns the result of converting the single-precision floating-point value
1475 | `a' to the 64-bit two's complement integer format.  The conversion is
1476 | performed according to the IEC/IEEE Standard for Binary Floating-Point
1477 | Arithmetic---which means in particular that the conversion is rounded
1478 | according to the current rounding mode.  If `a' is a NaN, the largest
1479 | positive integer is returned.  Otherwise, if the conversion overflows, the
1480 | largest integer with the same sign as `a' is returned.
1481 *----------------------------------------------------------------------------*/
1482 
1483 int64 float32_to_int64( float32 a STATUS_PARAM )
1484 {
1485     flag aSign;
1486     int_fast16_t aExp, shiftCount;
1487     uint32_t aSig;
1488     uint64_t aSig64, aSigExtra;
1489     a = float32_squash_input_denormal(a STATUS_VAR);
1490 
1491     aSig = extractFloat32Frac( a );
1492     aExp = extractFloat32Exp( a );
1493     aSign = extractFloat32Sign( a );
1494     shiftCount = 0xBE - aExp;
1495     if ( shiftCount < 0 ) {
1496         float_raise( float_flag_invalid STATUS_VAR);
1497         if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
1498             return LIT64( 0x7FFFFFFFFFFFFFFF );
1499         }
1500         return (int64_t) LIT64( 0x8000000000000000 );
1501     }
1502     if ( aExp ) aSig |= 0x00800000;
1503     aSig64 = aSig;
1504     aSig64 <<= 40;
1505     shift64ExtraRightJamming( aSig64, 0, shiftCount, &aSig64, &aSigExtra );
1506     return roundAndPackInt64( aSign, aSig64, aSigExtra STATUS_VAR );
1507 
1508 }
1509 
1510 /*----------------------------------------------------------------------------
1511 | Returns the result of converting the single-precision floating-point value
1512 | `a' to the 64-bit two's complement integer format.  The conversion is
1513 | performed according to the IEC/IEEE Standard for Binary Floating-Point
1514 | Arithmetic, except that the conversion is always rounded toward zero.  If
1515 | `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
1516 | conversion overflows, the largest integer with the same sign as `a' is
1517 | returned.
1518 *----------------------------------------------------------------------------*/
1519 
1520 int64 float32_to_int64_round_to_zero( float32 a STATUS_PARAM )
1521 {
1522     flag aSign;
1523     int_fast16_t aExp, shiftCount;
1524     uint32_t aSig;
1525     uint64_t aSig64;
1526     int64 z;
1527     a = float32_squash_input_denormal(a STATUS_VAR);
1528 
1529     aSig = extractFloat32Frac( a );
1530     aExp = extractFloat32Exp( a );
1531     aSign = extractFloat32Sign( a );
1532     shiftCount = aExp - 0xBE;
1533     if ( 0 <= shiftCount ) {
1534         if ( float32_val(a) != 0xDF000000 ) {
1535             float_raise( float_flag_invalid STATUS_VAR);
1536             if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
1537                 return LIT64( 0x7FFFFFFFFFFFFFFF );
1538             }
1539         }
1540         return (int64_t) LIT64( 0x8000000000000000 );
1541     }
1542     else if ( aExp <= 0x7E ) {
1543         if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
1544         return 0;
1545     }
1546     aSig64 = aSig | 0x00800000;
1547     aSig64 <<= 40;
1548     z = aSig64>>( - shiftCount );
1549     if ( (uint64_t) ( aSig64<<( shiftCount & 63 ) ) ) {
1550         STATUS(float_exception_flags) |= float_flag_inexact;
1551     }
1552     if ( aSign ) z = - z;
1553     return z;
1554 
1555 }
1556 
1557 /*----------------------------------------------------------------------------
1558 | Returns the result of converting the single-precision floating-point value
1559 | `a' to the double-precision floating-point format.  The conversion is
1560 | performed according to the IEC/IEEE Standard for Binary Floating-Point
1561 | Arithmetic.
1562 *----------------------------------------------------------------------------*/
1563 
1564 float64 float32_to_float64( float32 a STATUS_PARAM )
1565 {
1566     flag aSign;
1567     int_fast16_t aExp;
1568     uint32_t aSig;
1569     a = float32_squash_input_denormal(a STATUS_VAR);
1570 
1571     aSig = extractFloat32Frac( a );
1572     aExp = extractFloat32Exp( a );
1573     aSign = extractFloat32Sign( a );
1574     if ( aExp == 0xFF ) {
1575         if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
1576         return packFloat64( aSign, 0x7FF, 0 );
1577     }
1578     if ( aExp == 0 ) {
1579         if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
1580         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1581         --aExp;
1582     }
1583     return packFloat64( aSign, aExp + 0x380, ( (uint64_t) aSig )<<29 );
1584 
1585 }
1586 
1587 /*----------------------------------------------------------------------------
1588 | Returns the result of converting the single-precision floating-point value
1589 | `a' to the extended double-precision floating-point format.  The conversion
1590 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
1591 | Arithmetic.
1592 *----------------------------------------------------------------------------*/
1593 
1594 floatx80 float32_to_floatx80( float32 a STATUS_PARAM )
1595 {
1596     flag aSign;
1597     int_fast16_t aExp;
1598     uint32_t aSig;
1599 
1600     a = float32_squash_input_denormal(a STATUS_VAR);
1601     aSig = extractFloat32Frac( a );
1602     aExp = extractFloat32Exp( a );
1603     aSign = extractFloat32Sign( a );
1604     if ( aExp == 0xFF ) {
1605         if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
1606         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
1607     }
1608     if ( aExp == 0 ) {
1609         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
1610         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1611     }
1612     aSig |= 0x00800000;
1613     return packFloatx80( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<40 );
1614 
1615 }
1616 
1617 /*----------------------------------------------------------------------------
1618 | Returns the result of converting the single-precision floating-point value
1619 | `a' to the double-precision floating-point format.  The conversion is
1620 | performed according to the IEC/IEEE Standard for Binary Floating-Point
1621 | Arithmetic.
1622 *----------------------------------------------------------------------------*/
1623 
1624 float128 float32_to_float128( float32 a STATUS_PARAM )
1625 {
1626     flag aSign;
1627     int_fast16_t aExp;
1628     uint32_t aSig;
1629 
1630     a = float32_squash_input_denormal(a STATUS_VAR);
1631     aSig = extractFloat32Frac( a );
1632     aExp = extractFloat32Exp( a );
1633     aSign = extractFloat32Sign( a );
1634     if ( aExp == 0xFF ) {
1635         if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
1636         return packFloat128( aSign, 0x7FFF, 0, 0 );
1637     }
1638     if ( aExp == 0 ) {
1639         if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
1640         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1641         --aExp;
1642     }
1643     return packFloat128( aSign, aExp + 0x3F80, ( (uint64_t) aSig )<<25, 0 );
1644 
1645 }
1646 
1647 /*----------------------------------------------------------------------------
1648 | Rounds the single-precision floating-point value `a' to an integer, and
1649 | returns the result as a single-precision floating-point value.  The
1650 | operation is performed according to the IEC/IEEE Standard for Binary
1651 | Floating-Point Arithmetic.
1652 *----------------------------------------------------------------------------*/
1653 
1654 float32 float32_round_to_int( float32 a STATUS_PARAM)
1655 {
1656     flag aSign;
1657     int_fast16_t aExp;
1658     uint32_t lastBitMask, roundBitsMask;
1659     int8 roundingMode;
1660     uint32_t z;
1661     a = float32_squash_input_denormal(a STATUS_VAR);
1662 
1663     aExp = extractFloat32Exp( a );
1664     if ( 0x96 <= aExp ) {
1665         if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
1666             return propagateFloat32NaN( a, a STATUS_VAR );
1667         }
1668         return a;
1669     }
1670     if ( aExp <= 0x7E ) {
1671         if ( (uint32_t) ( float32_val(a)<<1 ) == 0 ) return a;
1672         STATUS(float_exception_flags) |= float_flag_inexact;
1673         aSign = extractFloat32Sign( a );
1674         switch ( STATUS(float_rounding_mode) ) {
1675          case float_round_nearest_even:
1676             if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
1677                 return packFloat32( aSign, 0x7F, 0 );
1678             }
1679             break;
1680          case float_round_down:
1681             return make_float32(aSign ? 0xBF800000 : 0);
1682          case float_round_up:
1683             return make_float32(aSign ? 0x80000000 : 0x3F800000);
1684         }
1685         return packFloat32( aSign, 0, 0 );
1686     }
1687     lastBitMask = 1;
1688     lastBitMask <<= 0x96 - aExp;
1689     roundBitsMask = lastBitMask - 1;
1690     z = float32_val(a);
1691     roundingMode = STATUS(float_rounding_mode);
1692     if ( roundingMode == float_round_nearest_even ) {
1693         z += lastBitMask>>1;
1694         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
1695     }
1696     else if ( roundingMode != float_round_to_zero ) {
1697         if ( extractFloat32Sign( make_float32(z) ) ^ ( roundingMode == float_round_up ) ) {
1698             z += roundBitsMask;
1699         }
1700     }
1701     z &= ~ roundBitsMask;
1702     if ( z != float32_val(a) ) STATUS(float_exception_flags) |= float_flag_inexact;
1703     return make_float32(z);
1704 
1705 }
1706 
1707 /*----------------------------------------------------------------------------
1708 | Returns the result of adding the absolute values of the single-precision
1709 | floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
1710 | before being returned.  `zSign' is ignored if the result is a NaN.
1711 | The addition is performed according to the IEC/IEEE Standard for Binary
1712 | Floating-Point Arithmetic.
1713 *----------------------------------------------------------------------------*/
1714 
1715 static float32 addFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
1716 {
1717     int_fast16_t aExp, bExp, zExp;
1718     uint32_t aSig, bSig, zSig;
1719     int_fast16_t expDiff;
1720 
1721     aSig = extractFloat32Frac( a );
1722     aExp = extractFloat32Exp( a );
1723     bSig = extractFloat32Frac( b );
1724     bExp = extractFloat32Exp( b );
1725     expDiff = aExp - bExp;
1726     aSig <<= 6;
1727     bSig <<= 6;
1728     if ( 0 < expDiff ) {
1729         if ( aExp == 0xFF ) {
1730             if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1731             return a;
1732         }
1733         if ( bExp == 0 ) {
1734             --expDiff;
1735         }
1736         else {
1737             bSig |= 0x20000000;
1738         }
1739         shift32RightJamming( bSig, expDiff, &bSig );
1740         zExp = aExp;
1741     }
1742     else if ( expDiff < 0 ) {
1743         if ( bExp == 0xFF ) {
1744             if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1745             return packFloat32( zSign, 0xFF, 0 );
1746         }
1747         if ( aExp == 0 ) {
1748             ++expDiff;
1749         }
1750         else {
1751             aSig |= 0x20000000;
1752         }
1753         shift32RightJamming( aSig, - expDiff, &aSig );
1754         zExp = bExp;
1755     }
1756     else {
1757         if ( aExp == 0xFF ) {
1758             if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1759             return a;
1760         }
1761         if ( aExp == 0 ) {
1762             if (STATUS(flush_to_zero)) {
1763                 if (aSig | bSig) {
1764                     float_raise(float_flag_output_denormal STATUS_VAR);
1765                 }
1766                 return packFloat32(zSign, 0, 0);
1767             }
1768             return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
1769         }
1770         zSig = 0x40000000 + aSig + bSig;
1771         zExp = aExp;
1772         goto roundAndPack;
1773     }
1774     aSig |= 0x20000000;
1775     zSig = ( aSig + bSig )<<1;
1776     --zExp;
1777     if ( (int32_t) zSig < 0 ) {
1778         zSig = aSig + bSig;
1779         ++zExp;
1780     }
1781  roundAndPack:
1782     return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
1783 
1784 }
1785 
1786 /*----------------------------------------------------------------------------
1787 | Returns the result of subtracting the absolute values of the single-
1788 | precision floating-point values `a' and `b'.  If `zSign' is 1, the
1789 | difference is negated before being returned.  `zSign' is ignored if the
1790 | result is a NaN.  The subtraction is performed according to the IEC/IEEE
1791 | Standard for Binary Floating-Point Arithmetic.
1792 *----------------------------------------------------------------------------*/
1793 
1794 static float32 subFloat32Sigs( float32 a, float32 b, flag zSign STATUS_PARAM)
1795 {
1796     int_fast16_t aExp, bExp, zExp;
1797     uint32_t aSig, bSig, zSig;
1798     int_fast16_t expDiff;
1799 
1800     aSig = extractFloat32Frac( a );
1801     aExp = extractFloat32Exp( a );
1802     bSig = extractFloat32Frac( b );
1803     bExp = extractFloat32Exp( b );
1804     expDiff = aExp - bExp;
1805     aSig <<= 7;
1806     bSig <<= 7;
1807     if ( 0 < expDiff ) goto aExpBigger;
1808     if ( expDiff < 0 ) goto bExpBigger;
1809     if ( aExp == 0xFF ) {
1810         if ( aSig | bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1811         float_raise( float_flag_invalid STATUS_VAR);
1812         return float32_default_nan;
1813     }
1814     if ( aExp == 0 ) {
1815         aExp = 1;
1816         bExp = 1;
1817     }
1818     if ( bSig < aSig ) goto aBigger;
1819     if ( aSig < bSig ) goto bBigger;
1820     return packFloat32( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
1821  bExpBigger:
1822     if ( bExp == 0xFF ) {
1823         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1824         return packFloat32( zSign ^ 1, 0xFF, 0 );
1825     }
1826     if ( aExp == 0 ) {
1827         ++expDiff;
1828     }
1829     else {
1830         aSig |= 0x40000000;
1831     }
1832     shift32RightJamming( aSig, - expDiff, &aSig );
1833     bSig |= 0x40000000;
1834  bBigger:
1835     zSig = bSig - aSig;
1836     zExp = bExp;
1837     zSign ^= 1;
1838     goto normalizeRoundAndPack;
1839  aExpBigger:
1840     if ( aExp == 0xFF ) {
1841         if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1842         return a;
1843     }
1844     if ( bExp == 0 ) {
1845         --expDiff;
1846     }
1847     else {
1848         bSig |= 0x40000000;
1849     }
1850     shift32RightJamming( bSig, expDiff, &bSig );
1851     aSig |= 0x40000000;
1852  aBigger:
1853     zSig = aSig - bSig;
1854     zExp = aExp;
1855  normalizeRoundAndPack:
1856     --zExp;
1857     return normalizeRoundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
1858 
1859 }
1860 
1861 /*----------------------------------------------------------------------------
1862 | Returns the result of adding the single-precision floating-point values `a'
1863 | and `b'.  The operation is performed according to the IEC/IEEE Standard for
1864 | Binary Floating-Point Arithmetic.
1865 *----------------------------------------------------------------------------*/
1866 
1867 float32 float32_add( float32 a, float32 b STATUS_PARAM )
1868 {
1869     flag aSign, bSign;
1870     a = float32_squash_input_denormal(a STATUS_VAR);
1871     b = float32_squash_input_denormal(b STATUS_VAR);
1872 
1873     aSign = extractFloat32Sign( a );
1874     bSign = extractFloat32Sign( b );
1875     if ( aSign == bSign ) {
1876         return addFloat32Sigs( a, b, aSign STATUS_VAR);
1877     }
1878     else {
1879         return subFloat32Sigs( a, b, aSign STATUS_VAR );
1880     }
1881 
1882 }
1883 
1884 /*----------------------------------------------------------------------------
1885 | Returns the result of subtracting the single-precision floating-point values
1886 | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
1887 | for Binary Floating-Point Arithmetic.
1888 *----------------------------------------------------------------------------*/
1889 
1890 float32 float32_sub( float32 a, float32 b STATUS_PARAM )
1891 {
1892     flag aSign, bSign;
1893     a = float32_squash_input_denormal(a STATUS_VAR);
1894     b = float32_squash_input_denormal(b STATUS_VAR);
1895 
1896     aSign = extractFloat32Sign( a );
1897     bSign = extractFloat32Sign( b );
1898     if ( aSign == bSign ) {
1899         return subFloat32Sigs( a, b, aSign STATUS_VAR );
1900     }
1901     else {
1902         return addFloat32Sigs( a, b, aSign STATUS_VAR );
1903     }
1904 
1905 }
1906 
1907 /*----------------------------------------------------------------------------
1908 | Returns the result of multiplying the single-precision floating-point values
1909 | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
1910 | for Binary Floating-Point Arithmetic.
1911 *----------------------------------------------------------------------------*/
1912 
1913 float32 float32_mul( float32 a, float32 b STATUS_PARAM )
1914 {
1915     flag aSign, bSign, zSign;
1916     int_fast16_t aExp, bExp, zExp;
1917     uint32_t aSig, bSig;
1918     uint64_t zSig64;
1919     uint32_t zSig;
1920 
1921     a = float32_squash_input_denormal(a STATUS_VAR);
1922     b = float32_squash_input_denormal(b STATUS_VAR);
1923 
1924     aSig = extractFloat32Frac( a );
1925     aExp = extractFloat32Exp( a );
1926     aSign = extractFloat32Sign( a );
1927     bSig = extractFloat32Frac( b );
1928     bExp = extractFloat32Exp( b );
1929     bSign = extractFloat32Sign( b );
1930     zSign = aSign ^ bSign;
1931     if ( aExp == 0xFF ) {
1932         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
1933             return propagateFloat32NaN( a, b STATUS_VAR );
1934         }
1935         if ( ( bExp | bSig ) == 0 ) {
1936             float_raise( float_flag_invalid STATUS_VAR);
1937             return float32_default_nan;
1938         }
1939         return packFloat32( zSign, 0xFF, 0 );
1940     }
1941     if ( bExp == 0xFF ) {
1942         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1943         if ( ( aExp | aSig ) == 0 ) {
1944             float_raise( float_flag_invalid STATUS_VAR);
1945             return float32_default_nan;
1946         }
1947         return packFloat32( zSign, 0xFF, 0 );
1948     }
1949     if ( aExp == 0 ) {
1950         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
1951         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1952     }
1953     if ( bExp == 0 ) {
1954         if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
1955         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1956     }
1957     zExp = aExp + bExp - 0x7F;
1958     aSig = ( aSig | 0x00800000 )<<7;
1959     bSig = ( bSig | 0x00800000 )<<8;
1960     shift64RightJamming( ( (uint64_t) aSig ) * bSig, 32, &zSig64 );
1961     zSig = zSig64;
1962     if ( 0 <= (int32_t) ( zSig<<1 ) ) {
1963         zSig <<= 1;
1964         --zExp;
1965     }
1966     return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
1967 
1968 }
1969 
1970 /*----------------------------------------------------------------------------
1971 | Returns the result of dividing the single-precision floating-point value `a'
1972 | by the corresponding value `b'.  The operation is performed according to the
1973 | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1974 *----------------------------------------------------------------------------*/
1975 
1976 float32 float32_div( float32 a, float32 b STATUS_PARAM )
1977 {
1978     flag aSign, bSign, zSign;
1979     int_fast16_t aExp, bExp, zExp;
1980     uint32_t aSig, bSig, zSig;
1981     a = float32_squash_input_denormal(a STATUS_VAR);
1982     b = float32_squash_input_denormal(b STATUS_VAR);
1983 
1984     aSig = extractFloat32Frac( a );
1985     aExp = extractFloat32Exp( a );
1986     aSign = extractFloat32Sign( a );
1987     bSig = extractFloat32Frac( b );
1988     bExp = extractFloat32Exp( b );
1989     bSign = extractFloat32Sign( b );
1990     zSign = aSign ^ bSign;
1991     if ( aExp == 0xFF ) {
1992         if ( aSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1993         if ( bExp == 0xFF ) {
1994             if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
1995             float_raise( float_flag_invalid STATUS_VAR);
1996             return float32_default_nan;
1997         }
1998         return packFloat32( zSign, 0xFF, 0 );
1999     }
2000     if ( bExp == 0xFF ) {
2001         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
2002         return packFloat32( zSign, 0, 0 );
2003     }
2004     if ( bExp == 0 ) {
2005         if ( bSig == 0 ) {
2006             if ( ( aExp | aSig ) == 0 ) {
2007                 float_raise( float_flag_invalid STATUS_VAR);
2008                 return float32_default_nan;
2009             }
2010             float_raise( float_flag_divbyzero STATUS_VAR);
2011             return packFloat32( zSign, 0xFF, 0 );
2012         }
2013         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
2014     }
2015     if ( aExp == 0 ) {
2016         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
2017         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
2018     }
2019     zExp = aExp - bExp + 0x7D;
2020     aSig = ( aSig | 0x00800000 )<<7;
2021     bSig = ( bSig | 0x00800000 )<<8;
2022     if ( bSig <= ( aSig + aSig ) ) {
2023         aSig >>= 1;
2024         ++zExp;
2025     }
2026     zSig = ( ( (uint64_t) aSig )<<32 ) / bSig;
2027     if ( ( zSig & 0x3F ) == 0 ) {
2028         zSig |= ( (uint64_t) bSig * zSig != ( (uint64_t) aSig )<<32 );
2029     }
2030     return roundAndPackFloat32( zSign, zExp, zSig STATUS_VAR );
2031 
2032 }
2033 
2034 /*----------------------------------------------------------------------------
2035 | Returns the remainder of the single-precision floating-point value `a'
2036 | with respect to the corresponding value `b'.  The operation is performed
2037 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2038 *----------------------------------------------------------------------------*/
2039 
2040 float32 float32_rem( float32 a, float32 b STATUS_PARAM )
2041 {
2042     flag aSign, zSign;
2043     int_fast16_t aExp, bExp, expDiff;
2044     uint32_t aSig, bSig;
2045     uint32_t q;
2046     uint64_t aSig64, bSig64, q64;
2047     uint32_t alternateASig;
2048     int32_t sigMean;
2049     a = float32_squash_input_denormal(a STATUS_VAR);
2050     b = float32_squash_input_denormal(b STATUS_VAR);
2051 
2052     aSig = extractFloat32Frac( a );
2053     aExp = extractFloat32Exp( a );
2054     aSign = extractFloat32Sign( a );
2055     bSig = extractFloat32Frac( b );
2056     bExp = extractFloat32Exp( b );
2057     if ( aExp == 0xFF ) {
2058         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
2059             return propagateFloat32NaN( a, b STATUS_VAR );
2060         }
2061         float_raise( float_flag_invalid STATUS_VAR);
2062         return float32_default_nan;
2063     }
2064     if ( bExp == 0xFF ) {
2065         if ( bSig ) return propagateFloat32NaN( a, b STATUS_VAR );
2066         return a;
2067     }
2068     if ( bExp == 0 ) {
2069         if ( bSig == 0 ) {
2070             float_raise( float_flag_invalid STATUS_VAR);
2071             return float32_default_nan;
2072         }
2073         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
2074     }
2075     if ( aExp == 0 ) {
2076         if ( aSig == 0 ) return a;
2077         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
2078     }
2079     expDiff = aExp - bExp;
2080     aSig |= 0x00800000;
2081     bSig |= 0x00800000;
2082     if ( expDiff < 32 ) {
2083         aSig <<= 8;
2084         bSig <<= 8;
2085         if ( expDiff < 0 ) {
2086             if ( expDiff < -1 ) return a;
2087             aSig >>= 1;
2088         }
2089         q = ( bSig <= aSig );
2090         if ( q ) aSig -= bSig;
2091         if ( 0 < expDiff ) {
2092             q = ( ( (uint64_t) aSig )<<32 ) / bSig;
2093             q >>= 32 - expDiff;
2094             bSig >>= 2;
2095             aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
2096         }
2097         else {
2098             aSig >>= 2;
2099             bSig >>= 2;
2100         }
2101     }
2102     else {
2103         if ( bSig <= aSig ) aSig -= bSig;
2104         aSig64 = ( (uint64_t) aSig )<<40;
2105         bSig64 = ( (uint64_t) bSig )<<40;
2106         expDiff -= 64;
2107         while ( 0 < expDiff ) {
2108             q64 = estimateDiv128To64( aSig64, 0, bSig64 );
2109             q64 = ( 2 < q64 ) ? q64 - 2 : 0;
2110             aSig64 = - ( ( bSig * q64 )<<38 );
2111             expDiff -= 62;
2112         }
2113         expDiff += 64;
2114         q64 = estimateDiv128To64( aSig64, 0, bSig64 );
2115         q64 = ( 2 < q64 ) ? q64 - 2 : 0;
2116         q = q64>>( 64 - expDiff );
2117         bSig <<= 6;
2118         aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
2119     }
2120     do {
2121         alternateASig = aSig;
2122         ++q;
2123         aSig -= bSig;
2124     } while ( 0 <= (int32_t) aSig );
2125     sigMean = aSig + alternateASig;
2126     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
2127         aSig = alternateASig;
2128     }
2129     zSign = ( (int32_t) aSig < 0 );
2130     if ( zSign ) aSig = - aSig;
2131     return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig STATUS_VAR );
2132 
2133 }
2134 
2135 /*----------------------------------------------------------------------------
2136 | Returns the result of multiplying the single-precision floating-point values
2137 | `a' and `b' then adding 'c', with no intermediate rounding step after the
2138 | multiplication.  The operation is performed according to the IEC/IEEE
2139 | Standard for Binary Floating-Point Arithmetic 754-2008.
2140 | The flags argument allows the caller to select negation of the
2141 | addend, the intermediate product, or the final result. (The difference
2142 | between this and having the caller do a separate negation is that negating
2143 | externally will flip the sign bit on NaNs.)
2144 *----------------------------------------------------------------------------*/
2145 
2146 float32 float32_muladd(float32 a, float32 b, float32 c, int flags STATUS_PARAM)
2147 {
2148     flag aSign, bSign, cSign, zSign;
2149     int_fast16_t aExp, bExp, cExp, pExp, zExp, expDiff;
2150     uint32_t aSig, bSig, cSig;
2151     flag pInf, pZero, pSign;
2152     uint64_t pSig64, cSig64, zSig64;
2153     uint32_t pSig;
2154     int shiftcount;
2155     flag signflip, infzero;
2156 
2157     a = float32_squash_input_denormal(a STATUS_VAR);
2158     b = float32_squash_input_denormal(b STATUS_VAR);
2159     c = float32_squash_input_denormal(c STATUS_VAR);
2160     aSig = extractFloat32Frac(a);
2161     aExp = extractFloat32Exp(a);
2162     aSign = extractFloat32Sign(a);
2163     bSig = extractFloat32Frac(b);
2164     bExp = extractFloat32Exp(b);
2165     bSign = extractFloat32Sign(b);
2166     cSig = extractFloat32Frac(c);
2167     cExp = extractFloat32Exp(c);
2168     cSign = extractFloat32Sign(c);
2169 
2170     infzero = ((aExp == 0 && aSig == 0 && bExp == 0xff && bSig == 0) ||
2171                (aExp == 0xff && aSig == 0 && bExp == 0 && bSig == 0));
2172 
2173     /* It is implementation-defined whether the cases of (0,inf,qnan)
2174      * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
2175      * they return if they do), so we have to hand this information
2176      * off to the target-specific pick-a-NaN routine.
2177      */
2178     if (((aExp == 0xff) && aSig) ||
2179         ((bExp == 0xff) && bSig) ||
2180         ((cExp == 0xff) && cSig)) {
2181         return propagateFloat32MulAddNaN(a, b, c, infzero STATUS_VAR);
2182     }
2183 
2184     if (infzero) {
2185         float_raise(float_flag_invalid STATUS_VAR);
2186         return float32_default_nan;
2187     }
2188 
2189     if (flags & float_muladd_negate_c) {
2190         cSign ^= 1;
2191     }
2192 
2193     signflip = (flags & float_muladd_negate_result) ? 1 : 0;
2194 
2195     /* Work out the sign and type of the product */
2196     pSign = aSign ^ bSign;
2197     if (flags & float_muladd_negate_product) {
2198         pSign ^= 1;
2199     }
2200     pInf = (aExp == 0xff) || (bExp == 0xff);
2201     pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);
2202 
2203     if (cExp == 0xff) {
2204         if (pInf && (pSign ^ cSign)) {
2205             /* addition of opposite-signed infinities => InvalidOperation */
2206             float_raise(float_flag_invalid STATUS_VAR);
2207             return float32_default_nan;
2208         }
2209         /* Otherwise generate an infinity of the same sign */
2210         return packFloat32(cSign ^ signflip, 0xff, 0);
2211     }
2212 
2213     if (pInf) {
2214         return packFloat32(pSign ^ signflip, 0xff, 0);
2215     }
2216 
2217     if (pZero) {
2218         if (cExp == 0) {
2219             if (cSig == 0) {
2220                 /* Adding two exact zeroes */
2221                 if (pSign == cSign) {
2222                     zSign = pSign;
2223                 } else if (STATUS(float_rounding_mode) == float_round_down) {
2224                     zSign = 1;
2225                 } else {
2226                     zSign = 0;
2227                 }
2228                 return packFloat32(zSign ^ signflip, 0, 0);
2229             }
2230             /* Exact zero plus a denorm */
2231             if (STATUS(flush_to_zero)) {
2232                 float_raise(float_flag_output_denormal STATUS_VAR);
2233                 return packFloat32(cSign ^ signflip, 0, 0);
2234             }
2235         }
2236         /* Zero plus something non-zero : just return the something */
2237         return packFloat32(cSign ^ signflip, cExp, cSig);
2238     }
2239 
2240     if (aExp == 0) {
2241         normalizeFloat32Subnormal(aSig, &aExp, &aSig);
2242     }
2243     if (bExp == 0) {
2244         normalizeFloat32Subnormal(bSig, &bExp, &bSig);
2245     }
2246 
2247     /* Calculate the actual result a * b + c */
2248 
2249     /* Multiply first; this is easy. */
2250     /* NB: we subtract 0x7e where float32_mul() subtracts 0x7f
2251      * because we want the true exponent, not the "one-less-than"
2252      * flavour that roundAndPackFloat32() takes.
2253      */
2254     pExp = aExp + bExp - 0x7e;
2255     aSig = (aSig | 0x00800000) << 7;
2256     bSig = (bSig | 0x00800000) << 8;
2257     pSig64 = (uint64_t)aSig * bSig;
2258     if ((int64_t)(pSig64 << 1) >= 0) {
2259         pSig64 <<= 1;
2260         pExp--;
2261     }
2262 
2263     zSign = pSign ^ signflip;
2264 
2265     /* Now pSig64 is the significand of the multiply, with the explicit bit in
2266      * position 62.
2267      */
2268     if (cExp == 0) {
2269         if (!cSig) {
2270             /* Throw out the special case of c being an exact zero now */
2271             shift64RightJamming(pSig64, 32, &pSig64);
2272             pSig = pSig64;
2273             return roundAndPackFloat32(zSign, pExp - 1,
2274                                        pSig STATUS_VAR);
2275         }
2276         normalizeFloat32Subnormal(cSig, &cExp, &cSig);
2277     }
2278 
2279     cSig64 = (uint64_t)cSig << (62 - 23);
2280     cSig64 |= LIT64(0x4000000000000000);
2281     expDiff = pExp - cExp;
2282 
2283     if (pSign == cSign) {
2284         /* Addition */
2285         if (expDiff > 0) {
2286             /* scale c to match p */
2287             shift64RightJamming(cSig64, expDiff, &cSig64);
2288             zExp = pExp;
2289         } else if (expDiff < 0) {
2290             /* scale p to match c */
2291             shift64RightJamming(pSig64, -expDiff, &pSig64);
2292             zExp = cExp;
2293         } else {
2294             /* no scaling needed */
2295             zExp = cExp;
2296         }
2297         /* Add significands and make sure explicit bit ends up in posn 62 */
2298         zSig64 = pSig64 + cSig64;
2299         if ((int64_t)zSig64 < 0) {
2300             shift64RightJamming(zSig64, 1, &zSig64);
2301         } else {
2302             zExp--;
2303         }
2304     } else {
2305         /* Subtraction */
2306         if (expDiff > 0) {
2307             shift64RightJamming(cSig64, expDiff, &cSig64);
2308             zSig64 = pSig64 - cSig64;
2309             zExp = pExp;
2310         } else if (expDiff < 0) {
2311             shift64RightJamming(pSig64, -expDiff, &pSig64);
2312             zSig64 = cSig64 - pSig64;
2313             zExp = cExp;
2314             zSign ^= 1;
2315         } else {
2316             zExp = pExp;
2317             if (cSig64 < pSig64) {
2318                 zSig64 = pSig64 - cSig64;
2319             } else if (pSig64 < cSig64) {
2320                 zSig64 = cSig64 - pSig64;
2321                 zSign ^= 1;
2322             } else {
2323                 /* Exact zero */
2324                 zSign = signflip;
2325                 if (STATUS(float_rounding_mode) == float_round_down) {
2326                     zSign ^= 1;
2327                 }
2328                 return packFloat32(zSign, 0, 0);
2329             }
2330         }
2331         --zExp;
2332         /* Normalize to put the explicit bit back into bit 62. */
2333         shiftcount = countLeadingZeros64(zSig64) - 1;
2334         zSig64 <<= shiftcount;
2335         zExp -= shiftcount;
2336     }
2337     shift64RightJamming(zSig64, 32, &zSig64);
2338     return roundAndPackFloat32(zSign, zExp, zSig64 STATUS_VAR);
2339 }
2340 
2341 
2342 /*----------------------------------------------------------------------------
2343 | Returns the square root of the single-precision floating-point value `a'.
2344 | The operation is performed according to the IEC/IEEE Standard for Binary
2345 | Floating-Point Arithmetic.
2346 *----------------------------------------------------------------------------*/
2347 
2348 float32 float32_sqrt( float32 a STATUS_PARAM )
2349 {
2350     flag aSign;
2351     int_fast16_t aExp, zExp;
2352     uint32_t aSig, zSig;
2353     uint64_t rem, term;
2354     a = float32_squash_input_denormal(a STATUS_VAR);
2355 
2356     aSig = extractFloat32Frac( a );
2357     aExp = extractFloat32Exp( a );
2358     aSign = extractFloat32Sign( a );
2359     if ( aExp == 0xFF ) {
2360         if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
2361         if ( ! aSign ) return a;
2362         float_raise( float_flag_invalid STATUS_VAR);
2363         return float32_default_nan;
2364     }
2365     if ( aSign ) {
2366         if ( ( aExp | aSig ) == 0 ) return a;
2367         float_raise( float_flag_invalid STATUS_VAR);
2368         return float32_default_nan;
2369     }
2370     if ( aExp == 0 ) {
2371         if ( aSig == 0 ) return float32_zero;
2372         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
2373     }
2374     zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
2375     aSig = ( aSig | 0x00800000 )<<8;
2376     zSig = estimateSqrt32( aExp, aSig ) + 2;
2377     if ( ( zSig & 0x7F ) <= 5 ) {
2378         if ( zSig < 2 ) {
2379             zSig = 0x7FFFFFFF;
2380             goto roundAndPack;
2381         }
2382         aSig >>= aExp & 1;
2383         term = ( (uint64_t) zSig ) * zSig;
2384         rem = ( ( (uint64_t) aSig )<<32 ) - term;
2385         while ( (int64_t) rem < 0 ) {
2386             --zSig;
2387             rem += ( ( (uint64_t) zSig )<<1 ) | 1;
2388         }
2389         zSig |= ( rem != 0 );
2390     }
2391     shift32RightJamming( zSig, 1, &zSig );
2392  roundAndPack:
2393     return roundAndPackFloat32( 0, zExp, zSig STATUS_VAR );
2394 
2395 }
2396 
2397 /*----------------------------------------------------------------------------
2398 | Returns the binary exponential of the single-precision floating-point value
2399 | `a'. The operation is performed according to the IEC/IEEE Standard for
2400 | Binary Floating-Point Arithmetic.
2401 |
2402 | Uses the following identities:
2403 |
2404 | 1. -------------------------------------------------------------------------
2405 |      x    x*ln(2)
2406 |     2  = e
2407 |
2408 | 2. -------------------------------------------------------------------------
2409 |                      2     3     4     5           n
2410 |      x        x     x     x     x     x           x
2411 |     e  = 1 + --- + --- + --- + --- + --- + ... + --- + ...
2412 |               1!    2!    3!    4!    5!          n!
2413 *----------------------------------------------------------------------------*/
2414 
2415 static const float64 float32_exp2_coefficients[15] =
2416 {
2417     const_float64( 0x3ff0000000000000ll ), /*  1 */
2418     const_float64( 0x3fe0000000000000ll ), /*  2 */
2419     const_float64( 0x3fc5555555555555ll ), /*  3 */
2420     const_float64( 0x3fa5555555555555ll ), /*  4 */
2421     const_float64( 0x3f81111111111111ll ), /*  5 */
2422     const_float64( 0x3f56c16c16c16c17ll ), /*  6 */
2423     const_float64( 0x3f2a01a01a01a01all ), /*  7 */
2424     const_float64( 0x3efa01a01a01a01all ), /*  8 */
2425     const_float64( 0x3ec71de3a556c734ll ), /*  9 */
2426     const_float64( 0x3e927e4fb7789f5cll ), /* 10 */
2427     const_float64( 0x3e5ae64567f544e4ll ), /* 11 */
2428     const_float64( 0x3e21eed8eff8d898ll ), /* 12 */
2429     const_float64( 0x3de6124613a86d09ll ), /* 13 */
2430     const_float64( 0x3da93974a8c07c9dll ), /* 14 */
2431     const_float64( 0x3d6ae7f3e733b81fll ), /* 15 */
2432 };
2433 
2434 float32 float32_exp2( float32 a STATUS_PARAM )
2435 {
2436     flag aSign;
2437     int_fast16_t aExp;
2438     uint32_t aSig;
2439     float64 r, x, xn;
2440     int i;
2441     a = float32_squash_input_denormal(a STATUS_VAR);
2442 
2443     aSig = extractFloat32Frac( a );
2444     aExp = extractFloat32Exp( a );
2445     aSign = extractFloat32Sign( a );
2446 
2447     if ( aExp == 0xFF) {
2448         if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
2449         return (aSign) ? float32_zero : a;
2450     }
2451     if (aExp == 0) {
2452         if (aSig == 0) return float32_one;
2453     }
2454 
2455     float_raise( float_flag_inexact STATUS_VAR);
2456 
2457     /* ******************************* */
2458     /* using float64 for approximation */
2459     /* ******************************* */
2460     x = float32_to_float64(a STATUS_VAR);
2461     x = float64_mul(x, float64_ln2 STATUS_VAR);
2462 
2463     xn = x;
2464     r = float64_one;
2465     for (i = 0 ; i < 15 ; i++) {
2466         float64 f;
2467 
2468         f = float64_mul(xn, float32_exp2_coefficients[i] STATUS_VAR);
2469         r = float64_add(r, f STATUS_VAR);
2470 
2471         xn = float64_mul(xn, x STATUS_VAR);
2472     }
2473 
2474     return float64_to_float32(r, status);
2475 }
2476 
2477 /*----------------------------------------------------------------------------
2478 | Returns the binary log of the single-precision floating-point value `a'.
2479 | The operation is performed according to the IEC/IEEE Standard for Binary
2480 | Floating-Point Arithmetic.
2481 *----------------------------------------------------------------------------*/
2482 float32 float32_log2( float32 a STATUS_PARAM )
2483 {
2484     flag aSign, zSign;
2485     int_fast16_t aExp;
2486     uint32_t aSig, zSig, i;
2487 
2488     a = float32_squash_input_denormal(a STATUS_VAR);
2489     aSig = extractFloat32Frac( a );
2490     aExp = extractFloat32Exp( a );
2491     aSign = extractFloat32Sign( a );
2492 
2493     if ( aExp == 0 ) {
2494         if ( aSig == 0 ) return packFloat32( 1, 0xFF, 0 );
2495         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
2496     }
2497     if ( aSign ) {
2498         float_raise( float_flag_invalid STATUS_VAR);
2499         return float32_default_nan;
2500     }
2501     if ( aExp == 0xFF ) {
2502         if ( aSig ) return propagateFloat32NaN( a, float32_zero STATUS_VAR );
2503         return a;
2504     }
2505 
2506     aExp -= 0x7F;
2507     aSig |= 0x00800000;
2508     zSign = aExp < 0;
2509     zSig = aExp << 23;
2510 
2511     for (i = 1 << 22; i > 0; i >>= 1) {
2512         aSig = ( (uint64_t)aSig * aSig ) >> 23;
2513         if ( aSig & 0x01000000 ) {
2514             aSig >>= 1;
2515             zSig |= i;
2516         }
2517     }
2518 
2519     if ( zSign )
2520         zSig = -zSig;
2521 
2522     return normalizeRoundAndPackFloat32( zSign, 0x85, zSig STATUS_VAR );
2523 }
2524 
2525 /*----------------------------------------------------------------------------
2526 | Returns 1 if the single-precision floating-point value `a' is equal to
2527 | the corresponding value `b', and 0 otherwise.  The invalid exception is
2528 | raised if either operand is a NaN.  Otherwise, the comparison is performed
2529 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2530 *----------------------------------------------------------------------------*/
2531 
2532 int float32_eq( float32 a, float32 b STATUS_PARAM )
2533 {
2534     uint32_t av, bv;
2535     a = float32_squash_input_denormal(a STATUS_VAR);
2536     b = float32_squash_input_denormal(b STATUS_VAR);
2537 
2538     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2539          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2540        ) {
2541         float_raise( float_flag_invalid STATUS_VAR);
2542         return 0;
2543     }
2544     av = float32_val(a);
2545     bv = float32_val(b);
2546     return ( av == bv ) || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
2547 }
2548 
2549 /*----------------------------------------------------------------------------
2550 | Returns 1 if the single-precision floating-point value `a' is less than
2551 | or equal to the corresponding value `b', and 0 otherwise.  The invalid
2552 | exception is raised if either operand is a NaN.  The comparison is performed
2553 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2554 *----------------------------------------------------------------------------*/
2555 
2556 int float32_le( float32 a, float32 b STATUS_PARAM )
2557 {
2558     flag aSign, bSign;
2559     uint32_t av, bv;
2560     a = float32_squash_input_denormal(a STATUS_VAR);
2561     b = float32_squash_input_denormal(b STATUS_VAR);
2562 
2563     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2564          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2565        ) {
2566         float_raise( float_flag_invalid STATUS_VAR);
2567         return 0;
2568     }
2569     aSign = extractFloat32Sign( a );
2570     bSign = extractFloat32Sign( b );
2571     av = float32_val(a);
2572     bv = float32_val(b);
2573     if ( aSign != bSign ) return aSign || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
2574     return ( av == bv ) || ( aSign ^ ( av < bv ) );
2575 
2576 }
2577 
2578 /*----------------------------------------------------------------------------
2579 | Returns 1 if the single-precision floating-point value `a' is less than
2580 | the corresponding value `b', and 0 otherwise.  The invalid exception is
2581 | raised if either operand is a NaN.  The comparison is performed according
2582 | to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2583 *----------------------------------------------------------------------------*/
2584 
2585 int float32_lt( float32 a, float32 b STATUS_PARAM )
2586 {
2587     flag aSign, bSign;
2588     uint32_t av, bv;
2589     a = float32_squash_input_denormal(a STATUS_VAR);
2590     b = float32_squash_input_denormal(b STATUS_VAR);
2591 
2592     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2593          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2594        ) {
2595         float_raise( float_flag_invalid STATUS_VAR);
2596         return 0;
2597     }
2598     aSign = extractFloat32Sign( a );
2599     bSign = extractFloat32Sign( b );
2600     av = float32_val(a);
2601     bv = float32_val(b);
2602     if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 );
2603     return ( av != bv ) && ( aSign ^ ( av < bv ) );
2604 
2605 }
2606 
2607 /*----------------------------------------------------------------------------
2608 | Returns 1 if the single-precision floating-point values `a' and `b' cannot
2609 | be compared, and 0 otherwise.  The invalid exception is raised if either
2610 | operand is a NaN.  The comparison is performed according to the IEC/IEEE
2611 | Standard for Binary Floating-Point Arithmetic.
2612 *----------------------------------------------------------------------------*/
2613 
2614 int float32_unordered( float32 a, float32 b STATUS_PARAM )
2615 {
2616     a = float32_squash_input_denormal(a STATUS_VAR);
2617     b = float32_squash_input_denormal(b STATUS_VAR);
2618 
2619     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2620          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2621        ) {
2622         float_raise( float_flag_invalid STATUS_VAR);
2623         return 1;
2624     }
2625     return 0;
2626 }
2627 
2628 /*----------------------------------------------------------------------------
2629 | Returns 1 if the single-precision floating-point value `a' is equal to
2630 | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
2631 | exception.  The comparison is performed according to the IEC/IEEE Standard
2632 | for Binary Floating-Point Arithmetic.
2633 *----------------------------------------------------------------------------*/
2634 
2635 int float32_eq_quiet( float32 a, float32 b STATUS_PARAM )
2636 {
2637     a = float32_squash_input_denormal(a STATUS_VAR);
2638     b = float32_squash_input_denormal(b STATUS_VAR);
2639 
2640     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2641          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2642        ) {
2643         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
2644             float_raise( float_flag_invalid STATUS_VAR);
2645         }
2646         return 0;
2647     }
2648     return ( float32_val(a) == float32_val(b) ) ||
2649             ( (uint32_t) ( ( float32_val(a) | float32_val(b) )<<1 ) == 0 );
2650 }
2651 
2652 /*----------------------------------------------------------------------------
2653 | Returns 1 if the single-precision floating-point value `a' is less than or
2654 | equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
2655 | cause an exception.  Otherwise, the comparison is performed according to the
2656 | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2657 *----------------------------------------------------------------------------*/
2658 
2659 int float32_le_quiet( float32 a, float32 b STATUS_PARAM )
2660 {
2661     flag aSign, bSign;
2662     uint32_t av, bv;
2663     a = float32_squash_input_denormal(a STATUS_VAR);
2664     b = float32_squash_input_denormal(b STATUS_VAR);
2665 
2666     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2667          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2668        ) {
2669         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
2670             float_raise( float_flag_invalid STATUS_VAR);
2671         }
2672         return 0;
2673     }
2674     aSign = extractFloat32Sign( a );
2675     bSign = extractFloat32Sign( b );
2676     av = float32_val(a);
2677     bv = float32_val(b);
2678     if ( aSign != bSign ) return aSign || ( (uint32_t) ( ( av | bv )<<1 ) == 0 );
2679     return ( av == bv ) || ( aSign ^ ( av < bv ) );
2680 
2681 }
2682 
2683 /*----------------------------------------------------------------------------
2684 | Returns 1 if the single-precision floating-point value `a' is less than
2685 | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
2686 | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
2687 | Standard for Binary Floating-Point Arithmetic.
2688 *----------------------------------------------------------------------------*/
2689 
2690 int float32_lt_quiet( float32 a, float32 b STATUS_PARAM )
2691 {
2692     flag aSign, bSign;
2693     uint32_t av, bv;
2694     a = float32_squash_input_denormal(a STATUS_VAR);
2695     b = float32_squash_input_denormal(b STATUS_VAR);
2696 
2697     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2698          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2699        ) {
2700         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
2701             float_raise( float_flag_invalid STATUS_VAR);
2702         }
2703         return 0;
2704     }
2705     aSign = extractFloat32Sign( a );
2706     bSign = extractFloat32Sign( b );
2707     av = float32_val(a);
2708     bv = float32_val(b);
2709     if ( aSign != bSign ) return aSign && ( (uint32_t) ( ( av | bv )<<1 ) != 0 );
2710     return ( av != bv ) && ( aSign ^ ( av < bv ) );
2711 
2712 }
2713 
2714 /*----------------------------------------------------------------------------
2715 | Returns 1 if the single-precision floating-point values `a' and `b' cannot
2716 | be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
2717 | comparison is performed according to the IEC/IEEE Standard for Binary
2718 | Floating-Point Arithmetic.
2719 *----------------------------------------------------------------------------*/
2720 
2721 int float32_unordered_quiet( float32 a, float32 b STATUS_PARAM )
2722 {
2723     a = float32_squash_input_denormal(a STATUS_VAR);
2724     b = float32_squash_input_denormal(b STATUS_VAR);
2725 
2726     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
2727          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
2728        ) {
2729         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
2730             float_raise( float_flag_invalid STATUS_VAR);
2731         }
2732         return 1;
2733     }
2734     return 0;
2735 }
2736 
2737 /*----------------------------------------------------------------------------
2738 | Returns the result of converting the double-precision floating-point value
2739 | `a' to the 32-bit two's complement integer format.  The conversion is
2740 | performed according to the IEC/IEEE Standard for Binary Floating-Point
2741 | Arithmetic---which means in particular that the conversion is rounded
2742 | according to the current rounding mode.  If `a' is a NaN, the largest
2743 | positive integer is returned.  Otherwise, if the conversion overflows, the
2744 | largest integer with the same sign as `a' is returned.
2745 *----------------------------------------------------------------------------*/
2746 
2747 int32 float64_to_int32( float64 a STATUS_PARAM )
2748 {
2749     flag aSign;
2750     int_fast16_t aExp, shiftCount;
2751     uint64_t aSig;
2752     a = float64_squash_input_denormal(a STATUS_VAR);
2753 
2754     aSig = extractFloat64Frac( a );
2755     aExp = extractFloat64Exp( a );
2756     aSign = extractFloat64Sign( a );
2757     if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
2758     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
2759     shiftCount = 0x42C - aExp;
2760     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
2761     return roundAndPackInt32( aSign, aSig STATUS_VAR );
2762 
2763 }
2764 
2765 /*----------------------------------------------------------------------------
2766 | Returns the result of converting the double-precision floating-point value
2767 | `a' to the 32-bit two's complement integer format.  The conversion is
2768 | performed according to the IEC/IEEE Standard for Binary Floating-Point
2769 | Arithmetic, except that the conversion is always rounded toward zero.
2770 | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
2771 | the conversion overflows, the largest integer with the same sign as `a' is
2772 | returned.
2773 *----------------------------------------------------------------------------*/
2774 
2775 int32 float64_to_int32_round_to_zero( float64 a STATUS_PARAM )
2776 {
2777     flag aSign;
2778     int_fast16_t aExp, shiftCount;
2779     uint64_t aSig, savedASig;
2780     int32_t z;
2781     a = float64_squash_input_denormal(a STATUS_VAR);
2782 
2783     aSig = extractFloat64Frac( a );
2784     aExp = extractFloat64Exp( a );
2785     aSign = extractFloat64Sign( a );
2786     if ( 0x41E < aExp ) {
2787         if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
2788         goto invalid;
2789     }
2790     else if ( aExp < 0x3FF ) {
2791         if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
2792         return 0;
2793     }
2794     aSig |= LIT64( 0x0010000000000000 );
2795     shiftCount = 0x433 - aExp;
2796     savedASig = aSig;
2797     aSig >>= shiftCount;
2798     z = aSig;
2799     if ( aSign ) z = - z;
2800     if ( ( z < 0 ) ^ aSign ) {
2801  invalid:
2802         float_raise( float_flag_invalid STATUS_VAR);
2803         return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
2804     }
2805     if ( ( aSig<<shiftCount ) != savedASig ) {
2806         STATUS(float_exception_flags) |= float_flag_inexact;
2807     }
2808     return z;
2809 
2810 }
2811 
2812 /*----------------------------------------------------------------------------
2813 | Returns the result of converting the double-precision floating-point value
2814 | `a' to the 16-bit two's complement integer format.  The conversion is
2815 | performed according to the IEC/IEEE Standard for Binary Floating-Point
2816 | Arithmetic, except that the conversion is always rounded toward zero.
2817 | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
2818 | the conversion overflows, the largest integer with the same sign as `a' is
2819 | returned.
2820 *----------------------------------------------------------------------------*/
2821 
2822 int_fast16_t float64_to_int16_round_to_zero(float64 a STATUS_PARAM)
2823 {
2824     flag aSign;
2825     int_fast16_t aExp, shiftCount;
2826     uint64_t aSig, savedASig;
2827     int32 z;
2828 
2829     aSig = extractFloat64Frac( a );
2830     aExp = extractFloat64Exp( a );
2831     aSign = extractFloat64Sign( a );
2832     if ( 0x40E < aExp ) {
2833         if ( ( aExp == 0x7FF ) && aSig ) {
2834             aSign = 0;
2835         }
2836         goto invalid;
2837     }
2838     else if ( aExp < 0x3FF ) {
2839         if ( aExp || aSig ) {
2840             STATUS(float_exception_flags) |= float_flag_inexact;
2841         }
2842         return 0;
2843     }
2844     aSig |= LIT64( 0x0010000000000000 );
2845     shiftCount = 0x433 - aExp;
2846     savedASig = aSig;
2847     aSig >>= shiftCount;
2848     z = aSig;
2849     if ( aSign ) {
2850         z = - z;
2851     }
2852     if ( ( (int16_t)z < 0 ) ^ aSign ) {
2853  invalid:
2854         float_raise( float_flag_invalid STATUS_VAR);
2855         return aSign ? (int32_t) 0xffff8000 : 0x7FFF;
2856     }
2857     if ( ( aSig<<shiftCount ) != savedASig ) {
2858         STATUS(float_exception_flags) |= float_flag_inexact;
2859     }
2860     return z;
2861 }
2862 
2863 /*----------------------------------------------------------------------------
2864 | Returns the result of converting the double-precision floating-point value
2865 | `a' to the 64-bit two's complement integer format.  The conversion is
2866 | performed according to the IEC/IEEE Standard for Binary Floating-Point
2867 | Arithmetic---which means in particular that the conversion is rounded
2868 | according to the current rounding mode.  If `a' is a NaN, the largest
2869 | positive integer is returned.  Otherwise, if the conversion overflows, the
2870 | largest integer with the same sign as `a' is returned.
2871 *----------------------------------------------------------------------------*/
2872 
2873 int64 float64_to_int64( float64 a STATUS_PARAM )
2874 {
2875     flag aSign;
2876     int_fast16_t aExp, shiftCount;
2877     uint64_t aSig, aSigExtra;
2878     a = float64_squash_input_denormal(a STATUS_VAR);
2879 
2880     aSig = extractFloat64Frac( a );
2881     aExp = extractFloat64Exp( a );
2882     aSign = extractFloat64Sign( a );
2883     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
2884     shiftCount = 0x433 - aExp;
2885     if ( shiftCount <= 0 ) {
2886         if ( 0x43E < aExp ) {
2887             float_raise( float_flag_invalid STATUS_VAR);
2888             if (    ! aSign
2889                  || (    ( aExp == 0x7FF )
2890                       && ( aSig != LIT64( 0x0010000000000000 ) ) )
2891                ) {
2892                 return LIT64( 0x7FFFFFFFFFFFFFFF );
2893             }
2894             return (int64_t) LIT64( 0x8000000000000000 );
2895         }
2896         aSigExtra = 0;
2897         aSig <<= - shiftCount;
2898     }
2899     else {
2900         shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
2901     }
2902     return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
2903 
2904 }
2905 
2906 /*----------------------------------------------------------------------------
2907 | Returns the result of converting the double-precision floating-point value
2908 | `a' to the 64-bit two's complement integer format.  The conversion is
2909 | performed according to the IEC/IEEE Standard for Binary Floating-Point
2910 | Arithmetic, except that the conversion is always rounded toward zero.
2911 | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
2912 | the conversion overflows, the largest integer with the same sign as `a' is
2913 | returned.
2914 *----------------------------------------------------------------------------*/
2915 
2916 int64 float64_to_int64_round_to_zero( float64 a STATUS_PARAM )
2917 {
2918     flag aSign;
2919     int_fast16_t aExp, shiftCount;
2920     uint64_t aSig;
2921     int64 z;
2922     a = float64_squash_input_denormal(a STATUS_VAR);
2923 
2924     aSig = extractFloat64Frac( a );
2925     aExp = extractFloat64Exp( a );
2926     aSign = extractFloat64Sign( a );
2927     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
2928     shiftCount = aExp - 0x433;
2929     if ( 0 <= shiftCount ) {
2930         if ( 0x43E <= aExp ) {
2931             if ( float64_val(a) != LIT64( 0xC3E0000000000000 ) ) {
2932                 float_raise( float_flag_invalid STATUS_VAR);
2933                 if (    ! aSign
2934                      || (    ( aExp == 0x7FF )
2935                           && ( aSig != LIT64( 0x0010000000000000 ) ) )
2936                    ) {
2937                     return LIT64( 0x7FFFFFFFFFFFFFFF );
2938                 }
2939             }
2940             return (int64_t) LIT64( 0x8000000000000000 );
2941         }
2942         z = aSig<<shiftCount;
2943     }
2944     else {
2945         if ( aExp < 0x3FE ) {
2946             if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
2947             return 0;
2948         }
2949         z = aSig>>( - shiftCount );
2950         if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) {
2951             STATUS(float_exception_flags) |= float_flag_inexact;
2952         }
2953     }
2954     if ( aSign ) z = - z;
2955     return z;
2956 
2957 }
2958 
2959 /*----------------------------------------------------------------------------
2960 | Returns the result of converting the double-precision floating-point value
2961 | `a' to the single-precision floating-point format.  The conversion is
2962 | performed according to the IEC/IEEE Standard for Binary Floating-Point
2963 | Arithmetic.
2964 *----------------------------------------------------------------------------*/
2965 
2966 float32 float64_to_float32( float64 a STATUS_PARAM )
2967 {
2968     flag aSign;
2969     int_fast16_t aExp;
2970     uint64_t aSig;
2971     uint32_t zSig;
2972     a = float64_squash_input_denormal(a STATUS_VAR);
2973 
2974     aSig = extractFloat64Frac( a );
2975     aExp = extractFloat64Exp( a );
2976     aSign = extractFloat64Sign( a );
2977     if ( aExp == 0x7FF ) {
2978         if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
2979         return packFloat32( aSign, 0xFF, 0 );
2980     }
2981     shift64RightJamming( aSig, 22, &aSig );
2982     zSig = aSig;
2983     if ( aExp || zSig ) {
2984         zSig |= 0x40000000;
2985         aExp -= 0x381;
2986     }
2987     return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
2988 
2989 }
2990 
2991 
2992 /*----------------------------------------------------------------------------
2993 | Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
2994 | half-precision floating-point value, returning the result.  After being
2995 | shifted into the proper positions, the three fields are simply added
2996 | together to form the result.  This means that any integer portion of `zSig'
2997 | will be added into the exponent.  Since a properly normalized significand
2998 | will have an integer portion equal to 1, the `zExp' input should be 1 less
2999 | than the desired result exponent whenever `zSig' is a complete, normalized
3000 | significand.
3001 *----------------------------------------------------------------------------*/
3002 static float16 packFloat16(flag zSign, int_fast16_t zExp, uint16_t zSig)
3003 {
3004     return make_float16(
3005         (((uint32_t)zSign) << 15) + (((uint32_t)zExp) << 10) + zSig);
3006 }
3007 
3008 /* Half precision floats come in two formats: standard IEEE and "ARM" format.
3009    The latter gains extra exponent range by omitting the NaN/Inf encodings.  */
3010 
3011 float32 float16_to_float32(float16 a, flag ieee STATUS_PARAM)
3012 {
3013     flag aSign;
3014     int_fast16_t aExp;
3015     uint32_t aSig;
3016 
3017     aSign = extractFloat16Sign(a);
3018     aExp = extractFloat16Exp(a);
3019     aSig = extractFloat16Frac(a);
3020 
3021     if (aExp == 0x1f && ieee) {
3022         if (aSig) {
3023             return commonNaNToFloat32(float16ToCommonNaN(a STATUS_VAR) STATUS_VAR);
3024         }
3025         return packFloat32(aSign, 0xff, 0);
3026     }
3027     if (aExp == 0) {
3028         int8 shiftCount;
3029 
3030         if (aSig == 0) {
3031             return packFloat32(aSign, 0, 0);
3032         }
3033 
3034         shiftCount = countLeadingZeros32( aSig ) - 21;
3035         aSig = aSig << shiftCount;
3036         aExp = -shiftCount;
3037     }
3038     return packFloat32( aSign, aExp + 0x70, aSig << 13);
3039 }
3040 
3041 float16 float32_to_float16(float32 a, flag ieee STATUS_PARAM)
3042 {
3043     flag aSign;
3044     int_fast16_t aExp;
3045     uint32_t aSig;
3046     uint32_t mask;
3047     uint32_t increment;
3048     int8 roundingMode;
3049     a = float32_squash_input_denormal(a STATUS_VAR);
3050 
3051     aSig = extractFloat32Frac( a );
3052     aExp = extractFloat32Exp( a );
3053     aSign = extractFloat32Sign( a );
3054     if ( aExp == 0xFF ) {
3055         if (aSig) {
3056             /* Input is a NaN */
3057             float16 r = commonNaNToFloat16( float32ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
3058             if (!ieee) {
3059                 return packFloat16(aSign, 0, 0);
3060             }
3061             return r;
3062         }
3063         /* Infinity */
3064         if (!ieee) {
3065             float_raise(float_flag_invalid STATUS_VAR);
3066             return packFloat16(aSign, 0x1f, 0x3ff);
3067         }
3068         return packFloat16(aSign, 0x1f, 0);
3069     }
3070     if (aExp == 0 && aSig == 0) {
3071         return packFloat16(aSign, 0, 0);
3072     }
3073     /* Decimal point between bits 22 and 23.  */
3074     aSig |= 0x00800000;
3075     aExp -= 0x7f;
3076     if (aExp < -14) {
3077         mask = 0x00ffffff;
3078         if (aExp >= -24) {
3079             mask >>= 25 + aExp;
3080         }
3081     } else {
3082         mask = 0x00001fff;
3083     }
3084     if (aSig & mask) {
3085         float_raise( float_flag_underflow STATUS_VAR );
3086         roundingMode = STATUS(float_rounding_mode);
3087         switch (roundingMode) {
3088         case float_round_nearest_even:
3089             increment = (mask + 1) >> 1;
3090             if ((aSig & mask) == increment) {
3091                 increment = aSig & (increment << 1);
3092             }
3093             break;
3094         case float_round_up:
3095             increment = aSign ? 0 : mask;
3096             break;
3097         case float_round_down:
3098             increment = aSign ? mask : 0;
3099             break;
3100         default: /* round_to_zero */
3101             increment = 0;
3102             break;
3103         }
3104         aSig += increment;
3105         if (aSig >= 0x01000000) {
3106             aSig >>= 1;
3107             aExp++;
3108         }
3109     } else if (aExp < -14
3110           && STATUS(float_detect_tininess) == float_tininess_before_rounding) {
3111         float_raise( float_flag_underflow STATUS_VAR);
3112     }
3113 
3114     if (ieee) {
3115         if (aExp > 15) {
3116             float_raise( float_flag_overflow | float_flag_inexact STATUS_VAR);
3117             return packFloat16(aSign, 0x1f, 0);
3118         }
3119     } else {
3120         if (aExp > 16) {
3121             float_raise(float_flag_invalid | float_flag_inexact STATUS_VAR);
3122             return packFloat16(aSign, 0x1f, 0x3ff);
3123         }
3124     }
3125     if (aExp < -24) {
3126         return packFloat16(aSign, 0, 0);
3127     }
3128     if (aExp < -14) {
3129         aSig >>= -14 - aExp;
3130         aExp = -14;
3131     }
3132     return packFloat16(aSign, aExp + 14, aSig >> 13);
3133 }
3134 
3135 /*----------------------------------------------------------------------------
3136 | Returns the result of converting the double-precision floating-point value
3137 | `a' to the extended double-precision floating-point format.  The conversion
3138 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
3139 | Arithmetic.
3140 *----------------------------------------------------------------------------*/
3141 
3142 floatx80 float64_to_floatx80( float64 a STATUS_PARAM )
3143 {
3144     flag aSign;
3145     int_fast16_t aExp;
3146     uint64_t aSig;
3147 
3148     a = float64_squash_input_denormal(a STATUS_VAR);
3149     aSig = extractFloat64Frac( a );
3150     aExp = extractFloat64Exp( a );
3151     aSign = extractFloat64Sign( a );
3152     if ( aExp == 0x7FF ) {
3153         if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
3154         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
3155     }
3156     if ( aExp == 0 ) {
3157         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
3158         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
3159     }
3160     return
3161         packFloatx80(
3162             aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
3163 
3164 }
3165 
3166 /*----------------------------------------------------------------------------
3167 | Returns the result of converting the double-precision floating-point value
3168 | `a' to the quadruple-precision floating-point format.  The conversion is
3169 | performed according to the IEC/IEEE Standard for Binary Floating-Point
3170 | Arithmetic.
3171 *----------------------------------------------------------------------------*/
3172 
3173 float128 float64_to_float128( float64 a STATUS_PARAM )
3174 {
3175     flag aSign;
3176     int_fast16_t aExp;
3177     uint64_t aSig, zSig0, zSig1;
3178 
3179     a = float64_squash_input_denormal(a STATUS_VAR);
3180     aSig = extractFloat64Frac( a );
3181     aExp = extractFloat64Exp( a );
3182     aSign = extractFloat64Sign( a );
3183     if ( aExp == 0x7FF ) {
3184         if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
3185         return packFloat128( aSign, 0x7FFF, 0, 0 );
3186     }
3187     if ( aExp == 0 ) {
3188         if ( aSig == 0 ) return packFloat128( aSign, 0, 0, 0 );
3189         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
3190         --aExp;
3191     }
3192     shift128Right( aSig, 0, 4, &zSig0, &zSig1 );
3193     return packFloat128( aSign, aExp + 0x3C00, zSig0, zSig1 );
3194 
3195 }
3196 
3197 /*----------------------------------------------------------------------------
3198 | Rounds the double-precision floating-point value `a' to an integer, and
3199 | returns the result as a double-precision floating-point value.  The
3200 | operation is performed according to the IEC/IEEE Standard for Binary
3201 | Floating-Point Arithmetic.
3202 *----------------------------------------------------------------------------*/
3203 
3204 float64 float64_round_to_int( float64 a STATUS_PARAM )
3205 {
3206     flag aSign;
3207     int_fast16_t aExp;
3208     uint64_t lastBitMask, roundBitsMask;
3209     int8 roundingMode;
3210     uint64_t z;
3211     a = float64_squash_input_denormal(a STATUS_VAR);
3212 
3213     aExp = extractFloat64Exp( a );
3214     if ( 0x433 <= aExp ) {
3215         if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
3216             return propagateFloat64NaN( a, a STATUS_VAR );
3217         }
3218         return a;
3219     }
3220     if ( aExp < 0x3FF ) {
3221         if ( (uint64_t) ( float64_val(a)<<1 ) == 0 ) return a;
3222         STATUS(float_exception_flags) |= float_flag_inexact;
3223         aSign = extractFloat64Sign( a );
3224         switch ( STATUS(float_rounding_mode) ) {
3225          case float_round_nearest_even:
3226             if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
3227                 return packFloat64( aSign, 0x3FF, 0 );
3228             }
3229             break;
3230          case float_round_down:
3231             return make_float64(aSign ? LIT64( 0xBFF0000000000000 ) : 0);
3232          case float_round_up:
3233             return make_float64(
3234             aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 ));
3235         }
3236         return packFloat64( aSign, 0, 0 );
3237     }
3238     lastBitMask = 1;
3239     lastBitMask <<= 0x433 - aExp;
3240     roundBitsMask = lastBitMask - 1;
3241     z = float64_val(a);
3242     roundingMode = STATUS(float_rounding_mode);
3243     if ( roundingMode == float_round_nearest_even ) {
3244         z += lastBitMask>>1;
3245         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
3246     }
3247     else if ( roundingMode != float_round_to_zero ) {
3248         if ( extractFloat64Sign( make_float64(z) ) ^ ( roundingMode == float_round_up ) ) {
3249             z += roundBitsMask;
3250         }
3251     }
3252     z &= ~ roundBitsMask;
3253     if ( z != float64_val(a) )
3254         STATUS(float_exception_flags) |= float_flag_inexact;
3255     return make_float64(z);
3256 
3257 }
3258 
3259 float64 float64_trunc_to_int( float64 a STATUS_PARAM)
3260 {
3261     int oldmode;
3262     float64 res;
3263     oldmode = STATUS(float_rounding_mode);
3264     STATUS(float_rounding_mode) = float_round_to_zero;
3265     res = float64_round_to_int(a STATUS_VAR);
3266     STATUS(float_rounding_mode) = oldmode;
3267     return res;
3268 }
3269 
3270 /*----------------------------------------------------------------------------
3271 | Returns the result of adding the absolute values of the double-precision
3272 | floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
3273 | before being returned.  `zSign' is ignored if the result is a NaN.
3274 | The addition is performed according to the IEC/IEEE Standard for Binary
3275 | Floating-Point Arithmetic.
3276 *----------------------------------------------------------------------------*/
3277 
3278 static float64 addFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
3279 {
3280     int_fast16_t aExp, bExp, zExp;
3281     uint64_t aSig, bSig, zSig;
3282     int_fast16_t expDiff;
3283 
3284     aSig = extractFloat64Frac( a );
3285     aExp = extractFloat64Exp( a );
3286     bSig = extractFloat64Frac( b );
3287     bExp = extractFloat64Exp( b );
3288     expDiff = aExp - bExp;
3289     aSig <<= 9;
3290     bSig <<= 9;
3291     if ( 0 < expDiff ) {
3292         if ( aExp == 0x7FF ) {
3293             if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3294             return a;
3295         }
3296         if ( bExp == 0 ) {
3297             --expDiff;
3298         }
3299         else {
3300             bSig |= LIT64( 0x2000000000000000 );
3301         }
3302         shift64RightJamming( bSig, expDiff, &bSig );
3303         zExp = aExp;
3304     }
3305     else if ( expDiff < 0 ) {
3306         if ( bExp == 0x7FF ) {
3307             if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3308             return packFloat64( zSign, 0x7FF, 0 );
3309         }
3310         if ( aExp == 0 ) {
3311             ++expDiff;
3312         }
3313         else {
3314             aSig |= LIT64( 0x2000000000000000 );
3315         }
3316         shift64RightJamming( aSig, - expDiff, &aSig );
3317         zExp = bExp;
3318     }
3319     else {
3320         if ( aExp == 0x7FF ) {
3321             if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3322             return a;
3323         }
3324         if ( aExp == 0 ) {
3325             if (STATUS(flush_to_zero)) {
3326                 if (aSig | bSig) {
3327                     float_raise(float_flag_output_denormal STATUS_VAR);
3328                 }
3329                 return packFloat64(zSign, 0, 0);
3330             }
3331             return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
3332         }
3333         zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
3334         zExp = aExp;
3335         goto roundAndPack;
3336     }
3337     aSig |= LIT64( 0x2000000000000000 );
3338     zSig = ( aSig + bSig )<<1;
3339     --zExp;
3340     if ( (int64_t) zSig < 0 ) {
3341         zSig = aSig + bSig;
3342         ++zExp;
3343     }
3344  roundAndPack:
3345     return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
3346 
3347 }
3348 
3349 /*----------------------------------------------------------------------------
3350 | Returns the result of subtracting the absolute values of the double-
3351 | precision floating-point values `a' and `b'.  If `zSign' is 1, the
3352 | difference is negated before being returned.  `zSign' is ignored if the
3353 | result is a NaN.  The subtraction is performed according to the IEC/IEEE
3354 | Standard for Binary Floating-Point Arithmetic.
3355 *----------------------------------------------------------------------------*/
3356 
3357 static float64 subFloat64Sigs( float64 a, float64 b, flag zSign STATUS_PARAM )
3358 {
3359     int_fast16_t aExp, bExp, zExp;
3360     uint64_t aSig, bSig, zSig;
3361     int_fast16_t expDiff;
3362 
3363     aSig = extractFloat64Frac( a );
3364     aExp = extractFloat64Exp( a );
3365     bSig = extractFloat64Frac( b );
3366     bExp = extractFloat64Exp( b );
3367     expDiff = aExp - bExp;
3368     aSig <<= 10;
3369     bSig <<= 10;
3370     if ( 0 < expDiff ) goto aExpBigger;
3371     if ( expDiff < 0 ) goto bExpBigger;
3372     if ( aExp == 0x7FF ) {
3373         if ( aSig | bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3374         float_raise( float_flag_invalid STATUS_VAR);
3375         return float64_default_nan;
3376     }
3377     if ( aExp == 0 ) {
3378         aExp = 1;
3379         bExp = 1;
3380     }
3381     if ( bSig < aSig ) goto aBigger;
3382     if ( aSig < bSig ) goto bBigger;
3383     return packFloat64( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
3384  bExpBigger:
3385     if ( bExp == 0x7FF ) {
3386         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3387         return packFloat64( zSign ^ 1, 0x7FF, 0 );
3388     }
3389     if ( aExp == 0 ) {
3390         ++expDiff;
3391     }
3392     else {
3393         aSig |= LIT64( 0x4000000000000000 );
3394     }
3395     shift64RightJamming( aSig, - expDiff, &aSig );
3396     bSig |= LIT64( 0x4000000000000000 );
3397  bBigger:
3398     zSig = bSig - aSig;
3399     zExp = bExp;
3400     zSign ^= 1;
3401     goto normalizeRoundAndPack;
3402  aExpBigger:
3403     if ( aExp == 0x7FF ) {
3404         if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3405         return a;
3406     }
3407     if ( bExp == 0 ) {
3408         --expDiff;
3409     }
3410     else {
3411         bSig |= LIT64( 0x4000000000000000 );
3412     }
3413     shift64RightJamming( bSig, expDiff, &bSig );
3414     aSig |= LIT64( 0x4000000000000000 );
3415  aBigger:
3416     zSig = aSig - bSig;
3417     zExp = aExp;
3418  normalizeRoundAndPack:
3419     --zExp;
3420     return normalizeRoundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
3421 
3422 }
3423 
3424 /*----------------------------------------------------------------------------
3425 | Returns the result of adding the double-precision floating-point values `a'
3426 | and `b'.  The operation is performed according to the IEC/IEEE Standard for
3427 | Binary Floating-Point Arithmetic.
3428 *----------------------------------------------------------------------------*/
3429 
3430 float64 float64_add( float64 a, float64 b STATUS_PARAM )
3431 {
3432     flag aSign, bSign;
3433     a = float64_squash_input_denormal(a STATUS_VAR);
3434     b = float64_squash_input_denormal(b STATUS_VAR);
3435 
3436     aSign = extractFloat64Sign( a );
3437     bSign = extractFloat64Sign( b );
3438     if ( aSign == bSign ) {
3439         return addFloat64Sigs( a, b, aSign STATUS_VAR );
3440     }
3441     else {
3442         return subFloat64Sigs( a, b, aSign STATUS_VAR );
3443     }
3444 
3445 }
3446 
3447 /*----------------------------------------------------------------------------
3448 | Returns the result of subtracting the double-precision floating-point values
3449 | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
3450 | for Binary Floating-Point Arithmetic.
3451 *----------------------------------------------------------------------------*/
3452 
3453 float64 float64_sub( float64 a, float64 b STATUS_PARAM )
3454 {
3455     flag aSign, bSign;
3456     a = float64_squash_input_denormal(a STATUS_VAR);
3457     b = float64_squash_input_denormal(b STATUS_VAR);
3458 
3459     aSign = extractFloat64Sign( a );
3460     bSign = extractFloat64Sign( b );
3461     if ( aSign == bSign ) {
3462         return subFloat64Sigs( a, b, aSign STATUS_VAR );
3463     }
3464     else {
3465         return addFloat64Sigs( a, b, aSign STATUS_VAR );
3466     }
3467 
3468 }
3469 
3470 /*----------------------------------------------------------------------------
3471 | Returns the result of multiplying the double-precision floating-point values
3472 | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
3473 | for Binary Floating-Point Arithmetic.
3474 *----------------------------------------------------------------------------*/
3475 
3476 float64 float64_mul( float64 a, float64 b STATUS_PARAM )
3477 {
3478     flag aSign, bSign, zSign;
3479     int_fast16_t aExp, bExp, zExp;
3480     uint64_t aSig, bSig, zSig0, zSig1;
3481 
3482     a = float64_squash_input_denormal(a STATUS_VAR);
3483     b = float64_squash_input_denormal(b STATUS_VAR);
3484 
3485     aSig = extractFloat64Frac( a );
3486     aExp = extractFloat64Exp( a );
3487     aSign = extractFloat64Sign( a );
3488     bSig = extractFloat64Frac( b );
3489     bExp = extractFloat64Exp( b );
3490     bSign = extractFloat64Sign( b );
3491     zSign = aSign ^ bSign;
3492     if ( aExp == 0x7FF ) {
3493         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
3494             return propagateFloat64NaN( a, b STATUS_VAR );
3495         }
3496         if ( ( bExp | bSig ) == 0 ) {
3497             float_raise( float_flag_invalid STATUS_VAR);
3498             return float64_default_nan;
3499         }
3500         return packFloat64( zSign, 0x7FF, 0 );
3501     }
3502     if ( bExp == 0x7FF ) {
3503         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3504         if ( ( aExp | aSig ) == 0 ) {
3505             float_raise( float_flag_invalid STATUS_VAR);
3506             return float64_default_nan;
3507         }
3508         return packFloat64( zSign, 0x7FF, 0 );
3509     }
3510     if ( aExp == 0 ) {
3511         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
3512         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
3513     }
3514     if ( bExp == 0 ) {
3515         if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
3516         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
3517     }
3518     zExp = aExp + bExp - 0x3FF;
3519     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
3520     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
3521     mul64To128( aSig, bSig, &zSig0, &zSig1 );
3522     zSig0 |= ( zSig1 != 0 );
3523     if ( 0 <= (int64_t) ( zSig0<<1 ) ) {
3524         zSig0 <<= 1;
3525         --zExp;
3526     }
3527     return roundAndPackFloat64( zSign, zExp, zSig0 STATUS_VAR );
3528 
3529 }
3530 
3531 /*----------------------------------------------------------------------------
3532 | Returns the result of dividing the double-precision floating-point value `a'
3533 | by the corresponding value `b'.  The operation is performed according to
3534 | the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
3535 *----------------------------------------------------------------------------*/
3536 
3537 float64 float64_div( float64 a, float64 b STATUS_PARAM )
3538 {
3539     flag aSign, bSign, zSign;
3540     int_fast16_t aExp, bExp, zExp;
3541     uint64_t aSig, bSig, zSig;
3542     uint64_t rem0, rem1;
3543     uint64_t term0, term1;
3544     a = float64_squash_input_denormal(a STATUS_VAR);
3545     b = float64_squash_input_denormal(b STATUS_VAR);
3546 
3547     aSig = extractFloat64Frac( a );
3548     aExp = extractFloat64Exp( a );
3549     aSign = extractFloat64Sign( a );
3550     bSig = extractFloat64Frac( b );
3551     bExp = extractFloat64Exp( b );
3552     bSign = extractFloat64Sign( b );
3553     zSign = aSign ^ bSign;
3554     if ( aExp == 0x7FF ) {
3555         if ( aSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3556         if ( bExp == 0x7FF ) {
3557             if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3558             float_raise( float_flag_invalid STATUS_VAR);
3559             return float64_default_nan;
3560         }
3561         return packFloat64( zSign, 0x7FF, 0 );
3562     }
3563     if ( bExp == 0x7FF ) {
3564         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3565         return packFloat64( zSign, 0, 0 );
3566     }
3567     if ( bExp == 0 ) {
3568         if ( bSig == 0 ) {
3569             if ( ( aExp | aSig ) == 0 ) {
3570                 float_raise( float_flag_invalid STATUS_VAR);
3571                 return float64_default_nan;
3572             }
3573             float_raise( float_flag_divbyzero STATUS_VAR);
3574             return packFloat64( zSign, 0x7FF, 0 );
3575         }
3576         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
3577     }
3578     if ( aExp == 0 ) {
3579         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
3580         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
3581     }
3582     zExp = aExp - bExp + 0x3FD;
3583     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
3584     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
3585     if ( bSig <= ( aSig + aSig ) ) {
3586         aSig >>= 1;
3587         ++zExp;
3588     }
3589     zSig = estimateDiv128To64( aSig, 0, bSig );
3590     if ( ( zSig & 0x1FF ) <= 2 ) {
3591         mul64To128( bSig, zSig, &term0, &term1 );
3592         sub128( aSig, 0, term0, term1, &rem0, &rem1 );
3593         while ( (int64_t) rem0 < 0 ) {
3594             --zSig;
3595             add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
3596         }
3597         zSig |= ( rem1 != 0 );
3598     }
3599     return roundAndPackFloat64( zSign, zExp, zSig STATUS_VAR );
3600 
3601 }
3602 
3603 /*----------------------------------------------------------------------------
3604 | Returns the remainder of the double-precision floating-point value `a'
3605 | with respect to the corresponding value `b'.  The operation is performed
3606 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
3607 *----------------------------------------------------------------------------*/
3608 
3609 float64 float64_rem( float64 a, float64 b STATUS_PARAM )
3610 {
3611     flag aSign, zSign;
3612     int_fast16_t aExp, bExp, expDiff;
3613     uint64_t aSig, bSig;
3614     uint64_t q, alternateASig;
3615     int64_t sigMean;
3616 
3617     a = float64_squash_input_denormal(a STATUS_VAR);
3618     b = float64_squash_input_denormal(b STATUS_VAR);
3619     aSig = extractFloat64Frac( a );
3620     aExp = extractFloat64Exp( a );
3621     aSign = extractFloat64Sign( a );
3622     bSig = extractFloat64Frac( b );
3623     bExp = extractFloat64Exp( b );
3624     if ( aExp == 0x7FF ) {
3625         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
3626             return propagateFloat64NaN( a, b STATUS_VAR );
3627         }
3628         float_raise( float_flag_invalid STATUS_VAR);
3629         return float64_default_nan;
3630     }
3631     if ( bExp == 0x7FF ) {
3632         if ( bSig ) return propagateFloat64NaN( a, b STATUS_VAR );
3633         return a;
3634     }
3635     if ( bExp == 0 ) {
3636         if ( bSig == 0 ) {
3637             float_raise( float_flag_invalid STATUS_VAR);
3638             return float64_default_nan;
3639         }
3640         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
3641     }
3642     if ( aExp == 0 ) {
3643         if ( aSig == 0 ) return a;
3644         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
3645     }
3646     expDiff = aExp - bExp;
3647     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
3648     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
3649     if ( expDiff < 0 ) {
3650         if ( expDiff < -1 ) return a;
3651         aSig >>= 1;
3652     }
3653     q = ( bSig <= aSig );
3654     if ( q ) aSig -= bSig;
3655     expDiff -= 64;
3656     while ( 0 < expDiff ) {
3657         q = estimateDiv128To64( aSig, 0, bSig );
3658         q = ( 2 < q ) ? q - 2 : 0;
3659         aSig = - ( ( bSig>>2 ) * q );
3660         expDiff -= 62;
3661     }
3662     expDiff += 64;
3663     if ( 0 < expDiff ) {
3664         q = estimateDiv128To64( aSig, 0, bSig );
3665         q = ( 2 < q ) ? q - 2 : 0;
3666         q >>= 64 - expDiff;
3667         bSig >>= 2;
3668         aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
3669     }
3670     else {
3671         aSig >>= 2;
3672         bSig >>= 2;
3673     }
3674     do {
3675         alternateASig = aSig;
3676         ++q;
3677         aSig -= bSig;
3678     } while ( 0 <= (int64_t) aSig );
3679     sigMean = aSig + alternateASig;
3680     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
3681         aSig = alternateASig;
3682     }
3683     zSign = ( (int64_t) aSig < 0 );
3684     if ( zSign ) aSig = - aSig;
3685     return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig STATUS_VAR );
3686 
3687 }
3688 
3689 /*----------------------------------------------------------------------------
3690 | Returns the result of multiplying the double-precision floating-point values
3691 | `a' and `b' then adding 'c', with no intermediate rounding step after the
3692 | multiplication.  The operation is performed according to the IEC/IEEE
3693 | Standard for Binary Floating-Point Arithmetic 754-2008.
3694 | The flags argument allows the caller to select negation of the
3695 | addend, the intermediate product, or the final result. (The difference
3696 | between this and having the caller do a separate negation is that negating
3697 | externally will flip the sign bit on NaNs.)
3698 *----------------------------------------------------------------------------*/
3699 
3700 float64 float64_muladd(float64 a, float64 b, float64 c, int flags STATUS_PARAM)
3701 {
3702     flag aSign, bSign, cSign, zSign;
3703     int_fast16_t aExp, bExp, cExp, pExp, zExp, expDiff;
3704     uint64_t aSig, bSig, cSig;
3705     flag pInf, pZero, pSign;
3706     uint64_t pSig0, pSig1, cSig0, cSig1, zSig0, zSig1;
3707     int shiftcount;
3708     flag signflip, infzero;
3709 
3710     a = float64_squash_input_denormal(a STATUS_VAR);
3711     b = float64_squash_input_denormal(b STATUS_VAR);
3712     c = float64_squash_input_denormal(c STATUS_VAR);
3713     aSig = extractFloat64Frac(a);
3714     aExp = extractFloat64Exp(a);
3715     aSign = extractFloat64Sign(a);
3716     bSig = extractFloat64Frac(b);
3717     bExp = extractFloat64Exp(b);
3718     bSign = extractFloat64Sign(b);
3719     cSig = extractFloat64Frac(c);
3720     cExp = extractFloat64Exp(c);
3721     cSign = extractFloat64Sign(c);
3722 
3723     infzero = ((aExp == 0 && aSig == 0 && bExp == 0x7ff && bSig == 0) ||
3724                (aExp == 0x7ff && aSig == 0 && bExp == 0 && bSig == 0));
3725 
3726     /* It is implementation-defined whether the cases of (0,inf,qnan)
3727      * and (inf,0,qnan) raise InvalidOperation or not (and what QNaN
3728      * they return if they do), so we have to hand this information
3729      * off to the target-specific pick-a-NaN routine.
3730      */
3731     if (((aExp == 0x7ff) && aSig) ||
3732         ((bExp == 0x7ff) && bSig) ||
3733         ((cExp == 0x7ff) && cSig)) {
3734         return propagateFloat64MulAddNaN(a, b, c, infzero STATUS_VAR);
3735     }
3736 
3737     if (infzero) {
3738         float_raise(float_flag_invalid STATUS_VAR);
3739         return float64_default_nan;
3740     }
3741 
3742     if (flags & float_muladd_negate_c) {
3743         cSign ^= 1;
3744     }
3745 
3746     signflip = (flags & float_muladd_negate_result) ? 1 : 0;
3747 
3748     /* Work out the sign and type of the product */
3749     pSign = aSign ^ bSign;
3750     if (flags & float_muladd_negate_product) {
3751         pSign ^= 1;
3752     }
3753     pInf = (aExp == 0x7ff) || (bExp == 0x7ff);
3754     pZero = ((aExp | aSig) == 0) || ((bExp | bSig) == 0);
3755 
3756     if (cExp == 0x7ff) {
3757         if (pInf && (pSign ^ cSign)) {
3758             /* addition of opposite-signed infinities => InvalidOperation */
3759             float_raise(float_flag_invalid STATUS_VAR);
3760             return float64_default_nan;
3761         }
3762         /* Otherwise generate an infinity of the same sign */
3763         return packFloat64(cSign ^ signflip, 0x7ff, 0);
3764     }
3765 
3766     if (pInf) {
3767         return packFloat64(pSign ^ signflip, 0x7ff, 0);
3768     }
3769 
3770     if (pZero) {
3771         if (cExp == 0) {
3772             if (cSig == 0) {
3773                 /* Adding two exact zeroes */
3774                 if (pSign == cSign) {
3775                     zSign = pSign;
3776                 } else if (STATUS(float_rounding_mode) == float_round_down) {
3777                     zSign = 1;
3778                 } else {
3779                     zSign = 0;
3780                 }
3781                 return packFloat64(zSign ^ signflip, 0, 0);
3782             }
3783             /* Exact zero plus a denorm */
3784             if (STATUS(flush_to_zero)) {
3785                 float_raise(float_flag_output_denormal STATUS_VAR);
3786                 return packFloat64(cSign ^ signflip, 0, 0);
3787             }
3788         }
3789         /* Zero plus something non-zero : just return the something */
3790         return packFloat64(cSign ^ signflip, cExp, cSig);
3791     }
3792 
3793     if (aExp == 0) {
3794         normalizeFloat64Subnormal(aSig, &aExp, &aSig);
3795     }
3796     if (bExp == 0) {
3797         normalizeFloat64Subnormal(bSig, &bExp, &bSig);
3798     }
3799 
3800     /* Calculate the actual result a * b + c */
3801 
3802     /* Multiply first; this is easy. */
3803     /* NB: we subtract 0x3fe where float64_mul() subtracts 0x3ff
3804      * because we want the true exponent, not the "one-less-than"
3805      * flavour that roundAndPackFloat64() takes.
3806      */
3807     pExp = aExp + bExp - 0x3fe;
3808     aSig = (aSig | LIT64(0x0010000000000000))<<10;
3809     bSig = (bSig | LIT64(0x0010000000000000))<<11;
3810     mul64To128(aSig, bSig, &pSig0, &pSig1);
3811     if ((int64_t)(pSig0 << 1) >= 0) {
3812         shortShift128Left(pSig0, pSig1, 1, &pSig0, &pSig1);
3813         pExp--;
3814     }
3815 
3816     zSign = pSign ^ signflip;
3817 
3818     /* Now [pSig0:pSig1] is the significand of the multiply, with the explicit
3819      * bit in position 126.
3820      */
3821     if (cExp == 0) {
3822         if (!cSig) {
3823             /* Throw out the special case of c being an exact zero now */
3824             shift128RightJamming(pSig0, pSig1, 64, &pSig0, &pSig1);
3825             return roundAndPackFloat64(zSign, pExp - 1,
3826                                        pSig1 STATUS_VAR);
3827         }
3828         normalizeFloat64Subnormal(cSig, &cExp, &cSig);
3829     }
3830 
3831     /* Shift cSig and add the explicit bit so [cSig0:cSig1] is the
3832      * significand of the addend, with the explicit bit in position 126.
3833      */
3834     cSig0 = cSig << (126 - 64 - 52);
3835     cSig1 = 0;
3836     cSig0 |= LIT64(0x4000000000000000);
3837     expDiff = pExp - cExp;
3838 
3839     if (pSign == cSign) {
3840         /* Addition */
3841         if (expDiff > 0) {
3842             /* scale c to match p */
3843             shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1);
3844             zExp = pExp;
3845         } else if (expDiff < 0) {
3846             /* scale p to match c */
3847             shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1);
3848             zExp = cExp;
3849         } else {
3850             /* no scaling needed */
3851             zExp = cExp;
3852         }
3853         /* Add significands and make sure explicit bit ends up in posn 126 */
3854         add128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
3855         if ((int64_t)zSig0 < 0) {
3856             shift128RightJamming(zSig0, zSig1, 1, &zSig0, &zSig1);
3857         } else {
3858             zExp--;
3859         }
3860         shift128RightJamming(zSig0, zSig1, 64, &zSig0, &zSig1);
3861         return roundAndPackFloat64(zSign, zExp, zSig1 STATUS_VAR);
3862     } else {
3863         /* Subtraction */
3864         if (expDiff > 0) {
3865             shift128RightJamming(cSig0, cSig1, expDiff, &cSig0, &cSig1);
3866             sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
3867             zExp = pExp;
3868         } else if (expDiff < 0) {
3869             shift128RightJamming(pSig0, pSig1, -expDiff, &pSig0, &pSig1);
3870             sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1);
3871             zExp = cExp;
3872             zSign ^= 1;
3873         } else {
3874             zExp = pExp;
3875             if (lt128(cSig0, cSig1, pSig0, pSig1)) {
3876                 sub128(pSig0, pSig1, cSig0, cSig1, &zSig0, &zSig1);
3877             } else if (lt128(pSig0, pSig1, cSig0, cSig1)) {
3878                 sub128(cSig0, cSig1, pSig0, pSig1, &zSig0, &zSig1);
3879                 zSign ^= 1;
3880             } else {
3881                 /* Exact zero */
3882                 zSign = signflip;
3883                 if (STATUS(float_rounding_mode) == float_round_down) {
3884                     zSign ^= 1;
3885                 }
3886                 return packFloat64(zSign, 0, 0);
3887             }
3888         }
3889         --zExp;
3890         /* Do the equivalent of normalizeRoundAndPackFloat64() but
3891          * starting with the significand in a pair of uint64_t.
3892          */
3893         if (zSig0) {
3894             shiftcount = countLeadingZeros64(zSig0) - 1;
3895             shortShift128Left(zSig0, zSig1, shiftcount, &zSig0, &zSig1);
3896             if (zSig1) {
3897                 zSig0 |= 1;
3898             }
3899             zExp -= shiftcount;
3900         } else {
3901             shiftcount = countLeadingZeros64(zSig1);
3902             if (shiftcount == 0) {
3903                 zSig0 = (zSig1 >> 1) | (zSig1 & 1);
3904                 zExp -= 63;
3905             } else {
3906                 shiftcount--;
3907                 zSig0 = zSig1 << shiftcount;
3908                 zExp -= (shiftcount + 64);
3909             }
3910         }
3911         return roundAndPackFloat64(zSign, zExp, zSig0 STATUS_VAR);
3912     }
3913 }
3914 
3915 /*----------------------------------------------------------------------------
3916 | Returns the square root of the double-precision floating-point value `a'.
3917 | The operation is performed according to the IEC/IEEE Standard for Binary
3918 | Floating-Point Arithmetic.
3919 *----------------------------------------------------------------------------*/
3920 
3921 float64 float64_sqrt( float64 a STATUS_PARAM )
3922 {
3923     flag aSign;
3924     int_fast16_t aExp, zExp;
3925     uint64_t aSig, zSig, doubleZSig;
3926     uint64_t rem0, rem1, term0, term1;
3927     a = float64_squash_input_denormal(a STATUS_VAR);
3928 
3929     aSig = extractFloat64Frac( a );
3930     aExp = extractFloat64Exp( a );
3931     aSign = extractFloat64Sign( a );
3932     if ( aExp == 0x7FF ) {
3933         if ( aSig ) return propagateFloat64NaN( a, a STATUS_VAR );
3934         if ( ! aSign ) return a;
3935         float_raise( float_flag_invalid STATUS_VAR);
3936         return float64_default_nan;
3937     }
3938     if ( aSign ) {
3939         if ( ( aExp | aSig ) == 0 ) return a;
3940         float_raise( float_flag_invalid STATUS_VAR);
3941         return float64_default_nan;
3942     }
3943     if ( aExp == 0 ) {
3944         if ( aSig == 0 ) return float64_zero;
3945         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
3946     }
3947     zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
3948     aSig |= LIT64( 0x0010000000000000 );
3949     zSig = estimateSqrt32( aExp, aSig>>21 );
3950     aSig <<= 9 - ( aExp & 1 );
3951     zSig = estimateDiv128To64( aSig, 0, zSig<<32 ) + ( zSig<<30 );
3952     if ( ( zSig & 0x1FF ) <= 5 ) {
3953         doubleZSig = zSig<<1;
3954         mul64To128( zSig, zSig, &term0, &term1 );
3955         sub128( aSig, 0, term0, term1, &rem0, &rem1 );
3956         while ( (int64_t) rem0 < 0 ) {
3957             --zSig;
3958             doubleZSig -= 2;
3959             add128( rem0, rem1, zSig>>63, doubleZSig | 1, &rem0, &rem1 );
3960         }
3961         zSig |= ( ( rem0 | rem1 ) != 0 );
3962     }
3963     return roundAndPackFloat64( 0, zExp, zSig STATUS_VAR );
3964 
3965 }
3966 
3967 /*----------------------------------------------------------------------------
3968 | Returns the binary log of the double-precision floating-point value `a'.
3969 | The operation is performed according to the IEC/IEEE Standard for Binary
3970 | Floating-Point Arithmetic.
3971 *----------------------------------------------------------------------------*/
3972 float64 float64_log2( float64 a STATUS_PARAM )
3973 {
3974     flag aSign, zSign;
3975     int_fast16_t aExp;
3976     uint64_t aSig, aSig0, aSig1, zSig, i;
3977     a = float64_squash_input_denormal(a STATUS_VAR);
3978 
3979     aSig = extractFloat64Frac( a );
3980     aExp = extractFloat64Exp( a );
3981     aSign = extractFloat64Sign( a );
3982 
3983     if ( aExp == 0 ) {
3984         if ( aSig == 0 ) return packFloat64( 1, 0x7FF, 0 );
3985         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
3986     }
3987     if ( aSign ) {
3988         float_raise( float_flag_invalid STATUS_VAR);
3989         return float64_default_nan;
3990     }
3991     if ( aExp == 0x7FF ) {
3992         if ( aSig ) return propagateFloat64NaN( a, float64_zero STATUS_VAR );
3993         return a;
3994     }
3995 
3996     aExp -= 0x3FF;
3997     aSig |= LIT64( 0x0010000000000000 );
3998     zSign = aExp < 0;
3999     zSig = (uint64_t)aExp << 52;
4000     for (i = 1LL << 51; i > 0; i >>= 1) {
4001         mul64To128( aSig, aSig, &aSig0, &aSig1 );
4002         aSig = ( aSig0 << 12 ) | ( aSig1 >> 52 );
4003         if ( aSig & LIT64( 0x0020000000000000 ) ) {
4004             aSig >>= 1;
4005             zSig |= i;
4006         }
4007     }
4008 
4009     if ( zSign )
4010         zSig = -zSig;
4011     return normalizeRoundAndPackFloat64( zSign, 0x408, zSig STATUS_VAR );
4012 }
4013 
4014 /*----------------------------------------------------------------------------
4015 | Returns 1 if the double-precision floating-point value `a' is equal to the
4016 | corresponding value `b', and 0 otherwise.  The invalid exception is raised
4017 | if either operand is a NaN.  Otherwise, the comparison is performed
4018 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4019 *----------------------------------------------------------------------------*/
4020 
4021 int float64_eq( float64 a, float64 b STATUS_PARAM )
4022 {
4023     uint64_t av, bv;
4024     a = float64_squash_input_denormal(a STATUS_VAR);
4025     b = float64_squash_input_denormal(b STATUS_VAR);
4026 
4027     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
4028          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
4029        ) {
4030         float_raise( float_flag_invalid STATUS_VAR);
4031         return 0;
4032     }
4033     av = float64_val(a);
4034     bv = float64_val(b);
4035     return ( av == bv ) || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
4036 
4037 }
4038 
4039 /*----------------------------------------------------------------------------
4040 | Returns 1 if the double-precision floating-point value `a' is less than or
4041 | equal to the corresponding value `b', and 0 otherwise.  The invalid
4042 | exception is raised if either operand is a NaN.  The comparison is performed
4043 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4044 *----------------------------------------------------------------------------*/
4045 
4046 int float64_le( float64 a, float64 b STATUS_PARAM )
4047 {
4048     flag aSign, bSign;
4049     uint64_t av, bv;
4050     a = float64_squash_input_denormal(a STATUS_VAR);
4051     b = float64_squash_input_denormal(b STATUS_VAR);
4052 
4053     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
4054          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
4055        ) {
4056         float_raise( float_flag_invalid STATUS_VAR);
4057         return 0;
4058     }
4059     aSign = extractFloat64Sign( a );
4060     bSign = extractFloat64Sign( b );
4061     av = float64_val(a);
4062     bv = float64_val(b);
4063     if ( aSign != bSign ) return aSign || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
4064     return ( av == bv ) || ( aSign ^ ( av < bv ) );
4065 
4066 }
4067 
4068 /*----------------------------------------------------------------------------
4069 | Returns 1 if the double-precision floating-point value `a' is less than
4070 | the corresponding value `b', and 0 otherwise.  The invalid exception is
4071 | raised if either operand is a NaN.  The comparison is performed according
4072 | to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4073 *----------------------------------------------------------------------------*/
4074 
4075 int float64_lt( float64 a, float64 b STATUS_PARAM )
4076 {
4077     flag aSign, bSign;
4078     uint64_t av, bv;
4079 
4080     a = float64_squash_input_denormal(a STATUS_VAR);
4081     b = float64_squash_input_denormal(b STATUS_VAR);
4082     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
4083          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
4084        ) {
4085         float_raise( float_flag_invalid STATUS_VAR);
4086         return 0;
4087     }
4088     aSign = extractFloat64Sign( a );
4089     bSign = extractFloat64Sign( b );
4090     av = float64_val(a);
4091     bv = float64_val(b);
4092     if ( aSign != bSign ) return aSign && ( (uint64_t) ( ( av | bv )<<1 ) != 0 );
4093     return ( av != bv ) && ( aSign ^ ( av < bv ) );
4094 
4095 }
4096 
4097 /*----------------------------------------------------------------------------
4098 | Returns 1 if the double-precision floating-point values `a' and `b' cannot
4099 | be compared, and 0 otherwise.  The invalid exception is raised if either
4100 | operand is a NaN.  The comparison is performed according to the IEC/IEEE
4101 | Standard for Binary Floating-Point Arithmetic.
4102 *----------------------------------------------------------------------------*/
4103 
4104 int float64_unordered( float64 a, float64 b STATUS_PARAM )
4105 {
4106     a = float64_squash_input_denormal(a STATUS_VAR);
4107     b = float64_squash_input_denormal(b STATUS_VAR);
4108 
4109     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
4110          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
4111        ) {
4112         float_raise( float_flag_invalid STATUS_VAR);
4113         return 1;
4114     }
4115     return 0;
4116 }
4117 
4118 /*----------------------------------------------------------------------------
4119 | Returns 1 if the double-precision floating-point value `a' is equal to the
4120 | corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
4121 | exception.The comparison is performed according to the IEC/IEEE Standard
4122 | for Binary Floating-Point Arithmetic.
4123 *----------------------------------------------------------------------------*/
4124 
4125 int float64_eq_quiet( float64 a, float64 b STATUS_PARAM )
4126 {
4127     uint64_t av, bv;
4128     a = float64_squash_input_denormal(a STATUS_VAR);
4129     b = float64_squash_input_denormal(b STATUS_VAR);
4130 
4131     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
4132          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
4133        ) {
4134         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
4135             float_raise( float_flag_invalid STATUS_VAR);
4136         }
4137         return 0;
4138     }
4139     av = float64_val(a);
4140     bv = float64_val(b);
4141     return ( av == bv ) || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
4142 
4143 }
4144 
4145 /*----------------------------------------------------------------------------
4146 | Returns 1 if the double-precision floating-point value `a' is less than or
4147 | equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
4148 | cause an exception.  Otherwise, the comparison is performed according to the
4149 | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4150 *----------------------------------------------------------------------------*/
4151 
4152 int float64_le_quiet( float64 a, float64 b STATUS_PARAM )
4153 {
4154     flag aSign, bSign;
4155     uint64_t av, bv;
4156     a = float64_squash_input_denormal(a STATUS_VAR);
4157     b = float64_squash_input_denormal(b STATUS_VAR);
4158 
4159     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
4160          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
4161        ) {
4162         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
4163             float_raise( float_flag_invalid STATUS_VAR);
4164         }
4165         return 0;
4166     }
4167     aSign = extractFloat64Sign( a );
4168     bSign = extractFloat64Sign( b );
4169     av = float64_val(a);
4170     bv = float64_val(b);
4171     if ( aSign != bSign ) return aSign || ( (uint64_t) ( ( av | bv )<<1 ) == 0 );
4172     return ( av == bv ) || ( aSign ^ ( av < bv ) );
4173 
4174 }
4175 
4176 /*----------------------------------------------------------------------------
4177 | Returns 1 if the double-precision floating-point value `a' is less than
4178 | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
4179 | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
4180 | Standard for Binary Floating-Point Arithmetic.
4181 *----------------------------------------------------------------------------*/
4182 
4183 int float64_lt_quiet( float64 a, float64 b STATUS_PARAM )
4184 {
4185     flag aSign, bSign;
4186     uint64_t av, bv;
4187     a = float64_squash_input_denormal(a STATUS_VAR);
4188     b = float64_squash_input_denormal(b STATUS_VAR);
4189 
4190     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
4191          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
4192        ) {
4193         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
4194             float_raise( float_flag_invalid STATUS_VAR);
4195         }
4196         return 0;
4197     }
4198     aSign = extractFloat64Sign( a );
4199     bSign = extractFloat64Sign( b );
4200     av = float64_val(a);
4201     bv = float64_val(b);
4202     if ( aSign != bSign ) return aSign && ( (uint64_t) ( ( av | bv )<<1 ) != 0 );
4203     return ( av != bv ) && ( aSign ^ ( av < bv ) );
4204 
4205 }
4206 
4207 /*----------------------------------------------------------------------------
4208 | Returns 1 if the double-precision floating-point values `a' and `b' cannot
4209 | be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
4210 | comparison is performed according to the IEC/IEEE Standard for Binary
4211 | Floating-Point Arithmetic.
4212 *----------------------------------------------------------------------------*/
4213 
4214 int float64_unordered_quiet( float64 a, float64 b STATUS_PARAM )
4215 {
4216     a = float64_squash_input_denormal(a STATUS_VAR);
4217     b = float64_squash_input_denormal(b STATUS_VAR);
4218 
4219     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
4220          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
4221        ) {
4222         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
4223             float_raise( float_flag_invalid STATUS_VAR);
4224         }
4225         return 1;
4226     }
4227     return 0;
4228 }
4229 
4230 /*----------------------------------------------------------------------------
4231 | Returns the result of converting the extended double-precision floating-
4232 | point value `a' to the 32-bit two's complement integer format.  The
4233 | conversion is performed according to the IEC/IEEE Standard for Binary
4234 | Floating-Point Arithmetic---which means in particular that the conversion
4235 | is rounded according to the current rounding mode.  If `a' is a NaN, the
4236 | largest positive integer is returned.  Otherwise, if the conversion
4237 | overflows, the largest integer with the same sign as `a' is returned.
4238 *----------------------------------------------------------------------------*/
4239 
4240 int32 floatx80_to_int32( floatx80 a STATUS_PARAM )
4241 {
4242     flag aSign;
4243     int32 aExp, shiftCount;
4244     uint64_t aSig;
4245 
4246     aSig = extractFloatx80Frac( a );
4247     aExp = extractFloatx80Exp( a );
4248     aSign = extractFloatx80Sign( a );
4249     if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0;
4250     shiftCount = 0x4037 - aExp;
4251     if ( shiftCount <= 0 ) shiftCount = 1;
4252     shift64RightJamming( aSig, shiftCount, &aSig );
4253     return roundAndPackInt32( aSign, aSig STATUS_VAR );
4254 
4255 }
4256 
4257 /*----------------------------------------------------------------------------
4258 | Returns the result of converting the extended double-precision floating-
4259 | point value `a' to the 32-bit two's complement integer format.  The
4260 | conversion is performed according to the IEC/IEEE Standard for Binary
4261 | Floating-Point Arithmetic, except that the conversion is always rounded
4262 | toward zero.  If `a' is a NaN, the largest positive integer is returned.
4263 | Otherwise, if the conversion overflows, the largest integer with the same
4264 | sign as `a' is returned.
4265 *----------------------------------------------------------------------------*/
4266 
4267 int32 floatx80_to_int32_round_to_zero( floatx80 a STATUS_PARAM )
4268 {
4269     flag aSign;
4270     int32 aExp, shiftCount;
4271     uint64_t aSig, savedASig;
4272     int32_t z;
4273 
4274     aSig = extractFloatx80Frac( a );
4275     aExp = extractFloatx80Exp( a );
4276     aSign = extractFloatx80Sign( a );
4277     if ( 0x401E < aExp ) {
4278         if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) aSign = 0;
4279         goto invalid;
4280     }
4281     else if ( aExp < 0x3FFF ) {
4282         if ( aExp || aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
4283         return 0;
4284     }
4285     shiftCount = 0x403E - aExp;
4286     savedASig = aSig;
4287     aSig >>= shiftCount;
4288     z = aSig;
4289     if ( aSign ) z = - z;
4290     if ( ( z < 0 ) ^ aSign ) {
4291  invalid:
4292         float_raise( float_flag_invalid STATUS_VAR);
4293         return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
4294     }
4295     if ( ( aSig<<shiftCount ) != savedASig ) {
4296         STATUS(float_exception_flags) |= float_flag_inexact;
4297     }
4298     return z;
4299 
4300 }
4301 
4302 /*----------------------------------------------------------------------------
4303 | Returns the result of converting the extended double-precision floating-
4304 | point value `a' to the 64-bit two's complement integer format.  The
4305 | conversion is performed according to the IEC/IEEE Standard for Binary
4306 | Floating-Point Arithmetic---which means in particular that the conversion
4307 | is rounded according to the current rounding mode.  If `a' is a NaN,
4308 | the largest positive integer is returned.  Otherwise, if the conversion
4309 | overflows, the largest integer with the same sign as `a' is returned.
4310 *----------------------------------------------------------------------------*/
4311 
4312 int64 floatx80_to_int64( floatx80 a STATUS_PARAM )
4313 {
4314     flag aSign;
4315     int32 aExp, shiftCount;
4316     uint64_t aSig, aSigExtra;
4317 
4318     aSig = extractFloatx80Frac( a );
4319     aExp = extractFloatx80Exp( a );
4320     aSign = extractFloatx80Sign( a );
4321     shiftCount = 0x403E - aExp;
4322     if ( shiftCount <= 0 ) {
4323         if ( shiftCount ) {
4324             float_raise( float_flag_invalid STATUS_VAR);
4325             if (    ! aSign
4326                  || (    ( aExp == 0x7FFF )
4327                       && ( aSig != LIT64( 0x8000000000000000 ) ) )
4328                ) {
4329                 return LIT64( 0x7FFFFFFFFFFFFFFF );
4330             }
4331             return (int64_t) LIT64( 0x8000000000000000 );
4332         }
4333         aSigExtra = 0;
4334     }
4335     else {
4336         shift64ExtraRightJamming( aSig, 0, shiftCount, &aSig, &aSigExtra );
4337     }
4338     return roundAndPackInt64( aSign, aSig, aSigExtra STATUS_VAR );
4339 
4340 }
4341 
4342 /*----------------------------------------------------------------------------
4343 | Returns the result of converting the extended double-precision floating-
4344 | point value `a' to the 64-bit two's complement integer format.  The
4345 | conversion is performed according to the IEC/IEEE Standard for Binary
4346 | Floating-Point Arithmetic, except that the conversion is always rounded
4347 | toward zero.  If `a' is a NaN, the largest positive integer is returned.
4348 | Otherwise, if the conversion overflows, the largest integer with the same
4349 | sign as `a' is returned.
4350 *----------------------------------------------------------------------------*/
4351 
4352 int64 floatx80_to_int64_round_to_zero( floatx80 a STATUS_PARAM )
4353 {
4354     flag aSign;
4355     int32 aExp, shiftCount;
4356     uint64_t aSig;
4357     int64 z;
4358 
4359     aSig = extractFloatx80Frac( a );
4360     aExp = extractFloatx80Exp( a );
4361     aSign = extractFloatx80Sign( a );
4362     shiftCount = aExp - 0x403E;
4363     if ( 0 <= shiftCount ) {
4364         aSig &= LIT64( 0x7FFFFFFFFFFFFFFF );
4365         if ( ( a.high != 0xC03E ) || aSig ) {
4366             float_raise( float_flag_invalid STATUS_VAR);
4367             if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) {
4368                 return LIT64( 0x7FFFFFFFFFFFFFFF );
4369             }
4370         }
4371         return (int64_t) LIT64( 0x8000000000000000 );
4372     }
4373     else if ( aExp < 0x3FFF ) {
4374         if ( aExp | aSig ) STATUS(float_exception_flags) |= float_flag_inexact;
4375         return 0;
4376     }
4377     z = aSig>>( - shiftCount );
4378     if ( (uint64_t) ( aSig<<( shiftCount & 63 ) ) ) {
4379         STATUS(float_exception_flags) |= float_flag_inexact;
4380     }
4381     if ( aSign ) z = - z;
4382     return z;
4383 
4384 }
4385 
4386 /*----------------------------------------------------------------------------
4387 | Returns the result of converting the extended double-precision floating-
4388 | point value `a' to the single-precision floating-point format.  The
4389 | conversion is performed according to the IEC/IEEE Standard for Binary
4390 | Floating-Point Arithmetic.
4391 *----------------------------------------------------------------------------*/
4392 
4393 float32 floatx80_to_float32( floatx80 a STATUS_PARAM )
4394 {
4395     flag aSign;
4396     int32 aExp;
4397     uint64_t aSig;
4398 
4399     aSig = extractFloatx80Frac( a );
4400     aExp = extractFloatx80Exp( a );
4401     aSign = extractFloatx80Sign( a );
4402     if ( aExp == 0x7FFF ) {
4403         if ( (uint64_t) ( aSig<<1 ) ) {
4404             return commonNaNToFloat32( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
4405         }
4406         return packFloat32( aSign, 0xFF, 0 );
4407     }
4408     shift64RightJamming( aSig, 33, &aSig );
4409     if ( aExp || aSig ) aExp -= 0x3F81;
4410     return roundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
4411 
4412 }
4413 
4414 /*----------------------------------------------------------------------------
4415 | Returns the result of converting the extended double-precision floating-
4416 | point value `a' to the double-precision floating-point format.  The
4417 | conversion is performed according to the IEC/IEEE Standard for Binary
4418 | Floating-Point Arithmetic.
4419 *----------------------------------------------------------------------------*/
4420 
4421 float64 floatx80_to_float64( floatx80 a STATUS_PARAM )
4422 {
4423     flag aSign;
4424     int32 aExp;
4425     uint64_t aSig, zSig;
4426 
4427     aSig = extractFloatx80Frac( a );
4428     aExp = extractFloatx80Exp( a );
4429     aSign = extractFloatx80Sign( a );
4430     if ( aExp == 0x7FFF ) {
4431         if ( (uint64_t) ( aSig<<1 ) ) {
4432             return commonNaNToFloat64( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
4433         }
4434         return packFloat64( aSign, 0x7FF, 0 );
4435     }
4436     shift64RightJamming( aSig, 1, &zSig );
4437     if ( aExp || aSig ) aExp -= 0x3C01;
4438     return roundAndPackFloat64( aSign, aExp, zSig STATUS_VAR );
4439 
4440 }
4441 
4442 /*----------------------------------------------------------------------------
4443 | Returns the result of converting the extended double-precision floating-
4444 | point value `a' to the quadruple-precision floating-point format.  The
4445 | conversion is performed according to the IEC/IEEE Standard for Binary
4446 | Floating-Point Arithmetic.
4447 *----------------------------------------------------------------------------*/
4448 
4449 float128 floatx80_to_float128( floatx80 a STATUS_PARAM )
4450 {
4451     flag aSign;
4452     int_fast16_t aExp;
4453     uint64_t aSig, zSig0, zSig1;
4454 
4455     aSig = extractFloatx80Frac( a );
4456     aExp = extractFloatx80Exp( a );
4457     aSign = extractFloatx80Sign( a );
4458     if ( ( aExp == 0x7FFF ) && (uint64_t) ( aSig<<1 ) ) {
4459         return commonNaNToFloat128( floatx80ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
4460     }
4461     shift128Right( aSig<<1, 0, 16, &zSig0, &zSig1 );
4462     return packFloat128( aSign, aExp, zSig0, zSig1 );
4463 
4464 }
4465 
4466 /*----------------------------------------------------------------------------
4467 | Rounds the extended double-precision floating-point value `a' to an integer,
4468 | and returns the result as an extended quadruple-precision floating-point
4469 | value.  The operation is performed according to the IEC/IEEE Standard for
4470 | Binary Floating-Point Arithmetic.
4471 *----------------------------------------------------------------------------*/
4472 
4473 floatx80 floatx80_round_to_int( floatx80 a STATUS_PARAM )
4474 {
4475     flag aSign;
4476     int32 aExp;
4477     uint64_t lastBitMask, roundBitsMask;
4478     int8 roundingMode;
4479     floatx80 z;
4480 
4481     aExp = extractFloatx80Exp( a );
4482     if ( 0x403E <= aExp ) {
4483         if ( ( aExp == 0x7FFF ) && (uint64_t) ( extractFloatx80Frac( a )<<1 ) ) {
4484             return propagateFloatx80NaN( a, a STATUS_VAR );
4485         }
4486         return a;
4487     }
4488     if ( aExp < 0x3FFF ) {
4489         if (    ( aExp == 0 )
4490              && ( (uint64_t) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
4491             return a;
4492         }
4493         STATUS(float_exception_flags) |= float_flag_inexact;
4494         aSign = extractFloatx80Sign( a );
4495         switch ( STATUS(float_rounding_mode) ) {
4496          case float_round_nearest_even:
4497             if ( ( aExp == 0x3FFE ) && (uint64_t) ( extractFloatx80Frac( a )<<1 )
4498                ) {
4499                 return
4500                     packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
4501             }
4502             break;
4503          case float_round_down:
4504             return
4505                   aSign ?
4506                       packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
4507                 : packFloatx80( 0, 0, 0 );
4508          case float_round_up:
4509             return
4510                   aSign ? packFloatx80( 1, 0, 0 )
4511                 : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
4512         }
4513         return packFloatx80( aSign, 0, 0 );
4514     }
4515     lastBitMask = 1;
4516     lastBitMask <<= 0x403E - aExp;
4517     roundBitsMask = lastBitMask - 1;
4518     z = a;
4519     roundingMode = STATUS(float_rounding_mode);
4520     if ( roundingMode == float_round_nearest_even ) {
4521         z.low += lastBitMask>>1;
4522         if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
4523     }
4524     else if ( roundingMode != float_round_to_zero ) {
4525         if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
4526             z.low += roundBitsMask;
4527         }
4528     }
4529     z.low &= ~ roundBitsMask;
4530     if ( z.low == 0 ) {
4531         ++z.high;
4532         z.low = LIT64( 0x8000000000000000 );
4533     }
4534     if ( z.low != a.low ) STATUS(float_exception_flags) |= float_flag_inexact;
4535     return z;
4536 
4537 }
4538 
4539 /*----------------------------------------------------------------------------
4540 | Returns the result of adding the absolute values of the extended double-
4541 | precision floating-point values `a' and `b'.  If `zSign' is 1, the sum is
4542 | negated before being returned.  `zSign' is ignored if the result is a NaN.
4543 | The addition is performed according to the IEC/IEEE Standard for Binary
4544 | Floating-Point Arithmetic.
4545 *----------------------------------------------------------------------------*/
4546 
4547 static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM)
4548 {
4549     int32 aExp, bExp, zExp;
4550     uint64_t aSig, bSig, zSig0, zSig1;
4551     int32 expDiff;
4552 
4553     aSig = extractFloatx80Frac( a );
4554     aExp = extractFloatx80Exp( a );
4555     bSig = extractFloatx80Frac( b );
4556     bExp = extractFloatx80Exp( b );
4557     expDiff = aExp - bExp;
4558     if ( 0 < expDiff ) {
4559         if ( aExp == 0x7FFF ) {
4560             if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4561             return a;
4562         }
4563         if ( bExp == 0 ) --expDiff;
4564         shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
4565         zExp = aExp;
4566     }
4567     else if ( expDiff < 0 ) {
4568         if ( bExp == 0x7FFF ) {
4569             if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4570             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
4571         }
4572         if ( aExp == 0 ) ++expDiff;
4573         shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
4574         zExp = bExp;
4575     }
4576     else {
4577         if ( aExp == 0x7FFF ) {
4578             if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) {
4579                 return propagateFloatx80NaN( a, b STATUS_VAR );
4580             }
4581             return a;
4582         }
4583         zSig1 = 0;
4584         zSig0 = aSig + bSig;
4585         if ( aExp == 0 ) {
4586             normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
4587             goto roundAndPack;
4588         }
4589         zExp = aExp;
4590         goto shiftRight1;
4591     }
4592     zSig0 = aSig + bSig;
4593     if ( (int64_t) zSig0 < 0 ) goto roundAndPack;
4594  shiftRight1:
4595     shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
4596     zSig0 |= LIT64( 0x8000000000000000 );
4597     ++zExp;
4598  roundAndPack:
4599     return
4600         roundAndPackFloatx80(
4601             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
4602 
4603 }
4604 
4605 /*----------------------------------------------------------------------------
4606 | Returns the result of subtracting the absolute values of the extended
4607 | double-precision floating-point values `a' and `b'.  If `zSign' is 1, the
4608 | difference is negated before being returned.  `zSign' is ignored if the
4609 | result is a NaN.  The subtraction is performed according to the IEC/IEEE
4610 | Standard for Binary Floating-Point Arithmetic.
4611 *----------------------------------------------------------------------------*/
4612 
4613 static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign STATUS_PARAM )
4614 {
4615     int32 aExp, bExp, zExp;
4616     uint64_t aSig, bSig, zSig0, zSig1;
4617     int32 expDiff;
4618     floatx80 z;
4619 
4620     aSig = extractFloatx80Frac( a );
4621     aExp = extractFloatx80Exp( a );
4622     bSig = extractFloatx80Frac( b );
4623     bExp = extractFloatx80Exp( b );
4624     expDiff = aExp - bExp;
4625     if ( 0 < expDiff ) goto aExpBigger;
4626     if ( expDiff < 0 ) goto bExpBigger;
4627     if ( aExp == 0x7FFF ) {
4628         if ( (uint64_t) ( ( aSig | bSig )<<1 ) ) {
4629             return propagateFloatx80NaN( a, b STATUS_VAR );
4630         }
4631         float_raise( float_flag_invalid STATUS_VAR);
4632         z.low = floatx80_default_nan_low;
4633         z.high = floatx80_default_nan_high;
4634         return z;
4635     }
4636     if ( aExp == 0 ) {
4637         aExp = 1;
4638         bExp = 1;
4639     }
4640     zSig1 = 0;
4641     if ( bSig < aSig ) goto aBigger;
4642     if ( aSig < bSig ) goto bBigger;
4643     return packFloatx80( STATUS(float_rounding_mode) == float_round_down, 0, 0 );
4644  bExpBigger:
4645     if ( bExp == 0x7FFF ) {
4646         if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4647         return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
4648     }
4649     if ( aExp == 0 ) ++expDiff;
4650     shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
4651  bBigger:
4652     sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
4653     zExp = bExp;
4654     zSign ^= 1;
4655     goto normalizeRoundAndPack;
4656  aExpBigger:
4657     if ( aExp == 0x7FFF ) {
4658         if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4659         return a;
4660     }
4661     if ( bExp == 0 ) --expDiff;
4662     shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
4663  aBigger:
4664     sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
4665     zExp = aExp;
4666  normalizeRoundAndPack:
4667     return
4668         normalizeRoundAndPackFloatx80(
4669             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
4670 
4671 }
4672 
4673 /*----------------------------------------------------------------------------
4674 | Returns the result of adding the extended double-precision floating-point
4675 | values `a' and `b'.  The operation is performed according to the IEC/IEEE
4676 | Standard for Binary Floating-Point Arithmetic.
4677 *----------------------------------------------------------------------------*/
4678 
4679 floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM )
4680 {
4681     flag aSign, bSign;
4682 
4683     aSign = extractFloatx80Sign( a );
4684     bSign = extractFloatx80Sign( b );
4685     if ( aSign == bSign ) {
4686         return addFloatx80Sigs( a, b, aSign STATUS_VAR );
4687     }
4688     else {
4689         return subFloatx80Sigs( a, b, aSign STATUS_VAR );
4690     }
4691 
4692 }
4693 
4694 /*----------------------------------------------------------------------------
4695 | Returns the result of subtracting the extended double-precision floating-
4696 | point values `a' and `b'.  The operation is performed according to the
4697 | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4698 *----------------------------------------------------------------------------*/
4699 
4700 floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM )
4701 {
4702     flag aSign, bSign;
4703 
4704     aSign = extractFloatx80Sign( a );
4705     bSign = extractFloatx80Sign( b );
4706     if ( aSign == bSign ) {
4707         return subFloatx80Sigs( a, b, aSign STATUS_VAR );
4708     }
4709     else {
4710         return addFloatx80Sigs( a, b, aSign STATUS_VAR );
4711     }
4712 
4713 }
4714 
4715 /*----------------------------------------------------------------------------
4716 | Returns the result of multiplying the extended double-precision floating-
4717 | point values `a' and `b'.  The operation is performed according to the
4718 | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4719 *----------------------------------------------------------------------------*/
4720 
4721 floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM )
4722 {
4723     flag aSign, bSign, zSign;
4724     int32 aExp, bExp, zExp;
4725     uint64_t aSig, bSig, zSig0, zSig1;
4726     floatx80 z;
4727 
4728     aSig = extractFloatx80Frac( a );
4729     aExp = extractFloatx80Exp( a );
4730     aSign = extractFloatx80Sign( a );
4731     bSig = extractFloatx80Frac( b );
4732     bExp = extractFloatx80Exp( b );
4733     bSign = extractFloatx80Sign( b );
4734     zSign = aSign ^ bSign;
4735     if ( aExp == 0x7FFF ) {
4736         if (    (uint64_t) ( aSig<<1 )
4737              || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
4738             return propagateFloatx80NaN( a, b STATUS_VAR );
4739         }
4740         if ( ( bExp | bSig ) == 0 ) goto invalid;
4741         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
4742     }
4743     if ( bExp == 0x7FFF ) {
4744         if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4745         if ( ( aExp | aSig ) == 0 ) {
4746  invalid:
4747             float_raise( float_flag_invalid STATUS_VAR);
4748             z.low = floatx80_default_nan_low;
4749             z.high = floatx80_default_nan_high;
4750             return z;
4751         }
4752         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
4753     }
4754     if ( aExp == 0 ) {
4755         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
4756         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
4757     }
4758     if ( bExp == 0 ) {
4759         if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
4760         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
4761     }
4762     zExp = aExp + bExp - 0x3FFE;
4763     mul64To128( aSig, bSig, &zSig0, &zSig1 );
4764     if ( 0 < (int64_t) zSig0 ) {
4765         shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
4766         --zExp;
4767     }
4768     return
4769         roundAndPackFloatx80(
4770             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
4771 
4772 }
4773 
4774 /*----------------------------------------------------------------------------
4775 | Returns the result of dividing the extended double-precision floating-point
4776 | value `a' by the corresponding value `b'.  The operation is performed
4777 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4778 *----------------------------------------------------------------------------*/
4779 
4780 floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM )
4781 {
4782     flag aSign, bSign, zSign;
4783     int32 aExp, bExp, zExp;
4784     uint64_t aSig, bSig, zSig0, zSig1;
4785     uint64_t rem0, rem1, rem2, term0, term1, term2;
4786     floatx80 z;
4787 
4788     aSig = extractFloatx80Frac( a );
4789     aExp = extractFloatx80Exp( a );
4790     aSign = extractFloatx80Sign( a );
4791     bSig = extractFloatx80Frac( b );
4792     bExp = extractFloatx80Exp( b );
4793     bSign = extractFloatx80Sign( b );
4794     zSign = aSign ^ bSign;
4795     if ( aExp == 0x7FFF ) {
4796         if ( (uint64_t) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4797         if ( bExp == 0x7FFF ) {
4798             if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4799             goto invalid;
4800         }
4801         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
4802     }
4803     if ( bExp == 0x7FFF ) {
4804         if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4805         return packFloatx80( zSign, 0, 0 );
4806     }
4807     if ( bExp == 0 ) {
4808         if ( bSig == 0 ) {
4809             if ( ( aExp | aSig ) == 0 ) {
4810  invalid:
4811                 float_raise( float_flag_invalid STATUS_VAR);
4812                 z.low = floatx80_default_nan_low;
4813                 z.high = floatx80_default_nan_high;
4814                 return z;
4815             }
4816             float_raise( float_flag_divbyzero STATUS_VAR);
4817             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
4818         }
4819         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
4820     }
4821     if ( aExp == 0 ) {
4822         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
4823         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
4824     }
4825     zExp = aExp - bExp + 0x3FFE;
4826     rem1 = 0;
4827     if ( bSig <= aSig ) {
4828         shift128Right( aSig, 0, 1, &aSig, &rem1 );
4829         ++zExp;
4830     }
4831     zSig0 = estimateDiv128To64( aSig, rem1, bSig );
4832     mul64To128( bSig, zSig0, &term0, &term1 );
4833     sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
4834     while ( (int64_t) rem0 < 0 ) {
4835         --zSig0;
4836         add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
4837     }
4838     zSig1 = estimateDiv128To64( rem1, 0, bSig );
4839     if ( (uint64_t) ( zSig1<<1 ) <= 8 ) {
4840         mul64To128( bSig, zSig1, &term1, &term2 );
4841         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
4842         while ( (int64_t) rem1 < 0 ) {
4843             --zSig1;
4844             add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
4845         }
4846         zSig1 |= ( ( rem1 | rem2 ) != 0 );
4847     }
4848     return
4849         roundAndPackFloatx80(
4850             STATUS(floatx80_rounding_precision), zSign, zExp, zSig0, zSig1 STATUS_VAR );
4851 
4852 }
4853 
4854 /*----------------------------------------------------------------------------
4855 | Returns the remainder of the extended double-precision floating-point value
4856 | `a' with respect to the corresponding value `b'.  The operation is performed
4857 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
4858 *----------------------------------------------------------------------------*/
4859 
4860 floatx80 floatx80_rem( floatx80 a, floatx80 b STATUS_PARAM )
4861 {
4862     flag aSign, zSign;
4863     int32 aExp, bExp, expDiff;
4864     uint64_t aSig0, aSig1, bSig;
4865     uint64_t q, term0, term1, alternateASig0, alternateASig1;
4866     floatx80 z;
4867 
4868     aSig0 = extractFloatx80Frac( a );
4869     aExp = extractFloatx80Exp( a );
4870     aSign = extractFloatx80Sign( a );
4871     bSig = extractFloatx80Frac( b );
4872     bExp = extractFloatx80Exp( b );
4873     if ( aExp == 0x7FFF ) {
4874         if (    (uint64_t) ( aSig0<<1 )
4875              || ( ( bExp == 0x7FFF ) && (uint64_t) ( bSig<<1 ) ) ) {
4876             return propagateFloatx80NaN( a, b STATUS_VAR );
4877         }
4878         goto invalid;
4879     }
4880     if ( bExp == 0x7FFF ) {
4881         if ( (uint64_t) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b STATUS_VAR );
4882         return a;
4883     }
4884     if ( bExp == 0 ) {
4885         if ( bSig == 0 ) {
4886  invalid:
4887             float_raise( float_flag_invalid STATUS_VAR);
4888             z.low = floatx80_default_nan_low;
4889             z.high = floatx80_default_nan_high;
4890             return z;
4891         }
4892         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
4893     }
4894     if ( aExp == 0 ) {
4895         if ( (uint64_t) ( aSig0<<1 ) == 0 ) return a;
4896         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
4897     }
4898     bSig |= LIT64( 0x8000000000000000 );
4899     zSign = aSign;
4900     expDiff = aExp - bExp;
4901     aSig1 = 0;
4902     if ( expDiff < 0 ) {
4903         if ( expDiff < -1 ) return a;
4904         shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
4905         expDiff = 0;
4906     }
4907     q = ( bSig <= aSig0 );
4908     if ( q ) aSig0 -= bSig;
4909     expDiff -= 64;
4910     while ( 0 < expDiff ) {
4911         q = estimateDiv128To64( aSig0, aSig1, bSig );
4912         q = ( 2 < q ) ? q - 2 : 0;
4913         mul64To128( bSig, q, &term0, &term1 );
4914         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
4915         shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
4916         expDiff -= 62;
4917     }
4918     expDiff += 64;
4919     if ( 0 < expDiff ) {
4920         q = estimateDiv128To64( aSig0, aSig1, bSig );
4921         q = ( 2 < q ) ? q - 2 : 0;
4922         q >>= 64 - expDiff;
4923         mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
4924         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
4925         shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
4926         while ( le128( term0, term1, aSig0, aSig1 ) ) {
4927             ++q;
4928             sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
4929         }
4930     }
4931     else {
4932         term1 = 0;
4933         term0 = bSig;
4934     }
4935     sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
4936     if (    lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
4937          || (    eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
4938               && ( q & 1 ) )
4939        ) {
4940         aSig0 = alternateASig0;
4941         aSig1 = alternateASig1;
4942         zSign = ! zSign;
4943     }
4944     return
4945         normalizeRoundAndPackFloatx80(
4946             80, zSign, bExp + expDiff, aSig0, aSig1 STATUS_VAR );
4947 
4948 }
4949 
4950 /*----------------------------------------------------------------------------
4951 | Returns the square root of the extended double-precision floating-point
4952 | value `a'.  The operation is performed according to the IEC/IEEE Standard
4953 | for Binary Floating-Point Arithmetic.
4954 *----------------------------------------------------------------------------*/
4955 
4956 floatx80 floatx80_sqrt( floatx80 a STATUS_PARAM )
4957 {
4958     flag aSign;
4959     int32 aExp, zExp;
4960     uint64_t aSig0, aSig1, zSig0, zSig1, doubleZSig0;
4961     uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
4962     floatx80 z;
4963 
4964     aSig0 = extractFloatx80Frac( a );
4965     aExp = extractFloatx80Exp( a );
4966     aSign = extractFloatx80Sign( a );
4967     if ( aExp == 0x7FFF ) {
4968         if ( (uint64_t) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a STATUS_VAR );
4969         if ( ! aSign ) return a;
4970         goto invalid;
4971     }
4972     if ( aSign ) {
4973         if ( ( aExp | aSig0 ) == 0 ) return a;
4974  invalid:
4975         float_raise( float_flag_invalid STATUS_VAR);
4976         z.low = floatx80_default_nan_low;
4977         z.high = floatx80_default_nan_high;
4978         return z;
4979     }
4980     if ( aExp == 0 ) {
4981         if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
4982         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
4983     }
4984     zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
4985     zSig0 = estimateSqrt32( aExp, aSig0>>32 );
4986     shift128Right( aSig0, 0, 2 + ( aExp & 1 ), &aSig0, &aSig1 );
4987     zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
4988     doubleZSig0 = zSig0<<1;
4989     mul64To128( zSig0, zSig0, &term0, &term1 );
4990     sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
4991     while ( (int64_t) rem0 < 0 ) {
4992         --zSig0;
4993         doubleZSig0 -= 2;
4994         add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
4995     }
4996     zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
4997     if ( ( zSig1 & LIT64( 0x3FFFFFFFFFFFFFFF ) ) <= 5 ) {
4998         if ( zSig1 == 0 ) zSig1 = 1;
4999         mul64To128( doubleZSig0, zSig1, &term1, &term2 );
5000         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
5001         mul64To128( zSig1, zSig1, &term2, &term3 );
5002         sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
5003         while ( (int64_t) rem1 < 0 ) {
5004             --zSig1;
5005             shortShift128Left( 0, zSig1, 1, &term2, &term3 );
5006             term3 |= 1;
5007             term2 |= doubleZSig0;
5008             add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
5009         }
5010         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
5011     }
5012     shortShift128Left( 0, zSig1, 1, &zSig0, &zSig1 );
5013     zSig0 |= doubleZSig0;
5014     return
5015         roundAndPackFloatx80(
5016             STATUS(floatx80_rounding_precision), 0, zExp, zSig0, zSig1 STATUS_VAR );
5017 
5018 }
5019 
5020 /*----------------------------------------------------------------------------
5021 | Returns 1 if the extended double-precision floating-point value `a' is equal
5022 | to the corresponding value `b', and 0 otherwise.  The invalid exception is
5023 | raised if either operand is a NaN.  Otherwise, the comparison is performed
5024 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
5025 *----------------------------------------------------------------------------*/
5026 
5027 int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM )
5028 {
5029 
5030     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
5031               && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
5032          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
5033               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
5034        ) {
5035         float_raise( float_flag_invalid STATUS_VAR);
5036         return 0;
5037     }
5038     return
5039            ( a.low == b.low )
5040         && (    ( a.high == b.high )
5041              || (    ( a.low == 0 )
5042                   && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) )
5043            );
5044 
5045 }
5046 
5047 /*----------------------------------------------------------------------------
5048 | Returns 1 if the extended double-precision floating-point value `a' is
5049 | less than or equal to the corresponding value `b', and 0 otherwise.  The
5050 | invalid exception is raised if either operand is a NaN.  The comparison is
5051 | performed according to the IEC/IEEE Standard for Binary Floating-Point
5052 | Arithmetic.
5053 *----------------------------------------------------------------------------*/
5054 
5055 int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM )
5056 {
5057     flag aSign, bSign;
5058 
5059     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
5060               && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
5061          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
5062               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
5063        ) {
5064         float_raise( float_flag_invalid STATUS_VAR);
5065         return 0;
5066     }
5067     aSign = extractFloatx80Sign( a );
5068     bSign = extractFloatx80Sign( b );
5069     if ( aSign != bSign ) {
5070         return
5071                aSign
5072             || (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
5073                  == 0 );
5074     }
5075     return
5076           aSign ? le128( b.high, b.low, a.high, a.low )
5077         : le128( a.high, a.low, b.high, b.low );
5078 
5079 }
5080 
5081 /*----------------------------------------------------------------------------
5082 | Returns 1 if the extended double-precision floating-point value `a' is
5083 | less than the corresponding value `b', and 0 otherwise.  The invalid
5084 | exception is raised if either operand is a NaN.  The comparison is performed
5085 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
5086 *----------------------------------------------------------------------------*/
5087 
5088 int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM )
5089 {
5090     flag aSign, bSign;
5091 
5092     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
5093               && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
5094          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
5095               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
5096        ) {
5097         float_raise( float_flag_invalid STATUS_VAR);
5098         return 0;
5099     }
5100     aSign = extractFloatx80Sign( a );
5101     bSign = extractFloatx80Sign( b );
5102     if ( aSign != bSign ) {
5103         return
5104                aSign
5105             && (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
5106                  != 0 );
5107     }
5108     return
5109           aSign ? lt128( b.high, b.low, a.high, a.low )
5110         : lt128( a.high, a.low, b.high, b.low );
5111 
5112 }
5113 
5114 /*----------------------------------------------------------------------------
5115 | Returns 1 if the extended double-precision floating-point values `a' and `b'
5116 | cannot be compared, and 0 otherwise.  The invalid exception is raised if
5117 | either operand is a NaN.   The comparison is performed according to the
5118 | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
5119 *----------------------------------------------------------------------------*/
5120 int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM )
5121 {
5122     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
5123               && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
5124          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
5125               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
5126        ) {
5127         float_raise( float_flag_invalid STATUS_VAR);
5128         return 1;
5129     }
5130     return 0;
5131 }
5132 
5133 /*----------------------------------------------------------------------------
5134 | Returns 1 if the extended double-precision floating-point value `a' is
5135 | equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
5136 | cause an exception.  The comparison is performed according to the IEC/IEEE
5137 | Standard for Binary Floating-Point Arithmetic.
5138 *----------------------------------------------------------------------------*/
5139 
5140 int floatx80_eq_quiet( floatx80 a, floatx80 b STATUS_PARAM )
5141 {
5142 
5143     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
5144               && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
5145          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
5146               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
5147        ) {
5148         if (    floatx80_is_signaling_nan( a )
5149              || floatx80_is_signaling_nan( b ) ) {
5150             float_raise( float_flag_invalid STATUS_VAR);
5151         }
5152         return 0;
5153     }
5154     return
5155            ( a.low == b.low )
5156         && (    ( a.high == b.high )
5157              || (    ( a.low == 0 )
5158                   && ( (uint16_t) ( ( a.high | b.high )<<1 ) == 0 ) )
5159            );
5160 
5161 }
5162 
5163 /*----------------------------------------------------------------------------
5164 | Returns 1 if the extended double-precision floating-point value `a' is less
5165 | than or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs
5166 | do not cause an exception.  Otherwise, the comparison is performed according
5167 | to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
5168 *----------------------------------------------------------------------------*/
5169 
5170 int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM )
5171 {
5172     flag aSign, bSign;
5173 
5174     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
5175               && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
5176          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
5177               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
5178        ) {
5179         if (    floatx80_is_signaling_nan( a )
5180              || floatx80_is_signaling_nan( b ) ) {
5181             float_raise( float_flag_invalid STATUS_VAR);
5182         }
5183         return 0;
5184     }
5185     aSign = extractFloatx80Sign( a );
5186     bSign = extractFloatx80Sign( b );
5187     if ( aSign != bSign ) {
5188         return
5189                aSign
5190             || (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
5191                  == 0 );
5192     }
5193     return
5194           aSign ? le128( b.high, b.low, a.high, a.low )
5195         : le128( a.high, a.low, b.high, b.low );
5196 
5197 }
5198 
5199 /*----------------------------------------------------------------------------
5200 | Returns 1 if the extended double-precision floating-point value `a' is less
5201 | than the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause
5202 | an exception.  Otherwise, the comparison is performed according to the
5203 | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
5204 *----------------------------------------------------------------------------*/
5205 
5206 int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM )
5207 {
5208     flag aSign, bSign;
5209 
5210     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
5211               && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
5212          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
5213               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
5214        ) {
5215         if (    floatx80_is_signaling_nan( a )
5216              || floatx80_is_signaling_nan( b ) ) {
5217             float_raise( float_flag_invalid STATUS_VAR);
5218         }
5219         return 0;
5220     }
5221     aSign = extractFloatx80Sign( a );
5222     bSign = extractFloatx80Sign( b );
5223     if ( aSign != bSign ) {
5224         return
5225                aSign
5226             && (    ( ( (uint16_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
5227                  != 0 );
5228     }
5229     return
5230           aSign ? lt128( b.high, b.low, a.high, a.low )
5231         : lt128( a.high, a.low, b.high, b.low );
5232 
5233 }
5234 
5235 /*----------------------------------------------------------------------------
5236 | Returns 1 if the extended double-precision floating-point values `a' and `b'
5237 | cannot be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.
5238 | The comparison is performed according to the IEC/IEEE Standard for Binary
5239 | Floating-Point Arithmetic.
5240 *----------------------------------------------------------------------------*/
5241 int floatx80_unordered_quiet( floatx80 a, floatx80 b STATUS_PARAM )
5242 {
5243     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
5244               && (uint64_t) ( extractFloatx80Frac( a )<<1 ) )
5245          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
5246               && (uint64_t) ( extractFloatx80Frac( b )<<1 ) )
5247        ) {
5248         if (    floatx80_is_signaling_nan( a )
5249              || floatx80_is_signaling_nan( b ) ) {
5250             float_raise( float_flag_invalid STATUS_VAR);
5251         }
5252         return 1;
5253     }
5254     return 0;
5255 }
5256 
5257 /*----------------------------------------------------------------------------
5258 | Returns the result of converting the quadruple-precision floating-point
5259 | value `a' to the 32-bit two's complement integer format.  The conversion
5260 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
5261 | Arithmetic---which means in particular that the conversion is rounded
5262 | according to the current rounding mode.  If `a' is a NaN, the largest
5263 | positive integer is returned.  Otherwise, if the conversion overflows, the
5264 | largest integer with the same sign as `a' is returned.
5265 *----------------------------------------------------------------------------*/
5266 
5267 int32 float128_to_int32( float128 a STATUS_PARAM )
5268 {
5269     flag aSign;
5270     int32 aExp, shiftCount;
5271     uint64_t aSig0, aSig1;
5272 
5273     aSig1 = extractFloat128Frac1( a );
5274     aSig0 = extractFloat128Frac0( a );
5275     aExp = extractFloat128Exp( a );
5276     aSign = extractFloat128Sign( a );
5277     if ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) aSign = 0;
5278     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
5279     aSig0 |= ( aSig1 != 0 );
5280     shiftCount = 0x4028 - aExp;
5281     if ( 0 < shiftCount ) shift64RightJamming( aSig0, shiftCount, &aSig0 );
5282     return roundAndPackInt32( aSign, aSig0 STATUS_VAR );
5283 
5284 }
5285 
5286 /*----------------------------------------------------------------------------
5287 | Returns the result of converting the quadruple-precision floating-point
5288 | value `a' to the 32-bit two's complement integer format.  The conversion
5289 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
5290 | Arithmetic, except that the conversion is always rounded toward zero.  If
5291 | `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
5292 | conversion overflows, the largest integer with the same sign as `a' is
5293 | returned.
5294 *----------------------------------------------------------------------------*/
5295 
5296 int32 float128_to_int32_round_to_zero( float128 a STATUS_PARAM )
5297 {
5298     flag aSign;
5299     int32 aExp, shiftCount;
5300     uint64_t aSig0, aSig1, savedASig;
5301     int32_t z;
5302 
5303     aSig1 = extractFloat128Frac1( a );
5304     aSig0 = extractFloat128Frac0( a );
5305     aExp = extractFloat128Exp( a );
5306     aSign = extractFloat128Sign( a );
5307     aSig0 |= ( aSig1 != 0 );
5308     if ( 0x401E < aExp ) {
5309         if ( ( aExp == 0x7FFF ) && aSig0 ) aSign = 0;
5310         goto invalid;
5311     }
5312     else if ( aExp < 0x3FFF ) {
5313         if ( aExp || aSig0 ) STATUS(float_exception_flags) |= float_flag_inexact;
5314         return 0;
5315     }
5316     aSig0 |= LIT64( 0x0001000000000000 );
5317     shiftCount = 0x402F - aExp;
5318     savedASig = aSig0;
5319     aSig0 >>= shiftCount;
5320     z = aSig0;
5321     if ( aSign ) z = - z;
5322     if ( ( z < 0 ) ^ aSign ) {
5323  invalid:
5324         float_raise( float_flag_invalid STATUS_VAR);
5325         return aSign ? (int32_t) 0x80000000 : 0x7FFFFFFF;
5326     }
5327     if ( ( aSig0<<shiftCount ) != savedASig ) {
5328         STATUS(float_exception_flags) |= float_flag_inexact;
5329     }
5330     return z;
5331 
5332 }
5333 
5334 /*----------------------------------------------------------------------------
5335 | Returns the result of converting the quadruple-precision floating-point
5336 | value `a' to the 64-bit two's complement integer format.  The conversion
5337 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
5338 | Arithmetic---which means in particular that the conversion is rounded
5339 | according to the current rounding mode.  If `a' is a NaN, the largest
5340 | positive integer is returned.  Otherwise, if the conversion overflows, the
5341 | largest integer with the same sign as `a' is returned.
5342 *----------------------------------------------------------------------------*/
5343 
5344 int64 float128_to_int64( float128 a STATUS_PARAM )
5345 {
5346     flag aSign;
5347     int32 aExp, shiftCount;
5348     uint64_t aSig0, aSig1;
5349 
5350     aSig1 = extractFloat128Frac1( a );
5351     aSig0 = extractFloat128Frac0( a );
5352     aExp = extractFloat128Exp( a );
5353     aSign = extractFloat128Sign( a );
5354     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
5355     shiftCount = 0x402F - aExp;
5356     if ( shiftCount <= 0 ) {
5357         if ( 0x403E < aExp ) {
5358             float_raise( float_flag_invalid STATUS_VAR);
5359             if (    ! aSign
5360                  || (    ( aExp == 0x7FFF )
5361                       && ( aSig1 || ( aSig0 != LIT64( 0x0001000000000000 ) ) )
5362                     )
5363                ) {
5364                 return LIT64( 0x7FFFFFFFFFFFFFFF );
5365             }
5366             return (int64_t) LIT64( 0x8000000000000000 );
5367         }
5368         shortShift128Left( aSig0, aSig1, - shiftCount, &aSig0, &aSig1 );
5369     }
5370     else {
5371         shift64ExtraRightJamming( aSig0, aSig1, shiftCount, &aSig0, &aSig1 );
5372     }
5373     return roundAndPackInt64( aSign, aSig0, aSig1 STATUS_VAR );
5374 
5375 }
5376 
5377 /*----------------------------------------------------------------------------
5378 | Returns the result of converting the quadruple-precision floating-point
5379 | value `a' to the 64-bit two's complement integer format.  The conversion
5380 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
5381 | Arithmetic, except that the conversion is always rounded toward zero.
5382 | If `a' is a NaN, the largest positive integer is returned.  Otherwise, if
5383 | the conversion overflows, the largest integer with the same sign as `a' is
5384 | returned.
5385 *----------------------------------------------------------------------------*/
5386 
5387 int64 float128_to_int64_round_to_zero( float128 a STATUS_PARAM )
5388 {
5389     flag aSign;
5390     int32 aExp, shiftCount;
5391     uint64_t aSig0, aSig1;
5392     int64 z;
5393 
5394     aSig1 = extractFloat128Frac1( a );
5395     aSig0 = extractFloat128Frac0( a );
5396     aExp = extractFloat128Exp( a );
5397     aSign = extractFloat128Sign( a );
5398     if ( aExp ) aSig0 |= LIT64( 0x0001000000000000 );
5399     shiftCount = aExp - 0x402F;
5400     if ( 0 < shiftCount ) {
5401         if ( 0x403E <= aExp ) {
5402             aSig0 &= LIT64( 0x0000FFFFFFFFFFFF );
5403             if (    ( a.high == LIT64( 0xC03E000000000000 ) )
5404                  && ( aSig1 < LIT64( 0x0002000000000000 ) ) ) {
5405                 if ( aSig1 ) STATUS(float_exception_flags) |= float_flag_inexact;
5406             }
5407             else {
5408                 float_raise( float_flag_invalid STATUS_VAR);
5409                 if ( ! aSign || ( ( aExp == 0x7FFF ) && ( aSig0 | aSig1 ) ) ) {
5410                     return LIT64( 0x7FFFFFFFFFFFFFFF );
5411                 }
5412             }
5413             return (int64_t) LIT64( 0x8000000000000000 );
5414         }
5415         z = ( aSig0<<shiftCount ) | ( aSig1>>( ( - shiftCount ) & 63 ) );
5416         if ( (uint64_t) ( aSig1<<shiftCount ) ) {
5417             STATUS(float_exception_flags) |= float_flag_inexact;
5418         }
5419     }
5420     else {
5421         if ( aExp < 0x3FFF ) {
5422             if ( aExp | aSig0 | aSig1 ) {
5423                 STATUS(float_exception_flags) |= float_flag_inexact;
5424             }
5425             return 0;
5426         }
5427         z = aSig0>>( - shiftCount );
5428         if (    aSig1
5429              || ( shiftCount && (uint64_t) ( aSig0<<( shiftCount & 63 ) ) ) ) {
5430             STATUS(float_exception_flags) |= float_flag_inexact;
5431         }
5432     }
5433     if ( aSign ) z = - z;
5434     return z;
5435 
5436 }
5437 
5438 /*----------------------------------------------------------------------------
5439 | Returns the result of converting the quadruple-precision floating-point
5440 | value `a' to the single-precision floating-point format.  The conversion
5441 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
5442 | Arithmetic.
5443 *----------------------------------------------------------------------------*/
5444 
5445 float32 float128_to_float32( float128 a STATUS_PARAM )
5446 {
5447     flag aSign;
5448     int32 aExp;
5449     uint64_t aSig0, aSig1;
5450     uint32_t zSig;
5451 
5452     aSig1 = extractFloat128Frac1( a );
5453     aSig0 = extractFloat128Frac0( a );
5454     aExp = extractFloat128Exp( a );
5455     aSign = extractFloat128Sign( a );
5456     if ( aExp == 0x7FFF ) {
5457         if ( aSig0 | aSig1 ) {
5458             return commonNaNToFloat32( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
5459         }
5460         return packFloat32( aSign, 0xFF, 0 );
5461     }
5462     aSig0 |= ( aSig1 != 0 );
5463     shift64RightJamming( aSig0, 18, &aSig0 );
5464     zSig = aSig0;
5465     if ( aExp || zSig ) {
5466         zSig |= 0x40000000;
5467         aExp -= 0x3F81;
5468     }
5469     return roundAndPackFloat32( aSign, aExp, zSig STATUS_VAR );
5470 
5471 }
5472 
5473 /*----------------------------------------------------------------------------
5474 | Returns the result of converting the quadruple-precision floating-point
5475 | value `a' to the double-precision floating-point format.  The conversion
5476 | is performed according to the IEC/IEEE Standard for Binary Floating-Point
5477 | Arithmetic.
5478 *----------------------------------------------------------------------------*/
5479 
5480 float64 float128_to_float64( float128 a STATUS_PARAM )
5481 {
5482     flag aSign;
5483     int32 aExp;
5484     uint64_t aSig0, aSig1;
5485 
5486     aSig1 = extractFloat128Frac1( a );
5487     aSig0 = extractFloat128Frac0( a );
5488     aExp = extractFloat128Exp( a );
5489     aSign = extractFloat128Sign( a );
5490     if ( aExp == 0x7FFF ) {
5491         if ( aSig0 | aSig1 ) {
5492             return commonNaNToFloat64( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
5493         }
5494         return packFloat64( aSign, 0x7FF, 0 );
5495     }
5496     shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
5497     aSig0 |= ( aSig1 != 0 );
5498     if ( aExp || aSig0 ) {
5499         aSig0 |= LIT64( 0x4000000000000000 );
5500         aExp -= 0x3C01;
5501     }
5502     return roundAndPackFloat64( aSign, aExp, aSig0 STATUS_VAR );
5503 
5504 }
5505 
5506 /*----------------------------------------------------------------------------
5507 | Returns the result of converting the quadruple-precision floating-point
5508 | value `a' to the extended double-precision floating-point format.  The
5509 | conversion is performed according to the IEC/IEEE Standard for Binary
5510 | Floating-Point Arithmetic.
5511 *----------------------------------------------------------------------------*/
5512 
5513 floatx80 float128_to_floatx80( float128 a STATUS_PARAM )
5514 {
5515     flag aSign;
5516     int32 aExp;
5517     uint64_t aSig0, aSig1;
5518 
5519     aSig1 = extractFloat128Frac1( a );
5520     aSig0 = extractFloat128Frac0( a );
5521     aExp = extractFloat128Exp( a );
5522     aSign = extractFloat128Sign( a );
5523     if ( aExp == 0x7FFF ) {
5524         if ( aSig0 | aSig1 ) {
5525             return commonNaNToFloatx80( float128ToCommonNaN( a STATUS_VAR ) STATUS_VAR );
5526         }
5527         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
5528     }
5529     if ( aExp == 0 ) {
5530         if ( ( aSig0 | aSig1 ) == 0 ) return packFloatx80( aSign, 0, 0 );
5531         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
5532     }
5533     else {
5534         aSig0 |= LIT64( 0x0001000000000000 );
5535     }
5536     shortShift128Left( aSig0, aSig1, 15, &aSig0, &aSig1 );
5537     return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1 STATUS_VAR );
5538 
5539 }
5540 
5541 /*----------------------------------------------------------------------------
5542 | Rounds the quadruple-precision floating-point value `a' to an integer, and
5543 | returns the result as a quadruple-precision floating-point value.  The
5544 | operation is performed according to the IEC/IEEE Standard for Binary
5545 | Floating-Point Arithmetic.
5546 *----------------------------------------------------------------------------*/
5547 
5548 float128 float128_round_to_int( float128 a STATUS_PARAM )
5549 {
5550     flag aSign;
5551     int32 aExp;
5552     uint64_t lastBitMask, roundBitsMask;
5553     int8 roundingMode;
5554     float128 z;
5555 
5556     aExp = extractFloat128Exp( a );
5557     if ( 0x402F <= aExp ) {
5558         if ( 0x406F <= aExp ) {
5559             if (    ( aExp == 0x7FFF )
5560                  && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) )
5561                ) {
5562                 return propagateFloat128NaN( a, a STATUS_VAR );
5563             }
5564             return a;
5565         }
5566         lastBitMask = 1;
5567         lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1;
5568         roundBitsMask = lastBitMask - 1;
5569         z = a;
5570         roundingMode = STATUS(float_rounding_mode);
5571         if ( roundingMode == float_round_nearest_even ) {
5572             if ( lastBitMask ) {
5573                 add128( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
5574                 if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
5575             }
5576             else {
5577                 if ( (int64_t) z.low < 0 ) {
5578                     ++z.high;
5579                     if ( (uint64_t) ( z.low<<1 ) == 0 ) z.high &= ~1;
5580                 }
5581             }
5582         }
5583         else if ( roundingMode != float_round_to_zero ) {
5584             if (   extractFloat128Sign( z )
5585                  ^ ( roundingMode == float_round_up ) ) {
5586                 add128( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
5587             }
5588         }
5589         z.low &= ~ roundBitsMask;
5590     }
5591     else {
5592         if ( aExp < 0x3FFF ) {
5593             if ( ( ( (uint64_t) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
5594             STATUS(float_exception_flags) |= float_flag_inexact;
5595             aSign = extractFloat128Sign( a );
5596             switch ( STATUS(float_rounding_mode) ) {
5597              case float_round_nearest_even:
5598                 if (    ( aExp == 0x3FFE )
5599                      && (   extractFloat128Frac0( a )
5600                           | extractFloat128Frac1( a ) )
5601                    ) {
5602                     return packFloat128( aSign, 0x3FFF, 0, 0 );
5603                 }
5604                 break;
5605              case float_round_down:
5606                 return
5607                       aSign ? packFloat128( 1, 0x3FFF, 0, 0 )
5608                     : packFloat128( 0, 0, 0, 0 );
5609              case float_round_up:
5610                 return
5611                       aSign ? packFloat128( 1, 0, 0, 0 )
5612                     : packFloat128( 0, 0x3FFF, 0, 0 );
5613             }
5614             return packFloat128( aSign, 0, 0, 0 );
5615         }
5616         lastBitMask = 1;
5617         lastBitMask <<= 0x402F - aExp;
5618         roundBitsMask = lastBitMask - 1;
5619         z.low = 0;
5620         z.high = a.high;
5621         roundingMode = STATUS(float_rounding_mode);
5622         if ( roundingMode == float_round_nearest_even ) {
5623             z.high += lastBitMask>>1;
5624             if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
5625                 z.high &= ~ lastBitMask;
5626             }
5627         }
5628         else if ( roundingMode != float_round_to_zero ) {
5629             if (   extractFloat128Sign( z )
5630                  ^ ( roundingMode == float_round_up ) ) {
5631                 z.high |= ( a.low != 0 );
5632                 z.high += roundBitsMask;
5633             }
5634         }
5635         z.high &= ~ roundBitsMask;
5636     }
5637     if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
5638         STATUS(float_exception_flags) |= float_flag_inexact;
5639     }
5640     return z;
5641 
5642 }
5643 
5644 /*----------------------------------------------------------------------------
5645 | Returns the result of adding the absolute values of the quadruple-precision
5646 | floating-point values `a' and `b'.  If `zSign' is 1, the sum is negated
5647 | before being returned.  `zSign' is ignored if the result is a NaN.
5648 | The addition is performed according to the IEC/IEEE Standard for Binary
5649 | Floating-Point Arithmetic.
5650 *----------------------------------------------------------------------------*/
5651 
5652 static float128 addFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
5653 {
5654     int32 aExp, bExp, zExp;
5655     uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
5656     int32 expDiff;
5657 
5658     aSig1 = extractFloat128Frac1( a );
5659     aSig0 = extractFloat128Frac0( a );
5660     aExp = extractFloat128Exp( a );
5661     bSig1 = extractFloat128Frac1( b );
5662     bSig0 = extractFloat128Frac0( b );
5663     bExp = extractFloat128Exp( b );
5664     expDiff = aExp - bExp;
5665     if ( 0 < expDiff ) {
5666         if ( aExp == 0x7FFF ) {
5667             if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
5668             return a;
5669         }
5670         if ( bExp == 0 ) {
5671             --expDiff;
5672         }
5673         else {
5674             bSig0 |= LIT64( 0x0001000000000000 );
5675         }
5676         shift128ExtraRightJamming(
5677             bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
5678         zExp = aExp;
5679     }
5680     else if ( expDiff < 0 ) {
5681         if ( bExp == 0x7FFF ) {
5682             if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
5683             return packFloat128( zSign, 0x7FFF, 0, 0 );
5684         }
5685         if ( aExp == 0 ) {
5686             ++expDiff;
5687         }
5688         else {
5689             aSig0 |= LIT64( 0x0001000000000000 );
5690         }
5691         shift128ExtraRightJamming(
5692             aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
5693         zExp = bExp;
5694     }
5695     else {
5696         if ( aExp == 0x7FFF ) {
5697             if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
5698                 return propagateFloat128NaN( a, b STATUS_VAR );
5699             }
5700             return a;
5701         }
5702         add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
5703         if ( aExp == 0 ) {
5704             if (STATUS(flush_to_zero)) {
5705                 if (zSig0 | zSig1) {
5706                     float_raise(float_flag_output_denormal STATUS_VAR);
5707                 }
5708                 return packFloat128(zSign, 0, 0, 0);
5709             }
5710             return packFloat128( zSign, 0, zSig0, zSig1 );
5711         }
5712         zSig2 = 0;
5713         zSig0 |= LIT64( 0x0002000000000000 );
5714         zExp = aExp;
5715         goto shiftRight1;
5716     }
5717     aSig0 |= LIT64( 0x0001000000000000 );
5718     add128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
5719     --zExp;
5720     if ( zSig0 < LIT64( 0x0002000000000000 ) ) goto roundAndPack;
5721     ++zExp;
5722  shiftRight1:
5723     shift128ExtraRightJamming(
5724         zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
5725  roundAndPack:
5726     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
5727 
5728 }
5729 
5730 /*----------------------------------------------------------------------------
5731 | Returns the result of subtracting the absolute values of the quadruple-
5732 | precision floating-point values `a' and `b'.  If `zSign' is 1, the
5733 | difference is negated before being returned.  `zSign' is ignored if the
5734 | result is a NaN.  The subtraction is performed according to the IEC/IEEE
5735 | Standard for Binary Floating-Point Arithmetic.
5736 *----------------------------------------------------------------------------*/
5737 
5738 static float128 subFloat128Sigs( float128 a, float128 b, flag zSign STATUS_PARAM)
5739 {
5740     int32 aExp, bExp, zExp;
5741     uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
5742     int32 expDiff;
5743     float128 z;
5744 
5745     aSig1 = extractFloat128Frac1( a );
5746     aSig0 = extractFloat128Frac0( a );
5747     aExp = extractFloat128Exp( a );
5748     bSig1 = extractFloat128Frac1( b );
5749     bSig0 = extractFloat128Frac0( b );
5750     bExp = extractFloat128Exp( b );
5751     expDiff = aExp - bExp;
5752     shortShift128Left( aSig0, aSig1, 14, &aSig0, &aSig1 );
5753     shortShift128Left( bSig0, bSig1, 14, &bSig0, &bSig1 );
5754     if ( 0 < expDiff ) goto aExpBigger;
5755     if ( expDiff < 0 ) goto bExpBigger;
5756     if ( aExp == 0x7FFF ) {
5757         if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
5758             return propagateFloat128NaN( a, b STATUS_VAR );
5759         }
5760         float_raise( float_flag_invalid STATUS_VAR);
5761         z.low = float128_default_nan_low;
5762         z.high = float128_default_nan_high;
5763         return z;
5764     }
5765     if ( aExp == 0 ) {
5766         aExp = 1;
5767         bExp = 1;
5768     }
5769     if ( bSig0 < aSig0 ) goto aBigger;
5770     if ( aSig0 < bSig0 ) goto bBigger;
5771     if ( bSig1 < aSig1 ) goto aBigger;
5772     if ( aSig1 < bSig1 ) goto bBigger;
5773     return packFloat128( STATUS(float_rounding_mode) == float_round_down, 0, 0, 0 );
5774  bExpBigger:
5775     if ( bExp == 0x7FFF ) {
5776         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
5777         return packFloat128( zSign ^ 1, 0x7FFF, 0, 0 );
5778     }
5779     if ( aExp == 0 ) {
5780         ++expDiff;
5781     }
5782     else {
5783         aSig0 |= LIT64( 0x4000000000000000 );
5784     }
5785     shift128RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
5786     bSig0 |= LIT64( 0x4000000000000000 );
5787  bBigger:
5788     sub128( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
5789     zExp = bExp;
5790     zSign ^= 1;
5791     goto normalizeRoundAndPack;
5792  aExpBigger:
5793     if ( aExp == 0x7FFF ) {
5794         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
5795         return a;
5796     }
5797     if ( bExp == 0 ) {
5798         --expDiff;
5799     }
5800     else {
5801         bSig0 |= LIT64( 0x4000000000000000 );
5802     }
5803     shift128RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
5804     aSig0 |= LIT64( 0x4000000000000000 );
5805  aBigger:
5806     sub128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
5807     zExp = aExp;
5808  normalizeRoundAndPack:
5809     --zExp;
5810     return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1 STATUS_VAR );
5811 
5812 }
5813 
5814 /*----------------------------------------------------------------------------
5815 | Returns the result of adding the quadruple-precision floating-point values
5816 | `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
5817 | for Binary Floating-Point Arithmetic.
5818 *----------------------------------------------------------------------------*/
5819 
5820 float128 float128_add( float128 a, float128 b STATUS_PARAM )
5821 {
5822     flag aSign, bSign;
5823 
5824     aSign = extractFloat128Sign( a );
5825     bSign = extractFloat128Sign( b );
5826     if ( aSign == bSign ) {
5827         return addFloat128Sigs( a, b, aSign STATUS_VAR );
5828     }
5829     else {
5830         return subFloat128Sigs( a, b, aSign STATUS_VAR );
5831     }
5832 
5833 }
5834 
5835 /*----------------------------------------------------------------------------
5836 | Returns the result of subtracting the quadruple-precision floating-point
5837 | values `a' and `b'.  The operation is performed according to the IEC/IEEE
5838 | Standard for Binary Floating-Point Arithmetic.
5839 *----------------------------------------------------------------------------*/
5840 
5841 float128 float128_sub( float128 a, float128 b STATUS_PARAM )
5842 {
5843     flag aSign, bSign;
5844 
5845     aSign = extractFloat128Sign( a );
5846     bSign = extractFloat128Sign( b );
5847     if ( aSign == bSign ) {
5848         return subFloat128Sigs( a, b, aSign STATUS_VAR );
5849     }
5850     else {
5851         return addFloat128Sigs( a, b, aSign STATUS_VAR );
5852     }
5853 
5854 }
5855 
5856 /*----------------------------------------------------------------------------
5857 | Returns the result of multiplying the quadruple-precision floating-point
5858 | values `a' and `b'.  The operation is performed according to the IEC/IEEE
5859 | Standard for Binary Floating-Point Arithmetic.
5860 *----------------------------------------------------------------------------*/
5861 
5862 float128 float128_mul( float128 a, float128 b STATUS_PARAM )
5863 {
5864     flag aSign, bSign, zSign;
5865     int32 aExp, bExp, zExp;
5866     uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
5867     float128 z;
5868 
5869     aSig1 = extractFloat128Frac1( a );
5870     aSig0 = extractFloat128Frac0( a );
5871     aExp = extractFloat128Exp( a );
5872     aSign = extractFloat128Sign( a );
5873     bSig1 = extractFloat128Frac1( b );
5874     bSig0 = extractFloat128Frac0( b );
5875     bExp = extractFloat128Exp( b );
5876     bSign = extractFloat128Sign( b );
5877     zSign = aSign ^ bSign;
5878     if ( aExp == 0x7FFF ) {
5879         if (    ( aSig0 | aSig1 )
5880              || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
5881             return propagateFloat128NaN( a, b STATUS_VAR );
5882         }
5883         if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
5884         return packFloat128( zSign, 0x7FFF, 0, 0 );
5885     }
5886     if ( bExp == 0x7FFF ) {
5887         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
5888         if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
5889  invalid:
5890             float_raise( float_flag_invalid STATUS_VAR);
5891             z.low = float128_default_nan_low;
5892             z.high = float128_default_nan_high;
5893             return z;
5894         }
5895         return packFloat128( zSign, 0x7FFF, 0, 0 );
5896     }
5897     if ( aExp == 0 ) {
5898         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
5899         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
5900     }
5901     if ( bExp == 0 ) {
5902         if ( ( bSig0 | bSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
5903         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
5904     }
5905     zExp = aExp + bExp - 0x4000;
5906     aSig0 |= LIT64( 0x0001000000000000 );
5907     shortShift128Left( bSig0, bSig1, 16, &bSig0, &bSig1 );
5908     mul128To256( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
5909     add128( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
5910     zSig2 |= ( zSig3 != 0 );
5911     if ( LIT64( 0x0002000000000000 ) <= zSig0 ) {
5912         shift128ExtraRightJamming(
5913             zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
5914         ++zExp;
5915     }
5916     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
5917 
5918 }
5919 
5920 /*----------------------------------------------------------------------------
5921 | Returns the result of dividing the quadruple-precision floating-point value
5922 | `a' by the corresponding value `b'.  The operation is performed according to
5923 | the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
5924 *----------------------------------------------------------------------------*/
5925 
5926 float128 float128_div( float128 a, float128 b STATUS_PARAM )
5927 {
5928     flag aSign, bSign, zSign;
5929     int32 aExp, bExp, zExp;
5930     uint64_t aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
5931     uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
5932     float128 z;
5933 
5934     aSig1 = extractFloat128Frac1( a );
5935     aSig0 = extractFloat128Frac0( a );
5936     aExp = extractFloat128Exp( a );
5937     aSign = extractFloat128Sign( a );
5938     bSig1 = extractFloat128Frac1( b );
5939     bSig0 = extractFloat128Frac0( b );
5940     bExp = extractFloat128Exp( b );
5941     bSign = extractFloat128Sign( b );
5942     zSign = aSign ^ bSign;
5943     if ( aExp == 0x7FFF ) {
5944         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
5945         if ( bExp == 0x7FFF ) {
5946             if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
5947             goto invalid;
5948         }
5949         return packFloat128( zSign, 0x7FFF, 0, 0 );
5950     }
5951     if ( bExp == 0x7FFF ) {
5952         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
5953         return packFloat128( zSign, 0, 0, 0 );
5954     }
5955     if ( bExp == 0 ) {
5956         if ( ( bSig0 | bSig1 ) == 0 ) {
5957             if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
5958  invalid:
5959                 float_raise( float_flag_invalid STATUS_VAR);
5960                 z.low = float128_default_nan_low;
5961                 z.high = float128_default_nan_high;
5962                 return z;
5963             }
5964             float_raise( float_flag_divbyzero STATUS_VAR);
5965             return packFloat128( zSign, 0x7FFF, 0, 0 );
5966         }
5967         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
5968     }
5969     if ( aExp == 0 ) {
5970         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( zSign, 0, 0, 0 );
5971         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
5972     }
5973     zExp = aExp - bExp + 0x3FFD;
5974     shortShift128Left(
5975         aSig0 | LIT64( 0x0001000000000000 ), aSig1, 15, &aSig0, &aSig1 );
5976     shortShift128Left(
5977         bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
5978     if ( le128( bSig0, bSig1, aSig0, aSig1 ) ) {
5979         shift128Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
5980         ++zExp;
5981     }
5982     zSig0 = estimateDiv128To64( aSig0, aSig1, bSig0 );
5983     mul128By64To192( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
5984     sub192( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
5985     while ( (int64_t) rem0 < 0 ) {
5986         --zSig0;
5987         add192( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
5988     }
5989     zSig1 = estimateDiv128To64( rem1, rem2, bSig0 );
5990     if ( ( zSig1 & 0x3FFF ) <= 4 ) {
5991         mul128By64To192( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
5992         sub192( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
5993         while ( (int64_t) rem1 < 0 ) {
5994             --zSig1;
5995             add192( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
5996         }
5997         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
5998     }
5999     shift128ExtraRightJamming( zSig0, zSig1, 0, 15, &zSig0, &zSig1, &zSig2 );
6000     return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
6001 
6002 }
6003 
6004 /*----------------------------------------------------------------------------
6005 | Returns the remainder of the quadruple-precision floating-point value `a'
6006 | with respect to the corresponding value `b'.  The operation is performed
6007 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
6008 *----------------------------------------------------------------------------*/
6009 
6010 float128 float128_rem( float128 a, float128 b STATUS_PARAM )
6011 {
6012     flag aSign, zSign;
6013     int32 aExp, bExp, expDiff;
6014     uint64_t aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
6015     uint64_t allZero, alternateASig0, alternateASig1, sigMean1;
6016     int64_t sigMean0;
6017     float128 z;
6018 
6019     aSig1 = extractFloat128Frac1( a );
6020     aSig0 = extractFloat128Frac0( a );
6021     aExp = extractFloat128Exp( a );
6022     aSign = extractFloat128Sign( a );
6023     bSig1 = extractFloat128Frac1( b );
6024     bSig0 = extractFloat128Frac0( b );
6025     bExp = extractFloat128Exp( b );
6026     if ( aExp == 0x7FFF ) {
6027         if (    ( aSig0 | aSig1 )
6028              || ( ( bExp == 0x7FFF ) && ( bSig0 | bSig1 ) ) ) {
6029             return propagateFloat128NaN( a, b STATUS_VAR );
6030         }
6031         goto invalid;
6032     }
6033     if ( bExp == 0x7FFF ) {
6034         if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b STATUS_VAR );
6035         return a;
6036     }
6037     if ( bExp == 0 ) {
6038         if ( ( bSig0 | bSig1 ) == 0 ) {
6039  invalid:
6040             float_raise( float_flag_invalid STATUS_VAR);
6041             z.low = float128_default_nan_low;
6042             z.high = float128_default_nan_high;
6043             return z;
6044         }
6045         normalizeFloat128Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
6046     }
6047     if ( aExp == 0 ) {
6048         if ( ( aSig0 | aSig1 ) == 0 ) return a;
6049         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
6050     }
6051     expDiff = aExp - bExp;
6052     if ( expDiff < -1 ) return a;
6053     shortShift128Left(
6054         aSig0 | LIT64( 0x0001000000000000 ),
6055         aSig1,
6056         15 - ( expDiff < 0 ),
6057         &aSig0,
6058         &aSig1
6059     );
6060     shortShift128Left(
6061         bSig0 | LIT64( 0x0001000000000000 ), bSig1, 15, &bSig0, &bSig1 );
6062     q = le128( bSig0, bSig1, aSig0, aSig1 );
6063     if ( q ) sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
6064     expDiff -= 64;
6065     while ( 0 < expDiff ) {
6066         q = estimateDiv128To64( aSig0, aSig1, bSig0 );
6067         q = ( 4 < q ) ? q - 4 : 0;
6068         mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
6069         shortShift192Left( term0, term1, term2, 61, &term1, &term2, &allZero );
6070         shortShift128Left( aSig0, aSig1, 61, &aSig0, &allZero );
6071         sub128( aSig0, 0, term1, term2, &aSig0, &aSig1 );
6072         expDiff -= 61;
6073     }
6074     if ( -64 < expDiff ) {
6075         q = estimateDiv128To64( aSig0, aSig1, bSig0 );
6076         q = ( 4 < q ) ? q - 4 : 0;
6077         q >>= - expDiff;
6078         shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
6079         expDiff += 52;
6080         if ( expDiff < 0 ) {
6081             shift128Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
6082         }
6083         else {
6084             shortShift128Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
6085         }
6086         mul128By64To192( bSig0, bSig1, q, &term0, &term1, &term2 );
6087         sub128( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
6088     }
6089     else {
6090         shift128Right( aSig0, aSig1, 12, &aSig0, &aSig1 );
6091         shift128Right( bSig0, bSig1, 12, &bSig0, &bSig1 );
6092     }
6093     do {
6094         alternateASig0 = aSig0;
6095         alternateASig1 = aSig1;
6096         ++q;
6097         sub128( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
6098     } while ( 0 <= (int64_t) aSig0 );
6099     add128(
6100         aSig0, aSig1, alternateASig0, alternateASig1, (uint64_t *)&sigMean0, &sigMean1 );
6101     if (    ( sigMean0 < 0 )
6102          || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
6103         aSig0 = alternateASig0;
6104         aSig1 = alternateASig1;
6105     }
6106     zSign = ( (int64_t) aSig0 < 0 );
6107     if ( zSign ) sub128( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
6108     return
6109         normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1 STATUS_VAR );
6110 
6111 }
6112 
6113 /*----------------------------------------------------------------------------
6114 | Returns the square root of the quadruple-precision floating-point value `a'.
6115 | The operation is performed according to the IEC/IEEE Standard for Binary
6116 | Floating-Point Arithmetic.
6117 *----------------------------------------------------------------------------*/
6118 
6119 float128 float128_sqrt( float128 a STATUS_PARAM )
6120 {
6121     flag aSign;
6122     int32 aExp, zExp;
6123     uint64_t aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
6124     uint64_t rem0, rem1, rem2, rem3, term0, term1, term2, term3;
6125     float128 z;
6126 
6127     aSig1 = extractFloat128Frac1( a );
6128     aSig0 = extractFloat128Frac0( a );
6129     aExp = extractFloat128Exp( a );
6130     aSign = extractFloat128Sign( a );
6131     if ( aExp == 0x7FFF ) {
6132         if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a STATUS_VAR );
6133         if ( ! aSign ) return a;
6134         goto invalid;
6135     }
6136     if ( aSign ) {
6137         if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
6138  invalid:
6139         float_raise( float_flag_invalid STATUS_VAR);
6140         z.low = float128_default_nan_low;
6141         z.high = float128_default_nan_high;
6142         return z;
6143     }
6144     if ( aExp == 0 ) {
6145         if ( ( aSig0 | aSig1 ) == 0 ) return packFloat128( 0, 0, 0, 0 );
6146         normalizeFloat128Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
6147     }
6148     zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFE;
6149     aSig0 |= LIT64( 0x0001000000000000 );
6150     zSig0 = estimateSqrt32( aExp, aSig0>>17 );
6151     shortShift128Left( aSig0, aSig1, 13 - ( aExp & 1 ), &aSig0, &aSig1 );
6152     zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0<<32 ) + ( zSig0<<30 );
6153     doubleZSig0 = zSig0<<1;
6154     mul64To128( zSig0, zSig0, &term0, &term1 );
6155     sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
6156     while ( (int64_t) rem0 < 0 ) {
6157         --zSig0;
6158         doubleZSig0 -= 2;
6159         add128( rem0, rem1, zSig0>>63, doubleZSig0 | 1, &rem0, &rem1 );
6160     }
6161     zSig1 = estimateDiv128To64( rem1, 0, doubleZSig0 );
6162     if ( ( zSig1 & 0x1FFF ) <= 5 ) {
6163         if ( zSig1 == 0 ) zSig1 = 1;
6164         mul64To128( doubleZSig0, zSig1, &term1, &term2 );
6165         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
6166         mul64To128( zSig1, zSig1, &term2, &term3 );
6167         sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
6168         while ( (int64_t) rem1 < 0 ) {
6169             --zSig1;
6170             shortShift128Left( 0, zSig1, 1, &term2, &term3 );
6171             term3 |= 1;
6172             term2 |= doubleZSig0;
6173             add192( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
6174         }
6175         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
6176     }
6177     shift128ExtraRightJamming( zSig0, zSig1, 0, 14, &zSig0, &zSig1, &zSig2 );
6178     return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2 STATUS_VAR );
6179 
6180 }
6181 
6182 /*----------------------------------------------------------------------------
6183 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
6184 | the corresponding value `b', and 0 otherwise.  The invalid exception is
6185 | raised if either operand is a NaN.  Otherwise, the comparison is performed
6186 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
6187 *----------------------------------------------------------------------------*/
6188 
6189 int float128_eq( float128 a, float128 b STATUS_PARAM )
6190 {
6191 
6192     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6193               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6194          || (    ( extractFloat128Exp( b ) == 0x7FFF )
6195               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6196        ) {
6197         float_raise( float_flag_invalid STATUS_VAR);
6198         return 0;
6199     }
6200     return
6201            ( a.low == b.low )
6202         && (    ( a.high == b.high )
6203              || (    ( a.low == 0 )
6204                   && ( (uint64_t) ( ( a.high | b.high )<<1 ) == 0 ) )
6205            );
6206 
6207 }
6208 
6209 /*----------------------------------------------------------------------------
6210 | Returns 1 if the quadruple-precision floating-point value `a' is less than
6211 | or equal to the corresponding value `b', and 0 otherwise.  The invalid
6212 | exception is raised if either operand is a NaN.  The comparison is performed
6213 | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
6214 *----------------------------------------------------------------------------*/
6215 
6216 int float128_le( float128 a, float128 b STATUS_PARAM )
6217 {
6218     flag aSign, bSign;
6219 
6220     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6221               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6222          || (    ( extractFloat128Exp( b ) == 0x7FFF )
6223               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6224        ) {
6225         float_raise( float_flag_invalid STATUS_VAR);
6226         return 0;
6227     }
6228     aSign = extractFloat128Sign( a );
6229     bSign = extractFloat128Sign( b );
6230     if ( aSign != bSign ) {
6231         return
6232                aSign
6233             || (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
6234                  == 0 );
6235     }
6236     return
6237           aSign ? le128( b.high, b.low, a.high, a.low )
6238         : le128( a.high, a.low, b.high, b.low );
6239 
6240 }
6241 
6242 /*----------------------------------------------------------------------------
6243 | Returns 1 if the quadruple-precision floating-point value `a' is less than
6244 | the corresponding value `b', and 0 otherwise.  The invalid exception is
6245 | raised if either operand is a NaN.  The comparison is performed according
6246 | to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
6247 *----------------------------------------------------------------------------*/
6248 
6249 int float128_lt( float128 a, float128 b STATUS_PARAM )
6250 {
6251     flag aSign, bSign;
6252 
6253     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6254               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6255          || (    ( extractFloat128Exp( b ) == 0x7FFF )
6256               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6257        ) {
6258         float_raise( float_flag_invalid STATUS_VAR);
6259         return 0;
6260     }
6261     aSign = extractFloat128Sign( a );
6262     bSign = extractFloat128Sign( b );
6263     if ( aSign != bSign ) {
6264         return
6265                aSign
6266             && (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
6267                  != 0 );
6268     }
6269     return
6270           aSign ? lt128( b.high, b.low, a.high, a.low )
6271         : lt128( a.high, a.low, b.high, b.low );
6272 
6273 }
6274 
6275 /*----------------------------------------------------------------------------
6276 | Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
6277 | be compared, and 0 otherwise.  The invalid exception is raised if either
6278 | operand is a NaN. The comparison is performed according to the IEC/IEEE
6279 | Standard for Binary Floating-Point Arithmetic.
6280 *----------------------------------------------------------------------------*/
6281 
6282 int float128_unordered( float128 a, float128 b STATUS_PARAM )
6283 {
6284     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6285               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6286          || (    ( extractFloat128Exp( b ) == 0x7FFF )
6287               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6288        ) {
6289         float_raise( float_flag_invalid STATUS_VAR);
6290         return 1;
6291     }
6292     return 0;
6293 }
6294 
6295 /*----------------------------------------------------------------------------
6296 | Returns 1 if the quadruple-precision floating-point value `a' is equal to
6297 | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
6298 | exception.  The comparison is performed according to the IEC/IEEE Standard
6299 | for Binary Floating-Point Arithmetic.
6300 *----------------------------------------------------------------------------*/
6301 
6302 int float128_eq_quiet( float128 a, float128 b STATUS_PARAM )
6303 {
6304 
6305     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6306               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6307          || (    ( extractFloat128Exp( b ) == 0x7FFF )
6308               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6309        ) {
6310         if (    float128_is_signaling_nan( a )
6311              || float128_is_signaling_nan( b ) ) {
6312             float_raise( float_flag_invalid STATUS_VAR);
6313         }
6314         return 0;
6315     }
6316     return
6317            ( a.low == b.low )
6318         && (    ( a.high == b.high )
6319              || (    ( a.low == 0 )
6320                   && ( (uint64_t) ( ( a.high | b.high )<<1 ) == 0 ) )
6321            );
6322 
6323 }
6324 
6325 /*----------------------------------------------------------------------------
6326 | Returns 1 if the quadruple-precision floating-point value `a' is less than
6327 | or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
6328 | cause an exception.  Otherwise, the comparison is performed according to the
6329 | IEC/IEEE Standard for Binary Floating-Point Arithmetic.
6330 *----------------------------------------------------------------------------*/
6331 
6332 int float128_le_quiet( float128 a, float128 b STATUS_PARAM )
6333 {
6334     flag aSign, bSign;
6335 
6336     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6337               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6338          || (    ( extractFloat128Exp( b ) == 0x7FFF )
6339               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6340        ) {
6341         if (    float128_is_signaling_nan( a )
6342              || float128_is_signaling_nan( b ) ) {
6343             float_raise( float_flag_invalid STATUS_VAR);
6344         }
6345         return 0;
6346     }
6347     aSign = extractFloat128Sign( a );
6348     bSign = extractFloat128Sign( b );
6349     if ( aSign != bSign ) {
6350         return
6351                aSign
6352             || (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
6353                  == 0 );
6354     }
6355     return
6356           aSign ? le128( b.high, b.low, a.high, a.low )
6357         : le128( a.high, a.low, b.high, b.low );
6358 
6359 }
6360 
6361 /*----------------------------------------------------------------------------
6362 | Returns 1 if the quadruple-precision floating-point value `a' is less than
6363 | the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
6364 | exception.  Otherwise, the comparison is performed according to the IEC/IEEE
6365 | Standard for Binary Floating-Point Arithmetic.
6366 *----------------------------------------------------------------------------*/
6367 
6368 int float128_lt_quiet( float128 a, float128 b STATUS_PARAM )
6369 {
6370     flag aSign, bSign;
6371 
6372     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6373               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6374          || (    ( extractFloat128Exp( b ) == 0x7FFF )
6375               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6376        ) {
6377         if (    float128_is_signaling_nan( a )
6378              || float128_is_signaling_nan( b ) ) {
6379             float_raise( float_flag_invalid STATUS_VAR);
6380         }
6381         return 0;
6382     }
6383     aSign = extractFloat128Sign( a );
6384     bSign = extractFloat128Sign( b );
6385     if ( aSign != bSign ) {
6386         return
6387                aSign
6388             && (    ( ( (uint64_t) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
6389                  != 0 );
6390     }
6391     return
6392           aSign ? lt128( b.high, b.low, a.high, a.low )
6393         : lt128( a.high, a.low, b.high, b.low );
6394 
6395 }
6396 
6397 /*----------------------------------------------------------------------------
6398 | Returns 1 if the quadruple-precision floating-point values `a' and `b' cannot
6399 | be compared, and 0 otherwise.  Quiet NaNs do not cause an exception.  The
6400 | comparison is performed according to the IEC/IEEE Standard for Binary
6401 | Floating-Point Arithmetic.
6402 *----------------------------------------------------------------------------*/
6403 
6404 int float128_unordered_quiet( float128 a, float128 b STATUS_PARAM )
6405 {
6406     if (    (    ( extractFloat128Exp( a ) == 0x7FFF )
6407               && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) )
6408          || (    ( extractFloat128Exp( b ) == 0x7FFF )
6409               && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )
6410        ) {
6411         if (    float128_is_signaling_nan( a )
6412              || float128_is_signaling_nan( b ) ) {
6413             float_raise( float_flag_invalid STATUS_VAR);
6414         }
6415         return 1;
6416     }
6417     return 0;
6418 }
6419 
6420 /* misc functions */
6421 float32 uint32_to_float32( uint32 a STATUS_PARAM )
6422 {
6423     return int64_to_float32(a STATUS_VAR);
6424 }
6425 
6426 float64 uint32_to_float64( uint32 a STATUS_PARAM )
6427 {
6428     return int64_to_float64(a STATUS_VAR);
6429 }
6430 
6431 uint32 float32_to_uint32( float32 a STATUS_PARAM )
6432 {
6433     int64_t v;
6434     uint32 res;
6435 
6436     v = float32_to_int64(a STATUS_VAR);
6437     if (v < 0) {
6438         res = 0;
6439         float_raise( float_flag_invalid STATUS_VAR);
6440     } else if (v > 0xffffffff) {
6441         res = 0xffffffff;
6442         float_raise( float_flag_invalid STATUS_VAR);
6443     } else {
6444         res = v;
6445     }
6446     return res;
6447 }
6448 
6449 uint32 float32_to_uint32_round_to_zero( float32 a STATUS_PARAM )
6450 {
6451     int64_t v;
6452     uint32 res;
6453 
6454     v = float32_to_int64_round_to_zero(a STATUS_VAR);
6455     if (v < 0) {
6456         res = 0;
6457         float_raise( float_flag_invalid STATUS_VAR);
6458     } else if (v > 0xffffffff) {
6459         res = 0xffffffff;
6460         float_raise( float_flag_invalid STATUS_VAR);
6461     } else {
6462         res = v;
6463     }
6464     return res;
6465 }
6466 
6467 uint_fast16_t float32_to_uint16_round_to_zero(float32 a STATUS_PARAM)
6468 {
6469     int64_t v;
6470     uint_fast16_t res;
6471 
6472     v = float32_to_int64_round_to_zero(a STATUS_VAR);
6473     if (v < 0) {
6474         res = 0;
6475         float_raise( float_flag_invalid STATUS_VAR);
6476     } else if (v > 0xffff) {
6477         res = 0xffff;
6478         float_raise( float_flag_invalid STATUS_VAR);
6479     } else {
6480         res = v;
6481     }
6482     return res;
6483 }
6484 
6485 uint32 float64_to_uint32( float64 a STATUS_PARAM )
6486 {
6487     int64_t v;
6488     uint32 res;
6489 
6490     v = float64_to_int64(a STATUS_VAR);
6491     if (v < 0) {
6492         res = 0;
6493         float_raise( float_flag_invalid STATUS_VAR);
6494     } else if (v > 0xffffffff) {
6495         res = 0xffffffff;
6496         float_raise( float_flag_invalid STATUS_VAR);
6497     } else {
6498         res = v;
6499     }
6500     return res;
6501 }
6502 
6503 uint32 float64_to_uint32_round_to_zero( float64 a STATUS_PARAM )
6504 {
6505     int64_t v;
6506     uint32 res;
6507 
6508     v = float64_to_int64_round_to_zero(a STATUS_VAR);
6509     if (v < 0) {
6510         res = 0;
6511         float_raise( float_flag_invalid STATUS_VAR);
6512     } else if (v > 0xffffffff) {
6513         res = 0xffffffff;
6514         float_raise( float_flag_invalid STATUS_VAR);
6515     } else {
6516         res = v;
6517     }
6518     return res;
6519 }
6520 
6521 uint_fast16_t float64_to_uint16_round_to_zero(float64 a STATUS_PARAM)
6522 {
6523     int64_t v;
6524     uint_fast16_t res;
6525 
6526     v = float64_to_int64_round_to_zero(a STATUS_VAR);
6527     if (v < 0) {
6528         res = 0;
6529         float_raise( float_flag_invalid STATUS_VAR);
6530     } else if (v > 0xffff) {
6531         res = 0xffff;
6532         float_raise( float_flag_invalid STATUS_VAR);
6533     } else {
6534         res = v;
6535     }
6536     return res;
6537 }
6538 
6539 /* FIXME: This looks broken.  */
6540 uint64_t float64_to_uint64 (float64 a STATUS_PARAM)
6541 {
6542     int64_t v;
6543 
6544     v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
6545     v += float64_val(a);
6546     v = float64_to_int64(make_float64(v) STATUS_VAR);
6547 
6548     return v - INT64_MIN;
6549 }
6550 
6551 uint64_t float64_to_uint64_round_to_zero (float64 a STATUS_PARAM)
6552 {
6553     int64_t v;
6554 
6555     v = float64_val(int64_to_float64(INT64_MIN STATUS_VAR));
6556     v += float64_val(a);
6557     v = float64_to_int64_round_to_zero(make_float64(v) STATUS_VAR);
6558 
6559     return v - INT64_MIN;
6560 }
6561 
6562 #define COMPARE(s, nan_exp)                                                  \
6563 INLINE int float ## s ## _compare_internal( float ## s a, float ## s b,      \
6564                                       int is_quiet STATUS_PARAM )            \
6565 {                                                                            \
6566     flag aSign, bSign;                                                       \
6567     uint ## s ## _t av, bv;                                                  \
6568     a = float ## s ## _squash_input_denormal(a STATUS_VAR);                  \
6569     b = float ## s ## _squash_input_denormal(b STATUS_VAR);                  \
6570                                                                              \
6571     if (( ( extractFloat ## s ## Exp( a ) == nan_exp ) &&                    \
6572          extractFloat ## s ## Frac( a ) ) ||                                 \
6573         ( ( extractFloat ## s ## Exp( b ) == nan_exp ) &&                    \
6574           extractFloat ## s ## Frac( b ) )) {                                \
6575         if (!is_quiet ||                                                     \
6576             float ## s ## _is_signaling_nan( a ) ||                          \
6577             float ## s ## _is_signaling_nan( b ) ) {                         \
6578             float_raise( float_flag_invalid STATUS_VAR);                     \
6579         }                                                                    \
6580         return float_relation_unordered;                                     \
6581     }                                                                        \
6582     aSign = extractFloat ## s ## Sign( a );                                  \
6583     bSign = extractFloat ## s ## Sign( b );                                  \
6584     av = float ## s ## _val(a);                                              \
6585     bv = float ## s ## _val(b);                                              \
6586     if ( aSign != bSign ) {                                                  \
6587         if ( (uint ## s ## _t) ( ( av | bv )<<1 ) == 0 ) {                   \
6588             /* zero case */                                                  \
6589             return float_relation_equal;                                     \
6590         } else {                                                             \
6591             return 1 - (2 * aSign);                                          \
6592         }                                                                    \
6593     } else {                                                                 \
6594         if (av == bv) {                                                      \
6595             return float_relation_equal;                                     \
6596         } else {                                                             \
6597             return 1 - 2 * (aSign ^ ( av < bv ));                            \
6598         }                                                                    \
6599     }                                                                        \
6600 }                                                                            \
6601                                                                              \
6602 int float ## s ## _compare( float ## s a, float ## s b STATUS_PARAM )        \
6603 {                                                                            \
6604     return float ## s ## _compare_internal(a, b, 0 STATUS_VAR);              \
6605 }                                                                            \
6606                                                                              \
6607 int float ## s ## _compare_quiet( float ## s a, float ## s b STATUS_PARAM )  \
6608 {                                                                            \
6609     return float ## s ## _compare_internal(a, b, 1 STATUS_VAR);              \
6610 }
6611 
6612 COMPARE(32, 0xff)
6613 COMPARE(64, 0x7ff)
6614 
6615 INLINE int floatx80_compare_internal( floatx80 a, floatx80 b,
6616                                       int is_quiet STATUS_PARAM )
6617 {
6618     flag aSign, bSign;
6619 
6620     if (( ( extractFloatx80Exp( a ) == 0x7fff ) &&
6621           ( extractFloatx80Frac( a )<<1 ) ) ||
6622         ( ( extractFloatx80Exp( b ) == 0x7fff ) &&
6623           ( extractFloatx80Frac( b )<<1 ) )) {
6624         if (!is_quiet ||
6625             floatx80_is_signaling_nan( a ) ||
6626             floatx80_is_signaling_nan( b ) ) {
6627             float_raise( float_flag_invalid STATUS_VAR);
6628         }
6629         return float_relation_unordered;
6630     }
6631     aSign = extractFloatx80Sign( a );
6632     bSign = extractFloatx80Sign( b );
6633     if ( aSign != bSign ) {
6634 
6635         if ( ( ( (uint16_t) ( ( a.high | b.high ) << 1 ) ) == 0) &&
6636              ( ( a.low | b.low ) == 0 ) ) {
6637             /* zero case */
6638             return float_relation_equal;
6639         } else {
6640             return 1 - (2 * aSign);
6641         }
6642     } else {
6643         if (a.low == b.low && a.high == b.high) {
6644             return float_relation_equal;
6645         } else {
6646             return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
6647         }
6648     }
6649 }
6650 
6651 int floatx80_compare( floatx80 a, floatx80 b STATUS_PARAM )
6652 {
6653     return floatx80_compare_internal(a, b, 0 STATUS_VAR);
6654 }
6655 
6656 int floatx80_compare_quiet( floatx80 a, floatx80 b STATUS_PARAM )
6657 {
6658     return floatx80_compare_internal(a, b, 1 STATUS_VAR);
6659 }
6660 
6661 INLINE int float128_compare_internal( float128 a, float128 b,
6662                                       int is_quiet STATUS_PARAM )
6663 {
6664     flag aSign, bSign;
6665 
6666     if (( ( extractFloat128Exp( a ) == 0x7fff ) &&
6667           ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ||
6668         ( ( extractFloat128Exp( b ) == 0x7fff ) &&
6669           ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) )) {
6670         if (!is_quiet ||
6671             float128_is_signaling_nan( a ) ||
6672             float128_is_signaling_nan( b ) ) {
6673             float_raise( float_flag_invalid STATUS_VAR);
6674         }
6675         return float_relation_unordered;
6676     }
6677     aSign = extractFloat128Sign( a );
6678     bSign = extractFloat128Sign( b );
6679     if ( aSign != bSign ) {
6680         if ( ( ( ( a.high | b.high )<<1 ) | a.low | b.low ) == 0 ) {
6681             /* zero case */
6682             return float_relation_equal;
6683         } else {
6684             return 1 - (2 * aSign);
6685         }
6686     } else {
6687         if (a.low == b.low && a.high == b.high) {
6688             return float_relation_equal;
6689         } else {
6690             return 1 - 2 * (aSign ^ ( lt128( a.high, a.low, b.high, b.low ) ));
6691         }
6692     }
6693 }
6694 
6695 int float128_compare( float128 a, float128 b STATUS_PARAM )
6696 {
6697     return float128_compare_internal(a, b, 0 STATUS_VAR);
6698 }
6699 
6700 int float128_compare_quiet( float128 a, float128 b STATUS_PARAM )
6701 {
6702     return float128_compare_internal(a, b, 1 STATUS_VAR);
6703 }
6704 
6705 /* min() and max() functions. These can't be implemented as
6706  * 'compare and pick one input' because that would mishandle
6707  * NaNs and +0 vs -0.
6708  */
6709 #define MINMAX(s, nan_exp)                                              \
6710 INLINE float ## s float ## s ## _minmax(float ## s a, float ## s b,     \
6711                                         int ismin STATUS_PARAM )        \
6712 {                                                                       \
6713     flag aSign, bSign;                                                  \
6714     uint ## s ## _t av, bv;                                             \
6715     a = float ## s ## _squash_input_denormal(a STATUS_VAR);             \
6716     b = float ## s ## _squash_input_denormal(b STATUS_VAR);             \
6717     if (float ## s ## _is_any_nan(a) ||                                 \
6718         float ## s ## _is_any_nan(b)) {                                 \
6719         return propagateFloat ## s ## NaN(a, b STATUS_VAR);             \
6720     }                                                                   \
6721     aSign = extractFloat ## s ## Sign(a);                               \
6722     bSign = extractFloat ## s ## Sign(b);                               \
6723     av = float ## s ## _val(a);                                         \
6724     bv = float ## s ## _val(b);                                         \
6725     if (aSign != bSign) {                                               \
6726         if (ismin) {                                                    \
6727             return aSign ? a : b;                                       \
6728         } else {                                                        \
6729             return aSign ? b : a;                                       \
6730         }                                                               \
6731     } else {                                                            \
6732         if (ismin) {                                                    \
6733             return (aSign ^ (av < bv)) ? a : b;                         \
6734         } else {                                                        \
6735             return (aSign ^ (av < bv)) ? b : a;                         \
6736         }                                                               \
6737     }                                                                   \
6738 }                                                                       \
6739                                                                         \
6740 float ## s float ## s ## _min(float ## s a, float ## s b STATUS_PARAM)  \
6741 {                                                                       \
6742     return float ## s ## _minmax(a, b, 1 STATUS_VAR);                   \
6743 }                                                                       \
6744                                                                         \
6745 float ## s float ## s ## _max(float ## s a, float ## s b STATUS_PARAM)  \
6746 {                                                                       \
6747     return float ## s ## _minmax(a, b, 0 STATUS_VAR);                   \
6748 }
6749 
6750 MINMAX(32, 0xff)
6751 MINMAX(64, 0x7ff)
6752 
6753 
6754 /* Multiply A by 2 raised to the power N.  */
6755 float32 float32_scalbn( float32 a, int n STATUS_PARAM )
6756 {
6757     flag aSign;
6758     int16_t aExp;
6759     uint32_t aSig;
6760 
6761     a = float32_squash_input_denormal(a STATUS_VAR);
6762     aSig = extractFloat32Frac( a );
6763     aExp = extractFloat32Exp( a );
6764     aSign = extractFloat32Sign( a );
6765 
6766     if ( aExp == 0xFF ) {
6767         if ( aSig ) {
6768             return propagateFloat32NaN( a, a STATUS_VAR );
6769         }
6770         return a;
6771     }
6772     if ( aExp != 0 )
6773         aSig |= 0x00800000;
6774     else if ( aSig == 0 )
6775         return a;
6776 
6777     if (n > 0x200) {
6778         n = 0x200;
6779     } else if (n < -0x200) {
6780         n = -0x200;
6781     }
6782 
6783     aExp += n - 1;
6784     aSig <<= 7;
6785     return normalizeRoundAndPackFloat32( aSign, aExp, aSig STATUS_VAR );
6786 }
6787 
6788 float64 float64_scalbn( float64 a, int n STATUS_PARAM )
6789 {
6790     flag aSign;
6791     int16_t aExp;
6792     uint64_t aSig;
6793 
6794     a = float64_squash_input_denormal(a STATUS_VAR);
6795     aSig = extractFloat64Frac( a );
6796     aExp = extractFloat64Exp( a );
6797     aSign = extractFloat64Sign( a );
6798 
6799     if ( aExp == 0x7FF ) {
6800         if ( aSig ) {
6801             return propagateFloat64NaN( a, a STATUS_VAR );
6802         }
6803         return a;
6804     }
6805     if ( aExp != 0 )
6806         aSig |= LIT64( 0x0010000000000000 );
6807     else if ( aSig == 0 )
6808         return a;
6809 
6810     if (n > 0x1000) {
6811         n = 0x1000;
6812     } else if (n < -0x1000) {
6813         n = -0x1000;
6814     }
6815 
6816     aExp += n - 1;
6817     aSig <<= 10;
6818     return normalizeRoundAndPackFloat64( aSign, aExp, aSig STATUS_VAR );
6819 }
6820 
6821 floatx80 floatx80_scalbn( floatx80 a, int n STATUS_PARAM )
6822 {
6823     flag aSign;
6824     int32_t aExp;
6825     uint64_t aSig;
6826 
6827     aSig = extractFloatx80Frac( a );
6828     aExp = extractFloatx80Exp( a );
6829     aSign = extractFloatx80Sign( a );
6830 
6831     if ( aExp == 0x7FFF ) {
6832         if ( aSig<<1 ) {
6833             return propagateFloatx80NaN( a, a STATUS_VAR );
6834         }
6835         return a;
6836     }
6837 
6838     if (aExp == 0 && aSig == 0)
6839         return a;
6840 
6841     if (n > 0x10000) {
6842         n = 0x10000;
6843     } else if (n < -0x10000) {
6844         n = -0x10000;
6845     }
6846 
6847     aExp += n;
6848     return normalizeRoundAndPackFloatx80( STATUS(floatx80_rounding_precision),
6849                                           aSign, aExp, aSig, 0 STATUS_VAR );
6850 }
6851 
6852 float128 float128_scalbn( float128 a, int n STATUS_PARAM )
6853 {
6854     flag aSign;
6855     int32_t aExp;
6856     uint64_t aSig0, aSig1;
6857 
6858     aSig1 = extractFloat128Frac1( a );
6859     aSig0 = extractFloat128Frac0( a );
6860     aExp = extractFloat128Exp( a );
6861     aSign = extractFloat128Sign( a );
6862     if ( aExp == 0x7FFF ) {
6863         if ( aSig0 | aSig1 ) {
6864             return propagateFloat128NaN( a, a STATUS_VAR );
6865         }
6866         return a;
6867     }
6868     if ( aExp != 0 )
6869         aSig0 |= LIT64( 0x0001000000000000 );
6870     else if ( aSig0 == 0 && aSig1 == 0 )
6871         return a;
6872 
6873     if (n > 0x10000) {
6874         n = 0x10000;
6875     } else if (n < -0x10000) {
6876         n = -0x10000;
6877     }
6878 
6879     aExp += n - 1;
6880     return normalizeRoundAndPackFloat128( aSign, aExp, aSig0, aSig1
6881                                           STATUS_VAR );
6882 
6883 }
6884