Changeset 94613 in vbox
- Timestamp:
- Apr 15, 2022 1:12:37 AM (3 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/libs/softfloat-3e/source/s_roundPackToExtF80.c
r94612 r94613 43 43 #include <iprt/assert.h> 44 44 45 #if 1 /* This approach for bias adjust is somewhat cleaner, though a bit slower. But it works correctly. */46 45 static extFloat80_t 47 46 softfloat_roundPackToExtF80Inner( … … 326 325 } 327 326 328 #else /* Messy integrated approach for bias adjust that doesn't quite work 100%: */329 330 extFloat80_t331 softfloat_roundPackToExtF80(332 bool sign,333 int_fast32_t exp,334 uint_fast64_t sig,335 uint_fast64_t sigExtra,336 uint_fast8_t roundingPrecision337 SOFTFLOAT_STATE_DECL_COMMA338 )339 {340 uint_fast8_t roundingMode;341 bool roundNearEven;342 uint_fast64_t roundIncrement, roundMask, roundBits;343 bool isTiny, doIncrement = 0;344 struct uint64_extra sig64Extra;345 union { struct extFloat80M s; extFloat80_t f; } uZ;346 RTAssertMsg2("softfloat_roundPackToExtF80: exp=%d sig=%RX64 sigExtra=%RX64 rp=%d\n", exp, sig, sigExtra, roundingPrecision);347 348 /*------------------------------------------------------------------------349 *------------------------------------------------------------------------*/350 roundingMode = softfloat_roundingMode;351 roundNearEven = (roundingMode == softfloat_round_near_even);352 if ( roundingPrecision == 80 ) goto precision80;353 if ( roundingPrecision == 64 ) {354 roundIncrement = UINT64_C( 0x0000000000000400 );355 roundMask = UINT64_C( 0x00000000000007FF );356 } else if ( roundingPrecision == 32 ) {357 roundIncrement = UINT64_C( 0x0000008000000000 );358 roundMask = UINT64_C( 0x000000FFFFFFFFFF );359 } else {360 goto precision80;361 }362 sig |= (sigExtra != 0);363 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {364 roundIncrement =365 (roundingMode366 == (sign ? softfloat_round_min : softfloat_round_max))367 ? roundMask368 : 0;369 }370 roundBits = sig & roundMask;371 /*------------------------------------------------------------------------372 *------------------------------------------------------------------------*/373 if ( 0x7FFD <= (uint32_t) (exp - 1) ) {374 if ( exp <= 0 ) {375 /*----------------------------------------------------------------376 *----------------------------------------------------------------*/377 bool fUnmaskedUnderflow = false; /* VBox: unmasked underflow bias adjust */378 isTiny =379 (softfloat_detectTininess380 == softfloat_tininess_beforeRounding)381 || (exp < 0)382 || (sig <= (uint64_t) (sig + roundIncrement));383 if ( (pState->exceptionMask & softfloat_flag_underflow) /* VBox: unmasked underflow bias adjust */384 || (exp == -63 && sig == 0 && sigExtra == 0) /* zero */ ) { /* VBox: unmasked underflow bias adjust */385 sig = softfloat_shiftRightJam64(sig, 1 - exp);386 } else { /* VBox: unmasked underflow bias adjust */387 //RTAssertMsg2("softfloat_roundPackToExtF80: #UE - bias adj: %d -> %d; sig=%#RX64\n", exp, exp + RTFLOAT80U_EXP_BIAS_ADJUST, sig); /* VBox: unmasked underflow bias adjust */388 softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); /* VBox: unmasked underflow bias adjust */389 exp += RTFLOAT80U_EXP_BIAS_ADJUST; /* VBox: unmasked underflow bias adjust */390 fUnmaskedUnderflow = true; /* VBox: unmasked underflow bias adjust */391 } /* VBox: unmasked underflow bias adjust */392 uint64_t const uOldSig = sig; /* VBox: C1 */393 roundBits = sig & roundMask;394 if ( roundBits ) {395 if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA );396 softfloat_exceptionFlags |= softfloat_flag_inexact;397 #ifdef SOFTFLOAT_ROUND_ODD398 if ( roundingMode == softfloat_round_odd ) {399 sig |= roundMask + 1;400 }401 #endif402 }403 sig += roundIncrement;404 if ( !fUnmaskedUnderflow ) { /* VBox: unmasked underflow bias adjust */405 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);406 } /* VBox: unmasked underflow bias adjust */407 roundIncrement = roundMask + 1;408 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {409 roundMask |= roundIncrement;410 }411 sig &= ~roundMask;412 if ( sig > uOldSig ) { /* VBox: C1 */413 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */414 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #1\n"); /* VBox: C1 */415 } /* VBox: C1 */416 goto packReturn;417 }418 if (419 (0x7FFE < exp)420 || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))421 ) {422 if ( !(pState->exceptionMask & softfloat_flag_overflow) ) { /* VBox: unmasked overflow bias adjust */423 //RTAssertMsg2("softfloat_roundPackToExtF80: #OE - bias adj: %d -> %d; sig=%#RX64'%016RX64\n", exp, (exp - RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX, sig, sigExtra); /* VBox: unmasked underflow bias adjust */424 exp = (exp - RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX; /* VBox: unmasked overflow bias adjust */425 softfloat_raiseFlags( softfloat_flag_overflow /* VBox: unmasked overflow bias adjust */426 | softfloat_flag_inexact SOFTFLOAT_STATE_ARG_COMMA ); /* VBox: unmasked overflow bias adjust */427 } else { /* VBox: unmasked overflow bias adjust */428 //RTAssertMsg2("softfloat_roundPackToExtF80: #OE - masked\n");429 goto overflow;430 } /* VBox: unmasked overflow bias adjust */431 }432 }433 /*------------------------------------------------------------------------434 *------------------------------------------------------------------------*/435 { /* VBox: C1 */436 uint64_t const uOldSig = sig; /* VBox: C1 */437 if ( roundBits ) {438 softfloat_exceptionFlags |= softfloat_flag_inexact;439 #ifdef SOFTFLOAT_ROUND_ODD440 if ( roundingMode == softfloat_round_odd ) {441 sig = (sig & ~roundMask) | (roundMask + 1);442 if ( sig > uOldSig ) { /* VBox: C1 */443 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */444 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #2\n"); /* VBox: C1 */445 } /* VBox: C1 */446 goto packReturn;447 }448 #endif449 }450 sig = (uint64_t) (sig + roundIncrement);451 if ( sig < roundIncrement ) {452 ++exp;453 sig = UINT64_C( 0x8000000000000000 );454 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */455 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #3\n"); /* VBox: C1 */456 }457 roundIncrement = roundMask + 1;458 if ( roundNearEven && (roundBits<<1 == roundIncrement) ) {459 roundMask |= roundIncrement;460 }461 sig &= ~roundMask;462 if ( sig > uOldSig ) { /* VBox: C1 */463 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */464 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #4\n"); /* VBox: C1 */465 } /* VBox: C1 */466 goto packReturn;467 } /* VBox: C1 */468 /*------------------------------------------------------------------------469 *------------------------------------------------------------------------*/470 precision80:471 doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);472 if ( ! roundNearEven && (roundingMode != softfloat_round_near_maxMag) ) {473 doIncrement =474 (roundingMode475 == (sign ? softfloat_round_min : softfloat_round_max))476 && sigExtra;477 }478 /*------------------------------------------------------------------------479 *------------------------------------------------------------------------*/480 if ( 0x7FFD <= (uint32_t) (exp - 1) ) {481 if ( exp <= 0 ) {482 /*----------------------------------------------------------------483 *----------------------------------------------------------------*/484 bool fUnmaskedUnderflow = false; /* VBox: unmasked underflow bias adjust */485 isTiny =486 (softfloat_detectTininess487 == softfloat_tininess_beforeRounding)488 || (exp < 0)489 || ! doIncrement490 || (sig < UINT64_C( 0xFFFFFFFFFFFFFFFF ));491 if ( exp == -63 && sig == 0 && sigExtra == 0 /* zero */ ) { /* VBox: unmasked underflow bias adjust */492 exp = 0; /* VBox: unmasked underflow bias adjust */493 } else if ( pState->exceptionMask & softfloat_flag_underflow ) { /* VBox: unmasked underflow bias adjust */494 sig64Extra =495 softfloat_shiftRightJam64Extra( sig, sigExtra, 1 - exp );496 if ( exp < -63 || sig64Extra.extra != 0 ) { /* VBox: unmasked underflow bias adjust */497 softfloat_exceptionFlags |= softfloat_flag_inexact; /* VBox: unmasked underflow bias adjust */498 } /* VBox: unmasked underflow bias adjust */499 exp = 0;500 sig = sig64Extra.v;501 sigExtra = sig64Extra.extra;502 } else { /* VBox: unmasked underflow bias adjust */503 RTAssertMsg2("softfloat_roundPackToExtF80: #UE/80 - bias adj: %d -> %d; sig=%#RX64'%016RX64 t=%d\n", /* VBox: unmasked underflow bias adjust */504 exp, (exp + RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX, sig, sigExtra, isTiny); /* VBox: unmasked underflow bias adjust */505 softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA ); /* VBox: unmasked underflow bias adjust */506 exp = (exp + RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX; /* VBox: unmasked underflow bias adjust */507 fUnmaskedUnderflow = true; /* VBox: unmasked underflow bias adjust */508 } /* VBox: unmasked underflow bias adjust */509 if ( sigExtra ) {510 if ( isTiny ) softfloat_raiseFlags( softfloat_flag_underflow SOFTFLOAT_STATE_ARG_COMMA );511 #ifdef SOFTFLOAT_ROUND_ODD512 if ( roundingMode == softfloat_round_odd ) {513 sig |= 1;514 goto packReturn;515 }516 #endif517 }518 doIncrement = (UINT64_C( 0x8000000000000000 ) <= sigExtra);519 if (520 ! roundNearEven521 && (roundingMode != softfloat_round_near_maxMag)522 ) {523 doIncrement =524 (roundingMode525 == (sign ? softfloat_round_min : softfloat_round_max))526 && sigExtra;527 }528 if ( doIncrement ) {529 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */530 RTAssertMsg2("softfloat_roundPackToExtF80: C1 #5\n"); /* VBox: C1 */531 ++sig;532 sig &=533 ~(uint_fast64_t)534 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))535 & roundNearEven);536 if ( !fUnmaskedUnderflow ) { /* VBox: unmasked underflow bias adjust */537 exp = ((sig & UINT64_C( 0x8000000000000000 )) != 0);538 } /* VBox: unmasked underflow bias adjust */539 }540 goto packReturn;541 }542 if (543 (0x7FFE < exp)544 || ((exp == 0x7FFE) && (sig == UINT64_C( 0xFFFFFFFFFFFFFFFF ))545 && doIncrement)546 ) {547 /*----------------------------------------------------------------548 *----------------------------------------------------------------*/549 roundMask = 0;550 overflow:551 softfloat_raiseFlags(552 softfloat_flag_overflow | softfloat_flag_inexact553 SOFTFLOAT_STATE_ARG_COMMA );554 if (555 roundNearEven556 || (roundingMode == softfloat_round_near_maxMag)557 || (roundingMode558 == (sign ? softfloat_round_min : softfloat_round_max))559 ) {560 if ( !(pState->exceptionMask & softfloat_flag_overflow) ) { /* VBox: unmasked overflow bias adjust */561 //RTAssertMsg2("softfloat_roundPackToExtF80: #OE/80a - bias adj: %d -> %d; sig=%#RX64'%016RX64\n", exp, (exp - RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX, sig, sigExtra); /* VBox: unmasked underflow bias adjust */562 exp = (exp - RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX; /* VBox: unmasked overflow bias adjust */563 } else { /* VBox: unmasked overflow bias adjust */564 exp = 0x7FFF;565 sig = UINT64_C( 0x8000000000000000 );566 softfloat_exceptionFlags |= softfloat_flag_c1; /* Inf means rounding up */ /* VBox: C1 */567 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #6\n"); /* VBox: C1 */568 goto packReturn;569 } /* VBox: unmasked overflow bias adjust */570 } else {571 if ( !(pState->exceptionMask & softfloat_flag_overflow) ) { /* VBox: unmasked overflow bias adjust */572 //RTAssertMsg2("softfloat_roundPackToExtF80: #OE/80b - bias adj: %d -> %d; sig=%#RX64'%016RX64\n", exp, (exp - RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX, sig, sigExtra); /* VBox: unmasked underflow bias adjust */573 exp = (exp - RTFLOAT80U_EXP_BIAS_ADJUST) & RTFLOAT80U_EXP_MAX; /* VBox: unmasked overflow bias adjust */574 } else { /* VBox: unmasked overflow bias adjust */575 exp = 0x7FFE;576 sig = ~roundMask;577 goto packReturn;578 }579 }580 }581 }582 /*------------------------------------------------------------------------583 *------------------------------------------------------------------------*/584 if ( sigExtra ) {585 softfloat_exceptionFlags |= softfloat_flag_inexact;586 #ifdef SOFTFLOAT_ROUND_ODD587 if ( roundingMode == softfloat_round_odd ) {588 sig |= 1;589 goto packReturn;590 }591 #endif592 }593 if ( doIncrement ) {594 uint64_t const uOldSig = sig; /* VBox */595 ++sig;596 if ( ! sig ) {597 ++exp;598 sig = UINT64_C( 0x8000000000000000 );599 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */600 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #7\n"); /* VBox: C1 */601 } else {602 sig &=603 ~(uint_fast64_t)604 (! (sigExtra & UINT64_C( 0x7FFFFFFFFFFFFFFF ))605 & roundNearEven);606 if ( sig > uOldSig ) { /* VBox: C1 */607 softfloat_exceptionFlags |= softfloat_flag_c1; /* VBox: C1 */608 //RTAssertMsg2("softfloat_roundPackToExtF80: C1 #8\n"); /* VBox: C1 */609 }610 }611 }612 /*------------------------------------------------------------------------613 *------------------------------------------------------------------------*/614 packReturn:615 uZ.s.signExp = packToExtF80UI64( sign, exp );616 uZ.s.signif = sig;617 return uZ.f;618 619 }620 621 #endif /* Messy integrated approach for bias adjust that doesn't quite work 100%: */
Note:
See TracChangeset
for help on using the changeset viewer.