]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Library/ArmSoftFloatLib/bits32/softfloat.c
759b8a0077e1be37e9e3e64e1347968d3bf4fa85
[mirror_edk2.git] / ArmPkg / Library / ArmSoftFloatLib / bits32 / softfloat.c
1 /* $NetBSD: softfloat.c,v 1.3 2013/01/10 08:16:11 matt Exp $ */
2
3 /*
4 * This version hacked for use with gcc -msoft-float by bjh21.
5 * (Mostly a case of #ifdefing out things GCC doesn't need or provides
6 * itself).
7 */
8
9 /*
10 * Things you may want to define:
11 *
12 * SOFTFLOAT_FOR_GCC - build only those functions necessary for GCC (with
13 * -msoft-float) to work. Include "softfloat-for-gcc.h" to get them
14 * properly renamed.
15 */
16
17 /*
18 * This differs from the standard bits32/softfloat.c in that float64
19 * is defined to be a 64-bit integer rather than a structure. The
20 * structure is float64s, with translation between the two going via
21 * float64u.
22 */
23
24 /*
25 ===============================================================================
26
27 This C source file is part of the SoftFloat IEC/IEEE Floating-Point
28 Arithmetic Package, Release 2a.
29
30 Written by John R. Hauser. This work was made possible in part by the
31 International Computer Science Institute, located at Suite 600, 1947 Center
32 Street, Berkeley, California 94704. Funding was partially provided by the
33 National Science Foundation under grant MIP-9311980. The original version
34 of this code was written as part of a project to build a fixed-point vector
35 processor in collaboration with the University of California at Berkeley,
36 overseen by Profs. Nelson Morgan and John Wawrzynek. More information
37 is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
38 arithmetic/SoftFloat.html'.
39
40 THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE. Although reasonable effort
41 has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
42 TIMES RESULT IN INCORRECT BEHAVIOR. USE OF THIS SOFTWARE IS RESTRICTED TO
43 PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
44 AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.
45
46 Derivative works are acceptable, even for commercial purposes, so long as
47 (1) they include prominent notice that the work is derivative, and (2) they
48 include prominent notice akin to these four paragraphs for those parts of
49 this code that are retained.
50
51 ===============================================================================
52 */
53
54 #if defined(LIBC_SCCS) && !defined(lint)
55 __RCSID("$NetBSD: softfloat.c,v 1.3 2013/01/10 08:16:11 matt Exp $");
56 #endif /* LIBC_SCCS and not lint */
57
58 #ifdef SOFTFLOAT_FOR_GCC
59 #include "softfloat-for-gcc.h"
60 #endif
61
62 #include "milieu.h"
63 #include "softfloat.h"
64
65 /*
66 * Conversions between floats as stored in memory and floats as
67 * SoftFloat uses them
68 */
69 #ifndef FLOAT64_DEMANGLE
70 #define FLOAT64_DEMANGLE(a) (a)
71 #endif
72 #ifndef FLOAT64_MANGLE
73 #define FLOAT64_MANGLE(a) (a)
74 #endif
75
76 /*
77 -------------------------------------------------------------------------------
78 Floating-point rounding mode and exception flags.
79 -------------------------------------------------------------------------------
80 */
81 #ifndef set_float_rounding_mode
82 fp_rnd float_rounding_mode = float_round_nearest_even;
83 fp_except float_exception_flags = 0;
84 #endif
85 #ifndef set_float_exception_inexact_flag
86 #define set_float_exception_inexact_flag() \
87 ((void)(float_exception_flags |= float_flag_inexact))
88 #endif
89
90 /*
91 -------------------------------------------------------------------------------
92 Primitive arithmetic functions, including multi-word arithmetic, and
93 division and square root approximations. (Can be specialized to target if
94 desired.)
95 -------------------------------------------------------------------------------
96 */
97 #include "softfloat-macros"
98
99 /*
100 -------------------------------------------------------------------------------
101 Functions and definitions to determine: (1) whether tininess for underflow
102 is detected before or after rounding by default, (2) what (if anything)
103 happens when exceptions are raised, (3) how signaling NaNs are distinguished
104 from quiet NaNs, (4) the default generated quiet NaNs, and (4) how NaNs
105 are propagated from function inputs to output. These details are target-
106 specific.
107 -------------------------------------------------------------------------------
108 */
109 #include "softfloat-specialize"
110
111 /*
112 -------------------------------------------------------------------------------
113 Returns the fraction bits of the single-precision floating-point value `a'.
114 -------------------------------------------------------------------------------
115 */
116 INLINE bits32 extractFloat32Frac( float32 a )
117 {
118
119 return a & 0x007FFFFF;
120
121 }
122
123 /*
124 -------------------------------------------------------------------------------
125 Returns the exponent bits of the single-precision floating-point value `a'.
126 -------------------------------------------------------------------------------
127 */
128 INLINE int16 extractFloat32Exp( float32 a )
129 {
130
131 return ( a>>23 ) & 0xFF;
132
133 }
134
135 /*
136 -------------------------------------------------------------------------------
137 Returns the sign bit of the single-precision floating-point value `a'.
138 -------------------------------------------------------------------------------
139 */
140 INLINE flag extractFloat32Sign( float32 a )
141 {
142
143 return a>>31;
144
145 }
146
147 /*
148 -------------------------------------------------------------------------------
149 Normalizes the subnormal single-precision floating-point value represented
150 by the denormalized significand `aSig'. The normalized exponent and
151 significand are stored at the locations pointed to by `zExpPtr' and
152 `zSigPtr', respectively.
153 -------------------------------------------------------------------------------
154 */
155 static void
156 normalizeFloat32Subnormal( bits32 aSig, int16 *zExpPtr, bits32 *zSigPtr )
157 {
158 int8 shiftCount;
159
160 shiftCount = countLeadingZeros32( aSig ) - 8;
161 *zSigPtr = aSig<<shiftCount;
162 *zExpPtr = 1 - shiftCount;
163
164 }
165
166 /*
167 -------------------------------------------------------------------------------
168 Packs the sign `zSign', exponent `zExp', and significand `zSig' into a
169 single-precision floating-point value, returning the result. After being
170 shifted into the proper positions, the three fields are simply added
171 together to form the result. This means that any integer portion of `zSig'
172 will be added into the exponent. Since a properly normalized significand
173 will have an integer portion equal to 1, the `zExp' input should be 1 less
174 than the desired result exponent whenever `zSig' is a complete, normalized
175 significand.
176 -------------------------------------------------------------------------------
177 */
178 INLINE float32 packFloat32( flag zSign, int16 zExp, bits32 zSig )
179 {
180
181 return ( ( (bits32) zSign )<<31 ) + ( ( (bits32) zExp )<<23 ) + zSig;
182
183 }
184
185 /*
186 -------------------------------------------------------------------------------
187 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
188 and significand `zSig', and returns the proper single-precision floating-
189 point value corresponding to the abstract input. Ordinarily, the abstract
190 value is simply rounded and packed into the single-precision format, with
191 the inexact exception raised if the abstract input cannot be represented
192 exactly. However, if the abstract value is too large, the overflow and
193 inexact exceptions are raised and an infinity or maximal finite value is
194 returned. If the abstract value is too small, the input value is rounded to
195 a subnormal number, and the underflow and inexact exceptions are raised if
196 the abstract input cannot be represented exactly as a subnormal single-
197 precision floating-point number.
198 The input significand `zSig' has its binary point between bits 30
199 and 29, which is 7 bits to the left of the usual location. This shifted
200 significand must be normalized or smaller. If `zSig' is not normalized,
201 `zExp' must be 0; in that case, the result returned is a subnormal number,
202 and it must not require rounding. In the usual case that `zSig' is
203 normalized, `zExp' must be 1 less than the ``true'' floating-point exponent.
204 The handling of underflow and overflow follows the IEC/IEEE Standard for
205 Binary Floating-Point Arithmetic.
206 -------------------------------------------------------------------------------
207 */
208 static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
209 {
210 int8 roundingMode;
211 flag roundNearestEven;
212 int8 roundIncrement, roundBits;
213 flag isTiny;
214
215 roundingMode = float_rounding_mode;
216 roundNearestEven = roundingMode == float_round_nearest_even;
217 roundIncrement = 0x40;
218 if ( ! roundNearestEven ) {
219 if ( roundingMode == float_round_to_zero ) {
220 roundIncrement = 0;
221 }
222 else {
223 roundIncrement = 0x7F;
224 if ( zSign ) {
225 if ( roundingMode == float_round_up ) roundIncrement = 0;
226 }
227 else {
228 if ( roundingMode == float_round_down ) roundIncrement = 0;
229 }
230 }
231 }
232 roundBits = zSig & 0x7F;
233 if ( 0xFD <= (bits16) zExp ) {
234 if ( ( 0xFD < zExp )
235 || ( ( zExp == 0xFD )
236 && ( (sbits32) ( zSig + roundIncrement ) < 0 ) )
237 ) {
238 float_raise( float_flag_overflow | float_flag_inexact );
239 return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 );
240 }
241 if ( zExp < 0 ) {
242 isTiny =
243 ( float_detect_tininess == float_tininess_before_rounding )
244 || ( zExp < -1 )
245 || ( zSig + roundIncrement < (uint32)0x80000000 );
246 shift32RightJamming( zSig, - zExp, &zSig );
247 zExp = 0;
248 roundBits = zSig & 0x7F;
249 if ( isTiny && roundBits ) float_raise( float_flag_underflow );
250 }
251 }
252 if ( roundBits ) set_float_exception_inexact_flag();
253 zSig = ( zSig + roundIncrement )>>7;
254 zSig &= ~ ( ( ( roundBits ^ 0x40 ) == 0 ) & roundNearestEven );
255 if ( zSig == 0 ) zExp = 0;
256 return packFloat32( zSign, zExp, zSig );
257
258 }
259
260 /*
261 -------------------------------------------------------------------------------
262 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
263 and significand `zSig', and returns the proper single-precision floating-
264 point value corresponding to the abstract input. This routine is just like
265 `roundAndPackFloat32' except that `zSig' does not have to be normalized.
266 Bit 31 of `zSig' must be zero, and `zExp' must be 1 less than the ``true''
267 floating-point exponent.
268 -------------------------------------------------------------------------------
269 */
270 static float32
271 normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig )
272 {
273 int8 shiftCount;
274
275 shiftCount = countLeadingZeros32( zSig ) - 1;
276 return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount );
277
278 }
279
280 /*
281 -------------------------------------------------------------------------------
282 Returns the least-significant 32 fraction bits of the double-precision
283 floating-point value `a'.
284 -------------------------------------------------------------------------------
285 */
286 INLINE bits32 extractFloat64Frac1( float64 a )
287 {
288
289 return (bits32)(FLOAT64_DEMANGLE(a) & LIT64(0x00000000FFFFFFFF));
290
291 }
292
293 /*
294 -------------------------------------------------------------------------------
295 Returns the most-significant 20 fraction bits of the double-precision
296 floating-point value `a'.
297 -------------------------------------------------------------------------------
298 */
299 INLINE bits32 extractFloat64Frac0( float64 a )
300 {
301
302 return (bits32)((FLOAT64_DEMANGLE(a) >> 32) & 0x000FFFFF);
303
304 }
305
306 /*
307 -------------------------------------------------------------------------------
308 Returns the exponent bits of the double-precision floating-point value `a'.
309 -------------------------------------------------------------------------------
310 */
311 INLINE int16 extractFloat64Exp( float64 a )
312 {
313
314 return (int16)((FLOAT64_DEMANGLE(a) >> 52) & 0x7FF);
315
316 }
317
318 /*
319 -------------------------------------------------------------------------------
320 Returns the sign bit of the double-precision floating-point value `a'.
321 -------------------------------------------------------------------------------
322 */
323 INLINE flag extractFloat64Sign( float64 a )
324 {
325
326 return (flag)(FLOAT64_DEMANGLE(a) >> 63);
327
328 }
329
330 /*
331 -------------------------------------------------------------------------------
332 Normalizes the subnormal double-precision floating-point value represented
333 by the denormalized significand formed by the concatenation of `aSig0' and
334 `aSig1'. The normalized exponent is stored at the location pointed to by
335 `zExpPtr'. The most significant 21 bits of the normalized significand are
336 stored at the location pointed to by `zSig0Ptr', and the least significant
337 32 bits of the normalized significand are stored at the location pointed to
338 by `zSig1Ptr'.
339 -------------------------------------------------------------------------------
340 */
341 static void
342 normalizeFloat64Subnormal(
343 bits32 aSig0,
344 bits32 aSig1,
345 int16 *zExpPtr,
346 bits32 *zSig0Ptr,
347 bits32 *zSig1Ptr
348 )
349 {
350 int8 shiftCount;
351
352 if ( aSig0 == 0 ) {
353 shiftCount = countLeadingZeros32( aSig1 ) - 11;
354 if ( shiftCount < 0 ) {
355 *zSig0Ptr = aSig1>>( - shiftCount );
356 *zSig1Ptr = aSig1<<( shiftCount & 31 );
357 }
358 else {
359 *zSig0Ptr = aSig1<<shiftCount;
360 *zSig1Ptr = 0;
361 }
362 *zExpPtr = - shiftCount - 31;
363 }
364 else {
365 shiftCount = countLeadingZeros32( aSig0 ) - 11;
366 shortShift64Left( aSig0, aSig1, shiftCount, zSig0Ptr, zSig1Ptr );
367 *zExpPtr = 1 - shiftCount;
368 }
369
370 }
371
372 /*
373 -------------------------------------------------------------------------------
374 Packs the sign `zSign', the exponent `zExp', and the significand formed by
375 the concatenation of `zSig0' and `zSig1' into a double-precision floating-
376 point value, returning the result. After being shifted into the proper
377 positions, the three fields `zSign', `zExp', and `zSig0' are simply added
378 together to form the most significant 32 bits of the result. This means
379 that any integer portion of `zSig0' will be added into the exponent. Since
380 a properly normalized significand will have an integer portion equal to 1,
381 the `zExp' input should be 1 less than the desired result exponent whenever
382 `zSig0' and `zSig1' concatenated form a complete, normalized significand.
383 -------------------------------------------------------------------------------
384 */
385 INLINE float64
386 packFloat64( flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1 )
387 {
388
389 return FLOAT64_MANGLE( ( ( (bits64) zSign )<<63 ) +
390 ( ( (bits64) zExp )<<52 ) +
391 ( ( (bits64) zSig0 )<<32 ) + zSig1 );
392
393
394 }
395
396 /*
397 -------------------------------------------------------------------------------
398 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
399 and extended significand formed by the concatenation of `zSig0', `zSig1',
400 and `zSig2', and returns the proper double-precision floating-point value
401 corresponding to the abstract input. Ordinarily, the abstract value is
402 simply rounded and packed into the double-precision format, with the inexact
403 exception raised if the abstract input cannot be represented exactly.
404 However, if the abstract value is too large, the overflow and inexact
405 exceptions are raised and an infinity or maximal finite value is returned.
406 If the abstract value is too small, the input value is rounded to a
407 subnormal number, and the underflow and inexact exceptions are raised if the
408 abstract input cannot be represented exactly as a subnormal double-precision
409 floating-point number.
410 The input significand must be normalized or smaller. If the input
411 significand is not normalized, `zExp' must be 0; in that case, the result
412 returned is a subnormal number, and it must not require rounding. In the
413 usual case that the input significand is normalized, `zExp' must be 1 less
414 than the ``true'' floating-point exponent. The handling of underflow and
415 overflow follows the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
416 -------------------------------------------------------------------------------
417 */
418 static float64
419 roundAndPackFloat64(
420 flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1, bits32 zSig2 )
421 {
422 int8 roundingMode;
423 flag roundNearestEven, increment, isTiny;
424
425 roundingMode = float_rounding_mode;
426 roundNearestEven = ( roundingMode == float_round_nearest_even );
427 increment = ( (sbits32) zSig2 < 0 );
428 if ( ! roundNearestEven ) {
429 if ( roundingMode == float_round_to_zero ) {
430 increment = 0;
431 }
432 else {
433 if ( zSign ) {
434 increment = ( roundingMode == float_round_down ) && zSig2;
435 }
436 else {
437 increment = ( roundingMode == float_round_up ) && zSig2;
438 }
439 }
440 }
441 if ( 0x7FD <= (bits16) zExp ) {
442 if ( ( 0x7FD < zExp )
443 || ( ( zExp == 0x7FD )
444 && eq64( 0x001FFFFF, 0xFFFFFFFF, zSig0, zSig1 )
445 && increment
446 )
447 ) {
448 float_raise( float_flag_overflow | float_flag_inexact );
449 if ( ( roundingMode == float_round_to_zero )
450 || ( zSign && ( roundingMode == float_round_up ) )
451 || ( ! zSign && ( roundingMode == float_round_down ) )
452 ) {
453 return packFloat64( zSign, 0x7FE, 0x000FFFFF, 0xFFFFFFFF );
454 }
455 return packFloat64( zSign, 0x7FF, 0, 0 );
456 }
457 if ( zExp < 0 ) {
458 isTiny =
459 ( float_detect_tininess == float_tininess_before_rounding )
460 || ( zExp < -1 )
461 || ! increment
462 || lt64( zSig0, zSig1, 0x001FFFFF, 0xFFFFFFFF );
463 shift64ExtraRightJamming(
464 zSig0, zSig1, zSig2, - zExp, &zSig0, &zSig1, &zSig2 );
465 zExp = 0;
466 if ( isTiny && zSig2 ) float_raise( float_flag_underflow );
467 if ( roundNearestEven ) {
468 increment = ( (sbits32) zSig2 < 0 );
469 }
470 else {
471 if ( zSign ) {
472 increment = ( roundingMode == float_round_down ) && zSig2;
473 }
474 else {
475 increment = ( roundingMode == float_round_up ) && zSig2;
476 }
477 }
478 }
479 }
480 if ( zSig2 ) set_float_exception_inexact_flag();
481 if ( increment ) {
482 add64( zSig0, zSig1, 0, 1, &zSig0, &zSig1 );
483 zSig1 &= ~ ( ( zSig2 + zSig2 == 0 ) & roundNearestEven );
484 }
485 else {
486 if ( ( zSig0 | zSig1 ) == 0 ) zExp = 0;
487 }
488 return packFloat64( zSign, zExp, zSig0, zSig1 );
489
490 }
491
492 /*
493 -------------------------------------------------------------------------------
494 Takes an abstract floating-point value having sign `zSign', exponent `zExp',
495 and significand formed by the concatenation of `zSig0' and `zSig1', and
496 returns the proper double-precision floating-point value corresponding
497 to the abstract input. This routine is just like `roundAndPackFloat64'
498 except that the input significand has fewer bits and does not have to be
499 normalized. In all cases, `zExp' must be 1 less than the ``true'' floating-
500 point exponent.
501 -------------------------------------------------------------------------------
502 */
503 static float64
504 normalizeRoundAndPackFloat64(
505 flag zSign, int16 zExp, bits32 zSig0, bits32 zSig1 )
506 {
507 int8 shiftCount;
508 bits32 zSig2;
509
510 if ( zSig0 == 0 ) {
511 zSig0 = zSig1;
512 zSig1 = 0;
513 zExp -= 32;
514 }
515 shiftCount = countLeadingZeros32( zSig0 ) - 11;
516 if ( 0 <= shiftCount ) {
517 zSig2 = 0;
518 shortShift64Left( zSig0, zSig1, shiftCount, &zSig0, &zSig1 );
519 }
520 else {
521 shift64ExtraRightJamming(
522 zSig0, zSig1, 0, - shiftCount, &zSig0, &zSig1, &zSig2 );
523 }
524 zExp -= shiftCount;
525 return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 );
526
527 }
528
529 /*
530 -------------------------------------------------------------------------------
531 Returns the result of converting the 32-bit two's complement integer `a' to
532 the single-precision floating-point format. The conversion is performed
533 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
534 -------------------------------------------------------------------------------
535 */
536 float32 int32_to_float32( int32 a )
537 {
538 flag zSign;
539
540 if ( a == 0 ) return 0;
541 if ( a == (sbits32) 0x80000000 ) return packFloat32( 1, 0x9E, 0 );
542 zSign = ( a < 0 );
543 return normalizeRoundAndPackFloat32(zSign, 0x9C, (uint32)(zSign ? - a : a));
544
545 }
546
547 /*
548 -------------------------------------------------------------------------------
549 Returns the result of converting the 32-bit two's complement integer `a' to
550 the double-precision floating-point format. The conversion is performed
551 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
552 -------------------------------------------------------------------------------
553 */
554 float64 int32_to_float64( int32 a )
555 {
556 flag zSign;
557 bits32 absA;
558 int8 shiftCount;
559 bits32 zSig0, zSig1;
560
561 if ( a == 0 ) return packFloat64( 0, 0, 0, 0 );
562 zSign = ( a < 0 );
563 absA = zSign ? - a : a;
564 shiftCount = countLeadingZeros32( absA ) - 11;
565 if ( 0 <= shiftCount ) {
566 zSig0 = absA<<shiftCount;
567 zSig1 = 0;
568 }
569 else {
570 shift64Right( absA, 0, - shiftCount, &zSig0, &zSig1 );
571 }
572 return packFloat64( zSign, 0x412 - shiftCount, zSig0, zSig1 );
573
574 }
575
576 #ifndef SOFTFLOAT_FOR_GCC
577 /*
578 -------------------------------------------------------------------------------
579 Returns the result of converting the single-precision floating-point value
580 `a' to the 32-bit two's complement integer format. The conversion is
581 performed according to the IEC/IEEE Standard for Binary Floating-Point
582 Arithmetic---which means in particular that the conversion is rounded
583 according to the current rounding mode. If `a' is a NaN, the largest
584 positive integer is returned. Otherwise, if the conversion overflows, the
585 largest integer with the same sign as `a' is returned.
586 -------------------------------------------------------------------------------
587 */
588 int32 float32_to_int32( float32 a )
589 {
590 flag aSign;
591 int16 aExp, shiftCount;
592 bits32 aSig, aSigExtra;
593 int32 z;
594 int8 roundingMode;
595
596 aSig = extractFloat32Frac( a );
597 aExp = extractFloat32Exp( a );
598 aSign = extractFloat32Sign( a );
599 shiftCount = aExp - 0x96;
600 if ( 0 <= shiftCount ) {
601 if ( 0x9E <= aExp ) {
602 if ( a != 0xCF000000 ) {
603 float_raise( float_flag_invalid );
604 if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) {
605 return 0x7FFFFFFF;
606 }
607 }
608 return (sbits32) 0x80000000;
609 }
610 z = ( aSig | 0x00800000 )<<shiftCount;
611 if ( aSign ) z = - z;
612 }
613 else {
614 if ( aExp < 0x7E ) {
615 aSigExtra = aExp | aSig;
616 z = 0;
617 }
618 else {
619 aSig |= 0x00800000;
620 aSigExtra = aSig<<( shiftCount & 31 );
621 z = aSig>>( - shiftCount );
622 }
623 if ( aSigExtra ) set_float_exception_inexact_flag();
624 roundingMode = float_rounding_mode;
625 if ( roundingMode == float_round_nearest_even ) {
626 if ( (sbits32) aSigExtra < 0 ) {
627 ++z;
628 if ( (bits32) ( aSigExtra<<1 ) == 0 ) z &= ~1;
629 }
630 if ( aSign ) z = - z;
631 }
632 else {
633 aSigExtra = ( aSigExtra != 0 );
634 if ( aSign ) {
635 z += ( roundingMode == float_round_down ) & aSigExtra;
636 z = - z;
637 }
638 else {
639 z += ( roundingMode == float_round_up ) & aSigExtra;
640 }
641 }
642 }
643 return z;
644
645 }
646 #endif
647
648 /*
649 -------------------------------------------------------------------------------
650 Returns the result of converting the single-precision floating-point value
651 `a' to the 32-bit two's complement integer format. The conversion is
652 performed according to the IEC/IEEE Standard for Binary Floating-Point
653 Arithmetic, except that the conversion is always rounded toward zero.
654 If `a' is a NaN, the largest positive integer is returned. Otherwise, if
655 the conversion overflows, the largest integer with the same sign as `a' is
656 returned.
657 -------------------------------------------------------------------------------
658 */
659 int32 float32_to_int32_round_to_zero( float32 a )
660 {
661 flag aSign;
662 int16 aExp, shiftCount;
663 bits32 aSig;
664 int32 z;
665
666 aSig = extractFloat32Frac( a );
667 aExp = extractFloat32Exp( a );
668 aSign = extractFloat32Sign( a );
669 shiftCount = aExp - 0x9E;
670 if ( 0 <= shiftCount ) {
671 if ( a != 0xCF000000 ) {
672 float_raise( float_flag_invalid );
673 if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) return 0x7FFFFFFF;
674 }
675 return (sbits32) 0x80000000;
676 }
677 else if ( aExp <= 0x7E ) {
678 if ( aExp | aSig ) set_float_exception_inexact_flag();
679 return 0;
680 }
681 aSig = ( aSig | 0x00800000 )<<8;
682 z = aSig>>( - shiftCount );
683 if ( (bits32) ( aSig<<( shiftCount & 31 ) ) ) {
684 set_float_exception_inexact_flag();
685 }
686 if ( aSign ) z = - z;
687 return z;
688
689 }
690
691 /*
692 -------------------------------------------------------------------------------
693 Returns the result of converting the single-precision floating-point value
694 `a' to the double-precision floating-point format. The conversion is
695 performed according to the IEC/IEEE Standard for Binary Floating-Point
696 Arithmetic.
697 -------------------------------------------------------------------------------
698 */
699 float64 float32_to_float64( float32 a )
700 {
701 flag aSign;
702 int16 aExp;
703 bits32 aSig, zSig0, zSig1;
704
705 aSig = extractFloat32Frac( a );
706 aExp = extractFloat32Exp( a );
707 aSign = extractFloat32Sign( a );
708 if ( aExp == 0xFF ) {
709 if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a ) );
710 return packFloat64( aSign, 0x7FF, 0, 0 );
711 }
712 if ( aExp == 0 ) {
713 if ( aSig == 0 ) return packFloat64( aSign, 0, 0, 0 );
714 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
715 --aExp;
716 }
717 shift64Right( aSig, 0, 3, &zSig0, &zSig1 );
718 return packFloat64( aSign, aExp + 0x380, zSig0, zSig1 );
719
720 }
721
722 #ifndef SOFTFLOAT_FOR_GCC
723 /*
724 -------------------------------------------------------------------------------
725 Rounds the single-precision floating-point value `a' to an integer,
726 and returns the result as a single-precision floating-point value. The
727 operation is performed according to the IEC/IEEE Standard for Binary
728 Floating-Point Arithmetic.
729 -------------------------------------------------------------------------------
730 */
731 float32 float32_round_to_int( float32 a )
732 {
733 flag aSign;
734 int16 aExp;
735 bits32 lastBitMask, roundBitsMask;
736 int8 roundingMode;
737 float32 z;
738
739 aExp = extractFloat32Exp( a );
740 if ( 0x96 <= aExp ) {
741 if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) {
742 return propagateFloat32NaN( a, a );
743 }
744 return a;
745 }
746 if ( aExp <= 0x7E ) {
747 if ( (bits32) ( a<<1 ) == 0 ) return a;
748 set_float_exception_inexact_flag();
749 aSign = extractFloat32Sign( a );
750 switch ( float_rounding_mode ) {
751 case float_round_nearest_even:
752 if ( ( aExp == 0x7E ) && extractFloat32Frac( a ) ) {
753 return packFloat32( aSign, 0x7F, 0 );
754 }
755 break;
756 case float_round_to_zero:
757 break;
758 case float_round_down:
759 return aSign ? 0xBF800000 : 0;
760 case float_round_up:
761 return aSign ? 0x80000000 : 0x3F800000;
762 }
763 return packFloat32( aSign, 0, 0 );
764 }
765 lastBitMask = 1;
766 lastBitMask <<= 0x96 - aExp;
767 roundBitsMask = lastBitMask - 1;
768 z = a;
769 roundingMode = float_rounding_mode;
770 if ( roundingMode == float_round_nearest_even ) {
771 z += lastBitMask>>1;
772 if ( ( z & roundBitsMask ) == 0 ) z &= ~ lastBitMask;
773 }
774 else if ( roundingMode != float_round_to_zero ) {
775 if ( extractFloat32Sign( z ) ^ ( roundingMode == float_round_up ) ) {
776 z += roundBitsMask;
777 }
778 }
779 z &= ~ roundBitsMask;
780 if ( z != a ) set_float_exception_inexact_flag();
781 return z;
782
783 }
784 #endif
785
786 /*
787 -------------------------------------------------------------------------------
788 Returns the result of adding the absolute values of the single-precision
789 floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
790 before being returned. `zSign' is ignored if the result is a NaN.
791 The addition is performed according to the IEC/IEEE Standard for Binary
792 Floating-Point Arithmetic.
793 -------------------------------------------------------------------------------
794 */
795 static float32 addFloat32Sigs( float32 a, float32 b, flag zSign )
796 {
797 int16 aExp, bExp, zExp;
798 bits32 aSig, bSig, zSig;
799 int16 expDiff;
800
801 aSig = extractFloat32Frac( a );
802 aExp = extractFloat32Exp( a );
803 bSig = extractFloat32Frac( b );
804 bExp = extractFloat32Exp( b );
805 expDiff = aExp - bExp;
806 aSig <<= 6;
807 bSig <<= 6;
808 if ( 0 < expDiff ) {
809 if ( aExp == 0xFF ) {
810 if ( aSig ) return propagateFloat32NaN( a, b );
811 return a;
812 }
813 if ( bExp == 0 ) {
814 --expDiff;
815 }
816 else {
817 bSig |= 0x20000000;
818 }
819 shift32RightJamming( bSig, expDiff, &bSig );
820 zExp = aExp;
821 }
822 else if ( expDiff < 0 ) {
823 if ( bExp == 0xFF ) {
824 if ( bSig ) return propagateFloat32NaN( a, b );
825 return packFloat32( zSign, 0xFF, 0 );
826 }
827 if ( aExp == 0 ) {
828 ++expDiff;
829 }
830 else {
831 aSig |= 0x20000000;
832 }
833 shift32RightJamming( aSig, - expDiff, &aSig );
834 zExp = bExp;
835 }
836 else {
837 if ( aExp == 0xFF ) {
838 if ( aSig | bSig ) return propagateFloat32NaN( a, b );
839 return a;
840 }
841 if ( aExp == 0 ) return packFloat32( zSign, 0, ( aSig + bSig )>>6 );
842 zSig = 0x40000000 + aSig + bSig;
843 zExp = aExp;
844 goto roundAndPack;
845 }
846 aSig |= 0x20000000;
847 zSig = ( aSig + bSig )<<1;
848 --zExp;
849 if ( (sbits32) zSig < 0 ) {
850 zSig = aSig + bSig;
851 ++zExp;
852 }
853 roundAndPack:
854 return roundAndPackFloat32( zSign, zExp, zSig );
855
856 }
857
858 /*
859 -------------------------------------------------------------------------------
860 Returns the result of subtracting the absolute values of the single-
861 precision floating-point values `a' and `b'. If `zSign' is 1, the
862 difference is negated before being returned. `zSign' is ignored if the
863 result is a NaN. The subtraction is performed according to the IEC/IEEE
864 Standard for Binary Floating-Point Arithmetic.
865 -------------------------------------------------------------------------------
866 */
867 static float32 subFloat32Sigs( float32 a, float32 b, flag zSign )
868 {
869 int16 aExp, bExp, zExp;
870 bits32 aSig, bSig, zSig;
871 int16 expDiff;
872
873 aSig = extractFloat32Frac( a );
874 aExp = extractFloat32Exp( a );
875 bSig = extractFloat32Frac( b );
876 bExp = extractFloat32Exp( b );
877 expDiff = aExp - bExp;
878 aSig <<= 7;
879 bSig <<= 7;
880 if ( 0 < expDiff ) goto aExpBigger;
881 if ( expDiff < 0 ) goto bExpBigger;
882 if ( aExp == 0xFF ) {
883 if ( aSig | bSig ) return propagateFloat32NaN( a, b );
884 float_raise( float_flag_invalid );
885 return float32_default_nan;
886 }
887 if ( aExp == 0 ) {
888 aExp = 1;
889 bExp = 1;
890 }
891 if ( bSig < aSig ) goto aBigger;
892 if ( aSig < bSig ) goto bBigger;
893 return packFloat32( float_rounding_mode == float_round_down, 0, 0 );
894 bExpBigger:
895 if ( bExp == 0xFF ) {
896 if ( bSig ) return propagateFloat32NaN( a, b );
897 return packFloat32( zSign ^ 1, 0xFF, 0 );
898 }
899 if ( aExp == 0 ) {
900 ++expDiff;
901 }
902 else {
903 aSig |= 0x40000000;
904 }
905 shift32RightJamming( aSig, - expDiff, &aSig );
906 bSig |= 0x40000000;
907 bBigger:
908 zSig = bSig - aSig;
909 zExp = bExp;
910 zSign ^= 1;
911 goto normalizeRoundAndPack;
912 aExpBigger:
913 if ( aExp == 0xFF ) {
914 if ( aSig ) return propagateFloat32NaN( a, b );
915 return a;
916 }
917 if ( bExp == 0 ) {
918 --expDiff;
919 }
920 else {
921 bSig |= 0x40000000;
922 }
923 shift32RightJamming( bSig, expDiff, &bSig );
924 aSig |= 0x40000000;
925 aBigger:
926 zSig = aSig - bSig;
927 zExp = aExp;
928 normalizeRoundAndPack:
929 --zExp;
930 return normalizeRoundAndPackFloat32( zSign, zExp, zSig );
931
932 }
933
934 /*
935 -------------------------------------------------------------------------------
936 Returns the result of adding the single-precision floating-point values `a'
937 and `b'. The operation is performed according to the IEC/IEEE Standard for
938 Binary Floating-Point Arithmetic.
939 -------------------------------------------------------------------------------
940 */
941 float32 float32_add( float32 a, float32 b )
942 {
943 flag aSign, bSign;
944
945 aSign = extractFloat32Sign( a );
946 bSign = extractFloat32Sign( b );
947 if ( aSign == bSign ) {
948 return addFloat32Sigs( a, b, aSign );
949 }
950 else {
951 return subFloat32Sigs( a, b, aSign );
952 }
953
954 }
955
956 /*
957 -------------------------------------------------------------------------------
958 Returns the result of subtracting the single-precision floating-point values
959 `a' and `b'. The operation is performed according to the IEC/IEEE Standard
960 for Binary Floating-Point Arithmetic.
961 -------------------------------------------------------------------------------
962 */
963 float32 float32_sub( float32 a, float32 b )
964 {
965 flag aSign, bSign;
966
967 aSign = extractFloat32Sign( a );
968 bSign = extractFloat32Sign( b );
969 if ( aSign == bSign ) {
970 return subFloat32Sigs( a, b, aSign );
971 }
972 else {
973 return addFloat32Sigs( a, b, aSign );
974 }
975
976 }
977
978 /*
979 -------------------------------------------------------------------------------
980 Returns the result of multiplying the single-precision floating-point values
981 `a' and `b'. The operation is performed according to the IEC/IEEE Standard
982 for Binary Floating-Point Arithmetic.
983 -------------------------------------------------------------------------------
984 */
985 float32 float32_mul( float32 a, float32 b )
986 {
987 flag aSign, bSign, zSign;
988 int16 aExp, bExp, zExp;
989 bits32 aSig, bSig, zSig0, zSig1;
990
991 aSig = extractFloat32Frac( a );
992 aExp = extractFloat32Exp( a );
993 aSign = extractFloat32Sign( a );
994 bSig = extractFloat32Frac( b );
995 bExp = extractFloat32Exp( b );
996 bSign = extractFloat32Sign( b );
997 zSign = aSign ^ bSign;
998 if ( aExp == 0xFF ) {
999 if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
1000 return propagateFloat32NaN( a, b );
1001 }
1002 if ( ( bExp | bSig ) == 0 ) {
1003 float_raise( float_flag_invalid );
1004 return float32_default_nan;
1005 }
1006 return packFloat32( zSign, 0xFF, 0 );
1007 }
1008 if ( bExp == 0xFF ) {
1009 if ( bSig ) return propagateFloat32NaN( a, b );
1010 if ( ( aExp | aSig ) == 0 ) {
1011 float_raise( float_flag_invalid );
1012 return float32_default_nan;
1013 }
1014 return packFloat32( zSign, 0xFF, 0 );
1015 }
1016 if ( aExp == 0 ) {
1017 if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
1018 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1019 }
1020 if ( bExp == 0 ) {
1021 if ( bSig == 0 ) return packFloat32( zSign, 0, 0 );
1022 normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1023 }
1024 zExp = aExp + bExp - 0x7F;
1025 aSig = ( aSig | 0x00800000 )<<7;
1026 bSig = ( bSig | 0x00800000 )<<8;
1027 mul32To64( aSig, bSig, &zSig0, &zSig1 );
1028 zSig0 |= ( zSig1 != 0 );
1029 if ( 0 <= (sbits32) ( zSig0<<1 ) ) {
1030 zSig0 <<= 1;
1031 --zExp;
1032 }
1033 return roundAndPackFloat32( zSign, zExp, zSig0 );
1034
1035 }
1036
1037 /*
1038 -------------------------------------------------------------------------------
1039 Returns the result of dividing the single-precision floating-point value `a'
1040 by the corresponding value `b'. The operation is performed according to the
1041 IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1042 -------------------------------------------------------------------------------
1043 */
1044 float32 float32_div( float32 a, float32 b )
1045 {
1046 flag aSign, bSign, zSign;
1047 int16 aExp, bExp, zExp;
1048 bits32 aSig, bSig, zSig, rem0, rem1, term0, term1;
1049
1050 aSig = extractFloat32Frac( a );
1051 aExp = extractFloat32Exp( a );
1052 aSign = extractFloat32Sign( a );
1053 bSig = extractFloat32Frac( b );
1054 bExp = extractFloat32Exp( b );
1055 bSign = extractFloat32Sign( b );
1056 zSign = aSign ^ bSign;
1057 if ( aExp == 0xFF ) {
1058 if ( aSig ) return propagateFloat32NaN( a, b );
1059 if ( bExp == 0xFF ) {
1060 if ( bSig ) return propagateFloat32NaN( a, b );
1061 float_raise( float_flag_invalid );
1062 return float32_default_nan;
1063 }
1064 return packFloat32( zSign, 0xFF, 0 );
1065 }
1066 if ( bExp == 0xFF ) {
1067 if ( bSig ) return propagateFloat32NaN( a, b );
1068 return packFloat32( zSign, 0, 0 );
1069 }
1070 if ( bExp == 0 ) {
1071 if ( bSig == 0 ) {
1072 if ( ( aExp | aSig ) == 0 ) {
1073 float_raise( float_flag_invalid );
1074 return float32_default_nan;
1075 }
1076 float_raise( float_flag_divbyzero );
1077 return packFloat32( zSign, 0xFF, 0 );
1078 }
1079 normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1080 }
1081 if ( aExp == 0 ) {
1082 if ( aSig == 0 ) return packFloat32( zSign, 0, 0 );
1083 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1084 }
1085 zExp = aExp - bExp + 0x7D;
1086 aSig = ( aSig | 0x00800000 )<<7;
1087 bSig = ( bSig | 0x00800000 )<<8;
1088 if ( bSig <= ( aSig + aSig ) ) {
1089 aSig >>= 1;
1090 ++zExp;
1091 }
1092 zSig = estimateDiv64To32( aSig, 0, bSig );
1093 if ( ( zSig & 0x3F ) <= 2 ) {
1094 mul32To64( bSig, zSig, &term0, &term1 );
1095 sub64( aSig, 0, term0, term1, &rem0, &rem1 );
1096 while ( (sbits32) rem0 < 0 ) {
1097 --zSig;
1098 add64( rem0, rem1, 0, bSig, &rem0, &rem1 );
1099 }
1100 zSig |= ( rem1 != 0 );
1101 }
1102 return roundAndPackFloat32( zSign, zExp, zSig );
1103
1104 }
1105
1106 #ifndef SOFTFLOAT_FOR_GCC
1107 /*
1108 -------------------------------------------------------------------------------
1109 Returns the remainder of the single-precision floating-point value `a'
1110 with respect to the corresponding value `b'. The operation is performed
1111 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1112 -------------------------------------------------------------------------------
1113 */
1114 float32 float32_rem( float32 a, float32 b )
1115 {
1116 flag aSign, bSign, zSign;
1117 int16 aExp, bExp, expDiff;
1118 bits32 aSig, bSig, q, allZero, alternateASig;
1119 sbits32 sigMean;
1120
1121 aSig = extractFloat32Frac( a );
1122 aExp = extractFloat32Exp( a );
1123 aSign = extractFloat32Sign( a );
1124 bSig = extractFloat32Frac( b );
1125 bExp = extractFloat32Exp( b );
1126 bSign = extractFloat32Sign( b );
1127 if ( aExp == 0xFF ) {
1128 if ( aSig || ( ( bExp == 0xFF ) && bSig ) ) {
1129 return propagateFloat32NaN( a, b );
1130 }
1131 float_raise( float_flag_invalid );
1132 return float32_default_nan;
1133 }
1134 if ( bExp == 0xFF ) {
1135 if ( bSig ) return propagateFloat32NaN( a, b );
1136 return a;
1137 }
1138 if ( bExp == 0 ) {
1139 if ( bSig == 0 ) {
1140 float_raise( float_flag_invalid );
1141 return float32_default_nan;
1142 }
1143 normalizeFloat32Subnormal( bSig, &bExp, &bSig );
1144 }
1145 if ( aExp == 0 ) {
1146 if ( aSig == 0 ) return a;
1147 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1148 }
1149 expDiff = aExp - bExp;
1150 aSig = ( aSig | 0x00800000 )<<8;
1151 bSig = ( bSig | 0x00800000 )<<8;
1152 if ( expDiff < 0 ) {
1153 if ( expDiff < -1 ) return a;
1154 aSig >>= 1;
1155 }
1156 q = ( bSig <= aSig );
1157 if ( q ) aSig -= bSig;
1158 expDiff -= 32;
1159 while ( 0 < expDiff ) {
1160 q = estimateDiv64To32( aSig, 0, bSig );
1161 q = ( 2 < q ) ? q - 2 : 0;
1162 aSig = - ( ( bSig>>2 ) * q );
1163 expDiff -= 30;
1164 }
1165 expDiff += 32;
1166 if ( 0 < expDiff ) {
1167 q = estimateDiv64To32( aSig, 0, bSig );
1168 q = ( 2 < q ) ? q - 2 : 0;
1169 q >>= 32 - expDiff;
1170 bSig >>= 2;
1171 aSig = ( ( aSig>>1 )<<( expDiff - 1 ) ) - bSig * q;
1172 }
1173 else {
1174 aSig >>= 2;
1175 bSig >>= 2;
1176 }
1177 do {
1178 alternateASig = aSig;
1179 ++q;
1180 aSig -= bSig;
1181 } while ( 0 <= (sbits32) aSig );
1182 sigMean = aSig + alternateASig;
1183 if ( ( sigMean < 0 ) || ( ( sigMean == 0 ) && ( q & 1 ) ) ) {
1184 aSig = alternateASig;
1185 }
1186 zSign = ( (sbits32) aSig < 0 );
1187 if ( zSign ) aSig = - aSig;
1188 return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig );
1189
1190 }
1191 #endif
1192
1193 #ifndef SOFTFLOAT_FOR_GCC
1194 /*
1195 -------------------------------------------------------------------------------
1196 Returns the square root of the single-precision floating-point value `a'.
1197 The operation is performed according to the IEC/IEEE Standard for Binary
1198 Floating-Point Arithmetic.
1199 -------------------------------------------------------------------------------
1200 */
1201 float32 float32_sqrt( float32 a )
1202 {
1203 flag aSign;
1204 int16 aExp, zExp;
1205 bits32 aSig, zSig, rem0, rem1, term0, term1;
1206
1207 aSig = extractFloat32Frac( a );
1208 aExp = extractFloat32Exp( a );
1209 aSign = extractFloat32Sign( a );
1210 if ( aExp == 0xFF ) {
1211 if ( aSig ) return propagateFloat32NaN( a, 0 );
1212 if ( ! aSign ) return a;
1213 float_raise( float_flag_invalid );
1214 return float32_default_nan;
1215 }
1216 if ( aSign ) {
1217 if ( ( aExp | aSig ) == 0 ) return a;
1218 float_raise( float_flag_invalid );
1219 return float32_default_nan;
1220 }
1221 if ( aExp == 0 ) {
1222 if ( aSig == 0 ) return 0;
1223 normalizeFloat32Subnormal( aSig, &aExp, &aSig );
1224 }
1225 zExp = ( ( aExp - 0x7F )>>1 ) + 0x7E;
1226 aSig = ( aSig | 0x00800000 )<<8;
1227 zSig = estimateSqrt32( aExp, aSig ) + 2;
1228 if ( ( zSig & 0x7F ) <= 5 ) {
1229 if ( zSig < 2 ) {
1230 zSig = 0x7FFFFFFF;
1231 goto roundAndPack;
1232 }
1233 else {
1234 aSig >>= aExp & 1;
1235 mul32To64( zSig, zSig, &term0, &term1 );
1236 sub64( aSig, 0, term0, term1, &rem0, &rem1 );
1237 while ( (sbits32) rem0 < 0 ) {
1238 --zSig;
1239 shortShift64Left( 0, zSig, 1, &term0, &term1 );
1240 term1 |= 1;
1241 add64( rem0, rem1, term0, term1, &rem0, &rem1 );
1242 }
1243 zSig |= ( ( rem0 | rem1 ) != 0 );
1244 }
1245 }
1246 shift32RightJamming( zSig, 1, &zSig );
1247 roundAndPack:
1248 return roundAndPackFloat32( 0, zExp, zSig );
1249
1250 }
1251 #endif
1252
1253 /*
1254 -------------------------------------------------------------------------------
1255 Returns 1 if the single-precision floating-point value `a' is equal to
1256 the corresponding value `b', and 0 otherwise. The comparison is performed
1257 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1258 -------------------------------------------------------------------------------
1259 */
1260 flag float32_eq( float32 a, float32 b )
1261 {
1262
1263 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1264 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1265 ) {
1266 if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
1267 float_raise( float_flag_invalid );
1268 }
1269 return 0;
1270 }
1271 return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
1272
1273 }
1274
1275 /*
1276 -------------------------------------------------------------------------------
1277 Returns 1 if the single-precision floating-point value `a' is less than
1278 or equal to the corresponding value `b', and 0 otherwise. The comparison
1279 is performed according to the IEC/IEEE Standard for Binary Floating-Point
1280 Arithmetic.
1281 -------------------------------------------------------------------------------
1282 */
1283 flag float32_le( float32 a, float32 b )
1284 {
1285 flag aSign, bSign;
1286
1287 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1288 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1289 ) {
1290 float_raise( float_flag_invalid );
1291 return 0;
1292 }
1293 aSign = extractFloat32Sign( a );
1294 bSign = extractFloat32Sign( b );
1295 if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
1296 return ( a == b ) || ( aSign ^ ( a < b ) );
1297
1298 }
1299
1300 /*
1301 -------------------------------------------------------------------------------
1302 Returns 1 if the single-precision floating-point value `a' is less than
1303 the corresponding value `b', and 0 otherwise. The comparison is performed
1304 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1305 -------------------------------------------------------------------------------
1306 */
1307 flag float32_lt( float32 a, float32 b )
1308 {
1309 flag aSign, bSign;
1310
1311 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1312 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1313 ) {
1314 float_raise( float_flag_invalid );
1315 return 0;
1316 }
1317 aSign = extractFloat32Sign( a );
1318 bSign = extractFloat32Sign( b );
1319 if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
1320 return ( a != b ) && ( aSign ^ ( a < b ) );
1321
1322 }
1323
1324 #ifndef SOFTFLOAT_FOR_GCC /* Not needed */
1325 /*
1326 -------------------------------------------------------------------------------
1327 Returns 1 if the single-precision floating-point value `a' is equal to
1328 the corresponding value `b', and 0 otherwise. The invalid exception is
1329 raised if either operand is a NaN. Otherwise, the comparison is performed
1330 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1331 -------------------------------------------------------------------------------
1332 */
1333 flag float32_eq_signaling( float32 a, float32 b )
1334 {
1335
1336 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1337 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1338 ) {
1339 float_raise( float_flag_invalid );
1340 return 0;
1341 }
1342 return ( a == b ) || ( (bits32) ( ( a | b )<<1 ) == 0 );
1343
1344 }
1345
1346 /*
1347 -------------------------------------------------------------------------------
1348 Returns 1 if the single-precision floating-point value `a' is less than or
1349 equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
1350 cause an exception. Otherwise, the comparison is performed according to the
1351 IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1352 -------------------------------------------------------------------------------
1353 */
1354 flag float32_le_quiet( float32 a, float32 b )
1355 {
1356 flag aSign, bSign;
1357 int16 aExp, bExp;
1358
1359 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1360 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1361 ) {
1362 if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
1363 float_raise( float_flag_invalid );
1364 }
1365 return 0;
1366 }
1367 aSign = extractFloat32Sign( a );
1368 bSign = extractFloat32Sign( b );
1369 if ( aSign != bSign ) return aSign || ( (bits32) ( ( a | b )<<1 ) == 0 );
1370 return ( a == b ) || ( aSign ^ ( a < b ) );
1371
1372 }
1373
1374 /*
1375 -------------------------------------------------------------------------------
1376 Returns 1 if the single-precision floating-point value `a' is less than
1377 the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
1378 exception. Otherwise, the comparison is performed according to the IEC/IEEE
1379 Standard for Binary Floating-Point Arithmetic.
1380 -------------------------------------------------------------------------------
1381 */
1382 flag float32_lt_quiet( float32 a, float32 b )
1383 {
1384 flag aSign, bSign;
1385
1386 if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) )
1387 || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) )
1388 ) {
1389 if ( float32_is_signaling_nan( a ) || float32_is_signaling_nan( b ) ) {
1390 float_raise( float_flag_invalid );
1391 }
1392 return 0;
1393 }
1394 aSign = extractFloat32Sign( a );
1395 bSign = extractFloat32Sign( b );
1396 if ( aSign != bSign ) return aSign && ( (bits32) ( ( a | b )<<1 ) != 0 );
1397 return ( a != b ) && ( aSign ^ ( a < b ) );
1398
1399 }
1400 #endif /* !SOFTFLOAT_FOR_GCC */
1401
1402 #ifndef SOFTFLOAT_FOR_GCC /* Not needed */
1403 /*
1404 -------------------------------------------------------------------------------
1405 Returns the result of converting the double-precision floating-point value
1406 `a' to the 32-bit two's complement integer format. The conversion is
1407 performed according to the IEC/IEEE Standard for Binary Floating-Point
1408 Arithmetic---which means in particular that the conversion is rounded
1409 according to the current rounding mode. If `a' is a NaN, the largest
1410 positive integer is returned. Otherwise, if the conversion overflows, the
1411 largest integer with the same sign as `a' is returned.
1412 -------------------------------------------------------------------------------
1413 */
1414 int32 float64_to_int32( float64 a )
1415 {
1416 flag aSign;
1417 int16 aExp, shiftCount;
1418 bits32 aSig0, aSig1, absZ, aSigExtra;
1419 int32 z;
1420 int8 roundingMode;
1421
1422 aSig1 = extractFloat64Frac1( a );
1423 aSig0 = extractFloat64Frac0( a );
1424 aExp = extractFloat64Exp( a );
1425 aSign = extractFloat64Sign( a );
1426 shiftCount = aExp - 0x413;
1427 if ( 0 <= shiftCount ) {
1428 if ( 0x41E < aExp ) {
1429 if ( ( aExp == 0x7FF ) && ( aSig0 | aSig1 ) ) aSign = 0;
1430 goto invalid;
1431 }
1432 shortShift64Left(
1433 aSig0 | 0x00100000, aSig1, shiftCount, &absZ, &aSigExtra );
1434 if ( 0x80000000 < absZ ) goto invalid;
1435 }
1436 else {
1437 aSig1 = ( aSig1 != 0 );
1438 if ( aExp < 0x3FE ) {
1439 aSigExtra = aExp | aSig0 | aSig1;
1440 absZ = 0;
1441 }
1442 else {
1443 aSig0 |= 0x00100000;
1444 aSigExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1;
1445 absZ = aSig0>>( - shiftCount );
1446 }
1447 }
1448 roundingMode = float_rounding_mode;
1449 if ( roundingMode == float_round_nearest_even ) {
1450 if ( (sbits32) aSigExtra < 0 ) {
1451 ++absZ;
1452 if ( (bits32) ( aSigExtra<<1 ) == 0 ) absZ &= ~1;
1453 }
1454 z = aSign ? - absZ : absZ;
1455 }
1456 else {
1457 aSigExtra = ( aSigExtra != 0 );
1458 if ( aSign ) {
1459 z = - ( absZ
1460 + ( ( roundingMode == float_round_down ) & aSigExtra ) );
1461 }
1462 else {
1463 z = absZ + ( ( roundingMode == float_round_up ) & aSigExtra );
1464 }
1465 }
1466 if ( ( aSign ^ ( z < 0 ) ) && z ) {
1467 invalid:
1468 float_raise( float_flag_invalid );
1469 return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
1470 }
1471 if ( aSigExtra ) set_float_exception_inexact_flag();
1472 return z;
1473
1474 }
1475 #endif /* !SOFTFLOAT_FOR_GCC */
1476
1477 /*
1478 -------------------------------------------------------------------------------
1479 Returns the result of converting the double-precision floating-point value
1480 `a' to the 32-bit two's complement integer format. The conversion is
1481 performed according to the IEC/IEEE Standard for Binary Floating-Point
1482 Arithmetic, except that the conversion is always rounded toward zero.
1483 If `a' is a NaN, the largest positive integer is returned. Otherwise, if
1484 the conversion overflows, the largest integer with the same sign as `a' is
1485 returned.
1486 -------------------------------------------------------------------------------
1487 */
1488 int32 float64_to_int32_round_to_zero( float64 a )
1489 {
1490 flag aSign;
1491 int16 aExp, shiftCount;
1492 bits32 aSig0, aSig1, absZ, aSigExtra;
1493 int32 z;
1494
1495 aSig1 = extractFloat64Frac1( a );
1496 aSig0 = extractFloat64Frac0( a );
1497 aExp = extractFloat64Exp( a );
1498 aSign = extractFloat64Sign( a );
1499 shiftCount = aExp - 0x413;
1500 if ( 0 <= shiftCount ) {
1501 if ( 0x41E < aExp ) {
1502 if ( ( aExp == 0x7FF ) && ( aSig0 | aSig1 ) ) aSign = 0;
1503 goto invalid;
1504 }
1505 shortShift64Left(
1506 aSig0 | 0x00100000, aSig1, shiftCount, &absZ, &aSigExtra );
1507 }
1508 else {
1509 if ( aExp < 0x3FF ) {
1510 if ( aExp | aSig0 | aSig1 ) {
1511 set_float_exception_inexact_flag();
1512 }
1513 return 0;
1514 }
1515 aSig0 |= 0x00100000;
1516 aSigExtra = ( aSig0<<( shiftCount & 31 ) ) | aSig1;
1517 absZ = aSig0>>( - shiftCount );
1518 }
1519 z = aSign ? - absZ : absZ;
1520 if ( ( aSign ^ ( z < 0 ) ) && z ) {
1521 invalid:
1522 float_raise( float_flag_invalid );
1523 return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF;
1524 }
1525 if ( aSigExtra ) set_float_exception_inexact_flag();
1526 return z;
1527
1528 }
1529
1530 /*
1531 -------------------------------------------------------------------------------
1532 Returns the result of converting the double-precision floating-point value
1533 `a' to the single-precision floating-point format. The conversion is
1534 performed according to the IEC/IEEE Standard for Binary Floating-Point
1535 Arithmetic.
1536 -------------------------------------------------------------------------------
1537 */
1538 float32 float64_to_float32( float64 a )
1539 {
1540 flag aSign;
1541 int16 aExp;
1542 bits32 aSig0, aSig1, zSig;
1543 bits32 allZero;
1544
1545 aSig1 = extractFloat64Frac1( a );
1546 aSig0 = extractFloat64Frac0( a );
1547 aExp = extractFloat64Exp( a );
1548 aSign = extractFloat64Sign( a );
1549 if ( aExp == 0x7FF ) {
1550 if ( aSig0 | aSig1 ) {
1551 return commonNaNToFloat32( float64ToCommonNaN( a ) );
1552 }
1553 return packFloat32( aSign, 0xFF, 0 );
1554 }
1555 shift64RightJamming( aSig0, aSig1, 22, &allZero, &zSig );
1556 if ( aExp ) zSig |= 0x40000000;
1557 return roundAndPackFloat32( aSign, aExp - 0x381, zSig );
1558
1559 }
1560
1561 #ifndef SOFTFLOAT_FOR_GCC
1562 /*
1563 -------------------------------------------------------------------------------
1564 Rounds the double-precision floating-point value `a' to an integer,
1565 and returns the result as a double-precision floating-point value. The
1566 operation is performed according to the IEC/IEEE Standard for Binary
1567 Floating-Point Arithmetic.
1568 -------------------------------------------------------------------------------
1569 */
1570 float64 float64_round_to_int( float64 a )
1571 {
1572 flag aSign;
1573 int16 aExp;
1574 bits32 lastBitMask, roundBitsMask;
1575 int8 roundingMode;
1576 float64 z;
1577
1578 aExp = extractFloat64Exp( a );
1579 if ( 0x413 <= aExp ) {
1580 if ( 0x433 <= aExp ) {
1581 if ( ( aExp == 0x7FF )
1582 && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) ) {
1583 return propagateFloat64NaN( a, a );
1584 }
1585 return a;
1586 }
1587 lastBitMask = 1;
1588 lastBitMask = ( lastBitMask<<( 0x432 - aExp ) )<<1;
1589 roundBitsMask = lastBitMask - 1;
1590 z = a;
1591 roundingMode = float_rounding_mode;
1592 if ( roundingMode == float_round_nearest_even ) {
1593 if ( lastBitMask ) {
1594 add64( z.high, z.low, 0, lastBitMask>>1, &z.high, &z.low );
1595 if ( ( z.low & roundBitsMask ) == 0 ) z.low &= ~ lastBitMask;
1596 }
1597 else {
1598 if ( (sbits32) z.low < 0 ) {
1599 ++z.high;
1600 if ( (bits32) ( z.low<<1 ) == 0 ) z.high &= ~1;
1601 }
1602 }
1603 }
1604 else if ( roundingMode != float_round_to_zero ) {
1605 if ( extractFloat64Sign( z )
1606 ^ ( roundingMode == float_round_up ) ) {
1607 add64( z.high, z.low, 0, roundBitsMask, &z.high, &z.low );
1608 }
1609 }
1610 z.low &= ~ roundBitsMask;
1611 }
1612 else {
1613 if ( aExp <= 0x3FE ) {
1614 if ( ( ( (bits32) ( a.high<<1 ) ) | a.low ) == 0 ) return a;
1615 set_float_exception_inexact_flag();
1616 aSign = extractFloat64Sign( a );
1617 switch ( float_rounding_mode ) {
1618 case float_round_nearest_even:
1619 if ( ( aExp == 0x3FE )
1620 && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) )
1621 ) {
1622 return packFloat64( aSign, 0x3FF, 0, 0 );
1623 }
1624 break;
1625 case float_round_down:
1626 return
1627 aSign ? packFloat64( 1, 0x3FF, 0, 0 )
1628 : packFloat64( 0, 0, 0, 0 );
1629 case float_round_up:
1630 return
1631 aSign ? packFloat64( 1, 0, 0, 0 )
1632 : packFloat64( 0, 0x3FF, 0, 0 );
1633 }
1634 return packFloat64( aSign, 0, 0, 0 );
1635 }
1636 lastBitMask = 1;
1637 lastBitMask <<= 0x413 - aExp;
1638 roundBitsMask = lastBitMask - 1;
1639 z.low = 0;
1640 z.high = a.high;
1641 roundingMode = float_rounding_mode;
1642 if ( roundingMode == float_round_nearest_even ) {
1643 z.high += lastBitMask>>1;
1644 if ( ( ( z.high & roundBitsMask ) | a.low ) == 0 ) {
1645 z.high &= ~ lastBitMask;
1646 }
1647 }
1648 else if ( roundingMode != float_round_to_zero ) {
1649 if ( extractFloat64Sign( z )
1650 ^ ( roundingMode == float_round_up ) ) {
1651 z.high |= ( a.low != 0 );
1652 z.high += roundBitsMask;
1653 }
1654 }
1655 z.high &= ~ roundBitsMask;
1656 }
1657 if ( ( z.low != a.low ) || ( z.high != a.high ) ) {
1658 set_float_exception_inexact_flag();
1659 }
1660 return z;
1661
1662 }
1663 #endif
1664
1665 /*
1666 -------------------------------------------------------------------------------
1667 Returns the result of adding the absolute values of the double-precision
1668 floating-point values `a' and `b'. If `zSign' is 1, the sum is negated
1669 before being returned. `zSign' is ignored if the result is a NaN.
1670 The addition is performed according to the IEC/IEEE Standard for Binary
1671 Floating-Point Arithmetic.
1672 -------------------------------------------------------------------------------
1673 */
1674 static float64 addFloat64Sigs( float64 a, float64 b, flag zSign )
1675 {
1676 int16 aExp, bExp, zExp;
1677 bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
1678 int16 expDiff;
1679
1680 aSig1 = extractFloat64Frac1( a );
1681 aSig0 = extractFloat64Frac0( a );
1682 aExp = extractFloat64Exp( a );
1683 bSig1 = extractFloat64Frac1( b );
1684 bSig0 = extractFloat64Frac0( b );
1685 bExp = extractFloat64Exp( b );
1686 expDiff = aExp - bExp;
1687 if ( 0 < expDiff ) {
1688 if ( aExp == 0x7FF ) {
1689 if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b );
1690 return a;
1691 }
1692 if ( bExp == 0 ) {
1693 --expDiff;
1694 }
1695 else {
1696 bSig0 |= 0x00100000;
1697 }
1698 shift64ExtraRightJamming(
1699 bSig0, bSig1, 0, expDiff, &bSig0, &bSig1, &zSig2 );
1700 zExp = aExp;
1701 }
1702 else if ( expDiff < 0 ) {
1703 if ( bExp == 0x7FF ) {
1704 if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
1705 return packFloat64( zSign, 0x7FF, 0, 0 );
1706 }
1707 if ( aExp == 0 ) {
1708 ++expDiff;
1709 }
1710 else {
1711 aSig0 |= 0x00100000;
1712 }
1713 shift64ExtraRightJamming(
1714 aSig0, aSig1, 0, - expDiff, &aSig0, &aSig1, &zSig2 );
1715 zExp = bExp;
1716 }
1717 else {
1718 if ( aExp == 0x7FF ) {
1719 if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
1720 return propagateFloat64NaN( a, b );
1721 }
1722 return a;
1723 }
1724 add64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
1725 if ( aExp == 0 ) return packFloat64( zSign, 0, zSig0, zSig1 );
1726 zSig2 = 0;
1727 zSig0 |= 0x00200000;
1728 zExp = aExp;
1729 goto shiftRight1;
1730 }
1731 aSig0 |= 0x00100000;
1732 add64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
1733 --zExp;
1734 if ( zSig0 < 0x00200000 ) goto roundAndPack;
1735 ++zExp;
1736 shiftRight1:
1737 shift64ExtraRightJamming( zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
1738 roundAndPack:
1739 return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 );
1740
1741 }
1742
1743 /*
1744 -------------------------------------------------------------------------------
1745 Returns the result of subtracting the absolute values of the double-
1746 precision floating-point values `a' and `b'. If `zSign' is 1, the
1747 difference is negated before being returned. `zSign' is ignored if the
1748 result is a NaN. The subtraction is performed according to the IEC/IEEE
1749 Standard for Binary Floating-Point Arithmetic.
1750 -------------------------------------------------------------------------------
1751 */
1752 static float64 subFloat64Sigs( float64 a, float64 b, flag zSign )
1753 {
1754 int16 aExp, bExp, zExp;
1755 bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1;
1756 int16 expDiff;
1757
1758 aSig1 = extractFloat64Frac1( a );
1759 aSig0 = extractFloat64Frac0( a );
1760 aExp = extractFloat64Exp( a );
1761 bSig1 = extractFloat64Frac1( b );
1762 bSig0 = extractFloat64Frac0( b );
1763 bExp = extractFloat64Exp( b );
1764 expDiff = aExp - bExp;
1765 shortShift64Left( aSig0, aSig1, 10, &aSig0, &aSig1 );
1766 shortShift64Left( bSig0, bSig1, 10, &bSig0, &bSig1 );
1767 if ( 0 < expDiff ) goto aExpBigger;
1768 if ( expDiff < 0 ) goto bExpBigger;
1769 if ( aExp == 0x7FF ) {
1770 if ( aSig0 | aSig1 | bSig0 | bSig1 ) {
1771 return propagateFloat64NaN( a, b );
1772 }
1773 float_raise( float_flag_invalid );
1774 return float64_default_nan;
1775 }
1776 if ( aExp == 0 ) {
1777 aExp = 1;
1778 bExp = 1;
1779 }
1780 if ( bSig0 < aSig0 ) goto aBigger;
1781 if ( aSig0 < bSig0 ) goto bBigger;
1782 if ( bSig1 < aSig1 ) goto aBigger;
1783 if ( aSig1 < bSig1 ) goto bBigger;
1784 return packFloat64( float_rounding_mode == float_round_down, 0, 0, 0 );
1785 bExpBigger:
1786 if ( bExp == 0x7FF ) {
1787 if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
1788 return packFloat64( zSign ^ 1, 0x7FF, 0, 0 );
1789 }
1790 if ( aExp == 0 ) {
1791 ++expDiff;
1792 }
1793 else {
1794 aSig0 |= 0x40000000;
1795 }
1796 shift64RightJamming( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
1797 bSig0 |= 0x40000000;
1798 bBigger:
1799 sub64( bSig0, bSig1, aSig0, aSig1, &zSig0, &zSig1 );
1800 zExp = bExp;
1801 zSign ^= 1;
1802 goto normalizeRoundAndPack;
1803 aExpBigger:
1804 if ( aExp == 0x7FF ) {
1805 if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b );
1806 return a;
1807 }
1808 if ( bExp == 0 ) {
1809 --expDiff;
1810 }
1811 else {
1812 bSig0 |= 0x40000000;
1813 }
1814 shift64RightJamming( bSig0, bSig1, expDiff, &bSig0, &bSig1 );
1815 aSig0 |= 0x40000000;
1816 aBigger:
1817 sub64( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1 );
1818 zExp = aExp;
1819 normalizeRoundAndPack:
1820 --zExp;
1821 return normalizeRoundAndPackFloat64( zSign, zExp - 10, zSig0, zSig1 );
1822
1823 }
1824
1825 /*
1826 -------------------------------------------------------------------------------
1827 Returns the result of adding the double-precision floating-point values `a'
1828 and `b'. The operation is performed according to the IEC/IEEE Standard for
1829 Binary Floating-Point Arithmetic.
1830 -------------------------------------------------------------------------------
1831 */
1832 float64 float64_add( float64 a, float64 b )
1833 {
1834 flag aSign, bSign;
1835
1836 aSign = extractFloat64Sign( a );
1837 bSign = extractFloat64Sign( b );
1838 if ( aSign == bSign ) {
1839 return addFloat64Sigs( a, b, aSign );
1840 }
1841 else {
1842 return subFloat64Sigs( a, b, aSign );
1843 }
1844
1845 }
1846
1847 /*
1848 -------------------------------------------------------------------------------
1849 Returns the result of subtracting the double-precision floating-point values
1850 `a' and `b'. The operation is performed according to the IEC/IEEE Standard
1851 for Binary Floating-Point Arithmetic.
1852 -------------------------------------------------------------------------------
1853 */
1854 float64 float64_sub( float64 a, float64 b )
1855 {
1856 flag aSign, bSign;
1857
1858 aSign = extractFloat64Sign( a );
1859 bSign = extractFloat64Sign( b );
1860 if ( aSign == bSign ) {
1861 return subFloat64Sigs( a, b, aSign );
1862 }
1863 else {
1864 return addFloat64Sigs( a, b, aSign );
1865 }
1866
1867 }
1868
1869 /*
1870 -------------------------------------------------------------------------------
1871 Returns the result of multiplying the double-precision floating-point values
1872 `a' and `b'. The operation is performed according to the IEC/IEEE Standard
1873 for Binary Floating-Point Arithmetic.
1874 -------------------------------------------------------------------------------
1875 */
1876 float64 float64_mul( float64 a, float64 b )
1877 {
1878 flag aSign, bSign, zSign;
1879 int16 aExp, bExp, zExp;
1880 bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2, zSig3;
1881
1882 aSig1 = extractFloat64Frac1( a );
1883 aSig0 = extractFloat64Frac0( a );
1884 aExp = extractFloat64Exp( a );
1885 aSign = extractFloat64Sign( a );
1886 bSig1 = extractFloat64Frac1( b );
1887 bSig0 = extractFloat64Frac0( b );
1888 bExp = extractFloat64Exp( b );
1889 bSign = extractFloat64Sign( b );
1890 zSign = aSign ^ bSign;
1891 if ( aExp == 0x7FF ) {
1892 if ( ( aSig0 | aSig1 )
1893 || ( ( bExp == 0x7FF ) && ( bSig0 | bSig1 ) ) ) {
1894 return propagateFloat64NaN( a, b );
1895 }
1896 if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid;
1897 return packFloat64( zSign, 0x7FF, 0, 0 );
1898 }
1899 if ( bExp == 0x7FF ) {
1900 if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
1901 if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
1902 invalid:
1903 float_raise( float_flag_invalid );
1904 return float64_default_nan;
1905 }
1906 return packFloat64( zSign, 0x7FF, 0, 0 );
1907 }
1908 if ( aExp == 0 ) {
1909 if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 );
1910 normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
1911 }
1912 if ( bExp == 0 ) {
1913 if ( ( bSig0 | bSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 );
1914 normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
1915 }
1916 zExp = aExp + bExp - 0x400;
1917 aSig0 |= 0x00100000;
1918 shortShift64Left( bSig0, bSig1, 12, &bSig0, &bSig1 );
1919 mul64To128( aSig0, aSig1, bSig0, bSig1, &zSig0, &zSig1, &zSig2, &zSig3 );
1920 add64( zSig0, zSig1, aSig0, aSig1, &zSig0, &zSig1 );
1921 zSig2 |= ( zSig3 != 0 );
1922 if ( 0x00200000 <= zSig0 ) {
1923 shift64ExtraRightJamming(
1924 zSig0, zSig1, zSig2, 1, &zSig0, &zSig1, &zSig2 );
1925 ++zExp;
1926 }
1927 return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 );
1928
1929 }
1930
1931 /*
1932 -------------------------------------------------------------------------------
1933 Returns the result of dividing the double-precision floating-point value `a'
1934 by the corresponding value `b'. The operation is performed according to the
1935 IEC/IEEE Standard for Binary Floating-Point Arithmetic.
1936 -------------------------------------------------------------------------------
1937 */
1938 float64 float64_div( float64 a, float64 b )
1939 {
1940 flag aSign, bSign, zSign;
1941 int16 aExp, bExp, zExp;
1942 bits32 aSig0, aSig1, bSig0, bSig1, zSig0, zSig1, zSig2;
1943 bits32 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
1944
1945 aSig1 = extractFloat64Frac1( a );
1946 aSig0 = extractFloat64Frac0( a );
1947 aExp = extractFloat64Exp( a );
1948 aSign = extractFloat64Sign( a );
1949 bSig1 = extractFloat64Frac1( b );
1950 bSig0 = extractFloat64Frac0( b );
1951 bExp = extractFloat64Exp( b );
1952 bSign = extractFloat64Sign( b );
1953 zSign = aSign ^ bSign;
1954 if ( aExp == 0x7FF ) {
1955 if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, b );
1956 if ( bExp == 0x7FF ) {
1957 if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
1958 goto invalid;
1959 }
1960 return packFloat64( zSign, 0x7FF, 0, 0 );
1961 }
1962 if ( bExp == 0x7FF ) {
1963 if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
1964 return packFloat64( zSign, 0, 0, 0 );
1965 }
1966 if ( bExp == 0 ) {
1967 if ( ( bSig0 | bSig1 ) == 0 ) {
1968 if ( ( aExp | aSig0 | aSig1 ) == 0 ) {
1969 invalid:
1970 float_raise( float_flag_invalid );
1971 return float64_default_nan;
1972 }
1973 float_raise( float_flag_divbyzero );
1974 return packFloat64( zSign, 0x7FF, 0, 0 );
1975 }
1976 normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
1977 }
1978 if ( aExp == 0 ) {
1979 if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( zSign, 0, 0, 0 );
1980 normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
1981 }
1982 zExp = aExp - bExp + 0x3FD;
1983 shortShift64Left( aSig0 | 0x00100000, aSig1, 11, &aSig0, &aSig1 );
1984 shortShift64Left( bSig0 | 0x00100000, bSig1, 11, &bSig0, &bSig1 );
1985 if ( le64( bSig0, bSig1, aSig0, aSig1 ) ) {
1986 shift64Right( aSig0, aSig1, 1, &aSig0, &aSig1 );
1987 ++zExp;
1988 }
1989 zSig0 = estimateDiv64To32( aSig0, aSig1, bSig0 );
1990 mul64By32To96( bSig0, bSig1, zSig0, &term0, &term1, &term2 );
1991 sub96( aSig0, aSig1, 0, term0, term1, term2, &rem0, &rem1, &rem2 );
1992 while ( (sbits32) rem0 < 0 ) {
1993 --zSig0;
1994 add96( rem0, rem1, rem2, 0, bSig0, bSig1, &rem0, &rem1, &rem2 );
1995 }
1996 zSig1 = estimateDiv64To32( rem1, rem2, bSig0 );
1997 if ( ( zSig1 & 0x3FF ) <= 4 ) {
1998 mul64By32To96( bSig0, bSig1, zSig1, &term1, &term2, &term3 );
1999 sub96( rem1, rem2, 0, term1, term2, term3, &rem1, &rem2, &rem3 );
2000 while ( (sbits32) rem1 < 0 ) {
2001 --zSig1;
2002 add96( rem1, rem2, rem3, 0, bSig0, bSig1, &rem1, &rem2, &rem3 );
2003 }
2004 zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
2005 }
2006 shift64ExtraRightJamming( zSig0, zSig1, 0, 11, &zSig0, &zSig1, &zSig2 );
2007 return roundAndPackFloat64( zSign, zExp, zSig0, zSig1, zSig2 );
2008
2009 }
2010
2011 #ifndef SOFTFLOAT_FOR_GCC
2012 /*
2013 -------------------------------------------------------------------------------
2014 Returns the remainder of the double-precision floating-point value `a'
2015 with respect to the corresponding value `b'. The operation is performed
2016 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2017 -------------------------------------------------------------------------------
2018 */
2019 float64 float64_rem( float64 a, float64 b )
2020 {
2021 flag aSign, bSign, zSign;
2022 int16 aExp, bExp, expDiff;
2023 bits32 aSig0, aSig1, bSig0, bSig1, q, term0, term1, term2;
2024 bits32 allZero, alternateASig0, alternateASig1, sigMean1;
2025 sbits32 sigMean0;
2026 float64 z;
2027
2028 aSig1 = extractFloat64Frac1( a );
2029 aSig0 = extractFloat64Frac0( a );
2030 aExp = extractFloat64Exp( a );
2031 aSign = extractFloat64Sign( a );
2032 bSig1 = extractFloat64Frac1( b );
2033 bSig0 = extractFloat64Frac0( b );
2034 bExp = extractFloat64Exp( b );
2035 bSign = extractFloat64Sign( b );
2036 if ( aExp == 0x7FF ) {
2037 if ( ( aSig0 | aSig1 )
2038 || ( ( bExp == 0x7FF ) && ( bSig0 | bSig1 ) ) ) {
2039 return propagateFloat64NaN( a, b );
2040 }
2041 goto invalid;
2042 }
2043 if ( bExp == 0x7FF ) {
2044 if ( bSig0 | bSig1 ) return propagateFloat64NaN( a, b );
2045 return a;
2046 }
2047 if ( bExp == 0 ) {
2048 if ( ( bSig0 | bSig1 ) == 0 ) {
2049 invalid:
2050 float_raise( float_flag_invalid );
2051 return float64_default_nan;
2052 }
2053 normalizeFloat64Subnormal( bSig0, bSig1, &bExp, &bSig0, &bSig1 );
2054 }
2055 if ( aExp == 0 ) {
2056 if ( ( aSig0 | aSig1 ) == 0 ) return a;
2057 normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
2058 }
2059 expDiff = aExp - bExp;
2060 if ( expDiff < -1 ) return a;
2061 shortShift64Left(
2062 aSig0 | 0x00100000, aSig1, 11 - ( expDiff < 0 ), &aSig0, &aSig1 );
2063 shortShift64Left( bSig0 | 0x00100000, bSig1, 11, &bSig0, &bSig1 );
2064 q = le64( bSig0, bSig1, aSig0, aSig1 );
2065 if ( q ) sub64( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
2066 expDiff -= 32;
2067 while ( 0 < expDiff ) {
2068 q = estimateDiv64To32( aSig0, aSig1, bSig0 );
2069 q = ( 4 < q ) ? q - 4 : 0;
2070 mul64By32To96( bSig0, bSig1, q, &term0, &term1, &term2 );
2071 shortShift96Left( term0, term1, term2, 29, &term1, &term2, &allZero );
2072 shortShift64Left( aSig0, aSig1, 29, &aSig0, &allZero );
2073 sub64( aSig0, 0, term1, term2, &aSig0, &aSig1 );
2074 expDiff -= 29;
2075 }
2076 if ( -32 < expDiff ) {
2077 q = estimateDiv64To32( aSig0, aSig1, bSig0 );
2078 q = ( 4 < q ) ? q - 4 : 0;
2079 q >>= - expDiff;
2080 shift64Right( bSig0, bSig1, 8, &bSig0, &bSig1 );
2081 expDiff += 24;
2082 if ( expDiff < 0 ) {
2083 shift64Right( aSig0, aSig1, - expDiff, &aSig0, &aSig1 );
2084 }
2085 else {
2086 shortShift64Left( aSig0, aSig1, expDiff, &aSig0, &aSig1 );
2087 }
2088 mul64By32To96( bSig0, bSig1, q, &term0, &term1, &term2 );
2089 sub64( aSig0, aSig1, term1, term2, &aSig0, &aSig1 );
2090 }
2091 else {
2092 shift64Right( aSig0, aSig1, 8, &aSig0, &aSig1 );
2093 shift64Right( bSig0, bSig1, 8, &bSig0, &bSig1 );
2094 }
2095 do {
2096 alternateASig0 = aSig0;
2097 alternateASig1 = aSig1;
2098 ++q;
2099 sub64( aSig0, aSig1, bSig0, bSig1, &aSig0, &aSig1 );
2100 } while ( 0 <= (sbits32) aSig0 );
2101 add64(
2102 aSig0, aSig1, alternateASig0, alternateASig1, &sigMean0, &sigMean1 );
2103 if ( ( sigMean0 < 0 )
2104 || ( ( ( sigMean0 | sigMean1 ) == 0 ) && ( q & 1 ) ) ) {
2105 aSig0 = alternateASig0;
2106 aSig1 = alternateASig1;
2107 }
2108 zSign = ( (sbits32) aSig0 < 0 );
2109 if ( zSign ) sub64( 0, 0, aSig0, aSig1, &aSig0, &aSig1 );
2110 return
2111 normalizeRoundAndPackFloat64( aSign ^ zSign, bExp - 4, aSig0, aSig1 );
2112
2113 }
2114 #endif
2115
2116 #ifndef SOFTFLOAT_FOR_GCC
2117 /*
2118 -------------------------------------------------------------------------------
2119 Returns the square root of the double-precision floating-point value `a'.
2120 The operation is performed according to the IEC/IEEE Standard for Binary
2121 Floating-Point Arithmetic.
2122 -------------------------------------------------------------------------------
2123 */
2124 float64 float64_sqrt( float64 a )
2125 {
2126 flag aSign;
2127 int16 aExp, zExp;
2128 bits32 aSig0, aSig1, zSig0, zSig1, zSig2, doubleZSig0;
2129 bits32 rem0, rem1, rem2, rem3, term0, term1, term2, term3;
2130 float64 z;
2131
2132 aSig1 = extractFloat64Frac1( a );
2133 aSig0 = extractFloat64Frac0( a );
2134 aExp = extractFloat64Exp( a );
2135 aSign = extractFloat64Sign( a );
2136 if ( aExp == 0x7FF ) {
2137 if ( aSig0 | aSig1 ) return propagateFloat64NaN( a, a );
2138 if ( ! aSign ) return a;
2139 goto invalid;
2140 }
2141 if ( aSign ) {
2142 if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a;
2143 invalid:
2144 float_raise( float_flag_invalid );
2145 return float64_default_nan;
2146 }
2147 if ( aExp == 0 ) {
2148 if ( ( aSig0 | aSig1 ) == 0 ) return packFloat64( 0, 0, 0, 0 );
2149 normalizeFloat64Subnormal( aSig0, aSig1, &aExp, &aSig0, &aSig1 );
2150 }
2151 zExp = ( ( aExp - 0x3FF )>>1 ) + 0x3FE;
2152 aSig0 |= 0x00100000;
2153 shortShift64Left( aSig0, aSig1, 11, &term0, &term1 );
2154 zSig0 = ( estimateSqrt32( aExp, term0 )>>1 ) + 1;
2155 if ( zSig0 == 0 ) zSig0 = 0x7FFFFFFF;
2156 doubleZSig0 = zSig0 + zSig0;
2157 shortShift64Left( aSig0, aSig1, 9 - ( aExp & 1 ), &aSig0, &aSig1 );
2158 mul32To64( zSig0, zSig0, &term0, &term1 );
2159 sub64( aSig0, aSig1, term0, term1, &rem0, &rem1 );
2160 while ( (sbits32) rem0 < 0 ) {
2161 --zSig0;
2162 doubleZSig0 -= 2;
2163 add64( rem0, rem1, 0, doubleZSig0 | 1, &rem0, &rem1 );
2164 }
2165 zSig1 = estimateDiv64To32( rem1, 0, doubleZSig0 );
2166 if ( ( zSig1 & 0x1FF ) <= 5 ) {
2167 if ( zSig1 == 0 ) zSig1 = 1;
2168 mul32To64( doubleZSig0, zSig1, &term1, &term2 );
2169 sub64( rem1, 0, term1, term2, &rem1, &rem2 );
2170 mul32To64( zSig1, zSig1, &term2, &term3 );
2171 sub96( rem1, rem2, 0, 0, term2, term3, &rem1, &rem2, &rem3 );
2172 while ( (sbits32) rem1 < 0 ) {
2173 --zSig1;
2174 shortShift64Left( 0, zSig1, 1, &term2, &term3 );
2175 term3 |= 1;
2176 term2 |= doubleZSig0;
2177 add96( rem1, rem2, rem3, 0, term2, term3, &rem1, &rem2, &rem3 );
2178 }
2179 zSig1 |= ( ( rem1 | rem2 | rem3 ) != 0 );
2180 }
2181 shift64ExtraRightJamming( zSig0, zSig1, 0, 10, &zSig0, &zSig1, &zSig2 );
2182 return roundAndPackFloat64( 0, zExp, zSig0, zSig1, zSig2 );
2183
2184 }
2185 #endif
2186
2187 /*
2188 -------------------------------------------------------------------------------
2189 Returns 1 if the double-precision floating-point value `a' is equal to
2190 the corresponding value `b', and 0 otherwise. The comparison is performed
2191 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2192 -------------------------------------------------------------------------------
2193 */
2194 flag float64_eq( float64 a, float64 b )
2195 {
2196
2197 if ( ( ( extractFloat64Exp( a ) == 0x7FF )
2198 && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
2199 || ( ( extractFloat64Exp( b ) == 0x7FF )
2200 && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
2201 ) {
2202 if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
2203 float_raise( float_flag_invalid );
2204 }
2205 return 0;
2206 }
2207 return ( a == b ) ||
2208 ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) == 0 );
2209
2210 }
2211
2212 /*
2213 -------------------------------------------------------------------------------
2214 Returns 1 if the double-precision floating-point value `a' is less than
2215 or equal to the corresponding value `b', and 0 otherwise. The comparison
2216 is performed according to the IEC/IEEE Standard for Binary Floating-Point
2217 Arithmetic.
2218 -------------------------------------------------------------------------------
2219 */
2220 flag float64_le( float64 a, float64 b )
2221 {
2222 flag aSign, bSign;
2223
2224 if ( ( ( extractFloat64Exp( a ) == 0x7FF )
2225 && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
2226 || ( ( extractFloat64Exp( b ) == 0x7FF )
2227 && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
2228 ) {
2229 float_raise( float_flag_invalid );
2230 return 0;
2231 }
2232 aSign = extractFloat64Sign( a );
2233 bSign = extractFloat64Sign( b );
2234 if ( aSign != bSign )
2235 return aSign ||
2236 ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) ==
2237 0 );
2238 return ( a == b ) ||
2239 ( aSign ^ ( FLOAT64_DEMANGLE(a) < FLOAT64_DEMANGLE(b) ) );
2240 }
2241
2242 /*
2243 -------------------------------------------------------------------------------
2244 Returns 1 if the double-precision floating-point value `a' is less than
2245 the corresponding value `b', and 0 otherwise. The comparison is performed
2246 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2247 -------------------------------------------------------------------------------
2248 */
2249 flag float64_lt( float64 a, float64 b )
2250 {
2251 flag aSign, bSign;
2252
2253 if ( ( ( extractFloat64Exp( a ) == 0x7FF )
2254 && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
2255 || ( ( extractFloat64Exp( b ) == 0x7FF )
2256 && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
2257 ) {
2258 float_raise( float_flag_invalid );
2259 return 0;
2260 }
2261 aSign = extractFloat64Sign( a );
2262 bSign = extractFloat64Sign( b );
2263 if ( aSign != bSign )
2264 return aSign &&
2265 ( (bits64) ( ( FLOAT64_DEMANGLE(a) | FLOAT64_DEMANGLE(b) )<<1 ) !=
2266 0 );
2267 return ( a != b ) &&
2268 ( aSign ^ ( FLOAT64_DEMANGLE(a) < FLOAT64_DEMANGLE(b) ) );
2269
2270 }
2271
2272 #ifndef SOFTFLOAT_FOR_GCC
2273 /*
2274 -------------------------------------------------------------------------------
2275 Returns 1 if the double-precision floating-point value `a' is equal to
2276 the corresponding value `b', and 0 otherwise. The invalid exception is
2277 raised if either operand is a NaN. Otherwise, the comparison is performed
2278 according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2279 -------------------------------------------------------------------------------
2280 */
2281 flag float64_eq_signaling( float64 a, float64 b )
2282 {
2283
2284 if ( ( ( extractFloat64Exp( a ) == 0x7FF )
2285 && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
2286 || ( ( extractFloat64Exp( b ) == 0x7FF )
2287 && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
2288 ) {
2289 float_raise( float_flag_invalid );
2290 return 0;
2291 }
2292 return ( a == b ) || ( (bits64) ( ( a | b )<<1 ) == 0 );
2293
2294 }
2295
2296 /*
2297 -------------------------------------------------------------------------------
2298 Returns 1 if the double-precision floating-point value `a' is less than or
2299 equal to the corresponding value `b', and 0 otherwise. Quiet NaNs do not
2300 cause an exception. Otherwise, the comparison is performed according to the
2301 IEC/IEEE Standard for Binary Floating-Point Arithmetic.
2302 -------------------------------------------------------------------------------
2303 */
2304 flag float64_le_quiet( float64 a, float64 b )
2305 {
2306 flag aSign, bSign;
2307
2308 if ( ( ( extractFloat64Exp( a ) == 0x7FF )
2309 && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
2310 || ( ( extractFloat64Exp( b ) == 0x7FF )
2311 && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
2312 ) {
2313 if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
2314 float_raise( float_flag_invalid );
2315 }
2316 return 0;
2317 }
2318 aSign = extractFloat64Sign( a );
2319 bSign = extractFloat64Sign( b );
2320 if ( aSign != bSign ) return aSign || ( (bits64) ( ( a | b )<<1 ) == 0 );
2321 return ( a == b ) || ( aSign ^ ( a < b ) );
2322
2323 }
2324
2325 /*
2326 -------------------------------------------------------------------------------
2327 Returns 1 if the double-precision floating-point value `a' is less than
2328 the corresponding value `b', and 0 otherwise. Quiet NaNs do not cause an
2329 exception. Otherwise, the comparison is performed according to the IEC/IEEE
2330 Standard for Binary Floating-Point Arithmetic.
2331 -------------------------------------------------------------------------------
2332 */
2333 flag float64_lt_quiet( float64 a, float64 b )
2334 {
2335 flag aSign, bSign;
2336
2337 if ( ( ( extractFloat64Exp( a ) == 0x7FF )
2338 && ( extractFloat64Frac0( a ) | extractFloat64Frac1( a ) ) )
2339 || ( ( extractFloat64Exp( b ) == 0x7FF )
2340 && ( extractFloat64Frac0( b ) | extractFloat64Frac1( b ) ) )
2341 ) {
2342 if ( float64_is_signaling_nan( a ) || float64_is_signaling_nan( b ) ) {
2343 float_raise( float_flag_invalid );
2344 }
2345 return 0;
2346 }
2347 aSign = extractFloat64Sign( a );
2348 bSign = extractFloat64Sign( b );
2349 if ( aSign != bSign ) return aSign && ( (bits64) ( ( a | b )<<1 ) != 0 );
2350 return ( a != b ) && ( aSign ^ ( a < b ) );
2351
2352 }
2353
2354 #endif