Merge /spare/repo/linux-2.6/
[sfrench/cifs-2.6.git] / arch / arm / nwfpe / softfloat.c
1 /*
2 ===============================================================================
3
4 This C source file is part of the SoftFloat IEC/IEEE Floating-point
5 Arithmetic Package, Release 2.
6
7 Written by John R. Hauser.  This work was made possible in part by the
8 International Computer Science Institute, located at Suite 600, 1947 Center
9 Street, Berkeley, California 94704.  Funding was partially provided by the
10 National Science Foundation under grant MIP-9311980.  The original version
11 of this code was written as part of a project to build a fixed-point vector
12 processor in collaboration with the University of California at Berkeley,
13 overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
14 is available through the web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
15 arithmetic/softfloat.html'.
16
17 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
18 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
19 TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
20 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
21 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
22
23 Derivative works are acceptable, even for commercial purposes, so long as
24 (1) they include prominent notice that the work is derivative, and (2) they
25 include prominent notice akin to these three paragraphs for those parts of
26 this code that are retained.
27
28 ===============================================================================
29 */
30
31 #include <asm/div64.h>
32
33 #include "fpa11.h"
34 //#include "milieu.h"
35 //#include "softfloat.h"
36
37 /*
38 -------------------------------------------------------------------------------
39 Primitive arithmetic functions, including multi-word arithmetic, and
40 division and square root approximations.  (Can be specialized to target if
41 desired.)
42 -------------------------------------------------------------------------------
43 */
44 #include "softfloat-macros"
45
46 /*
47 -------------------------------------------------------------------------------
48 Functions and definitions to determine:  (1) whether tininess for underflow
49 is detected before or after rounding by default, (2) what (if anything)
50 happens when exceptions are raised, (3) how signaling NaNs are distinguished
51 from quiet NaNs, (4) the default generated quiet NaNs, and (5) how NaNs
52 are propagated from function inputs to output.  These details are target-
53 specific.
54 -------------------------------------------------------------------------------
55 */
56 #include "softfloat-specialize"
57
58 /*
59 -------------------------------------------------------------------------------
60 Takes a 64-bit fixed-point value `absZ' with binary point between bits 6
61 and 7, and returns the properly rounded 32-bit integer corresponding to the
62 input.  If `zSign' is nonzero, the input is negated before being converted
63 to an integer.  Bit 63 of `absZ' must be zero.  Ordinarily, the fixed-point
64 input is simply rounded to an integer, with the inexact exception raised if
65 the input cannot be represented exactly as an integer.  If the fixed-point
66 input is too large, however, the invalid exception is raised and the largest
67 positive or negative integer is returned.
68 -------------------------------------------------------------------------------
69 */
70 static int32 roundAndPackInt32( struct roundingData *roundData, flag zSign, bits64 absZ )
71 {
72     int8 roundingMode;
73     flag roundNearestEven;
74     int8 roundIncrement, roundBits;
75     int32 z;
76
77     roundingMode = roundData->mode;
78     roundNearestEven = ( roundingMode == float_round_nearest_even );
79     roundIncrement = 0x40;
80     if ( ! roundNearestEven ) {
81         if ( roundingMode == float_round_to_zero ) {
82             roundIncrement = 0;
83         }
84         else {
85             roundIncrement = 0x7F;
86             if ( zSign ) {
87                 if ( roundingMode == float_round_up ) roundIncrement = 0;
88             }
89             else {
90                 if ( roundingMode == float_round_down ) roundIncrement = 0;
91             }
92         }
93     }
94     roundBits = absZ & 0x7F;
95     absZ = ( absZ + roundIncrement )>>7;
96     absZ &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
97     z = absZ;
98     if ( zSign ) z = - z;
99     if ( ( absZ>>32 ) || ( z && ( ( z < 0 ) ^ zSign ) ) ) {
100         roundData->exception |= float_flag_invalid;
101         return zSign ? 0x80000000 : 0x7FFFFFFF;
102     }
103     if ( roundBits ) roundData->exception |= float_flag_inexact;
104     return z;
105
106 }
107
108 /*
109 -------------------------------------------------------------------------------
110 Returns the fraction bits of the single-precision floating-point value `a'.
111 -------------------------------------------------------------------------------
112 */
113 INLINE bits32 extractFloat32Frac( float32 a )
114 {
115
116     return a & 0x007FFFFF;
117
118 }
119
120 /*
121 -------------------------------------------------------------------------------
122 Returns the exponent bits of the single-precision floating-point value `a'.
123 -------------------------------------------------------------------------------
124 */
125 INLINE int16 extractFloat32Exp( float32 a )
126 {
127
128     return ( a>>23 ) & 0xFF;
129
130 }
131
132 /*
133 -------------------------------------------------------------------------------
134 Returns the sign bit of the single-precision floating-point value `a'.
135 -------------------------------------------------------------------------------
136 */
137 #if 0   /* in softfloat.h */
138 INLINE flag extractFloat32Sign( float32 a )
139 {
140
141     return a>>31;
142
143 }
144 #endif
145
146 /*
147 -------------------------------------------------------------------------------
148 Normalizes the subnormal single-precision floating-point value represented
149 by the denormalized significand `aSig'.  The normalized exponent and
150 significand are stored at the locations pointed to by `zExpPtr' and
151 `zSigPtr', respectively.
152 -------------------------------------------------------------------------------
153 */
154 static void
155  normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
156 {
157     int8 shiftCount;
158
159     shiftCount = countLeadingZeros32( aSig ) - 8;
160     *zSigPtr = aSig<<shiftCount;
161     *zExpPtr = 1 - shiftCount;
162
163 }
164
165 /*
166 -------------------------------------------------------------------------------
167 Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
168 single-precision floating-point value, returning the result.  After being
169 shifted into the proper positions, the three fields are simply added
170 together to form the result.  This means that any integer portion of `zSig'
171 will be added into the exponent.  Since a properly normalized significand
172 will have an integer portion equal to 1, the `zExp' input should be 1 less
173 than the desired result exponent whenever `zSig' is a complete, normalized
174 significand.
175 -------------------------------------------------------------------------------
176 */
177 INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
178 {
179 #if 0
180    float32 f;
181    __asm__("@ packFloat32                               \n\
182             mov %0, %1, asl #31                         \n\
183             orr %0, %2, asl #23                         \n\
184             orr %0, %3"
185             : /* no outputs */
186             : "g" (f), "g" (zSign), "g" (zExp), "g" (zSig)
187             : "cc");
188    return f;
189 #else
190     return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
191 #endif 
192 }
193
194 /*
195 -------------------------------------------------------------------------------
196 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
197 and significand `zSig', and returns the proper single-precision floating-
198 point value corresponding to the abstract input.  Ordinarily, the abstract
199 value is simply rounded and packed into the single-precision format, with
200 the inexact exception raised if the abstract input cannot be represented
201 exactly.  If the abstract value is too large, however, the overflow and
202 inexact exceptions are raised and an infinity or maximal finite value is
203 returned.  If the abstract value is too small, the input value is rounded to
204 a subnormal number, and the underflow and inexact exceptions are raised if
205 the abstract input cannot be represented exactly as a subnormal single-
206 precision floating-point number.
207     The input significand `zSig' has its binary point between bits 30
208 and 29, which is 7 bits to the left of the usual location.  This shifted
209 significand must be normalized or smaller.  If `zSig' is not normalized,
210 `zExp' must be 0; in that case, the result returned is a subnormal number,
211 and it must not require rounding.  In the usual case that `zSig' is
212 normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
213 The handling of underflow and overflow follows the IEC/IEEE Standard for
214 Binary Floating-point Arithmetic.
215 -------------------------------------------------------------------------------
216 */
217 static float32 roundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
218 {
219     int8 roundingMode;
220     flag roundNearestEven;
221     int8 roundIncrement, roundBits;
222     flag isTiny;
223
224     roundingMode = roundData->mode;
225     roundNearestEven = ( roundingMode == float_round_nearest_even );
226     roundIncrement = 0x40;
227     if ( ! roundNearestEven ) {
228         if ( roundingMode == float_round_to_zero ) {
229             roundIncrement = 0;
230         }
231         else {
232             roundIncrement = 0x7F;
233             if ( zSign ) {
234                 if ( roundingMode == float_round_up ) roundIncrement = 0;
235             }
236             else {
237                 if ( roundingMode == float_round_down ) roundIncrement = 0;
238             }
239         }
240     }
241     roundBits = zSig & 0x7F;
242     if ( 0xFD <= (bits16) zExp ) {
243         if (    ( 0xFD < zExp )
244              || (    ( zExp == 0xFD )
245                   && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
246            ) {
247             roundData->exception |= float_flag_overflow | float_flag_inexact;
248             return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
249         }
250         if ( zExp < 0 ) {
251             isTiny =
252                    ( float_detect_tininess == float_tininess_before_rounding )
253                 || ( zExp < -1 )
254                 || ( zSig + roundIncrement < 0x80000000 );
255             shift32RightJamming( zSig, - zExp, &zSig );
256             zExp = 0;
257             roundBits = zSig & 0x7F;
258             if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
259         }
260     }
261     if ( roundBits ) roundData->exception |= float_flag_inexact;
262     zSig = ( zSig + roundIncrement )>>7;
263     zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
264     if ( zSig == 0 ) zExp = 0;
265     return packFloat32( zSign, zExp, zSig );
266
267 }
268
269 /*
270 -------------------------------------------------------------------------------
271 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
272 and significand `zSig', and returns the proper single-precision floating-
273 point value corresponding to the abstract input.  This routine is just like
274 `roundAndPackFloat32' except that `zSig' does not have to be normalized in
275 any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
276 point exponent.
277 -------------------------------------------------------------------------------
278 */
279 static float32
280  normalizeRoundAndPackFloat32( struct roundingData *roundData, flag zSign, int16 zExp, bits32 zSig )
281 {
282     int8 shiftCount;
283
284     shiftCount = countLeadingZeros32( zSig ) - 1;
285     return roundAndPackFloat32( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
286
287 }
288
289 /*
290 -------------------------------------------------------------------------------
291 Returns the fraction bits of the double-precision floating-point value `a'.
292 -------------------------------------------------------------------------------
293 */
294 INLINE bits64 extractFloat64Frac( float64 a )
295 {
296
297     return a & LIT64( 0x000FFFFFFFFFFFFF );
298
299 }
300
301 /*
302 -------------------------------------------------------------------------------
303 Returns the exponent bits of the double-precision floating-point value `a'.
304 -------------------------------------------------------------------------------
305 */
306 INLINE int16 extractFloat64Exp( float64 a )
307 {
308
309     return ( a>>52 ) & 0x7FF;
310
311 }
312
313 /*
314 -------------------------------------------------------------------------------
315 Returns the sign bit of the double-precision floating-point value `a'.
316 -------------------------------------------------------------------------------
317 */
318 #if 0   /* in softfloat.h */
319 INLINE flag extractFloat64Sign( float64 a )
320 {
321
322     return a>>63;
323
324 }
325 #endif
326
327 /*
328 -------------------------------------------------------------------------------
329 Normalizes the subnormal double-precision floating-point value represented
330 by the denormalized significand `aSig'.  The normalized exponent and
331 significand are stored at the locations pointed to by `zExpPtr' and
332 `zSigPtr', respectively.
333 -------------------------------------------------------------------------------
334 */
335 static void
336  normalizeFloat64Subnormal( bits64 aSig, int16 *zExpPtr, bits64 *zSigPtr )
337 {
338     int8 shiftCount;
339
340     shiftCount = countLeadingZeros64( aSig ) - 11;
341     *zSigPtr = aSig<<shiftCount;
342     *zExpPtr = 1 - shiftCount;
343
344 }
345
346 /*
347 -------------------------------------------------------------------------------
348 Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
349 double-precision floating-point value, returning the result.  After being
350 shifted into the proper positions, the three fields are simply added
351 together to form the result.  This means that any integer portion of `zSig'
352 will be added into the exponent.  Since a properly normalized significand
353 will have an integer portion equal to 1, the `zExp' input should be 1 less
354 than the desired result exponent whenever `zSig' is a complete, normalized
355 significand.
356 -------------------------------------------------------------------------------
357 */
358 INLINE float64 packFloat64( flag zSign, int16 zExp, bits64 zSig )
359 {
360
361     return ( ( (bits64) zSign )<<63 ) + ( ( (bits64) zExp )<<52 ) + zSig;
362
363 }
364
365 /*
366 -------------------------------------------------------------------------------
367 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
368 and significand `zSig', and returns the proper double-precision floating-
369 point value corresponding to the abstract input.  Ordinarily, the abstract
370 value is simply rounded and packed into the double-precision format, with
371 the inexact exception raised if the abstract input cannot be represented
372 exactly.  If the abstract value is too large, however, the overflow and
373 inexact exceptions are raised and an infinity or maximal finite value is
374 returned.  If the abstract value is too small, the input value is rounded to
375 a subnormal number, and the underflow and inexact exceptions are raised if
376 the abstract input cannot be represented exactly as a subnormal double-
377 precision floating-point number.
378     The input significand `zSig' has its binary point between bits 62
379 and 61, which is 10 bits to the left of the usual location.  This shifted
380 significand must be normalized or smaller.  If `zSig' is not normalized,
381 `zExp' must be 0; in that case, the result returned is a subnormal number,
382 and it must not require rounding.  In the usual case that `zSig' is
383 normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
384 The handling of underflow and overflow follows the IEC/IEEE Standard for
385 Binary Floating-point Arithmetic.
386 -------------------------------------------------------------------------------
387 */
388 static float64 roundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
389 {
390     int8 roundingMode;
391     flag roundNearestEven;
392     int16 roundIncrement, roundBits;
393     flag isTiny;
394
395     roundingMode = roundData->mode;
396     roundNearestEven = ( roundingMode == float_round_nearest_even );
397     roundIncrement = 0x200;
398     if ( ! roundNearestEven ) {
399         if ( roundingMode == float_round_to_zero ) {
400             roundIncrement = 0;
401         }
402         else {
403             roundIncrement = 0x3FF;
404             if ( zSign ) {
405                 if ( roundingMode == float_round_up ) roundIncrement = 0;
406             }
407             else {
408                 if ( roundingMode == float_round_down ) roundIncrement = 0;
409             }
410         }
411     }
412     roundBits = zSig & 0x3FF;
413     if ( 0x7FD <= (bits16) zExp ) {
414         if (    ( 0x7FD < zExp )
415              || (    ( zExp == 0x7FD )
416                   && ( (sbits64) ( zSig + roundIncrement ) < 0 ) )
417            ) {
418             //register int lr = __builtin_return_address(0);
419             //printk("roundAndPackFloat64 called from 0x%08x\n",lr);
420             roundData->exception |= float_flag_overflow | float_flag_inexact;
421             return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 );
422         }
423         if ( zExp < 0 ) {
424             isTiny =
425                    ( float_detect_tininess == float_tininess_before_rounding )
426                 || ( zExp < -1 )
427                 || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) );
428             shift64RightJamming( zSig, - zExp, &zSig );
429             zExp = 0;
430             roundBits = zSig & 0x3FF;
431             if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
432         }
433     }
434     if ( roundBits ) roundData->exception |= float_flag_inexact;
435     zSig = ( zSig + roundIncrement )>>10;
436     zSig &= ~ ( ( ( roundBits ^ 0x200 ) == 0 ) & roundNearestEven );
437     if ( zSig == 0 ) zExp = 0;
438     return packFloat64( zSign, zExp, zSig );
439
440 }
441
442 /*
443 -------------------------------------------------------------------------------
444 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
445 and significand `zSig', and returns the proper double-precision floating-
446 point value corresponding to the abstract input.  This routine is just like
447 `roundAndPackFloat64' except that `zSig' does not have to be normalized in
448 any way.  In all cases, `zExp' must be 1 less than the ``true'' floating-
449 point exponent.
450 -------------------------------------------------------------------------------
451 */
452 static float64
453  normalizeRoundAndPackFloat64( struct roundingData *roundData, flag zSign, int16 zExp, bits64 zSig )
454 {
455     int8 shiftCount;
456
457     shiftCount = countLeadingZeros64( zSig ) - 1;
458     return roundAndPackFloat64( roundData, zSign, zExp - shiftCount, zSig<<shiftCount );
459
460 }
461
462 #ifdef FLOATX80
463
464 /*
465 -------------------------------------------------------------------------------
466 Returns the fraction bits of the extended double-precision floating-point
467 value `a'.
468 -------------------------------------------------------------------------------
469 */
470 INLINE bits64 extractFloatx80Frac( floatx80 a )
471 {
472
473     return a.low;
474
475 }
476
477 /*
478 -------------------------------------------------------------------------------
479 Returns the exponent bits of the extended double-precision floating-point
480 value `a'.
481 -------------------------------------------------------------------------------
482 */
483 INLINE int32 extractFloatx80Exp( floatx80 a )
484 {
485
486     return a.high & 0x7FFF;
487
488 }
489
490 /*
491 -------------------------------------------------------------------------------
492 Returns the sign bit of the extended double-precision floating-point value
493 `a'.
494 -------------------------------------------------------------------------------
495 */
496 INLINE flag extractFloatx80Sign( floatx80 a )
497 {
498
499     return a.high>>15;
500
501 }
502
503 /*
504 -------------------------------------------------------------------------------
505 Normalizes the subnormal extended double-precision floating-point value
506 represented by the denormalized significand `aSig'.  The normalized exponent
507 and significand are stored at the locations pointed to by `zExpPtr' and
508 `zSigPtr', respectively.
509 -------------------------------------------------------------------------------
510 */
511 static void
512  normalizeFloatx80Subnormal( bits64 aSig, int32 *zExpPtr, bits64 *zSigPtr )
513 {
514     int8 shiftCount;
515
516     shiftCount = countLeadingZeros64( aSig );
517     *zSigPtr = aSig<<shiftCount;
518     *zExpPtr = 1 - shiftCount;
519
520 }
521
522 /*
523 -------------------------------------------------------------------------------
524 Packs the sign `zSign', exponent `zExp', and significand `zSig' into an
525 extended double-precision floating-point value, returning the result.
526 -------------------------------------------------------------------------------
527 */
528 INLINE floatx80 packFloatx80( flag zSign, int32 zExp, bits64 zSig )
529 {
530     floatx80 z;
531
532     z.low = zSig;
533     z.high = ( ( (bits16) zSign )<<15 ) + zExp;
534     return z;
535
536 }
537
538 /*
539 -------------------------------------------------------------------------------
540 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
541 and extended significand formed by the concatenation of `zSig0' and `zSig1',
542 and returns the proper extended double-precision floating-point value
543 corresponding to the abstract input.  Ordinarily, the abstract value is
544 rounded and packed into the extended double-precision format, with the
545 inexact exception raised if the abstract input cannot be represented
546 exactly.  If the abstract value is too large, however, the overflow and
547 inexact exceptions are raised and an infinity or maximal finite value is
548 returned.  If the abstract value is too small, the input value is rounded to
549 a subnormal number, and the underflow and inexact exceptions are raised if
550 the abstract input cannot be represented exactly as a subnormal extended
551 double-precision floating-point number.
552     If `roundingPrecision' is 32 or 64, the result is rounded to the same
553 number of bits as single or double precision, respectively.  Otherwise, the
554 result is rounded to the full precision of the extended double-precision
555 format.
556     The input significand must be normalized or smaller.  If the input
557 significand is not normalized, `zExp' must be 0; in that case, the result
558 returned is a subnormal number, and it must not require rounding.  The
559 handling of underflow and overflow follows the IEC/IEEE Standard for Binary
560 Floating-point Arithmetic.
561 -------------------------------------------------------------------------------
562 */
563 static floatx80
564  roundAndPackFloatx80(
565      struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
566  )
567 {
568     int8 roundingMode, roundingPrecision;
569     flag roundNearestEven, increment, isTiny;
570     int64 roundIncrement, roundMask, roundBits;
571
572     roundingMode = roundData->mode;
573     roundingPrecision = roundData->precision;
574     roundNearestEven = ( roundingMode == float_round_nearest_even );
575     if ( roundingPrecision == 80 ) goto precision80;
576     if ( roundingPrecision == 64 ) {
577         roundIncrement = LIT64( 0x0000000000000400 );
578         roundMask = LIT64( 0x00000000000007FF );
579     }
580     else if ( roundingPrecision == 32 ) {
581         roundIncrement = LIT64( 0x0000008000000000 );
582         roundMask = LIT64( 0x000000FFFFFFFFFF );
583     }
584     else {
585         goto precision80;
586     }
587     zSig0 |= ( zSig1 != 0 );
588     if ( ! roundNearestEven ) {
589         if ( roundingMode == float_round_to_zero ) {
590             roundIncrement = 0;
591         }
592         else {
593             roundIncrement = roundMask;
594             if ( zSign ) {
595                 if ( roundingMode == float_round_up ) roundIncrement = 0;
596             }
597             else {
598                 if ( roundingMode == float_round_down ) roundIncrement = 0;
599             }
600         }
601     }
602     roundBits = zSig0 & roundMask;
603     if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
604         if (    ( 0x7FFE < zExp )
605              || ( ( zExp == 0x7FFE ) && ( zSig0 + roundIncrement < zSig0 ) )
606            ) {
607             goto overflow;
608         }
609         if ( zExp <= 0 ) {
610             isTiny =
611                    ( float_detect_tininess == float_tininess_before_rounding )
612                 || ( zExp < 0 )
613                 || ( zSig0 <= zSig0 + roundIncrement );
614             shift64RightJamming( zSig0, 1 - zExp, &zSig0 );
615             zExp = 0;
616             roundBits = zSig0 & roundMask;
617             if ( isTiny && roundBits ) roundData->exception |= float_flag_underflow;
618             if ( roundBits ) roundData->exception |= float_flag_inexact;
619             zSig0 += roundIncrement;
620             if ( (sbits64) zSig0 < 0 ) zExp = 1;
621             roundIncrement = roundMask + 1;
622             if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
623                 roundMask |= roundIncrement;
624             }
625             zSig0 &= ~ roundMask;
626             return packFloatx80( zSign, zExp, zSig0 );
627         }
628     }
629     if ( roundBits ) roundData->exception |= float_flag_inexact;
630     zSig0 += roundIncrement;
631     if ( zSig0 < roundIncrement ) {
632         ++zExp;
633         zSig0 = LIT64( 0x8000000000000000 );
634     }
635     roundIncrement = roundMask + 1;
636     if ( roundNearestEven && ( roundBits<<1 == roundIncrement ) ) {
637         roundMask |= roundIncrement;
638     }
639     zSig0 &= ~ roundMask;
640     if ( zSig0 == 0 ) zExp = 0;
641     return packFloatx80( zSign, zExp, zSig0 );
642  precision80:
643     increment = ( (sbits64) zSig1 < 0 );
644     if ( ! roundNearestEven ) {
645         if ( roundingMode == float_round_to_zero ) {
646             increment = 0;
647         }
648         else {
649             if ( zSign ) {
650                 increment = ( roundingMode == float_round_down ) && zSig1;
651             }
652             else {
653                 increment = ( roundingMode == float_round_up ) && zSig1;
654             }
655         }
656     }
657     if ( 0x7FFD <= (bits32) ( zExp - 1 ) ) {
658         if (    ( 0x7FFE < zExp )
659              || (    ( zExp == 0x7FFE )
660                   && ( zSig0 == LIT64( 0xFFFFFFFFFFFFFFFF ) )
661                   && increment
662                 )
663            ) {
664             roundMask = 0;
665  overflow:
666             roundData->exception |= float_flag_overflow | float_flag_inexact;
667             if (    ( roundingMode == float_round_to_zero )
668                  || ( zSign && ( roundingMode == float_round_up ) )
669                  || ( ! zSign && ( roundingMode == float_round_down ) )
670                ) {
671                 return packFloatx80( zSign, 0x7FFE, ~ roundMask );
672             }
673             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
674         }
675         if ( zExp <= 0 ) {
676             isTiny =
677                    ( float_detect_tininess == float_tininess_before_rounding )
678                 || ( zExp < 0 )
679                 || ! increment
680                 || ( zSig0 < LIT64( 0xFFFFFFFFFFFFFFFF ) );
681             shift64ExtraRightJamming( zSig0, zSig1, 1 - zExp, &zSig0, &zSig1 );
682             zExp = 0;
683             if ( isTiny && zSig1 ) roundData->exception |= float_flag_underflow;
684             if ( zSig1 ) roundData->exception |= float_flag_inexact;
685             if ( roundNearestEven ) {
686                 increment = ( (sbits64) zSig1 < 0 );
687             }
688             else {
689                 if ( zSign ) {
690                     increment = ( roundingMode == float_round_down ) && zSig1;
691                 }
692                 else {
693                     increment = ( roundingMode == float_round_up ) && zSig1;
694                 }
695             }
696             if ( increment ) {
697                 ++zSig0;
698                 zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
699                 if ( (sbits64) zSig0 < 0 ) zExp = 1;
700             }
701             return packFloatx80( zSign, zExp, zSig0 );
702         }
703     }
704     if ( zSig1 ) roundData->exception |= float_flag_inexact;
705     if ( increment ) {
706         ++zSig0;
707         if ( zSig0 == 0 ) {
708             ++zExp;
709             zSig0 = LIT64( 0x8000000000000000 );
710         }
711         else {
712             zSig0 &= ~ ( ( zSig1 + zSig1 == 0 ) & roundNearestEven );
713         }
714     }
715     else {
716         if ( zSig0 == 0 ) zExp = 0;
717     }
718     
719     return packFloatx80( zSign, zExp, zSig0 );
720 }
721
722 /*
723 -------------------------------------------------------------------------------
724 Takes an abstract floating-point value having sign `zSign', exponent
725 `zExp', and significand formed by the concatenation of `zSig0' and `zSig1',
726 and returns the proper extended double-precision floating-point value
727 corresponding to the abstract input.  This routine is just like
728 `roundAndPackFloatx80' except that the input significand does not have to be
729 normalized.
730 -------------------------------------------------------------------------------
731 */
732 static floatx80
733  normalizeRoundAndPackFloatx80(
734      struct roundingData *roundData, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1
735  )
736 {
737     int8 shiftCount;
738
739     if ( zSig0 == 0 ) {
740         zSig0 = zSig1;
741         zSig1 = 0;
742         zExp -= 64;
743     }
744     shiftCount = countLeadingZeros64( zSig0 );
745     shortShift128Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
746     zExp -= shiftCount;
747     return
748         roundAndPackFloatx80( roundData, zSign, zExp, zSig0, zSig1 );
749
750 }
751
752 #endif
753
754 /*
755 -------------------------------------------------------------------------------
756 Returns the result of converting the 32-bit two's complement integer `a' to
757 the single-precision floating-point format.  The conversion is performed
758 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
759 -------------------------------------------------------------------------------
760 */
761 float32 int32_to_float32(struct roundingData *roundData, int32 a)
762 {
763     flag zSign;
764
765     if ( a == 0 ) return 0;
766     if ( a == 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
767     zSign = ( a < 0 );
768     return normalizeRoundAndPackFloat32( roundData, zSign, 0x9C, zSign ? - a : a );
769
770 }
771
772 /*
773 -------------------------------------------------------------------------------
774 Returns the result of converting the 32-bit two's complement integer `a' to
775 the double-precision floating-point format.  The conversion is performed
776 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
777 -------------------------------------------------------------------------------
778 */
779 float64 int32_to_float64( int32 a )
780 {
781     flag aSign;
782     uint32 absA;
783     int8 shiftCount;
784     bits64 zSig;
785
786     if ( a == 0 ) return 0;
787     aSign = ( a < 0 );
788     absA = aSign ? - a : a;
789     shiftCount = countLeadingZeros32( absA ) + 21;
790     zSig = absA;
791     return packFloat64( aSign, 0x432 - shiftCount, zSig<<shiftCount );
792
793 }
794
795 #ifdef FLOATX80
796
797 /*
798 -------------------------------------------------------------------------------
799 Returns the result of converting the 32-bit two's complement integer `a'
800 to the extended double-precision floating-point format.  The conversion
801 is performed according to the IEC/IEEE Standard for Binary Floating-point
802 Arithmetic.
803 -------------------------------------------------------------------------------
804 */
805 floatx80 int32_to_floatx80( int32 a )
806 {
807     flag zSign;
808     uint32 absA;
809     int8 shiftCount;
810     bits64 zSig;
811
812     if ( a == 0 ) return packFloatx80( 0, 0, 0 );
813     zSign = ( a < 0 );
814     absA = zSign ? - a : a;
815     shiftCount = countLeadingZeros32( absA ) + 32;
816     zSig = absA;
817     return packFloatx80( zSign, 0x403E - shiftCount, zSig<<shiftCount );
818
819 }
820
821 #endif
822
823 /*
824 -------------------------------------------------------------------------------
825 Returns the result of converting the single-precision floating-point value
826 `a' to the 32-bit two's complement integer format.  The conversion is
827 performed according to the IEC/IEEE Standard for Binary Floating-point
828 Arithmetic---which means in particular that the conversion is rounded
829 according to the current rounding mode.  If `a' is a NaN, the largest
830 positive integer is returned.  Otherwise, if the conversion overflows, the
831 largest integer with the same sign as `a' is returned.
832 -------------------------------------------------------------------------------
833 */
834 int32 float32_to_int32( struct roundingData *roundData, float32 a )
835 {
836     flag aSign;
837     int16 aExp, shiftCount;
838     bits32 aSig;
839     bits64 zSig;
840
841     aSig = extractFloat32Frac( a );
842     aExp = extractFloat32Exp( a );
843     aSign = extractFloat32Sign( a );
844     if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
845     if ( aExp ) aSig |= 0x00800000;
846     shiftCount = 0xAF - aExp;
847     zSig = aSig;
848     zSig <<= 32;
849     if ( 0 < shiftCount ) shift64RightJamming( zSig, shiftCount, &zSig );
850     return roundAndPackInt32( roundData, aSign, zSig );
851
852 }
853
854 /*
855 -------------------------------------------------------------------------------
856 Returns the result of converting the single-precision floating-point value
857 `a' to the 32-bit two's complement integer format.  The conversion is
858 performed according to the IEC/IEEE Standard for Binary Floating-point
859 Arithmetic, except that the conversion is always rounded toward zero.  If
860 `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
861 conversion overflows, the largest integer with the same sign as `a' is
862 returned.
863 -------------------------------------------------------------------------------
864 */
865 int32 float32_to_int32_round_to_zero( float32 a )
866 {
867     flag aSign;
868     int16 aExp, shiftCount;
869     bits32 aSig;
870     int32 z;
871
872     aSig = extractFloat32Frac( a );
873     aExp = extractFloat32Exp( a );
874     aSign = extractFloat32Sign( a );
875     shiftCount = aExp - 0x9E;
876     if ( 0 <= shiftCount ) {
877         if ( a == 0xCF000000 ) return 0x80000000;
878         float_raise( float_flag_invalid );
879         if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
880         return 0x80000000;
881     }
882     else if ( aExp <= 0x7E ) {
883         if ( aExp | aSig ) float_raise( float_flag_inexact );
884         return 0;
885     }
886     aSig = ( aSig | 0x00800000 )<<8;
887     z = aSig>>( - shiftCount );
888     if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
889         float_raise( float_flag_inexact );
890     }
891     return aSign ? - z : z;
892
893 }
894
895 /*
896 -------------------------------------------------------------------------------
897 Returns the result of converting the single-precision floating-point value
898 `a' to the double-precision floating-point format.  The conversion is
899 performed according to the IEC/IEEE Standard for Binary Floating-point
900 Arithmetic.
901 -------------------------------------------------------------------------------
902 */
903 float64 float32_to_float64( float32 a )
904 {
905     flag aSign;
906     int16 aExp;
907     bits32 aSig;
908
909     aSig = extractFloat32Frac( a );
910     aExp = extractFloat32Exp( a );
911     aSign = extractFloat32Sign( a );
912     if ( aExp == 0xFF ) {
913         if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) );
914         return packFloat64( aSign, 0x7FF, 0 );
915     }
916     if ( aExp == 0 ) {
917         if ( aSig == 0 ) return packFloat64( aSign, 0, 0 );
918         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
919         --aExp;
920     }
921     return packFloat64( aSign, aExp + 0x380, ( (bits64) aSig )<<29 );
922
923 }
924
925 #ifdef FLOATX80
926
927 /*
928 -------------------------------------------------------------------------------
929 Returns the result of converting the single-precision floating-point value
930 `a' to the extended double-precision floating-point format.  The conversion
931 is performed according to the IEC/IEEE Standard for Binary Floating-point
932 Arithmetic.
933 -------------------------------------------------------------------------------
934 */
935 floatx80 float32_to_floatx80( float32 a )
936 {
937     flag aSign;
938     int16 aExp;
939     bits32 aSig;
940
941     aSig = extractFloat32Frac( a );
942     aExp = extractFloat32Exp( a );
943     aSign = extractFloat32Sign( a );
944     if ( aExp == 0xFF ) {
945         if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a ) );
946         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
947     }
948     if ( aExp == 0 ) {
949         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
950         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
951     }
952     aSig |= 0x00800000;
953     return packFloatx80( aSign, aExp + 0x3F80, ( (bits64) aSig )<<40 );
954
955 }
956
957 #endif
958
959 /*
960 -------------------------------------------------------------------------------
961 Rounds the single-precision floating-point value `a' to an integer, and
962 returns the result as a single-precision floating-point value.  The
963 operation is performed according to the IEC/IEEE Standard for Binary
964 Floating-point Arithmetic.
965 -------------------------------------------------------------------------------
966 */
967 float32 float32_round_to_int( struct roundingData *roundData, float32 a )
968 {
969     flag aSign;
970     int16 aExp;
971     bits32 lastBitMask, roundBitsMask;
972     int8 roundingMode;
973     float32 z;
974
975     aExp = extractFloat32Exp( a );
976     if ( 0x96 <= aExp ) {
977         if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
978             return propagateFloat32NaN( a, a );
979         }
980         return a;
981     }
982     roundingMode = roundData->mode;
983     if ( aExp <= 0x7E ) {
984         if ( (bits32) ( a<<1 ) == 0 ) return a;
985         roundData->exception |= float_flag_inexact;
986         aSign = extractFloat32Sign( a );
987         switch ( roundingMode ) {
988          case float_round_nearest_even:
989             if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
990                 return packFloat32( aSign, 0x7F, 0 );
991             }
992             break;
993          case float_round_down:
994             return aSign ? 0xBF800000 : 0;
995          case float_round_up:
996             return aSign ? 0x80000000 : 0x3F800000;
997         }
998         return packFloat32( aSign, 0, 0 );
999     }
1000     lastBitMask = 1;
1001     lastBitMask <<= 0x96 - aExp;
1002     roundBitsMask = lastBitMask - 1;
1003     z = a;
1004     if ( roundingMode == float_round_nearest_even ) {
1005         z += lastBitMask>>1;
1006         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
1007     }
1008     else if ( roundingMode != float_round_to_zero ) {
1009         if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
1010             z += roundBitsMask;
1011         }
1012     }
1013     z &= ~ roundBitsMask;
1014     if ( z != a ) roundData->exception |= float_flag_inexact;
1015     return z;
1016
1017 }
1018
1019 /*
1020 -------------------------------------------------------------------------------
1021 Returns the result of adding the absolute values of the single-precision
1022 floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
1023 before being returned.  `zSign' is ignored if the result is a NaN.  The
1024 addition is performed according to the IEC/IEEE Standard for Binary
1025 Floating-point Arithmetic.
1026 -------------------------------------------------------------------------------
1027 */
1028 static float32 addFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
1029 {
1030     int16 aExp, bExp, zExp;
1031     bits32 aSig, bSig, zSig;
1032     int16 expDiff;
1033
1034     aSig = extractFloat32Frac( a );
1035     aExp = extractFloat32Exp( a );
1036     bSig = extractFloat32Frac( b );
1037     bExp = extractFloat32Exp( b );
1038     expDiff = aExp - bExp;
1039     aSig <<= 6;
1040     bSig <<= 6;
1041     if ( 0 < expDiff ) {
1042         if ( aExp == 0xFF ) {
1043             if ( aSig ) return propagateFloat32NaN( a, b );
1044             return a;
1045         }
1046         if ( bExp == 0 ) {
1047             --expDiff;
1048         }
1049         else {
1050             bSig |= 0x20000000;
1051         }
1052         shift32RightJamming( bSig, expDiff, &bSig );
1053         zExp = aExp;
1054     }
1055     else if ( expDiff < 0 ) {
1056         if ( bExp == 0xFF ) {
1057             if ( bSig ) return propagateFloat32NaN( a, b );
1058             return packFloat32( zSign, 0xFF, 0 );
1059         }
1060         if ( aExp == 0 ) {
1061             ++expDiff;
1062         }
1063         else {
1064             aSig |= 0x20000000;
1065         }
1066         shift32RightJamming( aSig, - expDiff, &aSig );
1067         zExp = bExp;
1068     }
1069     else {
1070         if ( aExp == 0xFF ) {
1071             if ( aSig | bSig ) return propagateFloat32NaN( a, b );
1072             return a;
1073         }
1074         if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
1075         zSig = 0x40000000 + aSig + bSig;
1076         zExp = aExp;
1077         goto roundAndPack;
1078     }
1079     aSig |= 0x20000000;
1080     zSig = ( aSig + bSig )<<1;
1081     --zExp;
1082     if ( (sbits32) zSig < 0 ) {
1083         zSig = aSig + bSig;
1084         ++zExp;
1085     }
1086  roundAndPack:
1087     return roundAndPackFloat32( roundData, zSign, zExp, zSig );
1088
1089 }
1090
1091 /*
1092 -------------------------------------------------------------------------------
1093 Returns the result of subtracting the absolute values of the single-
1094 precision floating-point values `a' and `b'.  If `zSign' is true, the
1095 difference is negated before being returned.  `zSign' is ignored if the
1096 result is a NaN.  The subtraction is performed according to the IEC/IEEE
1097 Standard for Binary Floating-point Arithmetic.
1098 -------------------------------------------------------------------------------
1099 */
1100 static float32 subFloat32Sigs( struct roundingData *roundData, float32 a, float32 b, flag zSign )
1101 {
1102     int16 aExp, bExp, zExp;
1103     bits32 aSig, bSig, zSig;
1104     int16 expDiff;
1105
1106     aSig = extractFloat32Frac( a );
1107     aExp = extractFloat32Exp( a );
1108     bSig = extractFloat32Frac( b );
1109     bExp = extractFloat32Exp( b );
1110     expDiff = aExp - bExp;
1111     aSig <<= 7;
1112     bSig <<= 7;
1113     if ( 0 < expDiff ) goto aExpBigger;
1114     if ( expDiff < 0 ) goto bExpBigger;
1115     if ( aExp == 0xFF ) {
1116         if ( aSig | bSig ) return propagateFloat32NaN( a, b );
1117         roundData->exception |= float_flag_invalid;
1118         return float32_default_nan;
1119     }
1120     if ( aExp == 0 ) {
1121         aExp = 1;
1122         bExp = 1;
1123     }
1124     if ( bSig < aSig ) goto aBigger;
1125     if ( aSig < bSig ) goto bBigger;
1126     return packFloat32( roundData->mode == float_round_down, 0, 0 );
1127  bExpBigger:
1128     if ( bExp == 0xFF ) {
1129         if ( bSig ) return propagateFloat32NaN( a, b );
1130         return packFloat32( zSign ^ 1, 0xFF, 0 );
1131     }
1132     if ( aExp == 0 ) {
1133         ++expDiff;
1134     }
1135     else {
1136         aSig |= 0x40000000;
1137     }
1138     shift32RightJamming( aSig, - expDiff, &aSig );
1139     bSig |= 0x40000000;
1140  bBigger:
1141     zSig = bSig - aSig;
1142     zExp = bExp;
1143     zSign ^= 1;
1144     goto normalizeRoundAndPack;
1145  aExpBigger:
1146     if ( aExp == 0xFF ) {
1147         if ( aSig ) return propagateFloat32NaN( a, b );
1148         return a;
1149     }
1150     if ( bExp == 0 ) {
1151         --expDiff;
1152     }
1153     else {
1154         bSig |= 0x40000000;
1155     }
1156     shift32RightJamming( bSig, expDiff, &bSig );
1157     aSig |= 0x40000000;
1158  aBigger:
1159     zSig = aSig - bSig;
1160     zExp = aExp;
1161  normalizeRoundAndPack:
1162     --zExp;
1163     return normalizeRoundAndPackFloat32( roundData, zSign, zExp, zSig );
1164
1165 }
1166
1167 /*
1168 -------------------------------------------------------------------------------
1169 Returns the result of adding the single-precision floating-point values `a'
1170 and `b'.  The operation is performed according to the IEC/IEEE Standard for
1171 Binary Floating-point Arithmetic.
1172 -------------------------------------------------------------------------------
1173 */
1174 float32 float32_add( struct roundingData *roundData, float32 a, float32 b )
1175 {
1176     flag aSign, bSign;
1177
1178     aSign = extractFloat32Sign( a );
1179     bSign = extractFloat32Sign( b );
1180     if ( aSign == bSign ) {
1181         return addFloat32Sigs( roundData, a, b, aSign );
1182     }
1183     else {
1184         return subFloat32Sigs( roundData, a, b, aSign );
1185     }
1186
1187 }
1188
1189 /*
1190 -------------------------------------------------------------------------------
1191 Returns the result of subtracting the single-precision floating-point values
1192 `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
1193 for Binary Floating-point Arithmetic.
1194 -------------------------------------------------------------------------------
1195 */
1196 float32 float32_sub( struct roundingData *roundData, float32 a, float32 b )
1197 {
1198     flag aSign, bSign;
1199
1200     aSign = extractFloat32Sign( a );
1201     bSign = extractFloat32Sign( b );
1202     if ( aSign == bSign ) {
1203         return subFloat32Sigs( roundData, a, b, aSign );
1204     }
1205     else {
1206         return addFloat32Sigs( roundData, a, b, aSign );
1207     }
1208
1209 }
1210
1211 /*
1212 -------------------------------------------------------------------------------
1213 Returns the result of multiplying the single-precision floating-point values
1214 `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
1215 for Binary Floating-point Arithmetic.
1216 -------------------------------------------------------------------------------
1217 */
1218 float32 float32_mul( struct roundingData *roundData, float32 a, float32 b )
1219 {
1220     flag aSign, bSign, zSign;
1221     int16 aExp, bExp, zExp;
1222     bits32 aSig, bSig;
1223     bits64 zSig64;
1224     bits32 zSig;
1225
1226     aSig = extractFloat32Frac( a );
1227     aExp = extractFloat32Exp( a );
1228     aSign = extractFloat32Sign( a );
1229     bSig = extractFloat32Frac( b );
1230     bExp = extractFloat32Exp( b );
1231     bSign = extractFloat32Sign( b );
1232     zSign = aSign ^ bSign;
1233     if ( aExp == 0xFF ) {
1234         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
1235             return propagateFloat32NaN( a, b );
1236         }
1237         if ( ( bExp | bSig ) == 0 ) {
1238             roundData->exception |= float_flag_invalid;
1239             return float32_default_nan;
1240         }
1241         return packFloat32( zSign, 0xFF, 0 );
1242     }
1243     if ( bExp == 0xFF ) {
1244         if ( bSig ) return propagateFloat32NaN( a, b );
1245         if ( ( aExp | aSig ) == 0 ) {
1246             roundData->exception |= float_flag_invalid;
1247             return float32_default_nan;
1248         }
1249         return packFloat32( zSign, 0xFF, 0 );
1250     }
1251     if ( aExp == 0 ) {
1252         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
1253         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1254     }
1255     if ( bExp == 0 ) {
1256         if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
1257         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1258     }
1259     zExp = aExp + bExp - 0x7F;
1260     aSig = ( aSig | 0x00800000 )<<7;
1261     bSig = ( bSig | 0x00800000 )<<8;
1262     shift64RightJamming( ( (bits64) aSig ) * bSig, 32, &zSig64 );
1263     zSig = zSig64;
1264     if ( 0 <= (sbits32) ( zSig<<1 ) ) {
1265         zSig <<= 1;
1266         --zExp;
1267     }
1268     return roundAndPackFloat32( roundData, zSign, zExp, zSig );
1269
1270 }
1271
1272 /*
1273 -------------------------------------------------------------------------------
1274 Returns the result of dividing the single-precision floating-point value `a'
1275 by the corresponding value `b'.  The operation is performed according to the
1276 IEC/IEEE Standard for Binary Floating-point Arithmetic.
1277 -------------------------------------------------------------------------------
1278 */
1279 float32 float32_div( struct roundingData *roundData, float32 a, float32 b )
1280 {
1281     flag aSign, bSign, zSign;
1282     int16 aExp, bExp, zExp;
1283     bits32 aSig, bSig, zSig;
1284
1285     aSig = extractFloat32Frac( a );
1286     aExp = extractFloat32Exp( a );
1287     aSign = extractFloat32Sign( a );
1288     bSig = extractFloat32Frac( b );
1289     bExp = extractFloat32Exp( b );
1290     bSign = extractFloat32Sign( b );
1291     zSign = aSign ^ bSign;
1292     if ( aExp == 0xFF ) {
1293         if ( aSig ) return propagateFloat32NaN( a, b );
1294         if ( bExp == 0xFF ) {
1295             if ( bSig ) return propagateFloat32NaN( a, b );
1296             roundData->exception |= float_flag_invalid;
1297             return float32_default_nan;
1298         }
1299         return packFloat32( zSign, 0xFF, 0 );
1300     }
1301     if ( bExp == 0xFF ) {
1302         if ( bSig ) return propagateFloat32NaN( a, b );
1303         return packFloat32( zSign, 0, 0 );
1304     }
1305     if ( bExp == 0 ) {
1306         if ( bSig == 0 ) {
1307             if ( ( aExp | aSig ) == 0 ) {
1308                 roundData->exception |= float_flag_invalid;
1309                 return float32_default_nan;
1310             }
1311             roundData->exception |= float_flag_divbyzero;
1312             return packFloat32( zSign, 0xFF, 0 );
1313         }
1314         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1315     }
1316     if ( aExp == 0 ) {
1317         if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
1318         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1319     }
1320     zExp = aExp - bExp + 0x7D;
1321     aSig = ( aSig | 0x00800000 )<<7;
1322     bSig = ( bSig | 0x00800000 )<<8;
1323     if ( bSig <= ( aSig + aSig ) ) {
1324         aSig >>= 1;
1325         ++zExp;
1326     }
1327     {
1328         bits64 tmp = ( (bits64) aSig )<<32;
1329         do_div( tmp, bSig );
1330         zSig = tmp;
1331     }
1332     if ( ( zSig & 0x3F ) == 0 ) {
1333         zSig |= ( ( (bits64) bSig ) * zSig != ( (bits64) aSig )<<32 );
1334     }
1335     return roundAndPackFloat32( roundData, zSign, zExp, zSig );
1336
1337 }
1338
1339 /*
1340 -------------------------------------------------------------------------------
1341 Returns the remainder of the single-precision floating-point value `a'
1342 with respect to the corresponding value `b'.  The operation is performed
1343 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1344 -------------------------------------------------------------------------------
1345 */
1346 float32 float32_rem( struct roundingData *roundData, float32 a, float32 b )
1347 {
1348     flag aSign, bSign, zSign;
1349     int16 aExp, bExp, expDiff;
1350     bits32 aSig, bSig;
1351     bits32 q;
1352     bits64 aSig64, bSig64, q64;
1353     bits32 alternateASig;
1354     sbits32 sigMean;
1355
1356     aSig = extractFloat32Frac( a );
1357     aExp = extractFloat32Exp( a );
1358     aSign = extractFloat32Sign( a );
1359     bSig = extractFloat32Frac( b );
1360     bExp = extractFloat32Exp( b );
1361     bSign = extractFloat32Sign( b );
1362     if ( aExp == 0xFF ) {
1363         if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
1364             return propagateFloat32NaN( a, b );
1365         }
1366         roundData->exception |= float_flag_invalid;
1367         return float32_default_nan;
1368     }
1369     if ( bExp == 0xFF ) {
1370         if ( bSig ) return propagateFloat32NaN( a, b );
1371         return a;
1372     }
1373     if ( bExp == 0 ) {
1374         if ( bSig == 0 ) {
1375             roundData->exception |= float_flag_invalid;
1376             return float32_default_nan;
1377         }
1378         normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1379     }
1380     if ( aExp == 0 ) {
1381         if ( aSig == 0 ) return a;
1382         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1383     }
1384     expDiff = aExp - bExp;
1385     aSig |= 0x00800000;
1386     bSig |= 0x00800000;
1387     if ( expDiff < 32 ) {
1388         aSig <<= 8;
1389         bSig <<= 8;
1390         if ( expDiff < 0 ) {
1391             if ( expDiff < -1 ) return a;
1392             aSig >>= 1;
1393         }
1394         q = ( bSig <= aSig );
1395         if ( q ) aSig -= bSig;
1396         if ( 0 < expDiff ) {
1397             bits64 tmp = ( (bits64) aSig )<<32;
1398             do_div( tmp, bSig );
1399             q = tmp;
1400             q >>= 32 - expDiff;
1401             bSig >>= 2;
1402             aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
1403         }
1404         else {
1405             aSig >>= 2;
1406             bSig >>= 2;
1407         }
1408     }
1409     else {
1410         if ( bSig <= aSig ) aSig -= bSig;
1411         aSig64 = ( (bits64) aSig )<<40;
1412         bSig64 = ( (bits64) bSig )<<40;
1413         expDiff -= 64;
1414         while ( 0 < expDiff ) {
1415             q64 = estimateDiv128To64( aSig64, 0, bSig64 );
1416             q64 = ( 2 < q64 ) ? q64 - 2 : 0;
1417             aSig64 = - ( ( bSig * q64 )<<38 );
1418             expDiff -= 62;
1419         }
1420         expDiff += 64;
1421         q64 = estimateDiv128To64( aSig64, 0, bSig64 );
1422         q64 = ( 2 < q64 ) ? q64 - 2 : 0;
1423         q = q64>>( 64 - expDiff );
1424         bSig <<= 6;
1425         aSig = ( ( aSig64>>33 )<<( expDiff - 1 ) ) - bSig * q;
1426     }
1427     do {
1428         alternateASig = aSig;
1429         ++q;
1430         aSig -= bSig;
1431     } while ( 0 <= (sbits32) aSig );
1432     sigMean = aSig + alternateASig;
1433     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
1434         aSig = alternateASig;
1435     }
1436     zSign = ( (sbits32) aSig < 0 );
1437     if ( zSign ) aSig = - aSig;
1438     return normalizeRoundAndPackFloat32( roundData, aSign ^ zSign, bExp, aSig );
1439
1440 }
1441
1442 /*
1443 -------------------------------------------------------------------------------
1444 Returns the square root of the single-precision floating-point value `a'.
1445 The operation is performed according to the IEC/IEEE Standard for Binary
1446 Floating-point Arithmetic.
1447 -------------------------------------------------------------------------------
1448 */
1449 float32 float32_sqrt( struct roundingData *roundData, float32 a )
1450 {
1451     flag aSign;
1452     int16 aExp, zExp;
1453     bits32 aSig, zSig;
1454     bits64 rem, term;
1455
1456     aSig = extractFloat32Frac( a );
1457     aExp = extractFloat32Exp( a );
1458     aSign = extractFloat32Sign( a );
1459     if ( aExp == 0xFF ) {
1460         if ( aSig ) return propagateFloat32NaN( a, 0 );
1461         if ( ! aSign ) return a;
1462         roundData->exception |= float_flag_invalid;
1463         return float32_default_nan;
1464     }
1465     if ( aSign ) {
1466         if ( ( aExp | aSig ) == 0 ) return a;
1467         roundData->exception |= float_flag_invalid;
1468         return float32_default_nan;
1469     }
1470     if ( aExp == 0 ) {
1471         if ( aSig == 0 ) return 0;
1472         normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1473     }
1474     zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
1475     aSig = ( aSig | 0x00800000 )<<8;
1476     zSig = estimateSqrt32( aExp, aSig ) + 2;
1477     if ( ( zSig & 0x7F ) <= 5 ) {
1478         if ( zSig < 2 ) {
1479             zSig = 0xFFFFFFFF;
1480         }
1481         else {
1482             aSig >>= aExp & 1;
1483             term = ( (bits64) zSig ) * zSig;
1484             rem = ( ( (bits64) aSig )<<32 ) - term;
1485             while ( (sbits64) rem < 0 ) {
1486                 --zSig;
1487                 rem += ( ( (bits64) zSig )<<1 ) | 1;
1488             }
1489             zSig |= ( rem != 0 );
1490         }
1491     }
1492     shift32RightJamming( zSig, 1, &zSig );
1493     return roundAndPackFloat32( roundData, 0, zExp, zSig );
1494
1495 }
1496
1497 /*
1498 -------------------------------------------------------------------------------
1499 Returns 1 if the single-precision floating-point value `a' is equal to the
1500 corresponding value `b', and 0 otherwise.  The comparison is performed
1501 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1502 -------------------------------------------------------------------------------
1503 */
1504 flag float32_eq( float32 a, float32 b )
1505 {
1506
1507     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1508          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1509        ) {
1510         if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
1511             float_raise( float_flag_invalid );
1512         }
1513         return 0;
1514     }
1515     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
1516
1517 }
1518
1519 /*
1520 -------------------------------------------------------------------------------
1521 Returns 1 if the single-precision floating-point value `a' is less than or
1522 equal to the corresponding value `b', and 0 otherwise.  The comparison is
1523 performed according to the IEC/IEEE Standard for Binary Floating-point
1524 Arithmetic.
1525 -------------------------------------------------------------------------------
1526 */
1527 flag float32_le( float32 a, float32 b )
1528 {
1529     flag aSign, bSign;
1530
1531     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1532          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1533        ) {
1534         float_raise( float_flag_invalid );
1535         return 0;
1536     }
1537     aSign = extractFloat32Sign( a );
1538     bSign = extractFloat32Sign( b );
1539     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
1540     return ( a == b ) || ( aSign ^ ( a < b ) );
1541
1542 }
1543
1544 /*
1545 -------------------------------------------------------------------------------
1546 Returns 1 if the single-precision floating-point value `a' is less than
1547 the corresponding value `b', and 0 otherwise.  The comparison is performed
1548 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1549 -------------------------------------------------------------------------------
1550 */
1551 flag float32_lt( float32 a, float32 b )
1552 {
1553     flag aSign, bSign;
1554
1555     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1556          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1557        ) {
1558         float_raise( float_flag_invalid );
1559         return 0;
1560     }
1561     aSign = extractFloat32Sign( a );
1562     bSign = extractFloat32Sign( b );
1563     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
1564     return ( a != b ) && ( aSign ^ ( a < b ) );
1565
1566 }
1567
1568 /*
1569 -------------------------------------------------------------------------------
1570 Returns 1 if the single-precision floating-point value `a' is equal to the
1571 corresponding value `b', and 0 otherwise.  The invalid exception is raised
1572 if either operand is a NaN.  Otherwise, the comparison is performed
1573 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
1574 -------------------------------------------------------------------------------
1575 */
1576 flag float32_eq_signaling( float32 a, float32 b )
1577 {
1578
1579     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1580          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1581        ) {
1582         float_raise( float_flag_invalid );
1583         return 0;
1584     }
1585     return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
1586
1587 }
1588
1589 /*
1590 -------------------------------------------------------------------------------
1591 Returns 1 if the single-precision floating-point value `a' is less than or
1592 equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
1593 cause an exception.  Otherwise, the comparison is performed according to the
1594 IEC/IEEE Standard for Binary Floating-point Arithmetic.
1595 -------------------------------------------------------------------------------
1596 */
1597 flag float32_le_quiet( float32 a, float32 b )
1598 {
1599     flag aSign, bSign;
1600     //int16 aExp, bExp;
1601
1602     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1603          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1604        ) {
1605         /* Do nothing, even if NaN as we're quiet */
1606         return 0;
1607     }
1608     aSign = extractFloat32Sign( a );
1609     bSign = extractFloat32Sign( b );
1610     if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
1611     return ( a == b ) || ( aSign ^ ( a < b ) );
1612
1613 }
1614
1615 /*
1616 -------------------------------------------------------------------------------
1617 Returns 1 if the single-precision floating-point value `a' is less than
1618 the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
1619 exception.  Otherwise, the comparison is performed according to the IEC/IEEE
1620 Standard for Binary Floating-point Arithmetic.
1621 -------------------------------------------------------------------------------
1622 */
1623 flag float32_lt_quiet( float32 a, float32 b )
1624 {
1625     flag aSign, bSign;
1626
1627     if (    ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1628          || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1629        ) {
1630         /* Do nothing, even if NaN as we're quiet */
1631         return 0;
1632     }
1633     aSign = extractFloat32Sign( a );
1634     bSign = extractFloat32Sign( b );
1635     if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
1636     return ( a != b ) && ( aSign ^ ( a < b ) );
1637
1638 }
1639
1640 /*
1641 -------------------------------------------------------------------------------
1642 Returns the result of converting the double-precision floating-point value
1643 `a' to the 32-bit two's complement integer format.  The conversion is
1644 performed according to the IEC/IEEE Standard for Binary Floating-point
1645 Arithmetic---which means in particular that the conversion is rounded
1646 according to the current rounding mode.  If `a' is a NaN, the largest
1647 positive integer is returned.  Otherwise, if the conversion overflows, the
1648 largest integer with the same sign as `a' is returned.
1649 -------------------------------------------------------------------------------
1650 */
1651 int32 float64_to_int32( struct roundingData *roundData, float64 a )
1652 {
1653     flag aSign;
1654     int16 aExp, shiftCount;
1655     bits64 aSig;
1656
1657     aSig = extractFloat64Frac( a );
1658     aExp = extractFloat64Exp( a );
1659     aSign = extractFloat64Sign( a );
1660     if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
1661     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
1662     shiftCount = 0x42C - aExp;
1663     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
1664     return roundAndPackInt32( roundData, aSign, aSig );
1665
1666 }
1667
1668 /*
1669 -------------------------------------------------------------------------------
1670 Returns the result of converting the double-precision floating-point value
1671 `a' to the 32-bit two's complement integer format.  The conversion is
1672 performed according to the IEC/IEEE Standard for Binary Floating-point
1673 Arithmetic, except that the conversion is always rounded toward zero.  If
1674 `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
1675 conversion overflows, the largest integer with the same sign as `a' is
1676 returned.
1677 -------------------------------------------------------------------------------
1678 */
1679 int32 float64_to_int32_round_to_zero( float64 a )
1680 {
1681     flag aSign;
1682     int16 aExp, shiftCount;
1683     bits64 aSig, savedASig;
1684     int32 z;
1685
1686     aSig = extractFloat64Frac( a );
1687     aExp = extractFloat64Exp( a );
1688     aSign = extractFloat64Sign( a );
1689     shiftCount = 0x433 - aExp;
1690     if ( shiftCount < 21 ) {
1691         if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
1692         goto invalid;
1693     }
1694     else if ( 52 < shiftCount ) {
1695         if ( aExp || aSig ) float_raise( float_flag_inexact );
1696         return 0;
1697     }
1698     aSig |= LIT64( 0x0010000000000000 );
1699     savedASig = aSig;
1700     aSig >>= shiftCount;
1701     z = aSig;
1702     if ( aSign ) z = - z;
1703     if ( ( z < 0 ) ^ aSign ) {
1704  invalid:
1705         float_raise( float_flag_invalid );
1706         return aSign ? 0x80000000 : 0x7FFFFFFF;
1707     }
1708     if ( ( aSig<<shiftCount ) != savedASig ) {
1709         float_raise( float_flag_inexact );
1710     }
1711     return z;
1712
1713 }
1714
1715 /*
1716 -------------------------------------------------------------------------------
1717 Returns the result of converting the double-precision floating-point value
1718 `a' to the 32-bit two's complement unsigned integer format.  The conversion
1719 is performed according to the IEC/IEEE Standard for Binary Floating-point
1720 Arithmetic---which means in particular that the conversion is rounded
1721 according to the current rounding mode.  If `a' is a NaN, the largest
1722 positive integer is returned.  Otherwise, if the conversion overflows, the
1723 largest positive integer is returned.
1724 -------------------------------------------------------------------------------
1725 */
1726 int32 float64_to_uint32( struct roundingData *roundData, float64 a )
1727 {
1728     flag aSign;
1729     int16 aExp, shiftCount;
1730     bits64 aSig;
1731
1732     aSig = extractFloat64Frac( a );
1733     aExp = extractFloat64Exp( a );
1734     aSign = 0; //extractFloat64Sign( a );
1735     //if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
1736     if ( aExp ) aSig |= LIT64( 0x0010000000000000 );
1737     shiftCount = 0x42C - aExp;
1738     if ( 0 < shiftCount ) shift64RightJamming( aSig, shiftCount, &aSig );
1739     return roundAndPackInt32( roundData, aSign, aSig );
1740 }
1741
1742 /*
1743 -------------------------------------------------------------------------------
1744 Returns the result of converting the double-precision floating-point value
1745 `a' to the 32-bit two's complement integer format.  The conversion is
1746 performed according to the IEC/IEEE Standard for Binary Floating-point
1747 Arithmetic, except that the conversion is always rounded toward zero.  If
1748 `a' is a NaN, the largest positive integer is returned.  Otherwise, if the
1749 conversion overflows, the largest positive integer is returned.
1750 -------------------------------------------------------------------------------
1751 */
1752 int32 float64_to_uint32_round_to_zero( float64 a )
1753 {
1754     flag aSign;
1755     int16 aExp, shiftCount;
1756     bits64 aSig, savedASig;
1757     int32 z;
1758
1759     aSig = extractFloat64Frac( a );
1760     aExp = extractFloat64Exp( a );
1761     aSign = extractFloat64Sign( a );
1762     shiftCount = 0x433 - aExp;
1763     if ( shiftCount < 21 ) {
1764         if ( ( aExp == 0x7FF ) && aSig ) aSign = 0;
1765         goto invalid;
1766     }
1767     else if ( 52 < shiftCount ) {
1768         if ( aExp || aSig ) float_raise( float_flag_inexact );
1769         return 0;
1770     }
1771     aSig |= LIT64( 0x0010000000000000 );
1772     savedASig = aSig;
1773     aSig >>= shiftCount;
1774     z = aSig;
1775     if ( aSign ) z = - z;
1776     if ( ( z < 0 ) ^ aSign ) {
1777  invalid:
1778         float_raise( float_flag_invalid );
1779         return aSign ? 0x80000000 : 0x7FFFFFFF;
1780     }
1781     if ( ( aSig<<shiftCount ) != savedASig ) {
1782         float_raise( float_flag_inexact );
1783     }
1784     return z;
1785 }
1786
1787 /*
1788 -------------------------------------------------------------------------------
1789 Returns the result of converting the double-precision floating-point value
1790 `a' to the single-precision floating-point format.  The conversion is
1791 performed according to the IEC/IEEE Standard for Binary Floating-point
1792 Arithmetic.
1793 -------------------------------------------------------------------------------
1794 */
1795 float32 float64_to_float32( struct roundingData *roundData, float64 a )
1796 {
1797     flag aSign;
1798     int16 aExp;
1799     bits64 aSig;
1800     bits32 zSig;
1801
1802     aSig = extractFloat64Frac( a );
1803     aExp = extractFloat64Exp( a );
1804     aSign = extractFloat64Sign( a );
1805     if ( aExp == 0x7FF ) {
1806         if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a ) );
1807         return packFloat32( aSign, 0xFF, 0 );
1808     }
1809     shift64RightJamming( aSig, 22, &aSig );
1810     zSig = aSig;
1811     if ( aExp || zSig ) {
1812         zSig |= 0x40000000;
1813         aExp -= 0x381;
1814     }
1815     return roundAndPackFloat32( roundData, aSign, aExp, zSig );
1816
1817 }
1818
1819 #ifdef FLOATX80
1820
1821 /*
1822 -------------------------------------------------------------------------------
1823 Returns the result of converting the double-precision floating-point value
1824 `a' to the extended double-precision floating-point format.  The conversion
1825 is performed according to the IEC/IEEE Standard for Binary Floating-point
1826 Arithmetic.
1827 -------------------------------------------------------------------------------
1828 */
1829 floatx80 float64_to_floatx80( float64 a )
1830 {
1831     flag aSign;
1832     int16 aExp;
1833     bits64 aSig;
1834
1835     aSig = extractFloat64Frac( a );
1836     aExp = extractFloat64Exp( a );
1837     aSign = extractFloat64Sign( a );
1838     if ( aExp == 0x7FF ) {
1839         if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a ) );
1840         return packFloatx80( aSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
1841     }
1842     if ( aExp == 0 ) {
1843         if ( aSig == 0 ) return packFloatx80( aSign, 0, 0 );
1844         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
1845     }
1846     return
1847         packFloatx80(
1848             aSign, aExp + 0x3C00, ( aSig | LIT64( 0x0010000000000000 ) )<<11 );
1849
1850 }
1851
1852 #endif
1853
1854 /*
1855 -------------------------------------------------------------------------------
1856 Rounds the double-precision floating-point value `a' to an integer, and
1857 returns the result as a double-precision floating-point value.  The
1858 operation is performed according to the IEC/IEEE Standard for Binary
1859 Floating-point Arithmetic.
1860 -------------------------------------------------------------------------------
1861 */
1862 float64 float64_round_to_int( struct roundingData *roundData, float64 a )
1863 {
1864     flag aSign;
1865     int16 aExp;
1866     bits64 lastBitMask, roundBitsMask;
1867     int8 roundingMode;
1868     float64 z;
1869
1870     aExp = extractFloat64Exp( a );
1871     if ( 0x433 <= aExp ) {
1872         if ( ( aExp == 0x7FF ) && extractFloat64Frac( a ) ) {
1873             return propagateFloat64NaN( a, a );
1874         }
1875         return a;
1876     }
1877     if ( aExp <= 0x3FE ) {
1878         if ( (bits64) ( a<<1 ) == 0 ) return a;
1879         roundData->exception |= float_flag_inexact;
1880         aSign = extractFloat64Sign( a );
1881         switch ( roundData->mode ) {
1882          case float_round_nearest_even:
1883             if ( ( aExp == 0x3FE ) && extractFloat64Frac( a ) ) {
1884                 return packFloat64( aSign, 0x3FF, 0 );
1885             }
1886             break;
1887          case float_round_down:
1888             return aSign ? LIT64( 0xBFF0000000000000 ) : 0;
1889          case float_round_up:
1890             return
1891             aSign ? LIT64( 0x8000000000000000 ) : LIT64( 0x3FF0000000000000 );
1892         }
1893         return packFloat64( aSign, 0, 0 );
1894     }
1895     lastBitMask = 1;
1896     lastBitMask <<= 0x433 - aExp;
1897     roundBitsMask = lastBitMask - 1;
1898     z = a;
1899     roundingMode = roundData->mode;
1900     if ( roundingMode == float_round_nearest_even ) {
1901         z += lastBitMask>>1;
1902         if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
1903     }
1904     else if ( roundingMode != float_round_to_zero ) {
1905         if ( extractFloat64Sign( z ) ^ ( roundingMode == float_round_up ) ) {
1906             z += roundBitsMask;
1907         }
1908     }
1909     z &= ~ roundBitsMask;
1910     if ( z != a ) roundData->exception |= float_flag_inexact;
1911     return z;
1912
1913 }
1914
1915 /*
1916 -------------------------------------------------------------------------------
1917 Returns the result of adding the absolute values of the double-precision
1918 floating-point values `a' and `b'.  If `zSign' is true, the sum is negated
1919 before being returned.  `zSign' is ignored if the result is a NaN.  The
1920 addition is performed according to the IEC/IEEE Standard for Binary
1921 Floating-point Arithmetic.
1922 -------------------------------------------------------------------------------
1923 */
1924 static float64 addFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
1925 {
1926     int16 aExp, bExp, zExp;
1927     bits64 aSig, bSig, zSig;
1928     int16 expDiff;
1929
1930     aSig = extractFloat64Frac( a );
1931     aExp = extractFloat64Exp( a );
1932     bSig = extractFloat64Frac( b );
1933     bExp = extractFloat64Exp( b );
1934     expDiff = aExp - bExp;
1935     aSig <<= 9;
1936     bSig <<= 9;
1937     if ( 0 < expDiff ) {
1938         if ( aExp == 0x7FF ) {
1939             if ( aSig ) return propagateFloat64NaN( a, b );
1940             return a;
1941         }
1942         if ( bExp == 0 ) {
1943             --expDiff;
1944         }
1945         else {
1946             bSig |= LIT64( 0x2000000000000000 );
1947         }
1948         shift64RightJamming( bSig, expDiff, &bSig );
1949         zExp = aExp;
1950     }
1951     else if ( expDiff < 0 ) {
1952         if ( bExp == 0x7FF ) {
1953             if ( bSig ) return propagateFloat64NaN( a, b );
1954             return packFloat64( zSign, 0x7FF, 0 );
1955         }
1956         if ( aExp == 0 ) {
1957             ++expDiff;
1958         }
1959         else {
1960             aSig |= LIT64( 0x2000000000000000 );
1961         }
1962         shift64RightJamming( aSig, - expDiff, &aSig );
1963         zExp = bExp;
1964     }
1965     else {
1966         if ( aExp == 0x7FF ) {
1967             if ( aSig | bSig ) return propagateFloat64NaN( a, b );
1968             return a;
1969         }
1970         if ( aExp == 0 ) return packFloat64( zSign, 0, ( aSig + bSig )>>9 );
1971         zSig = LIT64( 0x4000000000000000 ) + aSig + bSig;
1972         zExp = aExp;
1973         goto roundAndPack;
1974     }
1975     aSig |= LIT64( 0x2000000000000000 );
1976     zSig = ( aSig + bSig )<<1;
1977     --zExp;
1978     if ( (sbits64) zSig < 0 ) {
1979         zSig = aSig + bSig;
1980         ++zExp;
1981     }
1982  roundAndPack:
1983     return roundAndPackFloat64( roundData, zSign, zExp, zSig );
1984
1985 }
1986
1987 /*
1988 -------------------------------------------------------------------------------
1989 Returns the result of subtracting the absolute values of the double-
1990 precision floating-point values `a' and `b'.  If `zSign' is true, the
1991 difference is negated before being returned.  `zSign' is ignored if the
1992 result is a NaN.  The subtraction is performed according to the IEC/IEEE
1993 Standard for Binary Floating-point Arithmetic.
1994 -------------------------------------------------------------------------------
1995 */
1996 static float64 subFloat64Sigs( struct roundingData *roundData, float64 a, float64 b, flag zSign )
1997 {
1998     int16 aExp, bExp, zExp;
1999     bits64 aSig, bSig, zSig;
2000     int16 expDiff;
2001
2002     aSig = extractFloat64Frac( a );
2003     aExp = extractFloat64Exp( a );
2004     bSig = extractFloat64Frac( b );
2005     bExp = extractFloat64Exp( b );
2006     expDiff = aExp - bExp;
2007     aSig <<= 10;
2008     bSig <<= 10;
2009     if ( 0 < expDiff ) goto aExpBigger;
2010     if ( expDiff < 0 ) goto bExpBigger;
2011     if ( aExp == 0x7FF ) {
2012         if ( aSig | bSig ) return propagateFloat64NaN( a, b );
2013         roundData->exception |= float_flag_invalid;
2014         return float64_default_nan;
2015     }
2016     if ( aExp == 0 ) {
2017         aExp = 1;
2018         bExp = 1;
2019     }
2020     if ( bSig < aSig ) goto aBigger;
2021     if ( aSig < bSig ) goto bBigger;
2022     return packFloat64( roundData->mode == float_round_down, 0, 0 );
2023  bExpBigger:
2024     if ( bExp == 0x7FF ) {
2025         if ( bSig ) return propagateFloat64NaN( a, b );
2026         return packFloat64( zSign ^ 1, 0x7FF, 0 );
2027     }
2028     if ( aExp == 0 ) {
2029         ++expDiff;
2030     }
2031     else {
2032         aSig |= LIT64( 0x4000000000000000 );
2033     }
2034     shift64RightJamming( aSig, - expDiff, &aSig );
2035     bSig |= LIT64( 0x4000000000000000 );
2036  bBigger:
2037     zSig = bSig - aSig;
2038     zExp = bExp;
2039     zSign ^= 1;
2040     goto normalizeRoundAndPack;
2041  aExpBigger:
2042     if ( aExp == 0x7FF ) {
2043         if ( aSig ) return propagateFloat64NaN( a, b );
2044         return a;
2045     }
2046     if ( bExp == 0 ) {
2047         --expDiff;
2048     }
2049     else {
2050         bSig |= LIT64( 0x4000000000000000 );
2051     }
2052     shift64RightJamming( bSig, expDiff, &bSig );
2053     aSig |= LIT64( 0x4000000000000000 );
2054  aBigger:
2055     zSig = aSig - bSig;
2056     zExp = aExp;
2057  normalizeRoundAndPack:
2058     --zExp;
2059     return normalizeRoundAndPackFloat64( roundData, zSign, zExp, zSig );
2060
2061 }
2062
2063 /*
2064 -------------------------------------------------------------------------------
2065 Returns the result of adding the double-precision floating-point values `a'
2066 and `b'.  The operation is performed according to the IEC/IEEE Standard for
2067 Binary Floating-point Arithmetic.
2068 -------------------------------------------------------------------------------
2069 */
2070 float64 float64_add( struct roundingData *roundData, float64 a, float64 b )
2071 {
2072     flag aSign, bSign;
2073
2074     aSign = extractFloat64Sign( a );
2075     bSign = extractFloat64Sign( b );
2076     if ( aSign == bSign ) {
2077         return addFloat64Sigs( roundData, a, b, aSign );
2078     }
2079     else {
2080         return subFloat64Sigs( roundData, a, b, aSign );
2081     }
2082
2083 }
2084
2085 /*
2086 -------------------------------------------------------------------------------
2087 Returns the result of subtracting the double-precision floating-point values
2088 `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
2089 for Binary Floating-point Arithmetic.
2090 -------------------------------------------------------------------------------
2091 */
2092 float64 float64_sub( struct roundingData *roundData, float64 a, float64 b )
2093 {
2094     flag aSign, bSign;
2095
2096     aSign = extractFloat64Sign( a );
2097     bSign = extractFloat64Sign( b );
2098     if ( aSign == bSign ) {
2099         return subFloat64Sigs( roundData, a, b, aSign );
2100     }
2101     else {
2102         return addFloat64Sigs( roundData, a, b, aSign );
2103     }
2104
2105 }
2106
2107 /*
2108 -------------------------------------------------------------------------------
2109 Returns the result of multiplying the double-precision floating-point values
2110 `a' and `b'.  The operation is performed according to the IEC/IEEE Standard
2111 for Binary Floating-point Arithmetic.
2112 -------------------------------------------------------------------------------
2113 */
2114 float64 float64_mul( struct roundingData *roundData, float64 a, float64 b )
2115 {
2116     flag aSign, bSign, zSign;
2117     int16 aExp, bExp, zExp;
2118     bits64 aSig, bSig, zSig0, zSig1;
2119
2120     aSig = extractFloat64Frac( a );
2121     aExp = extractFloat64Exp( a );
2122     aSign = extractFloat64Sign( a );
2123     bSig = extractFloat64Frac( b );
2124     bExp = extractFloat64Exp( b );
2125     bSign = extractFloat64Sign( b );
2126     zSign = aSign ^ bSign;
2127     if ( aExp == 0x7FF ) {
2128         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
2129             return propagateFloat64NaN( a, b );
2130         }
2131         if ( ( bExp | bSig ) == 0 ) {
2132             roundData->exception |= float_flag_invalid;
2133             return float64_default_nan;
2134         }
2135         return packFloat64( zSign, 0x7FF, 0 );
2136     }
2137     if ( bExp == 0x7FF ) {
2138         if ( bSig ) return propagateFloat64NaN( a, b );
2139         if ( ( aExp | aSig ) == 0 ) {
2140             roundData->exception |= float_flag_invalid;
2141             return float64_default_nan;
2142         }
2143         return packFloat64( zSign, 0x7FF, 0 );
2144     }
2145     if ( aExp == 0 ) {
2146         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
2147         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
2148     }
2149     if ( bExp == 0 ) {
2150         if ( bSig == 0 ) return packFloat64( zSign, 0, 0 );
2151         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
2152     }
2153     zExp = aExp + bExp - 0x3FF;
2154     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
2155     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
2156     mul64To128( aSig, bSig, &zSig0, &zSig1 );
2157     zSig0 |= ( zSig1 != 0 );
2158     if ( 0 <= (sbits64) ( zSig0<<1 ) ) {
2159         zSig0 <<= 1;
2160         --zExp;
2161     }
2162     return roundAndPackFloat64( roundData, zSign, zExp, zSig0 );
2163
2164 }
2165
2166 /*
2167 -------------------------------------------------------------------------------
2168 Returns the result of dividing the double-precision floating-point value `a'
2169 by the corresponding value `b'.  The operation is performed according to
2170 the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2171 -------------------------------------------------------------------------------
2172 */
2173 float64 float64_div( struct roundingData *roundData, float64 a, float64 b )
2174 {
2175     flag aSign, bSign, zSign;
2176     int16 aExp, bExp, zExp;
2177     bits64 aSig, bSig, zSig;
2178     bits64 rem0, rem1;
2179     bits64 term0, term1;
2180
2181     aSig = extractFloat64Frac( a );
2182     aExp = extractFloat64Exp( a );
2183     aSign = extractFloat64Sign( a );
2184     bSig = extractFloat64Frac( b );
2185     bExp = extractFloat64Exp( b );
2186     bSign = extractFloat64Sign( b );
2187     zSign = aSign ^ bSign;
2188     if ( aExp == 0x7FF ) {
2189         if ( aSig ) return propagateFloat64NaN( a, b );
2190         if ( bExp == 0x7FF ) {
2191             if ( bSig ) return propagateFloat64NaN( a, b );
2192             roundData->exception |= float_flag_invalid;
2193             return float64_default_nan;
2194         }
2195         return packFloat64( zSign, 0x7FF, 0 );
2196     }
2197     if ( bExp == 0x7FF ) {
2198         if ( bSig ) return propagateFloat64NaN( a, b );
2199         return packFloat64( zSign, 0, 0 );
2200     }
2201     if ( bExp == 0 ) {
2202         if ( bSig == 0 ) {
2203             if ( ( aExp | aSig ) == 0 ) {
2204                 roundData->exception |= float_flag_invalid;
2205                 return float64_default_nan;
2206             }
2207             roundData->exception |= float_flag_divbyzero;
2208             return packFloat64( zSign, 0x7FF, 0 );
2209         }
2210         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
2211     }
2212     if ( aExp == 0 ) {
2213         if ( aSig == 0 ) return packFloat64( zSign, 0, 0 );
2214         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
2215     }
2216     zExp = aExp - bExp + 0x3FD;
2217     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<10;
2218     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
2219     if ( bSig <= ( aSig + aSig ) ) {
2220         aSig >>= 1;
2221         ++zExp;
2222     }
2223     zSig = estimateDiv128To64( aSig, 0, bSig );
2224     if ( ( zSig & 0x1FF ) <= 2 ) {
2225         mul64To128( bSig, zSig, &term0, &term1 );
2226         sub128( aSig, 0, term0, term1, &rem0, &rem1 );
2227         while ( (sbits64) rem0 < 0 ) {
2228             --zSig;
2229             add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
2230         }
2231         zSig |= ( rem1 != 0 );
2232     }
2233     return roundAndPackFloat64( roundData, zSign, zExp, zSig );
2234
2235 }
2236
2237 /*
2238 -------------------------------------------------------------------------------
2239 Returns the remainder of the double-precision floating-point value `a'
2240 with respect to the corresponding value `b'.  The operation is performed
2241 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2242 -------------------------------------------------------------------------------
2243 */
2244 float64 float64_rem( struct roundingData *roundData, float64 a, float64 b )
2245 {
2246     flag aSign, bSign, zSign;
2247     int16 aExp, bExp, expDiff;
2248     bits64 aSig, bSig;
2249     bits64 q, alternateASig;
2250     sbits64 sigMean;
2251
2252     aSig = extractFloat64Frac( a );
2253     aExp = extractFloat64Exp( a );
2254     aSign = extractFloat64Sign( a );
2255     bSig = extractFloat64Frac( b );
2256     bExp = extractFloat64Exp( b );
2257     bSign = extractFloat64Sign( b );
2258     if ( aExp == 0x7FF ) {
2259         if ( aSig || ( ( bExp == 0x7FF ) && bSig ) ) {
2260             return propagateFloat64NaN( a, b );
2261         }
2262         roundData->exception |= float_flag_invalid;
2263         return float64_default_nan;
2264     }
2265     if ( bExp == 0x7FF ) {
2266         if ( bSig ) return propagateFloat64NaN( a, b );
2267         return a;
2268     }
2269     if ( bExp == 0 ) {
2270         if ( bSig == 0 ) {
2271             roundData->exception |= float_flag_invalid;
2272             return float64_default_nan;
2273         }
2274         normalizeFloat64Subnormal( bSig, &bExp, &bSig );
2275     }
2276     if ( aExp == 0 ) {
2277         if ( aSig == 0 ) return a;
2278         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
2279     }
2280     expDiff = aExp - bExp;
2281     aSig = ( aSig | LIT64( 0x0010000000000000 ) )<<11;
2282     bSig = ( bSig | LIT64( 0x0010000000000000 ) )<<11;
2283     if ( expDiff < 0 ) {
2284         if ( expDiff < -1 ) return a;
2285         aSig >>= 1;
2286     }
2287     q = ( bSig <= aSig );
2288     if ( q ) aSig -= bSig;
2289     expDiff -= 64;
2290     while ( 0 < expDiff ) {
2291         q = estimateDiv128To64( aSig, 0, bSig );
2292         q = ( 2 < q ) ? q - 2 : 0;
2293         aSig = - ( ( bSig>>2 ) * q );
2294         expDiff -= 62;
2295     }
2296     expDiff += 64;
2297     if ( 0 < expDiff ) {
2298         q = estimateDiv128To64( aSig, 0, bSig );
2299         q = ( 2 < q ) ? q - 2 : 0;
2300         q >>= 64 - expDiff;
2301         bSig >>= 2;
2302         aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
2303     }
2304     else {
2305         aSig >>= 2;
2306         bSig >>= 2;
2307     }
2308     do {
2309         alternateASig = aSig;
2310         ++q;
2311         aSig -= bSig;
2312     } while ( 0 <= (sbits64) aSig );
2313     sigMean = aSig + alternateASig;
2314     if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
2315         aSig = alternateASig;
2316     }
2317     zSign = ( (sbits64) aSig < 0 );
2318     if ( zSign ) aSig = - aSig;
2319     return normalizeRoundAndPackFloat64( roundData, aSign ^ zSign, bExp, aSig );
2320
2321 }
2322
2323 /*
2324 -------------------------------------------------------------------------------
2325 Returns the square root of the double-precision floating-point value `a'.
2326 The operation is performed according to the IEC/IEEE Standard for Binary
2327 Floating-point Arithmetic.
2328 -------------------------------------------------------------------------------
2329 */
2330 float64 float64_sqrt( struct roundingData *roundData, float64 a )
2331 {
2332     flag aSign;
2333     int16 aExp, zExp;
2334     bits64 aSig, zSig;
2335     bits64 rem0, rem1, term0, term1; //, shiftedRem;
2336     //float64 z;
2337
2338     aSig = extractFloat64Frac( a );
2339     aExp = extractFloat64Exp( a );
2340     aSign = extractFloat64Sign( a );
2341     if ( aExp == 0x7FF ) {
2342         if ( aSig ) return propagateFloat64NaN( a, a );
2343         if ( ! aSign ) return a;
2344         roundData->exception |= float_flag_invalid;
2345         return float64_default_nan;
2346     }
2347     if ( aSign ) {
2348         if ( ( aExp | aSig ) == 0 ) return a;
2349         roundData->exception |= float_flag_invalid;
2350         return float64_default_nan;
2351     }
2352     if ( aExp == 0 ) {
2353         if ( aSig == 0 ) return 0;
2354         normalizeFloat64Subnormal( aSig, &aExp, &aSig );
2355     }
2356     zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
2357     aSig |= LIT64( 0x0010000000000000 );
2358     zSig = estimateSqrt32( aExp, aSig>>21 );
2359     zSig <<= 31;
2360     aSig <<= 9 - ( aExp & 1 );
2361     zSig = estimateDiv128To64( aSig, 0, zSig ) + zSig + 2;
2362     if ( ( zSig & 0x3FF ) <= 5 ) {
2363         if ( zSig < 2 ) {
2364             zSig = LIT64( 0xFFFFFFFFFFFFFFFF );
2365         }
2366         else {
2367             aSig <<= 2;
2368             mul64To128( zSig, zSig, &term0, &term1 );
2369             sub128( aSig, 0, term0, term1, &rem0, &rem1 );
2370             while ( (sbits64) rem0 < 0 ) {
2371                 --zSig;
2372                 shortShift128Left( 0, zSig, 1, &term0, &term1 );
2373                 term1 |= 1;
2374                 add128( rem0, rem1, term0, term1, &rem0, &rem1 );
2375             }
2376             zSig |= ( ( rem0 | rem1 ) != 0 );
2377         }
2378     }
2379     shift64RightJamming( zSig, 1, &zSig );
2380     return roundAndPackFloat64( roundData, 0, zExp, zSig );
2381
2382 }
2383
2384 /*
2385 -------------------------------------------------------------------------------
2386 Returns 1 if the double-precision floating-point value `a' is equal to the
2387 corresponding value `b', and 0 otherwise.  The comparison is performed
2388 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2389 -------------------------------------------------------------------------------
2390 */
2391 flag float64_eq( float64 a, float64 b )
2392 {
2393
2394     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2395          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2396        ) {
2397         if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
2398             float_raise( float_flag_invalid );
2399         }
2400         return 0;
2401     }
2402     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
2403
2404 }
2405
2406 /*
2407 -------------------------------------------------------------------------------
2408 Returns 1 if the double-precision floating-point value `a' is less than or
2409 equal to the corresponding value `b', and 0 otherwise.  The comparison is
2410 performed according to the IEC/IEEE Standard for Binary Floating-point
2411 Arithmetic.
2412 -------------------------------------------------------------------------------
2413 */
2414 flag float64_le( float64 a, float64 b )
2415 {
2416     flag aSign, bSign;
2417
2418     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2419          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2420        ) {
2421         float_raise( float_flag_invalid );
2422         return 0;
2423     }
2424     aSign = extractFloat64Sign( a );
2425     bSign = extractFloat64Sign( b );
2426     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
2427     return ( a == b ) || ( aSign ^ ( a < b ) );
2428
2429 }
2430
2431 /*
2432 -------------------------------------------------------------------------------
2433 Returns 1 if the double-precision floating-point value `a' is less than
2434 the corresponding value `b', and 0 otherwise.  The comparison is performed
2435 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2436 -------------------------------------------------------------------------------
2437 */
2438 flag float64_lt( float64 a, float64 b )
2439 {
2440     flag aSign, bSign;
2441
2442     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2443          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2444        ) {
2445         float_raise( float_flag_invalid );
2446         return 0;
2447     }
2448     aSign = extractFloat64Sign( a );
2449     bSign = extractFloat64Sign( b );
2450     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
2451     return ( a != b ) && ( aSign ^ ( a < b ) );
2452
2453 }
2454
2455 /*
2456 -------------------------------------------------------------------------------
2457 Returns 1 if the double-precision floating-point value `a' is equal to the
2458 corresponding value `b', and 0 otherwise.  The invalid exception is raised
2459 if either operand is a NaN.  Otherwise, the comparison is performed
2460 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2461 -------------------------------------------------------------------------------
2462 */
2463 flag float64_eq_signaling( float64 a, float64 b )
2464 {
2465
2466     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2467          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2468        ) {
2469         float_raise( float_flag_invalid );
2470         return 0;
2471     }
2472     return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
2473
2474 }
2475
2476 /*
2477 -------------------------------------------------------------------------------
2478 Returns 1 if the double-precision floating-point value `a' is less than or
2479 equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs do not
2480 cause an exception.  Otherwise, the comparison is performed according to the
2481 IEC/IEEE Standard for Binary Floating-point Arithmetic.
2482 -------------------------------------------------------------------------------
2483 */
2484 flag float64_le_quiet( float64 a, float64 b )
2485 {
2486     flag aSign, bSign;
2487     //int16 aExp, bExp;
2488
2489     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2490          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2491        ) {
2492         /* Do nothing, even if NaN as we're quiet */
2493         return 0;
2494     }
2495     aSign = extractFloat64Sign( a );
2496     bSign = extractFloat64Sign( b );
2497     if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
2498     return ( a == b ) || ( aSign ^ ( a < b ) );
2499
2500 }
2501
2502 /*
2503 -------------------------------------------------------------------------------
2504 Returns 1 if the double-precision floating-point value `a' is less than
2505 the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause an
2506 exception.  Otherwise, the comparison is performed according to the IEC/IEEE
2507 Standard for Binary Floating-point Arithmetic.
2508 -------------------------------------------------------------------------------
2509 */
2510 flag float64_lt_quiet( float64 a, float64 b )
2511 {
2512     flag aSign, bSign;
2513
2514     if (    ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) )
2515          || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) )
2516        ) {
2517         /* Do nothing, even if NaN as we're quiet */
2518         return 0;
2519     }
2520     aSign = extractFloat64Sign( a );
2521     bSign = extractFloat64Sign( b );
2522     if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
2523     return ( a != b ) && ( aSign ^ ( a < b ) );
2524
2525 }
2526
2527 #ifdef FLOATX80
2528
2529 /*
2530 -------------------------------------------------------------------------------
2531 Returns the result of converting the extended double-precision floating-
2532 point value `a' to the 32-bit two's complement integer format.  The
2533 conversion is performed according to the IEC/IEEE Standard for Binary
2534 Floating-point Arithmetic---which means in particular that the conversion
2535 is rounded according to the current rounding mode.  If `a' is a NaN, the
2536 largest positive integer is returned.  Otherwise, if the conversion
2537 overflows, the largest integer with the same sign as `a' is returned.
2538 -------------------------------------------------------------------------------
2539 */
2540 int32 floatx80_to_int32( struct roundingData *roundData, floatx80 a )
2541 {
2542     flag aSign;
2543     int32 aExp, shiftCount;
2544     bits64 aSig;
2545
2546     aSig = extractFloatx80Frac( a );
2547     aExp = extractFloatx80Exp( a );
2548     aSign = extractFloatx80Sign( a );
2549     if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
2550     shiftCount = 0x4037 - aExp;
2551     if ( shiftCount <= 0 ) shiftCount = 1;
2552     shift64RightJamming( aSig, shiftCount, &aSig );
2553     return roundAndPackInt32( roundData, aSign, aSig );
2554
2555 }
2556
2557 /*
2558 -------------------------------------------------------------------------------
2559 Returns the result of converting the extended double-precision floating-
2560 point value `a' to the 32-bit two's complement integer format.  The
2561 conversion is performed according to the IEC/IEEE Standard for Binary
2562 Floating-point Arithmetic, except that the conversion is always rounded
2563 toward zero.  If `a' is a NaN, the largest positive integer is returned.
2564 Otherwise, if the conversion overflows, the largest integer with the same
2565 sign as `a' is returned.
2566 -------------------------------------------------------------------------------
2567 */
2568 int32 floatx80_to_int32_round_to_zero( floatx80 a )
2569 {
2570     flag aSign;
2571     int32 aExp, shiftCount;
2572     bits64 aSig, savedASig;
2573     int32 z;
2574
2575     aSig = extractFloatx80Frac( a );
2576     aExp = extractFloatx80Exp( a );
2577     aSign = extractFloatx80Sign( a );
2578     shiftCount = 0x403E - aExp;
2579     if ( shiftCount < 32 ) {
2580         if ( ( aExp == 0x7FFF ) && (bits64) ( aSig<<1 ) ) aSign = 0;
2581         goto invalid;
2582     }
2583     else if ( 63 < shiftCount ) {
2584         if ( aExp || aSig ) float_raise( float_flag_inexact );
2585         return 0;
2586     }
2587     savedASig = aSig;
2588     aSig >>= shiftCount;
2589     z = aSig;
2590     if ( aSign ) z = - z;
2591     if ( ( z < 0 ) ^ aSign ) {
2592  invalid:
2593         float_raise( float_flag_invalid );
2594         return aSign ? 0x80000000 : 0x7FFFFFFF;
2595     }
2596     if ( ( aSig<<shiftCount ) != savedASig ) {
2597         float_raise( float_flag_inexact );
2598     }
2599     return z;
2600
2601 }
2602
2603 /*
2604 -------------------------------------------------------------------------------
2605 Returns the result of converting the extended double-precision floating-
2606 point value `a' to the single-precision floating-point format.  The
2607 conversion is performed according to the IEC/IEEE Standard for Binary
2608 Floating-point Arithmetic.
2609 -------------------------------------------------------------------------------
2610 */
2611 float32 floatx80_to_float32( struct roundingData *roundData, floatx80 a )
2612 {
2613     flag aSign;
2614     int32 aExp;
2615     bits64 aSig;
2616
2617     aSig = extractFloatx80Frac( a );
2618     aExp = extractFloatx80Exp( a );
2619     aSign = extractFloatx80Sign( a );
2620     if ( aExp == 0x7FFF ) {
2621         if ( (bits64) ( aSig<<1 ) ) {
2622             return commonNaNToFloat32( floatx80ToCommonNaN( a ) );
2623         }
2624         return packFloat32( aSign, 0xFF, 0 );
2625     }
2626     shift64RightJamming( aSig, 33, &aSig );
2627     if ( aExp || aSig ) aExp -= 0x3F81;
2628     return roundAndPackFloat32( roundData, aSign, aExp, aSig );
2629
2630 }
2631
2632 /*
2633 -------------------------------------------------------------------------------
2634 Returns the result of converting the extended double-precision floating-
2635 point value `a' to the double-precision floating-point format.  The
2636 conversion is performed according to the IEC/IEEE Standard for Binary
2637 Floating-point Arithmetic.
2638 -------------------------------------------------------------------------------
2639 */
2640 float64 floatx80_to_float64( struct roundingData *roundData, floatx80 a )
2641 {
2642     flag aSign;
2643     int32 aExp;
2644     bits64 aSig, zSig;
2645
2646     aSig = extractFloatx80Frac( a );
2647     aExp = extractFloatx80Exp( a );
2648     aSign = extractFloatx80Sign( a );
2649     if ( aExp == 0x7FFF ) {
2650         if ( (bits64) ( aSig<<1 ) ) {
2651             return commonNaNToFloat64( floatx80ToCommonNaN( a ) );
2652         }
2653         return packFloat64( aSign, 0x7FF, 0 );
2654     }
2655     shift64RightJamming( aSig, 1, &zSig );
2656     if ( aExp || aSig ) aExp -= 0x3C01;
2657     return roundAndPackFloat64( roundData, aSign, aExp, zSig );
2658
2659 }
2660
2661 /*
2662 -------------------------------------------------------------------------------
2663 Rounds the extended double-precision floating-point value `a' to an integer,
2664 and returns the result as an extended quadruple-precision floating-point
2665 value.  The operation is performed according to the IEC/IEEE Standard for
2666 Binary Floating-point Arithmetic.
2667 -------------------------------------------------------------------------------
2668 */
2669 floatx80 floatx80_round_to_int( struct roundingData *roundData, floatx80 a )
2670 {
2671     flag aSign;
2672     int32 aExp;
2673     bits64 lastBitMask, roundBitsMask;
2674     int8 roundingMode;
2675     floatx80 z;
2676
2677     aExp = extractFloatx80Exp( a );
2678     if ( 0x403E <= aExp ) {
2679         if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) {
2680             return propagateFloatx80NaN( a, a );
2681         }
2682         return a;
2683     }
2684     if ( aExp <= 0x3FFE ) {
2685         if (    ( aExp == 0 )
2686              && ( (bits64) ( extractFloatx80Frac( a )<<1 ) == 0 ) ) {
2687             return a;
2688         }
2689         roundData->exception |= float_flag_inexact;
2690         aSign = extractFloatx80Sign( a );
2691         switch ( roundData->mode ) {
2692          case float_round_nearest_even:
2693             if ( ( aExp == 0x3FFE ) && (bits64) ( extractFloatx80Frac( a )<<1 )
2694                ) {
2695                 return
2696                     packFloatx80( aSign, 0x3FFF, LIT64( 0x8000000000000000 ) );
2697             }
2698             break;
2699          case float_round_down:
2700             return
2701                   aSign ?
2702                       packFloatx80( 1, 0x3FFF, LIT64( 0x8000000000000000 ) )
2703                 : packFloatx80( 0, 0, 0 );
2704          case float_round_up:
2705             return
2706                   aSign ? packFloatx80( 1, 0, 0 )
2707                 : packFloatx80( 0, 0x3FFF, LIT64( 0x8000000000000000 ) );
2708         }
2709         return packFloatx80( aSign, 0, 0 );
2710     }
2711     lastBitMask = 1;
2712     lastBitMask <<= 0x403E - aExp;
2713     roundBitsMask = lastBitMask - 1;
2714     z = a;
2715     roundingMode = roundData->mode;
2716     if ( roundingMode == float_round_nearest_even ) {
2717         z.low += lastBitMask>>1;
2718         if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
2719     }
2720     else if ( roundingMode != float_round_to_zero ) {
2721         if ( extractFloatx80Sign( z ) ^ ( roundingMode == float_round_up ) ) {
2722             z.low += roundBitsMask;
2723         }
2724     }
2725     z.low &= ~ roundBitsMask;
2726     if ( z.low == 0 ) {
2727         ++z.high;
2728         z.low = LIT64( 0x8000000000000000 );
2729     }
2730     if ( z.low != a.low ) roundData->exception |= float_flag_inexact;
2731     return z;
2732
2733 }
2734
2735 /*
2736 -------------------------------------------------------------------------------
2737 Returns the result of adding the absolute values of the extended double-
2738 precision floating-point values `a' and `b'.  If `zSign' is true, the sum is
2739 negated before being returned.  `zSign' is ignored if the result is a NaN.
2740 The addition is performed according to the IEC/IEEE Standard for Binary
2741 Floating-point Arithmetic.
2742 -------------------------------------------------------------------------------
2743 */
2744 static floatx80 addFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
2745 {
2746     int32 aExp, bExp, zExp;
2747     bits64 aSig, bSig, zSig0, zSig1;
2748     int32 expDiff;
2749
2750     aSig = extractFloatx80Frac( a );
2751     aExp = extractFloatx80Exp( a );
2752     bSig = extractFloatx80Frac( b );
2753     bExp = extractFloatx80Exp( b );
2754     expDiff = aExp - bExp;
2755     if ( 0 < expDiff ) {
2756         if ( aExp == 0x7FFF ) {
2757             if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
2758             return a;
2759         }
2760         if ( bExp == 0 ) --expDiff;
2761         shift64ExtraRightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
2762         zExp = aExp;
2763     }
2764     else if ( expDiff < 0 ) {
2765         if ( bExp == 0x7FFF ) {
2766             if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
2767             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
2768         }
2769         if ( aExp == 0 ) ++expDiff;
2770         shift64ExtraRightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
2771         zExp = bExp;
2772     }
2773     else {
2774         if ( aExp == 0x7FFF ) {
2775             if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
2776                 return propagateFloatx80NaN( a, b );
2777             }
2778             return a;
2779         }
2780         zSig1 = 0;
2781         zSig0 = aSig + bSig;
2782         if ( aExp == 0 ) {
2783             normalizeFloatx80Subnormal( zSig0, &zExp, &zSig0 );
2784             goto roundAndPack;
2785         }
2786         zExp = aExp;
2787         goto shiftRight1;
2788     }
2789     
2790     zSig0 = aSig + bSig;
2791
2792     if ( (sbits64) zSig0 < 0 ) goto roundAndPack; 
2793  shiftRight1:
2794     shift64ExtraRightJamming( zSig0, zSig1, 1, &zSig0, &zSig1 );
2795     zSig0 |= LIT64( 0x8000000000000000 );
2796     ++zExp;
2797  roundAndPack:
2798     return
2799         roundAndPackFloatx80(
2800             roundData, zSign, zExp, zSig0, zSig1 );
2801
2802 }
2803
2804 /*
2805 -------------------------------------------------------------------------------
2806 Returns the result of subtracting the absolute values of the extended
2807 double-precision floating-point values `a' and `b'.  If `zSign' is true,
2808 the difference is negated before being returned.  `zSign' is ignored if the
2809 result is a NaN.  The subtraction is performed according to the IEC/IEEE
2810 Standard for Binary Floating-point Arithmetic.
2811 -------------------------------------------------------------------------------
2812 */
2813 static floatx80 subFloatx80Sigs( struct roundingData *roundData, floatx80 a, floatx80 b, flag zSign )
2814 {
2815     int32 aExp, bExp, zExp;
2816     bits64 aSig, bSig, zSig0, zSig1;
2817     int32 expDiff;
2818     floatx80 z;
2819
2820     aSig = extractFloatx80Frac( a );
2821     aExp = extractFloatx80Exp( a );
2822     bSig = extractFloatx80Frac( b );
2823     bExp = extractFloatx80Exp( b );
2824     expDiff = aExp - bExp;
2825     if ( 0 < expDiff ) goto aExpBigger;
2826     if ( expDiff < 0 ) goto bExpBigger;
2827     if ( aExp == 0x7FFF ) {
2828         if ( (bits64) ( ( aSig | bSig )<<1 ) ) {
2829             return propagateFloatx80NaN( a, b );
2830         }
2831         roundData->exception |= float_flag_invalid;
2832         z.low = floatx80_default_nan_low;
2833         z.high = floatx80_default_nan_high;
2834         return z;
2835     }
2836     if ( aExp == 0 ) {
2837         aExp = 1;
2838         bExp = 1;
2839     }
2840     zSig1 = 0;
2841     if ( bSig < aSig ) goto aBigger;
2842     if ( aSig < bSig ) goto bBigger;
2843     return packFloatx80( roundData->mode == float_round_down, 0, 0 );
2844  bExpBigger:
2845     if ( bExp == 0x7FFF ) {
2846         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
2847         return packFloatx80( zSign ^ 1, 0x7FFF, LIT64( 0x8000000000000000 ) );
2848     }
2849     if ( aExp == 0 ) ++expDiff;
2850     shift128RightJamming( aSig, 0, - expDiff, &aSig, &zSig1 );
2851  bBigger:
2852     sub128( bSig, 0, aSig, zSig1, &zSig0, &zSig1 );
2853     zExp = bExp;
2854     zSign ^= 1;
2855     goto normalizeRoundAndPack;
2856  aExpBigger:
2857     if ( aExp == 0x7FFF ) {
2858         if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
2859         return a;
2860     }
2861     if ( bExp == 0 ) --expDiff;
2862     shift128RightJamming( bSig, 0, expDiff, &bSig, &zSig1 );
2863  aBigger:
2864     sub128( aSig, 0, bSig, zSig1, &zSig0, &zSig1 );
2865     zExp = aExp;
2866  normalizeRoundAndPack:
2867     return
2868         normalizeRoundAndPackFloatx80(
2869             roundData, zSign, zExp, zSig0, zSig1 );
2870
2871 }
2872
2873 /*
2874 -------------------------------------------------------------------------------
2875 Returns the result of adding the extended double-precision floating-point
2876 values `a' and `b'.  The operation is performed according to the IEC/IEEE
2877 Standard for Binary Floating-point Arithmetic.
2878 -------------------------------------------------------------------------------
2879 */
2880 floatx80 floatx80_add( struct roundingData *roundData, floatx80 a, floatx80 b )
2881 {
2882     flag aSign, bSign;
2883     
2884     aSign = extractFloatx80Sign( a );
2885     bSign = extractFloatx80Sign( b );
2886     if ( aSign == bSign ) {
2887         return addFloatx80Sigs( roundData, a, b, aSign );
2888     }
2889     else {
2890         return subFloatx80Sigs( roundData, a, b, aSign );
2891     }
2892     
2893 }
2894
2895 /*
2896 -------------------------------------------------------------------------------
2897 Returns the result of subtracting the extended double-precision floating-
2898 point values `a' and `b'.  The operation is performed according to the
2899 IEC/IEEE Standard for Binary Floating-point Arithmetic.
2900 -------------------------------------------------------------------------------
2901 */
2902 floatx80 floatx80_sub( struct roundingData *roundData, floatx80 a, floatx80 b )
2903 {
2904     flag aSign, bSign;
2905
2906     aSign = extractFloatx80Sign( a );
2907     bSign = extractFloatx80Sign( b );
2908     if ( aSign == bSign ) {
2909         return subFloatx80Sigs( roundData, a, b, aSign );
2910     }
2911     else {
2912         return addFloatx80Sigs( roundData, a, b, aSign );
2913     }
2914
2915 }
2916
2917 /*
2918 -------------------------------------------------------------------------------
2919 Returns the result of multiplying the extended double-precision floating-
2920 point values `a' and `b'.  The operation is performed according to the
2921 IEC/IEEE Standard for Binary Floating-point Arithmetic.
2922 -------------------------------------------------------------------------------
2923 */
2924 floatx80 floatx80_mul( struct roundingData *roundData, floatx80 a, floatx80 b )
2925 {
2926     flag aSign, bSign, zSign;
2927     int32 aExp, bExp, zExp;
2928     bits64 aSig, bSig, zSig0, zSig1;
2929     floatx80 z;
2930
2931     aSig = extractFloatx80Frac( a );
2932     aExp = extractFloatx80Exp( a );
2933     aSign = extractFloatx80Sign( a );
2934     bSig = extractFloatx80Frac( b );
2935     bExp = extractFloatx80Exp( b );
2936     bSign = extractFloatx80Sign( b );
2937     zSign = aSign ^ bSign;
2938     if ( aExp == 0x7FFF ) {
2939         if (    (bits64) ( aSig<<1 )
2940              || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
2941             return propagateFloatx80NaN( a, b );
2942         }
2943         if ( ( bExp | bSig ) == 0 ) goto invalid;
2944         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
2945     }
2946     if ( bExp == 0x7FFF ) {
2947         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
2948         if ( ( aExp | aSig ) == 0 ) {
2949  invalid:
2950             roundData->exception |= float_flag_invalid;
2951             z.low = floatx80_default_nan_low;
2952             z.high = floatx80_default_nan_high;
2953             return z;
2954         }
2955         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
2956     }
2957     if ( aExp == 0 ) {
2958         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
2959         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
2960     }
2961     if ( bExp == 0 ) {
2962         if ( bSig == 0 ) return packFloatx80( zSign, 0, 0 );
2963         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
2964     }
2965     zExp = aExp + bExp - 0x3FFE;
2966     mul64To128( aSig, bSig, &zSig0, &zSig1 );
2967     if ( 0 < (sbits64) zSig0 ) {
2968         shortShift128Left( zSig0, zSig1, 1, &zSig0, &zSig1 );
2969         --zExp;
2970     }
2971     return
2972         roundAndPackFloatx80(
2973             roundData, zSign, zExp, zSig0, zSig1 );
2974
2975 }
2976
2977 /*
2978 -------------------------------------------------------------------------------
2979 Returns the result of dividing the extended double-precision floating-point
2980 value `a' by the corresponding value `b'.  The operation is performed
2981 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
2982 -------------------------------------------------------------------------------
2983 */
2984 floatx80 floatx80_div( struct roundingData *roundData, floatx80 a, floatx80 b )
2985 {
2986     flag aSign, bSign, zSign;
2987     int32 aExp, bExp, zExp;
2988     bits64 aSig, bSig, zSig0, zSig1;
2989     bits64 rem0, rem1, rem2, term0, term1, term2;
2990     floatx80 z;
2991
2992     aSig = extractFloatx80Frac( a );
2993     aExp = extractFloatx80Exp( a );
2994     aSign = extractFloatx80Sign( a );
2995     bSig = extractFloatx80Frac( b );
2996     bExp = extractFloatx80Exp( b );
2997     bSign = extractFloatx80Sign( b );
2998     zSign = aSign ^ bSign;
2999     if ( aExp == 0x7FFF ) {
3000         if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b );
3001         if ( bExp == 0x7FFF ) {
3002             if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
3003             goto invalid;
3004         }
3005         return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
3006     }
3007     if ( bExp == 0x7FFF ) {
3008         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
3009         return packFloatx80( zSign, 0, 0 );
3010     }
3011     if ( bExp == 0 ) {
3012         if ( bSig == 0 ) {
3013             if ( ( aExp | aSig ) == 0 ) {
3014  invalid:
3015                 roundData->exception |= float_flag_invalid;
3016                 z.low = floatx80_default_nan_low;
3017                 z.high = floatx80_default_nan_high;
3018                 return z;
3019             }
3020             roundData->exception |= float_flag_divbyzero;
3021             return packFloatx80( zSign, 0x7FFF, LIT64( 0x8000000000000000 ) );
3022         }
3023         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
3024     }
3025     if ( aExp == 0 ) {
3026         if ( aSig == 0 ) return packFloatx80( zSign, 0, 0 );
3027         normalizeFloatx80Subnormal( aSig, &aExp, &aSig );
3028     }
3029     zExp = aExp - bExp + 0x3FFE;
3030     rem1 = 0;
3031     if ( bSig <= aSig ) {
3032         shift128Right( aSig, 0, 1, &aSig, &rem1 );
3033         ++zExp;
3034     }
3035     zSig0 = estimateDiv128To64( aSig, rem1, bSig );
3036     mul64To128( bSig, zSig0, &term0, &term1 );
3037     sub128( aSig, rem1, term0, term1, &rem0, &rem1 );
3038     while ( (sbits64) rem0 < 0 ) {
3039         --zSig0;
3040         add128( rem0, rem1, 0, bSig, &rem0, &rem1 );
3041     }
3042     zSig1 = estimateDiv128To64( rem1, 0, bSig );
3043     if ( (bits64) ( zSig1<<1 ) <= 8 ) {
3044         mul64To128( bSig, zSig1, &term1, &term2 );
3045         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
3046         while ( (sbits64) rem1 < 0 ) {
3047             --zSig1;
3048             add128( rem1, rem2, 0, bSig, &rem1, &rem2 );
3049         }
3050         zSig1 |= ( ( rem1 | rem2 ) != 0 );
3051     }
3052     return
3053         roundAndPackFloatx80(
3054             roundData, zSign, zExp, zSig0, zSig1 );
3055
3056 }
3057
3058 /*
3059 -------------------------------------------------------------------------------
3060 Returns the remainder of the extended double-precision floating-point value
3061 `a' with respect to the corresponding value `b'.  The operation is performed
3062 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
3063 -------------------------------------------------------------------------------
3064 */
3065 floatx80 floatx80_rem( struct roundingData *roundData, floatx80 a, floatx80 b )
3066 {
3067     flag aSign, bSign, zSign;
3068     int32 aExp, bExp, expDiff;
3069     bits64 aSig0, aSig1, bSig;
3070     bits64 q, term0, term1, alternateASig0, alternateASig1;
3071     floatx80 z;
3072
3073     aSig0 = extractFloatx80Frac( a );
3074     aExp = extractFloatx80Exp( a );
3075     aSign = extractFloatx80Sign( a );
3076     bSig = extractFloatx80Frac( b );
3077     bExp = extractFloatx80Exp( b );
3078     bSign = extractFloatx80Sign( b );
3079     if ( aExp == 0x7FFF ) {
3080         if (    (bits64) ( aSig0<<1 )
3081              || ( ( bExp == 0x7FFF ) && (bits64) ( bSig<<1 ) ) ) {
3082             return propagateFloatx80NaN( a, b );
3083         }
3084         goto invalid;
3085     }
3086     if ( bExp == 0x7FFF ) {
3087         if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b );
3088         return a;
3089     }
3090     if ( bExp == 0 ) {
3091         if ( bSig == 0 ) {
3092  invalid:
3093             roundData->exception |= float_flag_invalid;
3094             z.low = floatx80_default_nan_low;
3095             z.high = floatx80_default_nan_high;
3096             return z;
3097         }
3098         normalizeFloatx80Subnormal( bSig, &bExp, &bSig );
3099     }
3100     if ( aExp == 0 ) {
3101         if ( (bits64) ( aSig0<<1 ) == 0 ) return a;
3102         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
3103     }
3104     bSig |= LIT64( 0x8000000000000000 );
3105     zSign = aSign;
3106     expDiff = aExp - bExp;
3107     aSig1 = 0;
3108     if ( expDiff < 0 ) {
3109         if ( expDiff < -1 ) return a;
3110         shift128Right( aSig0, 0, 1, &aSig0, &aSig1 );
3111         expDiff = 0;
3112     }
3113     q = ( bSig <= aSig0 );
3114     if ( q ) aSig0 -= bSig;
3115     expDiff -= 64;
3116     while ( 0 < expDiff ) {
3117         q = estimateDiv128To64( aSig0, aSig1, bSig );
3118         q = ( 2 < q ) ? q - 2 : 0;
3119         mul64To128( bSig, q, &term0, &term1 );
3120         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3121         shortShift128Left( aSig0, aSig1, 62, &aSig0, &aSig1 );
3122         expDiff -= 62;
3123     }
3124     expDiff += 64;
3125     if ( 0 < expDiff ) {
3126         q = estimateDiv128To64( aSig0, aSig1, bSig );
3127         q = ( 2 < q ) ? q - 2 : 0;
3128         q >>= 64 - expDiff;
3129         mul64To128( bSig, q<<( 64 - expDiff ), &term0, &term1 );
3130         sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3131         shortShift128Left( 0, bSig, 64 - expDiff, &term0, &term1 );
3132         while ( le128( term0, term1, aSig0, aSig1 ) ) {
3133             ++q;
3134             sub128( aSig0, aSig1, term0, term1, &aSig0, &aSig1 );
3135         }
3136     }
3137     else {
3138         term1 = 0;
3139         term0 = bSig;
3140     }
3141     sub128( term0, term1, aSig0, aSig1, &alternateASig0, &alternateASig1 );
3142     if (    lt128( alternateASig0, alternateASig1, aSig0, aSig1 )
3143          || (    eq128( alternateASig0, alternateASig1, aSig0, aSig1 )
3144               && ( q & 1 ) )
3145        ) {
3146         aSig0 = alternateASig0;
3147         aSig1 = alternateASig1;
3148         zSign = ! zSign;
3149     }
3150
3151     return
3152         normalizeRoundAndPackFloatx80(
3153             roundData, zSign, bExp + expDiff, aSig0, aSig1 );
3154
3155 }
3156
3157 /*
3158 -------------------------------------------------------------------------------
3159 Returns the square root of the extended double-precision floating-point
3160 value `a'.  The operation is performed according to the IEC/IEEE Standard
3161 for Binary Floating-point Arithmetic.
3162 -------------------------------------------------------------------------------
3163 */
3164 floatx80 floatx80_sqrt( struct roundingData *roundData, floatx80 a )
3165 {
3166     flag aSign;
3167     int32 aExp, zExp;
3168     bits64 aSig0, aSig1, zSig0, zSig1;
3169     bits64 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
3170     bits64 shiftedRem0, shiftedRem1;
3171     floatx80 z;
3172
3173     aSig0 = extractFloatx80Frac( a );
3174     aExp = extractFloatx80Exp( a );
3175     aSign = extractFloatx80Sign( a );
3176     if ( aExp == 0x7FFF ) {
3177         if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaN( a, a );
3178         if ( ! aSign ) return a;
3179         goto invalid;
3180     }
3181     if ( aSign ) {
3182         if ( ( aExp | aSig0 ) == 0 ) return a;
3183  invalid:
3184         roundData->exception |= float_flag_invalid;
3185         z.low = floatx80_default_nan_low;
3186         z.high = floatx80_default_nan_high;
3187         return z;
3188     }
3189     if ( aExp == 0 ) {
3190         if ( aSig0 == 0 ) return packFloatx80( 0, 0, 0 );
3191         normalizeFloatx80Subnormal( aSig0, &aExp, &aSig0 );
3192     }
3193     zExp = ( ( aExp - 0x3FFF )>>1 ) + 0x3FFF;
3194     zSig0 = estimateSqrt32( aExp, aSig0>>32 );
3195     zSig0 <<= 31;
3196     aSig1 = 0;
3197     shift128Right( aSig0, 0, ( aExp & 1 ) + 2, &aSig0, &aSig1 );
3198     zSig0 = estimateDiv128To64( aSig0, aSig1, zSig0 ) + zSig0 + 4;
3199     if ( 0 <= (sbits64) zSig0 ) zSig0 = LIT64( 0xFFFFFFFFFFFFFFFF );
3200     shortShift128Left( aSig0, aSig1, 2, &aSig0, &aSig1 );
3201     mul64To128( zSig0, zSig0, &term0, &term1 );
3202     sub128( aSig0, aSig1, term0, term1, &rem0, &rem1 );
3203     while ( (sbits64) rem0 < 0 ) {
3204         --zSig0;
3205         shortShift128Left( 0, zSig0, 1, &term0, &term1 );
3206         term1 |= 1;
3207         add128( rem0, rem1, term0, term1, &rem0, &rem1 );
3208     }
3209     shortShift128Left( rem0, rem1, 63, &shiftedRem0, &shiftedRem1 );
3210     zSig1 = estimateDiv128To64( shiftedRem0, shiftedRem1, zSig0 );
3211     if ( (bits64) ( zSig1<<1 ) <= 10 ) {
3212         if ( zSig1 == 0 ) zSig1 = 1;
3213         mul64To128( zSig0, zSig1, &term1, &term2 );
3214         shortShift128Left( term1, term2, 1, &term1, &term2 );
3215         sub128( rem1, 0, term1, term2, &rem1, &rem2 );
3216         mul64To128( zSig1, zSig1, &term2, &term3 );
3217         sub192( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
3218         while ( (sbits64) rem1 < 0 ) {
3219             --zSig1;
3220             shortShift192Left( 0, zSig0, zSig1, 1, &term1, &term2, &term3 );
3221             term3 |= 1;
3222             add192(
3223                 rem1, rem2, rem3, term1, term2, term3, &rem1, &rem2, &rem3 );
3224         }
3225         zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
3226     }
3227     return
3228         roundAndPackFloatx80(
3229             roundData, 0, zExp, zSig0, zSig1 );
3230
3231 }
3232
3233 /*
3234 -------------------------------------------------------------------------------
3235 Returns 1 if the extended double-precision floating-point value `a' is
3236 equal to the corresponding value `b', and 0 otherwise.  The comparison is
3237 performed according to the IEC/IEEE Standard for Binary Floating-point
3238 Arithmetic.
3239 -------------------------------------------------------------------------------
3240 */
3241 flag floatx80_eq( floatx80 a, floatx80 b )
3242 {
3243
3244     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
3245               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3246          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
3247               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3248        ) {
3249         if (    floatx80_is_signaling_nan( a )
3250              || floatx80_is_signaling_nan( b ) ) {
3251             float_raise( float_flag_invalid );
3252         }
3253         return 0;
3254     }
3255     return
3256            ( a.low == b.low )
3257         && (    ( a.high == b.high )
3258              || (    ( a.low == 0 )
3259                   && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
3260            );
3261
3262 }
3263
3264 /*
3265 -------------------------------------------------------------------------------
3266 Returns 1 if the extended double-precision floating-point value `a' is
3267 less than or equal to the corresponding value `b', and 0 otherwise.  The
3268 comparison is performed according to the IEC/IEEE Standard for Binary
3269 Floating-point Arithmetic.
3270 -------------------------------------------------------------------------------
3271 */
3272 flag floatx80_le( floatx80 a, floatx80 b )
3273 {
3274     flag aSign, bSign;
3275
3276     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
3277               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3278          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
3279               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3280        ) {
3281         float_raise( float_flag_invalid );
3282         return 0;
3283     }
3284     aSign = extractFloatx80Sign( a );
3285     bSign = extractFloatx80Sign( b );
3286     if ( aSign != bSign ) {
3287         return
3288                aSign
3289             || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3290                  == 0 );
3291     }
3292     return
3293           aSign ? le128( b.high, b.low, a.high, a.low )
3294         : le128( a.high, a.low, b.high, b.low );
3295
3296 }
3297
3298 /*
3299 -------------------------------------------------------------------------------
3300 Returns 1 if the extended double-precision floating-point value `a' is
3301 less than the corresponding value `b', and 0 otherwise.  The comparison
3302 is performed according to the IEC/IEEE Standard for Binary Floating-point
3303 Arithmetic.
3304 -------------------------------------------------------------------------------
3305 */
3306 flag floatx80_lt( floatx80 a, floatx80 b )
3307 {
3308     flag aSign, bSign;
3309
3310     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
3311               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3312          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
3313               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3314        ) {
3315         float_raise( float_flag_invalid );
3316         return 0;
3317     }
3318     aSign = extractFloatx80Sign( a );
3319     bSign = extractFloatx80Sign( b );
3320     if ( aSign != bSign ) {
3321         return
3322                aSign
3323             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3324                  != 0 );
3325     }
3326     return
3327           aSign ? lt128( b.high, b.low, a.high, a.low )
3328         : lt128( a.high, a.low, b.high, b.low );
3329
3330 }
3331
3332 /*
3333 -------------------------------------------------------------------------------
3334 Returns 1 if the extended double-precision floating-point value `a' is equal
3335 to the corresponding value `b', and 0 otherwise.  The invalid exception is
3336 raised if either operand is a NaN.  Otherwise, the comparison is performed
3337 according to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
3338 -------------------------------------------------------------------------------
3339 */
3340 flag floatx80_eq_signaling( floatx80 a, floatx80 b )
3341 {
3342
3343     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
3344               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3345          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
3346               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3347        ) {
3348         float_raise( float_flag_invalid );
3349         return 0;
3350     }
3351     return
3352            ( a.low == b.low )
3353         && (    ( a.high == b.high )
3354              || (    ( a.low == 0 )
3355                   && ( (bits16) ( ( a.high | b.high )<<1 ) == 0 ) )
3356            );
3357
3358 }
3359
3360 /*
3361 -------------------------------------------------------------------------------
3362 Returns 1 if the extended double-precision floating-point value `a' is less
3363 than or equal to the corresponding value `b', and 0 otherwise.  Quiet NaNs
3364 do not cause an exception.  Otherwise, the comparison is performed according
3365 to the IEC/IEEE Standard for Binary Floating-point Arithmetic.
3366 -------------------------------------------------------------------------------
3367 */
3368 flag floatx80_le_quiet( floatx80 a, floatx80 b )
3369 {
3370     flag aSign, bSign;
3371
3372     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
3373               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3374          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
3375               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3376        ) {
3377         /* Do nothing, even if NaN as we're quiet */
3378         return 0;
3379     }
3380     aSign = extractFloatx80Sign( a );
3381     bSign = extractFloatx80Sign( b );
3382     if ( aSign != bSign ) {
3383         return
3384                aSign
3385             || (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3386                  == 0 );
3387     }
3388     return
3389           aSign ? le128( b.high, b.low, a.high, a.low )
3390         : le128( a.high, a.low, b.high, b.low );
3391
3392 }
3393
3394 /*
3395 -------------------------------------------------------------------------------
3396 Returns 1 if the extended double-precision floating-point value `a' is less
3397 than the corresponding value `b', and 0 otherwise.  Quiet NaNs do not cause
3398 an exception.  Otherwise, the comparison is performed according to the
3399 IEC/IEEE Standard for Binary Floating-point Arithmetic.
3400 -------------------------------------------------------------------------------
3401 */
3402 flag floatx80_lt_quiet( floatx80 a, floatx80 b )
3403 {
3404     flag aSign, bSign;
3405
3406     if (    (    ( extractFloatx80Exp( a ) == 0x7FFF )
3407               && (bits64) ( extractFloatx80Frac( a )<<1 ) )
3408          || (    ( extractFloatx80Exp( b ) == 0x7FFF )
3409               && (bits64) ( extractFloatx80Frac( b )<<1 ) )
3410        ) {
3411         /* Do nothing, even if NaN as we're quiet */
3412         return 0;
3413     }
3414     aSign = extractFloatx80Sign( a );
3415     bSign = extractFloatx80Sign( b );
3416     if ( aSign != bSign ) {
3417         return
3418                aSign
3419             && (    ( ( (bits16) ( ( a.high | b.high )<<1 ) ) | a.low | b.low )
3420                  != 0 );
3421     }
3422     return
3423           aSign ? lt128( b.high, b.low, a.high, a.low )
3424         : lt128( a.high, a.low, b.high, b.low );
3425
3426 }
3427
3428 #endif
3429