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