|
|
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: ! 36: #if 0 // moved to struct float_ctrl ! 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; ! 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: } ! 117: ! 118: /*---------------------------------------------------------------------------- ! 119: | Functions for storing sign, exponent and significand of extended ! 120: | double-precision floating-point intermediate result for external use. ! 121: *----------------------------------------------------------------------------*/ ! 122: static void saveFloatx80Internal( int8 prec, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, float_ctrl* c ) ! 123: { ! 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 ); ! 130: ! 131: } ! 132: ! 133: static void saveFloat64Internal( flag zSign, int16 zExp, bits64 zSig, float_ctrl* c ) ! 134: { ! 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 ); ! 141: ! 142: } ! 143: ! 144: static void saveFloat32Internal( flag zSign, int16 zExp, bits32 zSig, float_ctrl* c ) ! 145: { ! 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 ); ! 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: ! 161: static void getRoundedFloatInternal( int8 roundingPrecision, flag *pzSign, int32 *pzExp, bits64 *pzSig, float_ctrl* c ) ! 162: { ! 163: int64 roundIncrement, roundMask, roundBits; ! 164: flag increment; ! 165: ! 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; ! 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 ); ! 184: if ( c->floatx80_internal_mode != float_round_nearest_even ) { ! 185: if ( c->floatx80_internal_mode == float_round_to_zero ) { ! 186: roundIncrement = 0; ! 187: } else { ! 188: roundIncrement = roundMask; ! 189: if ( zSign ) { ! 190: if ( c->floatx80_internal_mode == float_round_up ) roundIncrement = 0; ! 191: } else { ! 192: if ( c->floatx80_internal_mode == float_round_down ) roundIncrement = 0; ! 193: } ! 194: } ! 195: } ! 196: ! 197: roundBits = zSig0 & roundMask; ! 198: ! 199: zSig0 += roundIncrement; ! 200: if ( zSig0 < (bits64)roundIncrement ) { ! 201: ++zExp; ! 202: zSig0 = LIT64( 0x8000000000000000 ); ! 203: } ! 204: roundIncrement = roundMask + 1; ! 205: if ( c->floatx80_internal_mode == float_round_nearest_even && ( roundBits<<1 == roundIncrement ) ) { ! 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 ); ! 218: if ( c->floatx80_internal_mode != float_round_nearest_even ) { ! 219: if ( c->floatx80_internal_mode == float_round_to_zero ) { ! 220: increment = 0; ! 221: } else { ! 222: if ( zSign ) { ! 223: increment = ( c->floatx80_internal_mode == float_round_down ) && zSig1; ! 224: } else { ! 225: increment = ( c->floatx80_internal_mode == float_round_up ) && zSig1; ! 226: } ! 227: } ! 228: } ! 229: if ( increment ) { ! 230: ++zSig0; ! 231: if ( zSig0 == 0 ) { ! 232: ++zExp; ! 233: zSig0 = LIT64( 0x8000000000000000 ); ! 234: } else { ! 235: zSig0 &= ~ ( ( (bits64) ( zSig1<<1 ) == 0 ) & ( c->floatx80_internal_mode == float_round_nearest_even ) ); ! 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: ! 248: floatx80 getFloatInternalOverflow( float_ctrl* c ) ! 249: { ! 250: flag zSign; ! 251: int32 zExp; ! 252: bits64 zSig; ! 253: ! 254: getRoundedFloatInternal( c->floatx80_internal_precision, &zSign, &zExp, &zSig, c ); ! 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: ! 266: floatx80 getFloatInternalUnderflow( float_ctrl* c ) ! 267: { ! 268: flag zSign; ! 269: int32 zExp; ! 270: bits64 zSig; ! 271: ! 272: getRoundedFloatInternal( c->floatx80_internal_precision, &zSign, &zExp, &zSig, c ); ! 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: ! 284: floatx80 getFloatInternalRoundedAll( float_ctrl* c ) ! 285: { ! 286: flag zSign; ! 287: int32 zExp; ! 288: bits64 zSig, zSig32, zSig64, zSig80; ! 289: ! 290: if (c->floatx80_internal_precision == 80) { ! 291: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig80, c ); ! 292: zSig = zSig80; ! 293: } else if (c->floatx80_internal_precision == 64) { ! 294: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig80, c ); ! 295: getRoundedFloatInternal( 64, &zSign, &zExp, &zSig64, c ); ! 296: zSig = zSig64; ! 297: zSig |= zSig80 & LIT64( 0x00000000000007FF ); ! 298: } else { ! 299: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig80, c ); ! 300: getRoundedFloatInternal( 64, &zSign, &zExp, &zSig64, c ); ! 301: getRoundedFloatInternal( 32, &zSign, &zExp, &zSig32, c ); ! 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: ! 311: floatx80 getFloatInternalRoundedSome( float_ctrl* c ) ! 312: { ! 313: flag zSign; ! 314: int32 zExp; ! 315: bits64 zSig, zSig32, zSig64, zSig80; ! 316: ! 317: if (c->floatx80_internal_precision == 80) { ! 318: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig80, c ); ! 319: zSig = zSig80; ! 320: } else if (c->floatx80_internal_precision == 64) { ! 321: getRoundedFloatInternal( 64, &zSign, &zExp, &zSig64, c ); ! 322: zSig80 = c->floatx80_internal_sig0; ! 323: if (zSig64 != (zSig80 & LIT64( 0xFFFFFFFFFFFFF800 ))) { ! 324: zSig80++; ! 325: } ! 326: zSig = zSig64; ! 327: zSig |= zSig80 & LIT64( 0x00000000000007FF ); ! 328: } else { ! 329: getRoundedFloatInternal( 32, &zSign, &zExp, &zSig32, c ); ! 330: zSig80 = c->floatx80_internal_sig0; ! 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: ! 342: floatx80 getFloatInternalFloatx80( float_ctrl* c ) ! 343: { ! 344: flag zSign; ! 345: int32 zExp; ! 346: bits64 zSig; ! 347: ! 348: getRoundedFloatInternal( 80, &zSign, &zExp, &zSig, c ); ! 349: ! 350: return packFloatx80( zSign, zExp & 0x7FFF, zSig ); ! 351: ! 352: } ! 353: ! 354: floatx80 getFloatInternalUnrounded( float_ctrl* c ) ! 355: { ! 356: flag zSign = c->floatx80_internal_sign; ! 357: int32 zExp = c->floatx80_internal_exp; ! 358: bits64 zSig = c->floatx80_internal_sig0; ! 359: ! 360: return packFloatx80( zSign, zExp & 0x7FFF, zSig ); ! 361: ! 362: } ! 363: ! 364: bits64 getFloatInternalGRS( float_ctrl* c ) ! 365: { ! 366: #if 1 ! 367: if (c->floatx80_internal_sig1) ! 368: return 5; ! 369: ! 370: if (c->floatx80_internal_precision == 64 && ! 371: c->floatx80_internal_sig0 & LIT64( 0x00000000000007FF )) { ! 372: return 1; ! 373: } ! 374: if (c->floatx80_internal_precision == 32 && ! 375: c->floatx80_internal_sig0 & LIT64( 0x000000FFFFFFFFFF )) { ! 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: ! 411: static int32 roundAndPackInt32( flag zSign, bits64 absZ, float_ctrl* c ) ! 412: { ! 413: int8 roundingMode; ! 414: flag roundNearestEven; ! 415: int8 roundIncrement, roundBits; ! 416: int32 z; ! 417: ! 418: roundingMode = get_float_rounding_mode( c ); ! 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 ) ) ) { ! 442: float_raise( float_flag_invalid, c ); ! 443: return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; ! 444: } ! 445: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 446: return z; ! 447: ! 448: } ! 449: ! 450: #ifdef SOFTFLOAT_68K // 30-01-2017: Added for Previous ! 451: static int16 roundAndPackInt16( flag zSign, bits64 absZ, float_ctrl* c ) ! 452: { ! 453: int8 roundingMode; ! 454: flag roundNearestEven; ! 455: int8 roundIncrement, roundBits; ! 456: int16 z; ! 457: ! 458: roundingMode = get_float_rounding_mode( c ); ! 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 ) ) ) { ! 482: float_raise( float_flag_invalid, c ); ! 483: return zSign ? (sbits16) 0x8000 : 0x7FFF; ! 484: } ! 485: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 486: return z; ! 487: ! 488: } ! 489: ! 490: static int8 roundAndPackInt8( flag zSign, bits64 absZ, float_ctrl* c ) ! 491: { ! 492: int8 roundingMode; ! 493: flag roundNearestEven; ! 494: int8 roundIncrement, roundBits; ! 495: int8 z; ! 496: ! 497: roundingMode = get_float_rounding_mode( c ); ! 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 ) ) ) { ! 521: float_raise( float_flag_invalid, c ); ! 522: return zSign ? (sbits8) 0x80 : 0x7F; ! 523: } ! 524: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 525: return z; ! 526: ! 527: } ! 528: #endif // End of addition for Previous ! 529: ! 530: #ifdef SOFTFLOAT_I860 // 29-04-2017: Added for Previous ! 531: static int32 roundAndPackInt32_2( flag zSign, bits64 absZ, float_ctrl* c ) ! 532: { ! 533: int8 roundingMode; ! 534: flag roundNearestEven; ! 535: int8 roundIncrement, roundBits; ! 536: int32 z; ! 537: ! 538: roundingMode = get_float_rounding_mode( c ); ! 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 ) ) ) { ! 562: float_raise( float_flag_invalid, c ); ! 563: return zSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; ! 564: } ! 565: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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: ! 583: static int64 roundAndPackInt64( flag zSign, bits64 absZ0, bits64 absZ1, float_ctrl* c ) ! 584: { ! 585: int8 roundingMode; ! 586: flag roundNearestEven, increment; ! 587: int64 z; ! 588: ! 589: roundingMode = get_float_rounding_mode( c ); ! 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: ! 615: float_raise( float_flag_invalid, c ); ! 616: return ! 617: zSign ? (sbits64) LIT64( 0x8000000000000000 ) ! 618: : LIT64( 0x7FFFFFFFFFFFFFFF ); ! 619: } ! 620: if ( absZ1 ) float_raise( float_flag_inexact, c ); ! 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: ! 712: static float32 roundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig, float_ctrl* c ) ! 713: { ! 714: int8 roundingMode; ! 715: flag roundNearestEven; ! 716: int8 roundIncrement, roundBits; ! 717: flag isTiny; ! 718: ! 719: roundingMode = get_float_rounding_mode( c ); ! 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 ! 743: float_raise( float_flag_overflow, c ); ! 744: saveFloat32Internal( zSign, zExp, zSig, c ); ! 745: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 = ! 753: ( get_float_detect_tininess(c) == float_tininess_before_rounding ) ! 754: || ( zExp < -1 ) ! 755: || ( zSig + roundIncrement < 0x80000000 ); ! 756: #ifdef SOFTFLOAT_68K ! 757: if ( isTiny ) { ! 758: float_raise( float_flag_underflow, c ); ! 759: saveFloat32Internal( zSign, zExp, zSig, c ); ! 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: } ! 770: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 ! 779: static float32 roundAndPackFloat32_2( flag zSign, int16 zExp, bits32 zSig, float_ctrl* c ) ! 780: { ! 781: int8 roundingMode; ! 782: flag roundNearestEven; ! 783: int8 roundIncrement, roundBits; ! 784: flag isTiny; ! 785: ! 786: roundingMode = get_float_rounding_mode( c ); ! 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: ) { ! 809: float_raise( float_flag_overflow | float_flag_inexact, c ); ! 810: return packFloat32( zSign, 0xFF, 0 ) - ( roundIncrement == 0 ); ! 811: } ! 812: if ( zExp < 0 ) { ! 813: isTiny = ! 814: #ifndef SOFTFLOAT_I860 ! 815: ( get_float_detect_tininess(c) == float_tininess_before_rounding ) || ! 816: #endif ! 817: ( zExp < -1 ) || ! 818: ( zSig + roundIncrement < 0x80000000 ); ! 819: shift32RightJamming( zSig, - zExp, &zSig ); ! 820: zExp = 0; ! 821: roundBits = zSig & 0x7F; ! 822: if ( isTiny && roundBits ) float_raise( float_flag_underflow, c ); ! 823: } ! 824: } ! 825: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 ! 844: normalizeRoundAndPackFloat32( flag zSign, int16 zExp, bits32 zSig, float_ctrl* c ) ! 845: { ! 846: int8 shiftCount; ! 847: ! 848: shiftCount = countLeadingZeros32( zSig ) - 1; ! 849: return roundAndPackFloat32( zSign, zExp - shiftCount, zSig<<shiftCount, c ); ! 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: ! 940: static float64 roundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig, float_ctrl* c ) ! 941: { ! 942: int8 roundingMode; ! 943: flag roundNearestEven; ! 944: int16 roundIncrement, roundBits; ! 945: flag isTiny; ! 946: ! 947: roundingMode = get_float_rounding_mode( c ); ! 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 ! 971: float_raise( float_flag_overflow, c ); ! 972: saveFloat64Internal( zSign, zExp, zSig, c ); ! 973: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 = ! 981: ( get_float_detect_tininess(c) == float_tininess_before_rounding ) ! 982: || ( zExp < -1 ) ! 983: || ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) ); ! 984: #ifdef SOFTFLOAT_68K ! 985: if ( isTiny ) { ! 986: float_raise( float_flag_underflow, c ); ! 987: saveFloat64Internal( zSign, zExp, zSig, c ); ! 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: } ! 998: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 ! 1007: static float64 roundAndPackFloat64_2( flag zSign, int16 zExp, bits64 zSig, float_ctrl* c ) ! 1008: { ! 1009: int8 roundingMode; ! 1010: flag roundNearestEven; ! 1011: int16 roundIncrement, roundBits; ! 1012: flag isTiny; ! 1013: ! 1014: roundingMode = get_float_rounding_mode( c ); ! 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: ) { ! 1037: float_raise( float_flag_overflow | float_flag_inexact, c ); ! 1038: return packFloat64( zSign, 0x7FF, 0 ) - ( roundIncrement == 0 ); ! 1039: } ! 1040: if ( zExp < 0 ) { ! 1041: isTiny = ! 1042: #ifndef SOFTFLOAT_I860 ! 1043: ( get_float_detect_tininess(c) == float_tininess_before_rounding ) || ! 1044: #endif ! 1045: ( zExp < -1 ) || ! 1046: ( zSig + roundIncrement < LIT64( 0x8000000000000000 ) ); ! 1047: shift64RightJamming( zSig, - zExp, &zSig ); ! 1048: zExp = 0; ! 1049: roundBits = zSig & 0x3FF; ! 1050: if ( isTiny && roundBits ) float_raise( float_flag_underflow, c ); ! 1051: } ! 1052: } ! 1053: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 ! 1072: normalizeRoundAndPackFloat64( flag zSign, int16 zExp, bits64 zSig, float_ctrl* c ) ! 1073: { ! 1074: int8 shiftCount; ! 1075: ! 1076: shiftCount = countLeadingZeros64( zSig ) - 1; ! 1077: return roundAndPackFloat64( zSign, zExp - shiftCount, zSig<<shiftCount, c ); ! 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 = ! 1201: ( get_float_detect_tininess(c) == float_tininess_before_rounding ) ! 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 ! 1222: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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: } ! 1235: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 = ! 1297: ( get_float_detect_tininess(c) == float_tininess_before_rounding ) ! 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 ! 1318: if ( zSig1 ) float_raise( float_flag_inexact, c ); ! 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: } ! 1341: if ( zSig1 ) float_raise( float_flag_inexact, c ); ! 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 ! 1359: floatx80 roundAndPackFloatx80( int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, float_ctrl* c ) ! 1360: { ! 1361: int8 roundingMode; ! 1362: flag roundNearestEven, increment; ! 1363: int64 roundIncrement, roundMask, roundBits; ! 1364: int32 expOffset; ! 1365: ! 1366: roundingMode = get_float_rounding_mode( c ); ! 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 ) ) ) { ! 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 ); ! 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 ) ) { ! 1408: float_raise( float_flag_underflow, c ); ! 1409: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, c ); ! 1410: shift64RightJamming( zSig0, -( zExp - ( expOffset + 1 ) ), &zSig0 ); ! 1411: zExp = expOffset + 1; ! 1412: roundBits = zSig0 & roundMask; ! 1413: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 ) { ! 1423: float_raise( float_flag_inexact, c ); ! 1424: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, c ); ! 1425: } ! 1426: zSig0 += roundIncrement; ! 1427: if ( zSig0 < (bits64)roundIncrement ) { ! 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; ! 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 ); ! 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 ) { ! 1468: float_raise( float_flag_underflow, c ); ! 1469: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, c ); ! 1470: shift64ExtraRightJamming( zSig0, zSig1, -zExp, &zSig0, &zSig1 ); ! 1471: zExp = 0; ! 1472: if ( zSig1 ) float_raise( float_flag_inexact, c ); ! 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 ) { ! 1491: float_raise( float_flag_inexact, c ); ! 1492: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, c ); ! 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 ! 1511: static floatx80 roundSigAndPackFloatx80( int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, float_ctrl* c ) ! 1512: { ! 1513: int8 roundingMode; ! 1514: flag roundNearestEven, isTiny; ! 1515: int64 roundIncrement, roundMask, roundBits; ! 1516: ! 1517: roundingMode = get_float_rounding_mode( c ); ! 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 { ! 1526: return roundAndPackFloatx80( 80, zSign, zExp, zSig0, zSig1, c ); ! 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: ) { ! 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 ); ! 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 = ! 1563: ( get_float_detect_tininess(c) == float_tininess_before_rounding ) ! 1564: || ( zExp < -1 ) ! 1565: || ( zSig0 <= zSig0 + roundIncrement ); ! 1566: if ( isTiny ) { ! 1567: float_raise( float_flag_underflow, c ); ! 1568: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, c ); ! 1569: } ! 1570: shift64RightJamming( zSig0, -zExp, &zSig0 ); ! 1571: zExp = 0; ! 1572: roundBits = zSig0 & roundMask; ! 1573: if ( roundBits ) float_raise( float_flag_inexact, c ); ! 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 ) { ! 1583: float_raise( float_flag_inexact, c ); ! 1584: saveFloatx80Internal( roundingPrecision, zSign, zExp, zSig0, zSig1, c ); ! 1585: } ! 1586: zSig0 += roundIncrement; ! 1587: if ( zSig0 < (bits64)roundIncrement ) { ! 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: ! 1610: static floatx80 normalizeRoundAndPackFloatx80( int8 roundingPrecision, flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, float_ctrl* c ) ! 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 ! 1623: roundAndPackFloatx80( roundingPrecision, zSign, zExp, zSig0, zSig1, c ); ! 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: ! 1759: float128 roundAndPackFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, bits64 zSig2, float_ctrl* c ) ! 1760: { ! 1761: int8 roundingMode; ! 1762: flag roundNearestEven, increment, isTiny; ! 1763: ! 1764: roundingMode = get_float_rounding_mode( c ); ! 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 ! 1793: float_raise( float_flag_overflow, c ); ! 1794: if ( zSig2 ) float_raise( float_flag_inexact, c ); ! 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 = ! 1814: ( get_float_detect_tininess(c) == float_tininess_before_rounding ) ! 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 ! 1827: if ( isTiny ) float_raise( float_flag_underflow, c ); ! 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: } ! 1844: if ( zSig2 ) float_raise( float_flag_inexact, c ); ! 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: ! 1866: float128 normalizeRoundAndPackFloat128( flag zSign, int32 zExp, bits64 zSig0, bits64 zSig1, float_ctrl* c ) ! 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; ! 1886: return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2, c ); ! 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: ! 1898: float32 int32_to_float32( int32 a, float_ctrl* c ) ! 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 ); ! 1905: return normalizeRoundAndPackFloat32( zSign, 0x9C, zSign ? - a : a, c ); ! 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: ! 1990: float32 int64_to_float32( int64 a, float_ctrl* c ) ! 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: } ! 2012: return roundAndPackFloat32( zSign, 0x9C - shiftCount, absA, c ); ! 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: ! 2023: float64 int64_to_float64( int64 a, float_ctrl* c ) ! 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 ); ! 2032: return normalizeRoundAndPackFloat64( zSign, 0x43C, zSign ? - a : a, c ); ! 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: ! 2108: int32 float32_to_int32( float32 a, float_ctrl* c ) ! 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 ! 2125: return roundAndPackInt32_2( aSign, aSig64, c ); ! 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: ! 2142: int32 float32_to_int32_round_to_zero( float32 a, float_ctrl* c ) ! 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 ! 2156: float_raise( float_flag_invalid, c ); ! 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 ! 2166: if ( aExp | aSig ) float_raise( float_flag_inexact, c ); ! 2167: #else ! 2168: if ( aExp | aSig ) float_raise( float_flag_inexact, c ); ! 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 ! 2176: float_raise( float_flag_inexact, c ); ! 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: ! 2196: int64 float32_to_int64( float32 a, float_ctrl* c ) ! 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 ) { ! 2208: float_raise( float_flag_invalid, c ); ! 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 ); ! 2218: return roundAndPackInt64( aSign, aSig64, aSigExtra, c ); ! 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: ! 2232: int64 float32_to_int64_round_to_zero( float32 a, float_ctrl* c ) ! 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 ) { ! 2246: float_raise( float_flag_invalid, c ); ! 2247: if ( ! aSign || ( ( aExp == 0xFF ) && aSig ) ) { ! 2248: return LIT64( 0x7FFFFFFFFFFFFFFF ); ! 2249: } ! 2250: } ! 2251: return (sbits64) LIT64( 0x8000000000000000 ); ! 2252: } ! 2253: else if ( aExp <= 0x7E ) { ! 2254: if ( aExp | aSig ) float_raise( float_flag_inexact, c ); ! 2255: return 0; ! 2256: } ! 2257: aSig64 = aSig | 0x00800000; ! 2258: aSig64 <<= 40; ! 2259: z = aSig64>>( - shiftCount ); ! 2260: if ( (bits64) ( aSig64<<( shiftCount & 63 ) ) ) { ! 2261: float_raise( float_flag_inexact, c ); ! 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: ! 2275: float64 float32_to_float64( float32 a, float_ctrl* c ) ! 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 ) { ! 2285: if ( aSig ) return commonNaNToFloat64( float32ToCommonNaN( a, c ) ); ! 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: ! 2306: floatx80 float32_to_floatx80( float32 a, float_ctrl* c ) ! 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 ) { ! 2316: if ( aSig ) return commonNaNToFloatx80( float32ToCommonNaN( a, c ) ); ! 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: ! 2362: float128 float32_to_float128( float32 a, float_ctrl* c ) ! 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 ) { ! 2372: if ( aSig ) return commonNaNToFloat128( float32ToCommonNaN( a, c ) ); ! 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: ! 2393: float32 float32_round_to_int( float32 a, float_ctrl* c ) ! 2394: { ! 2395: flag aSign; ! 2396: int16 aExp; ! 2397: bits32 lastBitMask, roundBitsMask; ! 2398: int8 roundingMode; ! 2399: float32 z; ! 2400: ! 2401: roundingMode = get_float_rounding_mode( c ); ! 2402: aExp = extractFloat32Exp( a ); ! 2403: if ( 0x96 <= aExp ) { ! 2404: if ( ( aExp == 0xFF ) && extractFloat32Frac( a ) ) { ! 2405: return propagateFloat32NaN( a, a, c ); ! 2406: } ! 2407: return a; ! 2408: } ! 2409: if ( aExp <= 0x7E ) { ! 2410: if ( (bits32) ( a<<1 ) == 0 ) return a; ! 2411: float_raise( float_flag_inexact, c ); ! 2412: aSign = extractFloat32Sign( a ); ! 2413: switch ( roundingMode ) { ! 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; ! 2440: if ( z != a ) float_raise( float_flag_inexact, c ); ! 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: ! 2453: static float32 addFloat32Sigs( float32 a, float32 b, flag zSign, float_ctrl* c ) ! 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 ) { ! 2468: if ( aSig ) return propagateFloat32NaN( a, b, c ); ! 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 ) { ! 2482: if ( bSig ) return propagateFloat32NaN( a, b, c ); ! 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 ) { ! 2496: if ( aSig | bSig ) return propagateFloat32NaN( a, b, c ); ! 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 ! 2513: return roundAndPackFloat32_2( zSign, zExp, zSig, c ); ! 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: ! 2528: static float32 subFloat32Sigs( float32 a, float32 b, flag zSign, float_ctrl* c ) ! 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 ) { ! 2547: if ( aSig | bSig ) return propagateFloat32NaN( a, b, c ); ! 2548: #ifdef SOFTFLOAT_I860 ! 2549: float_raise( float_flag_invalid, c ); ! 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 ! 2562: return packFloat32( get_float_rounding_mode( c ) == float_round_down, 0, 0 ); ! 2563: #else ! 2564: return packFloat32( float_rounding_mode == float_round_down, 0, 0 ); ! 2565: #endif ! 2566: bExpBigger: ! 2567: if ( bExp == 0xFF ) { ! 2568: if ( bSig ) return propagateFloat32NaN( a, b, c ); ! 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 ) { ! 2586: if ( aSig ) return propagateFloat32NaN( a, b, c ); ! 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; ! 2604: return roundAndPackFloat32_2( zSign, zExp - shiftCount, zSig<<shiftCount, c ); ! 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: ! 2617: float32 float32_add( float32 a, float32 b, float_ctrl* c ) ! 2618: { ! 2619: flag aSign, bSign; ! 2620: ! 2621: aSign = extractFloat32Sign( a ); ! 2622: bSign = extractFloat32Sign( b ); ! 2623: if ( aSign == bSign ) { ! 2624: return addFloat32Sigs( a, b, aSign, c ); ! 2625: } ! 2626: else { ! 2627: return subFloat32Sigs( a, b, aSign, c ); ! 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: ! 2638: float32 float32_sub( float32 a, float32 b, float_ctrl* c ) ! 2639: { ! 2640: flag aSign, bSign; ! 2641: ! 2642: aSign = extractFloat32Sign( a ); ! 2643: bSign = extractFloat32Sign( b ); ! 2644: if ( aSign == bSign ) { ! 2645: return subFloat32Sigs( a, b, aSign, c ); ! 2646: } ! 2647: else { ! 2648: return addFloat32Sigs( a, b, aSign, c ); ! 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: ! 2659: float32 float32_mul( float32 a, float32 b, float_ctrl* c ) ! 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 ) ) { ! 2676: return propagateFloat32NaN( a, b, c ); ! 2677: } ! 2678: if ( ( bExp | bSig ) == 0 ) { ! 2679: #ifdef SOFTFLOAT_I860 ! 2680: float_raise( float_flag_invalid, c ); ! 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 ) { ! 2689: if ( bSig ) return propagateFloat32NaN( a, b, c ); ! 2690: if ( ( aExp | aSig ) == 0 ) { ! 2691: #ifdef SOFTFLOAT_I860 ! 2692: float_raise( float_flag_invalid, c ); ! 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 ! 2718: return roundAndPackFloat32_2( zSign, zExp, zSig, c ); ! 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: ! 2731: float32 float32_div( float32 a, float32 b, float_ctrl* c ) ! 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 ) { ! 2745: if ( aSig ) return propagateFloat32NaN( a, b, c ); ! 2746: if ( bExp == 0xFF ) { ! 2747: if ( bSig ) return propagateFloat32NaN( a, b, c ); ! 2748: #ifdef SOFTFLOAT_I860 ! 2749: float_raise( float_flag_invalid, c ); ! 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 ) { ! 2758: if ( bSig ) return propagateFloat32NaN( a, b, c ); ! 2759: return packFloat32( zSign, 0, 0 ); ! 2760: } ! 2761: if ( bExp == 0 ) { ! 2762: if ( bSig == 0 ) { ! 2763: if ( ( aExp | aSig ) == 0 ) { ! 2764: #ifdef SOFTFLOAT_I860 ! 2765: float_raise( float_flag_invalid, c ); ! 2766: #else ! 2767: float_raise( float_flag_invalid ); ! 2768: #endif ! 2769: return float32_default_nan; ! 2770: } ! 2771: #ifdef SOFTFLOAT_I860 ! 2772: float_raise( float_flag_divbyzero, c ); ! 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 ! 2796: return roundAndPackFloat32_2( zSign, zExp, zSig, c ); ! 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: ! 2809: float32 float32_rem( float32 a, float32 b, float_ctrl* c ) ! 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 ) ) { ! 2827: return propagateFloat32NaN( a, b, c ); ! 2828: } ! 2829: float_raise( float_flag_invalid, c ); ! 2830: return float32_default_nan; ! 2831: } ! 2832: if ( bExp == 0xFF ) { ! 2833: if ( bSig ) return propagateFloat32NaN( a, b, c ); ! 2834: return a; ! 2835: } ! 2836: if ( bExp == 0 ) { ! 2837: if ( bSig == 0 ) { ! 2838: float_raise( float_flag_invalid, c ); ! 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; ! 2899: return normalizeRoundAndPackFloat32( aSign ^ zSign, bExp, aSig, c ); ! 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: ! 2909: float32 float32_sqrt( float32 a, float_ctrl* c ) ! 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 ) { ! 2920: if ( aSig ) return propagateFloat32NaN( a, 0, c ); ! 2921: if ( ! aSign ) return a; ! 2922: #ifdef SOFTFLOAT_I860 ! 2923: float_raise( float_flag_invalid, c ); ! 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 ! 2932: float_raise( float_flag_invalid, c ); ! 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 ! 2962: return roundAndPackFloat32_2( 0, zExp, zSig, c ); ! 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: ! 2975: flag float32_eq( float32 a, float32 b, float_ctrl* c ) ! 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 ! 2982: float_raise( float_flag_invalid, c ); ! 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: ! 3000: flag float32_le( float32 a, float32 b, float_ctrl* c ) ! 3001: { ! 3002: flag aSign, bSign; ! 3003: ! 3004: if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) ! 3005: || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ! 3006: ) { ! 3007: #ifdef SOFTFLOAT_I860 ! 3008: float_raise( float_flag_invalid, c ); ! 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: ! 3027: flag float32_lt( float32 a, float32 b, float_ctrl* c ) ! 3028: { ! 3029: flag aSign, bSign; ! 3030: ! 3031: if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) ! 3032: || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ! 3033: ) { ! 3034: #ifdef SOFTFLOAT_I860 ! 3035: float_raise( float_flag_invalid, c ); ! 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: ! 3055: flag float32_gt( float32 a, float32 b, float_ctrl* c ) ! 3056: { ! 3057: flag aSign, bSign; ! 3058: ! 3059: if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) ! 3060: || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ! 3061: ) { ! 3062: #ifdef SOFTFLOAT_I860 ! 3063: float_raise( float_flag_invalid, c ); ! 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: ! 3084: flag float32_eq_signaling( float32 a, float32 b, float_ctrl* c ) ! 3085: { ! 3086: if ( ( ( extractFloat32Exp( a ) == 0xFF ) && extractFloat32Frac( a ) ) ! 3087: || ( ( extractFloat32Exp( b ) == 0xFF ) && extractFloat32Frac( b ) ) ! 3088: ) { ! 3089: float_raise( float_flag_invalid, c ); ! 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: ! 3103: flag float32_le_quiet( float32 a, float32 b, float_ctrl* c ) ! 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 ) ) { ! 3112: float_raise( float_flag_invalid, c ); ! 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: ! 3130: flag float32_lt_quiet( float32 a, float32 b, float_ctrl* c ) ! 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 ) ) { ! 3138: float_raise( float_flag_invalid, c ); ! 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: ! 3159: int32 float64_to_int32( float64 a, float_ctrl* c ) ! 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 ! 3173: return roundAndPackInt32_2( aSign, aSig, c ); ! 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: ! 3190: int32 float64_to_int32_round_to_zero( float64 a, float_ctrl* c ) ! 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 ! 3206: if ( aExp || aSig ) float_raise( float_flag_inexact, c ); ! 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 ! 3222: float_raise( float_flag_invalid, c ); ! 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 ! 3230: float_raise( float_flag_inexact, c ); ! 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: ! 3249: int64 float64_to_int64( float64 a, float_ctrl* c ) ! 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 ) { ! 3262: float_raise( float_flag_invalid, c ); ! 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: } ! 3277: return roundAndPackInt64( aSign, aSig, aSigExtra, c ); ! 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: ! 3291: int64 float64_to_int64_round_to_zero( float64 a, float_ctrl* c ) ! 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 ) ) { ! 3306: float_raise( float_flag_invalid, c ); ! 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 ) { ! 3320: if ( aExp | aSig ) float_raise( float_flag_inexact, c ); ! 3321: return 0; ! 3322: } ! 3323: z = aSig>>( - shiftCount ); ! 3324: if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { ! 3325: float_raise( float_flag_inexact, c ); ! 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: ! 3340: float32 float64_to_float32( float64 a, float_ctrl* c ) ! 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 ) { ! 3351: if ( aSig ) return commonNaNToFloat32( float64ToCommonNaN( a, c ) ); ! 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 ! 3361: return roundAndPackFloat32_2( aSign, aExp, zSig, c ); ! 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: ! 3377: floatx80 float64_to_floatx80( float64 a, float_ctrl* c ) ! 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 ) { ! 3387: if ( aSig ) return commonNaNToFloatx80( float64ToCommonNaN( a, c ) ); ! 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: ! 3435: float128 float64_to_float128( float64 a, float_ctrl* c ) ! 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 ) { ! 3445: if ( aSig ) return commonNaNToFloat128( float64ToCommonNaN( a, c ) ); ! 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: ! 3467: float64 float64_round_to_int( float64 a, float_ctrl* c ) ! 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 ) ) { ! 3478: return propagateFloat64NaN( a, a, c ); ! 3479: } ! 3480: return a; ! 3481: } ! 3482: if ( aExp < 0x3FF ) { ! 3483: if ( (bits64) ( a<<1 ) == 0 ) return a; ! 3484: float_raise( float_flag_inexact, c ); ! 3485: aSign = extractFloat64Sign( a ); ! 3486: switch ( get_float_rounding_mode( c ) ) { ! 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; ! 3504: roundingMode = get_float_rounding_mode( c ); ! 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; ! 3515: if ( z != a ) float_raise( float_flag_inexact, c ); ! 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: ! 3528: static float64 addFloat64Sigs( float64 a, float64 b, flag zSign, float_ctrl* c ) ! 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 ) { ! 3543: if ( aSig ) return propagateFloat64NaN( a, b, c ); ! 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 ) { ! 3557: if ( bSig ) return propagateFloat64NaN( a, b, c ); ! 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 ) { ! 3571: if ( aSig | bSig ) return propagateFloat64NaN( a, b, c ); ! 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 ! 3588: return roundAndPackFloat64_2( zSign, zExp, zSig, c ); ! 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: ! 3603: static float64 subFloat64Sigs( float64 a, float64 b, flag zSign, float_ctrl* c ) ! 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 ) { ! 3622: if ( aSig | bSig ) return propagateFloat64NaN( a, b, c ); ! 3623: #ifdef SOFTFLOAT_I860 ! 3624: float_raise( float_flag_invalid, c ); ! 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 ! 3637: return packFloat64( get_float_rounding_mode( c ) == float_round_down, 0, 0 ); ! 3638: #else ! 3639: return packFloat64( float_rounding_mode == float_round_down, 0, 0 ); ! 3640: #endif ! 3641: bExpBigger: ! 3642: if ( bExp == 0x7FF ) { ! 3643: if ( bSig ) return propagateFloat64NaN( a, b, c ); ! 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 ) { ! 3661: if ( aSig ) return propagateFloat64NaN( a, b, c ); ! 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; ! 3679: return roundAndPackFloat64_2( zSign, zExp - shiftCount, zSig<<shiftCount, c ); ! 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: ! 3692: float64 float64_add( float64 a, float64 b, float_ctrl* c ) ! 3693: { ! 3694: flag aSign, bSign; ! 3695: ! 3696: aSign = extractFloat64Sign( a ); ! 3697: bSign = extractFloat64Sign( b ); ! 3698: if ( aSign == bSign ) { ! 3699: return addFloat64Sigs( a, b, aSign, c ); ! 3700: } ! 3701: else { ! 3702: return subFloat64Sigs( a, b, aSign, c ); ! 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: ! 3713: float64 float64_sub( float64 a, float64 b, float_ctrl* c ) ! 3714: { ! 3715: flag aSign, bSign; ! 3716: ! 3717: aSign = extractFloat64Sign( a ); ! 3718: bSign = extractFloat64Sign( b ); ! 3719: if ( aSign == bSign ) { ! 3720: return subFloat64Sigs( a, b, aSign, c ); ! 3721: } ! 3722: else { ! 3723: return addFloat64Sigs( a, b, aSign, c ); ! 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: ! 3734: float64 float64_mul( float64 a, float64 b, float_ctrl* c ) ! 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 ) ) { ! 3749: return propagateFloat64NaN( a, b, c ); ! 3750: } ! 3751: if ( ( bExp | bSig ) == 0 ) { ! 3752: #ifdef SOFTFLOAT_I860 ! 3753: float_raise( float_flag_invalid, c ); ! 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 ) { ! 3762: if ( bSig ) return propagateFloat64NaN( a, b, c ); ! 3763: if ( ( aExp | aSig ) == 0 ) { ! 3764: #ifdef SOFTFLOAT_I860 ! 3765: float_raise( float_flag_invalid, c ); ! 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 ! 3791: return roundAndPackFloat64_2( zSign, zExp, zSig0, c ); ! 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: ! 3804: float64 float64_div( float64 a, float64 b, float_ctrl* c ) ! 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 ) { ! 3820: if ( aSig ) return propagateFloat64NaN( a, b, c ); ! 3821: if ( bExp == 0x7FF ) { ! 3822: if ( bSig ) return propagateFloat64NaN( a, b, c ); ! 3823: #ifdef SOFTFLOAT_I860 ! 3824: float_raise( float_flag_invalid, c ); ! 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 ) { ! 3833: if ( bSig ) return propagateFloat64NaN( a, b, c ); ! 3834: return packFloat64( zSign, 0, 0 ); ! 3835: } ! 3836: if ( bExp == 0 ) { ! 3837: if ( bSig == 0 ) { ! 3838: if ( ( aExp | aSig ) == 0 ) { ! 3839: #ifdef SOFTFLOAT_I860 ! 3840: float_raise( float_flag_invalid, c ); ! 3841: #else ! 3842: float_raise( float_flag_invalid ); ! 3843: #endif ! 3844: return float64_default_nan; ! 3845: } ! 3846: #ifdef SOFTFLOAT_I860 ! 3847: float_raise( float_flag_divbyzero, c ); ! 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 ! 3877: return roundAndPackFloat64_2( zSign, zExp, zSig, c ); ! 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: ! 3890: float64 float64_rem( float64 a, float64 b, float_ctrl* c ) ! 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 ) ) { ! 3906: return propagateFloat64NaN( a, b, c ); ! 3907: } ! 3908: float_raise( float_flag_invalid, c ); ! 3909: return float64_default_nan; ! 3910: } ! 3911: if ( bExp == 0x7FF ) { ! 3912: if ( bSig ) return propagateFloat64NaN( a, b, c ); ! 3913: return a; ! 3914: } ! 3915: if ( bExp == 0 ) { ! 3916: if ( bSig == 0 ) { ! 3917: float_raise( float_flag_invalid, c ); ! 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; ! 3965: return normalizeRoundAndPackFloat64( aSign ^ zSign, bExp, aSig, c ); ! 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: ! 3975: float64 float64_sqrt( float64 a, float_ctrl* c ) ! 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 ) { ! 3986: if ( aSig ) return propagateFloat64NaN( a, a, c ); ! 3987: if ( ! aSign ) return a; ! 3988: #ifdef SOFTFLOAT_I860 ! 3989: float_raise( float_flag_invalid, c ); ! 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 ! 3998: float_raise( float_flag_invalid, c ); ! 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 ! 4025: return roundAndPackFloat64_2( 0, zExp, zSig, c ); ! 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: ! 4038: flag float64_eq( float64 a, float64 b, float_ctrl* c ) ! 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 ! 4045: float_raise( float_flag_invalid, c ); ! 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: ! 4063: flag float64_le( float64 a, float64 b, float_ctrl* c ) ! 4064: { ! 4065: flag aSign, bSign; ! 4066: ! 4067: if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) ! 4068: || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) ! 4069: ) { ! 4070: #ifdef SOFTFLOAT_I860 ! 4071: float_raise( float_flag_invalid, c ); ! 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: ! 4090: flag float64_lt( float64 a, float64 b, float_ctrl* c ) ! 4091: { ! 4092: flag aSign, bSign; ! 4093: ! 4094: if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) ! 4095: || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) ! 4096: ) { ! 4097: #ifdef SOFTFLOAT_I860 ! 4098: float_raise( float_flag_invalid, c ); ! 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: ! 4118: flag float64_gt( float64 a, float64 b, float_ctrl* c ) ! 4119: { ! 4120: flag aSign, bSign; ! 4121: ! 4122: if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) ! 4123: || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) ! 4124: ) { ! 4125: #ifdef SOFTFLOAT_I860 ! 4126: float_raise( float_flag_invalid, c ); ! 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: ! 4147: flag float64_eq_signaling( float64 a, float64 b, float_ctrl* c ) ! 4148: { ! 4149: if ( ( ( extractFloat64Exp( a ) == 0x7FF ) && extractFloat64Frac( a ) ) ! 4150: || ( ( extractFloat64Exp( b ) == 0x7FF ) && extractFloat64Frac( b ) ) ! 4151: ) { ! 4152: float_raise( float_flag_invalid, c ); ! 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: ! 4166: flag float64_le_quiet( float64 a, float64 b, float_ctrl* c ) ! 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 ) ) { ! 4175: float_raise( float_flag_invalid, c ); ! 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: ! 4193: flag float64_lt_quiet( float64 a, float64 b, float_ctrl* c ) ! 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 ) ) { ! 4201: float_raise( float_flag_invalid, c ); ! 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: ! 4224: int32 floatx80_to_int32( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 4236: a = propagateFloatx80NaNOneArg( a, c ); ! 4237: if ( a.low == aSig ) float_raise( float_flag_invalid, c ); ! 4238: return (sbits32)(a.low>>32); ! 4239: } ! 4240: float_raise( float_flag_invalid, c ); ! 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 ); ! 4249: return roundAndPackInt32( aSign, aSig, c ); ! 4250: ! 4251: } ! 4252: #ifdef SOFTFLOAT_68K // 30-01-2017: Addition for Previous ! 4253: int16 floatx80_to_int16( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 4264: a = propagateFloatx80NaNOneArg( a, c ); ! 4265: if ( a.low == aSig ) float_raise( float_flag_invalid, c ); ! 4266: return (sbits16)(a.low>>48); ! 4267: } ! 4268: float_raise( float_flag_invalid, c ); ! 4269: return aSign ? (sbits16) 0x8000 : 0x7FFF; ! 4270: } ! 4271: shiftCount = 0x4037 - aExp; ! 4272: if ( shiftCount <= 0 ) shiftCount = 1; ! 4273: shift64RightJamming( aSig, shiftCount, &aSig ); ! 4274: return roundAndPackInt16( aSign, aSig, c ); ! 4275: ! 4276: } ! 4277: int8 floatx80_to_int8( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 4288: a = propagateFloatx80NaNOneArg( a, c ); ! 4289: if ( a.low == aSig ) float_raise( float_flag_invalid, c ); ! 4290: return (sbits8)(a.low>>56); ! 4291: } ! 4292: float_raise( float_flag_invalid, c ); ! 4293: return aSign ? (sbits8) 0x80 : 0x7F; ! 4294: } ! 4295: shiftCount = 0x4037 - aExp; ! 4296: if ( shiftCount <= 0 ) shiftCount = 1; ! 4297: shift64RightJamming( aSig, shiftCount, &aSig ); ! 4298: return roundAndPackInt8( aSign, aSig, c ); ! 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: ! 4313: int32 floatx80_to_int32_round_to_zero( floatx80 a, float_ctrl* c ) ! 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 ) { ! 4328: if ( aExp || aSig ) float_raise( float_flag_inexact, c ); ! 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: ! 4339: float_raise( float_flag_invalid, c ); ! 4340: return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; ! 4341: } ! 4342: if ( ( aSig<<shiftCount ) != savedASig ) { ! 4343: float_raise( float_flag_inexact, c ); ! 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: ! 4359: int64 floatx80_to_int64( floatx80 a, float_ctrl* c ) ! 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 ) { ! 4371: float_raise( float_flag_invalid, c ); ! 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: } ! 4385: return roundAndPackInt64( aSign, aSig, aSigExtra, c ); ! 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: ! 4399: int64 floatx80_to_int64_round_to_zero( floatx80 a, float_ctrl* c ) ! 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 ) { ! 4413: float_raise( float_flag_invalid, c ); ! 4414: if ( ! aSign || ( ( aExp == 0x7FFF ) && aSig ) ) { ! 4415: return LIT64( 0x7FFFFFFFFFFFFFFF ); ! 4416: } ! 4417: } ! 4418: return (sbits64) LIT64( 0x8000000000000000 ); ! 4419: } ! 4420: else if ( aExp < 0x3FFF ) { ! 4421: if ( aExp | aSig ) float_raise( float_flag_inexact, c ); ! 4422: return 0; ! 4423: } ! 4424: z = aSig>>( - shiftCount ); ! 4425: if ( (bits64) ( aSig<<( shiftCount & 63 ) ) ) { ! 4426: float_raise( float_flag_inexact, c ); ! 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: ! 4440: float32 floatx80_to_float32( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 4451: return commonNaNToFloat32( floatx80ToCommonNaN( a, c ) ); ! 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 ! 4466: return roundAndPackFloat32( aSign, aExp, aSig, c ); ! 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: ! 4477: float64 floatx80_to_float64( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 4488: return commonNaNToFloat64( floatx80ToCommonNaN( a, c ) ); ! 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 ! 4503: return roundAndPackFloat64( aSign, aExp, zSig, c ); ! 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: ! 4515: floatx80 floatx80_to_floatx80( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 4526: return propagateFloatx80NaNOneArg( a, c ); ! 4527: } ! 4528: if ( aExp == 0 && aSig != 0 ) { ! 4529: return normalizeRoundAndPackFloatx80( get_float_rounding_precision(c), aSign, aExp, aSig, 0, c ); ! 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: ! 4545: float128 floatx80_to_float128( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 4555: return commonNaNToFloat128( floatx80ToCommonNaN( a, c ) ); ! 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 ! 4571: floatx80 floatx80_round32( floatx80 a, float_ctrl* c ) ! 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: ! 4588: return roundSigAndPackFloatx80( 32, aSign, aExp, aSig, 0, c ); ! 4589: ! 4590: } ! 4591: ! 4592: floatx80 floatx80_round64( floatx80 a, float_ctrl* c ) ! 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: ! 4609: return roundSigAndPackFloatx80( 64, aSign, aExp, aSig, 0, c ); ! 4610: ! 4611: } ! 4612: ! 4613: floatx80 floatx80_round_to_float32( floatx80 a, float_ctrl* c ) ! 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 ) { ! 4624: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, c ); ! 4625: return a; ! 4626: } ! 4627: if ( aExp == 0 ) { ! 4628: if ( aSig == 0 ) return a; ! 4629: normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); ! 4630: } ! 4631: ! 4632: return roundAndPackFloatx80( 32, aSign, aExp, aSig, 0, c ); ! 4633: ! 4634: } ! 4635: ! 4636: floatx80 floatx80_round_to_float64( floatx80 a, float_ctrl* c ) ! 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 ) { ! 4647: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, c ); ! 4648: return a; ! 4649: } ! 4650: if ( aExp == 0 ) { ! 4651: if ( aSig == 0 ) return a; ! 4652: normalizeFloatx80Subnormal( aSig, &aExp, &aSig ); ! 4653: } ! 4654: ! 4655: return roundAndPackFloatx80( 64, aSign, aExp, aSig, 0, c ); ! 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: ! 4716: floatx80 floatx80_round_to_int( floatx80 a, float_ctrl* c ) ! 4717: { ! 4718: flag aSign; ! 4719: int32 aExp; ! 4720: bits64 lastBitMask, roundBitsMask; ! 4721: int8 roundingMode; ! 4722: floatx80 z; ! 4723: ! 4724: roundingMode = get_float_rounding_mode( c ); ! 4725: aExp = extractFloatx80Exp( a ); ! 4726: if ( 0x403E <= aExp ) { ! 4727: if ( ( aExp == 0x7FFF ) && (bits64) ( extractFloatx80Frac( a )<<1 ) ) { ! 4728: return propagateFloatx80NaNOneArg( a, c ); ! 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: } ! 4741: float_raise( float_flag_inexact, c ); ! 4742: aSign = extractFloatx80Sign( a ); ! 4743: switch ( roundingMode ) { ! 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: } ! 4781: if ( z.low != a.low ) float_raise( float_flag_inexact, c ); ! 4782: return z; ! 4783: ! 4784: } ! 4785: ! 4786: #ifdef SOFTFLOAT_68K // 09-01-2017: Added for Previous ! 4787: floatx80 floatx80_round_to_int_toward_zero( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 4797: return propagateFloatx80NaNOneArg( a, c ); ! 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: } ! 4810: float_raise( float_flag_inexact, c ); ! 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: } ! 4823: if ( z.low != a.low ) float_raise( float_flag_inexact, c ); ! 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: ! 4837: static floatx80 addFloatx80Sigs( floatx80 a, floatx80 b, flag zSign, float_ctrl* c ) ! 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 ) { ! 4858: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 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 ) { ! 4869: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 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 ) ) { ! 4881: return propagateFloatx80NaN( a, b, c ); ! 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( ! 4909: get_float_rounding_precision(c), zSign, zExp, zSig0, zSig1, c ); ! 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: ! 4921: static floatx80 subFloatx80Sigs( floatx80 a, floatx80 b, flag zSign, float_ctrl* c ) ! 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 ) ) { ! 4937: return propagateFloatx80NaN( a, b, c ); ! 4938: } ! 4939: float_raise( float_flag_invalid, c ); ! 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; ! 4953: return packFloatx80( get_float_rounding_mode( c ) == float_round_down, 0, 0 ); ! 4954: bExpBigger: ! 4955: if ( bExp == 0x7FFF ) { ! 4956: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 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 ) { ! 4970: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 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( ! 4983: get_float_rounding_precision(c), zSign, zExp, zSig0, zSig1, c ); ! 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: ! 4993: floatx80 floatx80_add( floatx80 a, floatx80 b, float_ctrl* c ) ! 4994: { ! 4995: flag aSign, bSign; ! 4996: ! 4997: aSign = extractFloatx80Sign( a ); ! 4998: bSign = extractFloatx80Sign( b ); ! 4999: if ( aSign == bSign ) { ! 5000: return addFloatx80Sigs( a, b, aSign, c ); ! 5001: } ! 5002: else { ! 5003: return subFloatx80Sigs( a, b, aSign, c ); ! 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: ! 5014: floatx80 floatx80_sub( floatx80 a, floatx80 b, float_ctrl* c ) ! 5015: { ! 5016: flag aSign, bSign; ! 5017: ! 5018: aSign = extractFloatx80Sign( a ); ! 5019: bSign = extractFloatx80Sign( b ); ! 5020: if ( aSign == bSign ) { ! 5021: return subFloatx80Sigs( a, b, aSign, c ); ! 5022: } ! 5023: else { ! 5024: return addFloatx80Sigs( a, b, aSign, c ); ! 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: ! 5035: floatx80 floatx80_mul( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ) ) ) { ! 5052: return propagateFloatx80NaN( a, b, c ); ! 5053: } ! 5054: if ( ( bExp | bSig ) == 0 ) goto invalid; ! 5055: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); ! 5056: } ! 5057: if ( bExp == 0x7FFF ) { ! 5058: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5059: if ( ( aExp | aSig ) == 0 ) { ! 5060: invalid: ! 5061: float_raise( float_flag_invalid, c ); ! 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( ! 5084: get_float_rounding_precision(c), zSign, zExp, zSig0, zSig1, c ); ! 5085: ! 5086: } ! 5087: ! 5088: #ifdef SOFTFLOAT_68K // 21-01-2017: Added for Previous ! 5089: floatx80 floatx80_sglmul( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ) ) ) { ! 5106: return propagateFloatx80NaN( a, b, c ); ! 5107: } ! 5108: if ( ( bExp | bSig ) == 0 ) goto invalid; ! 5109: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); ! 5110: } ! 5111: if ( bExp == 0x7FFF ) { ! 5112: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5113: if ( ( aExp | aSig ) == 0 ) { ! 5114: invalid: ! 5115: float_raise( float_flag_invalid, c ); ! 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: } ! 5138: return roundSigAndPackFloatx80( 32, zSign, zExp, zSig0, zSig1, c ); ! 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: ! 5149: floatx80 floatx80_div( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ) { ! 5165: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5166: if ( bExp == 0x7FFF ) { ! 5167: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5168: goto invalid; ! 5169: } ! 5170: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); ! 5171: } ! 5172: if ( bExp == 0x7FFF ) { ! 5173: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5174: return packFloatx80( zSign, 0, 0 ); ! 5175: } ! 5176: if ( bExp == 0 ) { ! 5177: if ( bSig == 0 ) { ! 5178: if ( ( aExp | aSig ) == 0 ) { ! 5179: invalid: ! 5180: float_raise( float_flag_invalid, c ); ! 5181: z.low = floatx80_default_nan_low; ! 5182: z.high = floatx80_default_nan_high; ! 5183: return z; ! 5184: } ! 5185: float_raise( float_flag_divbyzero, c ); ! 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( ! 5219: get_float_rounding_precision(c), zSign, zExp, zSig0, zSig1, c ); ! 5220: ! 5221: } ! 5222: ! 5223: #ifdef SOFTFLOAT_68K // 21-01-2017: Addition for Previous ! 5224: floatx80 floatx80_sgldiv( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ) { ! 5240: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5241: if ( bExp == 0x7FFF ) { ! 5242: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5243: goto invalid; ! 5244: } ! 5245: return packFloatx80( zSign, 0x7FFF, floatx80_default_infinity_low ); ! 5246: } ! 5247: if ( bExp == 0x7FFF ) { ! 5248: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5249: return packFloatx80( zSign, 0, 0 ); ! 5250: } ! 5251: if ( bExp == 0 ) { ! 5252: if ( bSig == 0 ) { ! 5253: if ( ( aExp | aSig ) == 0 ) { ! 5254: invalid: ! 5255: float_raise( float_flag_invalid, c ); ! 5256: z.low = floatx80_default_nan_low; ! 5257: z.high = floatx80_default_nan_high; ! 5258: return z; ! 5259: } ! 5260: float_raise( float_flag_divbyzero, c ); ! 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: } ! 5292: return roundSigAndPackFloatx80( 32, zSign, zExp, zSig0, zSig1, c ); ! 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 ! 5394: floatx80 floatx80_rem( floatx80 a, floatx80 b, bits64 *q, flag *s, float_ctrl* c ) ! 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 ) ) ) { ! 5412: return propagateFloatx80NaN( a, b, c ); ! 5413: } ! 5414: goto invalid; ! 5415: } ! 5416: if ( bExp == 0x7FFF ) { ! 5417: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5418: *s = (aSign != bSign); ! 5419: *q = 0; ! 5420: return a; ! 5421: } ! 5422: if ( bExp == 0 ) { ! 5423: if ( bSig == 0 ) { ! 5424: invalid: ! 5425: float_raise( float_flag_invalid, c ); ! 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( ! 5497: 80, zSign, bExp + expDiff, aSig0, aSig1, c ); ! 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: ! 5508: floatx80 floatx80_mod( floatx80 a, floatx80 b, bits64 *q, flag *s, float_ctrl* c ) ! 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 ) ) ) { ! 5526: return propagateFloatx80NaN( a, b, c ); ! 5527: } ! 5528: goto invalid; ! 5529: } ! 5530: if ( bExp == 0x7FFF ) { ! 5531: if ( (bits64) ( bSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 5532: *s = (aSign != bSign); ! 5533: *q = 0; ! 5534: return a; ! 5535: } ! 5536: if ( bExp == 0 ) { ! 5537: if ( bSig == 0 ) { ! 5538: invalid: ! 5539: float_raise( float_flag_invalid, c ); ! 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( ! 5593: 80, zSign, bExp + expDiff, aSig0, aSig1, c ); ! 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: ! 5604: floatx80 floatx80_sqrt( floatx80 a, float_ctrl* c ) ! 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 ) { ! 5616: if ( (bits64) ( aSig0<<1 ) ) return propagateFloatx80NaNOneArg( a, c ); ! 5617: if ( ! aSign ) return a; ! 5618: goto invalid; ! 5619: } ! 5620: if ( aSign ) { ! 5621: if ( ( aExp | aSig0 ) == 0 ) return a; ! 5622: invalid: ! 5623: float_raise( float_flag_invalid, c ); ! 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( ! 5664: get_float_rounding_precision(c), 0, zExp, zSig0, zSig1, c ); ! 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: ! 5674: floatx80 floatx80_getman( floatx80 a, float_ctrl* c ) ! 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 ) { ! 5685: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, c ); ! 5686: float_raise( float_flag_invalid, c ); ! 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: ! 5697: return roundAndPackFloatx80( get_float_rounding_precision(c), aSign, 0x3FFF, aSig, 0, c ); ! 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: ! 5705: floatx80 floatx80_getexp( floatx80 a, float_ctrl* c ) ! 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 ) { ! 5716: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, c ); ! 5717: float_raise( float_flag_invalid, c ); ! 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: ! 5739: floatx80 floatx80_scale( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ) ) ) { ! 5755: return propagateFloatx80NaN( a, b, c ); ! 5756: } ! 5757: float_raise( float_flag_invalid, c ); ! 5758: a.low = floatx80_default_nan_low; ! 5759: a.high = floatx80_default_nan_high; ! 5760: return a; ! 5761: } ! 5762: if ( aExp == 0x7FFF ) { ! 5763: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaN( a, b, c ); ! 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( ! 5777: get_float_rounding_precision(c), aSign, aExp, aSig, 0, c ); ! 5778: } ! 5779: ! 5780: shiftCount = 0x403E - bExp; ! 5781: bSig >>= shiftCount; ! 5782: aExp = bSign ? ( aExp - bSig ) : ( aExp + bSig ); ! 5783: ! 5784: return roundAndPackFloatx80( ! 5785: get_float_rounding_precision(c), aSign, aExp, aSig, 0, c ); ! 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: ! 5795: floatx80 floatx80_abs( floatx80 a, float_ctrl* c ) ! 5796: { ! 5797: int32 aExp; ! 5798: bits64 aSig; ! 5799: ! 5800: aSig = extractFloatx80Frac(a); ! 5801: aExp = extractFloatx80Exp(a); ! 5802: ! 5803: if ( aExp == 0x7FFF && (bits64) ( aSig<<1 ) ) { ! 5804: return propagateFloatx80NaNOneArg( a, c ); ! 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( ! 5813: get_float_rounding_precision(c), 0, aExp, aSig, 0, c ); ! 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: ! 5823: floatx80 floatx80_neg( floatx80 a, float_ctrl* c ) ! 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 ) ) { ! 5834: return propagateFloatx80NaNOneArg( a, c ); ! 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( ! 5845: get_float_rounding_precision(c), aSign, aExp, aSig, 0, c ); ! 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: ! 5855: floatx80 floatx80_cmp( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ), ! 5871: packFloatx80( 0, bExp, bSig ), c ); ! 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: ! 5893: floatx80 floatx80_tst( floatx80 a, float_ctrl* c ) ! 5894: { ! 5895: int32 aExp; ! 5896: bits64 aSig; ! 5897: ! 5898: aSig = extractFloatx80Frac( a ); ! 5899: aExp = extractFloatx80Exp( a ); ! 5900: ! 5901: if ( aExp == 0x7FFF && (bits64) ( aSig<<1 ) ) ! 5902: return propagateFloatx80NaNOneArg( a, c ); ! 5903: ! 5904: return a; ! 5905: } ! 5906: ! 5907: floatx80 floatx80_move( floatx80 a, float_ctrl* c ) ! 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 ) { ! 5918: if ( (bits64) ( aSig<<1 ) ) return propagateFloatx80NaNOneArg( a, c ); ! 5919: return a; ! 5920: } ! 5921: if ( aExp == 0 ) { ! 5922: if ( aSig == 0 ) return a; ! 5923: normalizeRoundAndPackFloatx80( get_float_rounding_precision(c), aSign, aExp, aSig, 0, c ); ! 5924: } ! 5925: return roundAndPackFloatx80( get_float_rounding_precision(c), aSign, aExp, aSig, 0, c ); ! 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: ! 5938: flag floatx80_eq( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ) ) { ! 5947: float_raise( float_flag_invalid, c ); ! 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: ! 5967: flag floatx80_le( floatx80 a, floatx80 b, float_ctrl* c ) ! 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: ) { ! 5976: float_raise( float_flag_invalid, c ); ! 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: ! 6000: flag floatx80_lt( floatx80 a, floatx80 b, float_ctrl* c ) ! 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: ) { ! 6009: float_raise( float_flag_invalid, c ); ! 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: ! 6033: flag floatx80_eq_signaling( floatx80 a, floatx80 b, float_ctrl* c ) ! 6034: { ! 6035: if ( ( ( extractFloatx80Exp( a ) == 0x7FFF ) ! 6036: && (bits64) ( extractFloatx80Frac( a )<<1 ) ) ! 6037: || ( ( extractFloatx80Exp( b ) == 0x7FFF ) ! 6038: && (bits64) ( extractFloatx80Frac( b )<<1 ) ) ! 6039: ) { ! 6040: float_raise( float_flag_invalid, c ); ! 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: ! 6059: flag floatx80_le_quiet( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ) ) { ! 6070: float_raise( float_flag_invalid, c ); ! 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: ! 6095: flag floatx80_lt_quiet( floatx80 a, floatx80 b, float_ctrl* c ) ! 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 ) ) { ! 6106: float_raise( float_flag_invalid, c ); ! 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: ! 6138: int32 float128_to_int32( float128 a, float_ctrl* c ) ! 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 ); ! 6153: return roundAndPackInt32( aSign, aSig0, c ); ! 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: ! 6167: int32 float128_to_int32_round_to_zero( float128 a, float_ctrl* c ) ! 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 ) { ! 6184: if ( aExp || aSig0 ) float_raise( float_flag_inexact, c ); ! 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: ! 6196: float_raise( float_flag_invalid, c ); ! 6197: return aSign ? (sbits32) 0x80000000 : 0x7FFFFFFF; ! 6198: } ! 6199: if ( ( aSig0<<shiftCount ) != savedASig ) { ! 6200: float_raise( float_flag_inexact, c ); ! 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: ! 6216: int64 float128_to_int64( float128 a, float_ctrl* c ) ! 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 ) { ! 6230: float_raise( float_flag_invalid, c ); ! 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: } ! 6245: return roundAndPackInt64( aSign, aSig0, aSig1, c ); ! 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: ! 6259: int64 float128_to_int64_round_to_zero( float128 a, float_ctrl* c ) ! 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 ) ) ) { ! 6277: if ( aSig1 ) float_raise( float_flag_inexact, c ); ! 6278: } ! 6279: else { ! 6280: float_raise( float_flag_invalid, c ); ! 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 ) ) { ! 6289: float_raise( float_flag_inexact, c ); ! 6290: } ! 6291: } ! 6292: else { ! 6293: if ( aExp < 0x3FFF ) { ! 6294: if ( aExp | aSig0 | aSig1 ) { ! 6295: float_raise( float_flag_inexact, c ); ! 6296: } ! 6297: return 0; ! 6298: } ! 6299: z = aSig0>>( - shiftCount ); ! 6300: if ( aSig1 ! 6301: || ( shiftCount && (bits64) ( aSig0<<( shiftCount & 63 ) ) ) ) { ! 6302: float_raise( float_flag_inexact, c ); ! 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: ! 6317: float32 float128_to_float32( float128 a, float_ctrl* c ) ! 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 ) { ! 6330: return commonNaNToFloat32( float128ToCommonNaN( a, c ) ); ! 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: } ! 6341: return roundAndPackFloat32( aSign, aExp, zSig, c ); ! 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: ! 6352: float64 float128_to_float64( float128 a, float_ctrl* c ) ! 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 ) { ! 6364: return commonNaNToFloat64( float128ToCommonNaN( a, c ) ); ! 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: } ! 6374: return roundAndPackFloat64( aSign, aExp, aSig0, c ); ! 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: ! 6387: floatx80 float128_to_floatx80( float128 a, float_ctrl* c ) ! 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 ) { ! 6399: return commonNaNToFloatx80( float128ToCommonNaN( a, c ) ); ! 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 ); ! 6411: return roundAndPackFloatx80( 80, aSign, aExp, aSig0, aSig1, c ); ! 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: ! 6424: float128 float128_round_to_int( float128 a, float_ctrl* c ) ! 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: ) { ! 6438: return propagateFloat128NaN( a, a, c ); ! 6439: } ! 6440: return a; ! 6441: } ! 6442: lastBitMask = 1; ! 6443: lastBitMask = ( lastBitMask<<( 0x406E - aExp ) )<<1; ! 6444: roundBitsMask = lastBitMask - 1; ! 6445: z = a; ! 6446: roundingMode = get_float_rounding_mode( c ); ! 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; ! 6470: float_raise( float_flag_inexact, c ); ! 6471: aSign = extractFloat128Sign( a ); ! 6472: roundingMode = get_float_rounding_mode( c ); ! 6473: switch ( roundingMode ) { ! 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; ! 6498: roundingMode = get_float_rounding_mode( c ); ! 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 ) ) { ! 6515: float_raise( float_flag_inexact, c ); ! 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: ! 6529: static float128 addFloat128Sigs( float128 a, float128 b, flag zSign, float_ctrl* c ) ! 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 ) { ! 6544: if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b, c ); ! 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 ) { ! 6559: if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b, c ); ! 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 ) { ! 6575: return propagateFloat128NaN( a, b, c ); ! 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: ! 6595: return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2, c ); ! 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: ! 6607: static float128 subFloat128Sigs( float128 a, float128 b, flag zSign, float_ctrl* c ) ! 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 ) { ! 6627: return propagateFloat128NaN( a, b, c ); ! 6628: } ! 6629: float_raise( float_flag_invalid, c ); ! 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; ! 6642: return packFloat128( get_float_rounding_mode( c ) == float_round_down, 0, 0, 0 ); ! 6643: bExpBigger: ! 6644: if ( bExp == 0x7FFF ) { ! 6645: if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b, c ); ! 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 ) { ! 6663: if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b, c ); ! 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; ! 6679: return normalizeRoundAndPackFloat128( zSign, zExp - 14, zSig0, zSig1, c ); ! 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: ! 6689: float128 float128_add( float128 a, float128 b, float_ctrl* c ) ! 6690: { ! 6691: flag aSign, bSign; ! 6692: ! 6693: aSign = extractFloat128Sign( a ); ! 6694: bSign = extractFloat128Sign( b ); ! 6695: if ( aSign == bSign ) { ! 6696: return addFloat128Sigs( a, b, aSign, c ); ! 6697: } ! 6698: else { ! 6699: return subFloat128Sigs( a, b, aSign, c ); ! 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: ! 6710: float128 float128_sub( float128 a, float128 b, float_ctrl* c ) ! 6711: { ! 6712: flag aSign, bSign; ! 6713: ! 6714: aSign = extractFloat128Sign( a ); ! 6715: bSign = extractFloat128Sign( b ); ! 6716: if ( aSign == bSign ) { ! 6717: return subFloat128Sigs( a, b, aSign, c ); ! 6718: } ! 6719: else { ! 6720: return addFloat128Sigs( a, b, aSign, c ); ! 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: ! 6731: float128 float128_mul( float128 a, float128 b, float_ctrl* c ) ! 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 ) ) ) { ! 6750: return propagateFloat128NaN( a, b, c ); ! 6751: } ! 6752: if ( ( bExp | bSig0 | bSig1 ) == 0 ) goto invalid; ! 6753: return packFloat128( zSign, 0x7FFF, 0, 0 ); ! 6754: } ! 6755: if ( bExp == 0x7FFF ) { ! 6756: if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b, c ); ! 6757: if ( ( aExp | aSig0 | aSig1 ) == 0 ) { ! 6758: invalid: ! 6759: float_raise( float_flag_invalid, c ); ! 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: } ! 6785: return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2, c ); ! 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: ! 6795: float128 float128_div( float128 a, float128 b, float_ctrl* c ) ! 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 ) { ! 6813: if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, b, c ); ! 6814: if ( bExp == 0x7FFF ) { ! 6815: if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b, c ); ! 6816: goto invalid; ! 6817: } ! 6818: return packFloat128( zSign, 0x7FFF, 0, 0 ); ! 6819: } ! 6820: if ( bExp == 0x7FFF ) { ! 6821: if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b, c ); ! 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: ! 6828: float_raise( float_flag_invalid, c ); ! 6829: z.low = float128_default_nan_low; ! 6830: z.high = float128_default_nan_high; ! 6831: return z; ! 6832: } ! 6833: float_raise( float_flag_divbyzero, c ); ! 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 ); ! 6869: return roundAndPackFloat128( zSign, zExp, zSig0, zSig1, zSig2, c ); ! 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: ! 6879: float128 float128_rem( float128 a, float128 b, float_ctrl* c ) ! 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 ) ) ) { ! 6899: return propagateFloat128NaN( a, b, c ); ! 6900: } ! 6901: goto invalid; ! 6902: } ! 6903: if ( bExp == 0x7FFF ) { ! 6904: if ( bSig0 | bSig1 ) return propagateFloat128NaN( a, b, c ); ! 6905: return a; ! 6906: } ! 6907: if ( bExp == 0 ) { ! 6908: if ( ( bSig0 | bSig1 ) == 0 ) { ! 6909: invalid: ! 6910: float_raise( float_flag_invalid, c ); ! 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 ! 6979: normalizeRoundAndPackFloat128( aSign ^ zSign, bExp - 4, aSig0, aSig1, c ); ! 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: ! 6989: float128 float128_sqrt( float128 a, float_ctrl* c ) ! 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 ) { ! 7002: if ( aSig0 | aSig1 ) return propagateFloat128NaN( a, a, c ); ! 7003: if ( ! aSign ) return a; ! 7004: goto invalid; ! 7005: } ! 7006: if ( aSign ) { ! 7007: if ( ( aExp | aSig0 | aSig1 ) == 0 ) return a; ! 7008: invalid: ! 7009: float_raise( float_flag_invalid, c ); ! 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 ); ! 7048: return roundAndPackFloat128( 0, zExp, zSig0, zSig1, zSig2, c ); ! 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: ! 7058: flag float128_eq( float128 a, float128 b, float_ctrl* c ) ! 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 ) ) { ! 7067: float_raise( float_flag_invalid, c ); ! 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: ! 7087: flag float128_le( float128 a, float128 b, float_ctrl* c ) ! 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: ) { ! 7096: float_raise( float_flag_invalid, c ); ! 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: ! 7119: flag float128_lt( float128 a, float128 b, float_ctrl* c ) ! 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: ) { ! 7128: float_raise( float_flag_invalid, c ); ! 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: ! 7152: flag float128_eq_signaling( float128 a, float128 b, float_ctrl* c ) ! 7153: { ! 7154: if ( ( ( extractFloat128Exp( a ) == 0x7FFF ) ! 7155: && ( extractFloat128Frac0( a ) | extractFloat128Frac1( a ) ) ) ! 7156: || ( ( extractFloat128Exp( b ) == 0x7FFF ) ! 7157: && ( extractFloat128Frac0( b ) | extractFloat128Frac1( b ) ) ) ! 7158: ) { ! 7159: float_raise( float_flag_invalid, c ); ! 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: ! 7178: flag float128_le_quiet( float128 a, float128 b, float_ctrl* c ) ! 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 ) ) { ! 7189: float_raise( float_flag_invalid, c ); ! 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: ! 7214: flag float128_lt_quiet( float128 a, float128 b, float_ctrl* c ) ! 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 ) ) { ! 7225: float_raise( float_flag_invalid, c ); ! 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.