rewrite code for biasing unmasked underflow for floatx80 in softfloat3e (from hack to clean code)
This commit is contained in:
parent
805bb6b985
commit
632d8780de
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user