rewrite code for biasing unmasked underflow for floatx80 in softfloat3e (from hack to clean code)

This commit is contained in:
Stanislav Shwartsman 2024-04-28 06:41:29 +03:00
parent 805bb6b985
commit 632d8780de

View File

@ -76,9 +76,14 @@ extFloat80_t
/*----------------------------------------------------------------
*----------------------------------------------------------------*/
isTiny = (exp < 0) || (sig <= (uint64_t) (sig + roundIncrement));
if (isTiny && sig && ! softfloat_isMaskedException(status, softfloat_flag_underflow)) {
softfloat_raiseFlags(status, softfloat_flag_underflow);
exp += 0x6000;
}
else {
sig = softfloat_shiftRightJam64(sig, 1 - exp);
sigExact = sig;
roundBits = sig & roundMask;
sigExact = sig;
sig += roundIncrement;
exp = ((sig & UINT64_C(0x8000000000000000)) != 0);
roundIncrement = roundMask + 1;
@ -86,25 +91,21 @@ extFloat80_t
roundMask |= roundIncrement;
}
sig &= ~roundMask;
if (isTiny) {
if (roundBits || (sig && ! softfloat_isMaskedException(status, softfloat_flag_underflow)))
softfloat_raiseFlags(status, softfloat_flag_underflow);
}
if (roundBits) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
if (sig > sigExact) softfloat_setRoundingUp(status);
if (isTiny)
softfloat_raiseFlags(status, softfloat_flag_underflow);
}
return packToExtF80(sign, exp, sig);
}
}
if ((0x7FFE < exp) || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))) {
goto overflow;
}
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (roundBits) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
}
sigExact = sig;
sig = (uint64_t) (sig + roundIncrement);
if (sig < roundIncrement) {
@ -117,7 +118,10 @@ extFloat80_t
roundMask |= roundIncrement;
}
sig &= ~roundMask;
if (roundBits) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
if (sig > sigExact) softfloat_setRoundingUp(status);
}
return packToExtF80(sign, exp, sig);
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
@ -134,16 +138,20 @@ extFloat80_t
/*----------------------------------------------------------------
*----------------------------------------------------------------*/
isTiny = (exp < 0) || ! doIncrement || (sig < UINT64_C(0xFFFFFFFFFFFFFFFF));
if (isTiny && sig && ! softfloat_isMaskedException(status, softfloat_flag_underflow)) {
softfloat_raiseFlags(status, softfloat_flag_underflow);
exp += 0x6000;
}
else {
sig64Extra = softfloat_shiftRightJam64Extra(sig, sigExtra, 1 - exp);
exp = 0;
sig = sig64Extra.v;
sigExtra = sig64Extra.extra;
if (isTiny) {
if (sigExtra || (sig && ! softfloat_isMaskedException(status, softfloat_flag_underflow)))
if (sigExtra) {
softfloat_raiseFlags(status, softfloat_flag_inexact);
if (isTiny)
softfloat_raiseFlags(status, softfloat_flag_underflow);
}
if (sigExtra)
softfloat_raiseFlags(status, softfloat_flag_inexact);
doIncrement = (UINT64_C(0x8000000000000000) <= sigExtra);
if (! roundNearEven && (roundingMode != softfloat_round_near_maxMag)) {
doIncrement =
@ -159,6 +167,7 @@ extFloat80_t
}
return packToExtF80(sign, exp, sig);
}
}
if ((0x7FFE < exp) || ((exp == 0x7FFE) && (sig == UINT64_C(0xFFFFFFFFFFFFFFFF)) && doIncrement)) {
/*----------------------------------------------------------------
*----------------------------------------------------------------*/
@ -206,18 +215,11 @@ extFloat80_t
extFloat80_t
softfloat_roundPackToExtF80(bool sign, int32_t exp, uint64_t sig, uint64_t sigExtra, uint8_t roundingPrecision, struct softfloat_status_t *status)
{
softfloat_status_t round_status = *status;
extFloat80_t result = SoftFloat_roundPackToExtF80(sign, exp, sig, sigExtra, roundingPrecision, status);
// bias unmasked underflow
if (status->softfloat_exceptionFlags & ~status->softfloat_exceptionMasks & softfloat_flag_underflow) {
softfloat_raiseFlags(&round_status, softfloat_flag_underflow);
result = SoftFloat_roundPackToExtF80(sign, exp + 0x6000, sig, sigExtra, roundingPrecision, &round_status);
*status = round_status;
}
// bias unmasked overflow
if (status->softfloat_exceptionFlags & ~status->softfloat_exceptionMasks & softfloat_flag_overflow) {
softfloat_status_t round_status = *status;
softfloat_raiseFlags(&round_status, softfloat_flag_overflow);
result = SoftFloat_roundPackToExtF80(sign, exp - 0x6000, sig, sigExtra, roundingPrecision, &round_status);
*status = round_status;