rewrite floatx80 bias unmasked overflow handling

This commit is contained in:
Stanislav Shwartsman 2024-04-28 10:16:31 +03:00
parent 89bfe81834
commit 2059854e04

View File

@ -40,7 +40,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "softfloat.h" #include "softfloat.h"
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_roundPackToExtF80(bool sign, int32_t exp, uint64_t sig, uint64_t sigExtra, uint8_t roundingPrecision, struct softfloat_status_t *status)
{ {
uint8_t roundingMode; uint8_t roundingMode;
bool roundNearEven; bool roundNearEven;
@ -101,7 +101,13 @@ extFloat80_t
} }
} }
if ((0x7FFE < exp) || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))) { if ((0x7FFE < exp) || ((exp == 0x7FFE) && ((uint64_t) (sig + roundIncrement) < sig))) {
goto overflow; if (! softfloat_isMaskedException(status, softfloat_flag_overflow)) {
softfloat_raiseFlags(status, softfloat_flag_overflow);
exp -= 0x6000;
}
else {
goto overflow;
}
} }
} }
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
@ -169,23 +175,29 @@ extFloat80_t
} }
} }
if ((0x7FFE < exp) || ((exp == 0x7FFE) && (sig == UINT64_C(0xFFFFFFFFFFFFFFFF)) && doIncrement)) { if ((0x7FFE < exp) || ((exp == 0x7FFE) && (sig == UINT64_C(0xFFFFFFFFFFFFFFFF)) && doIncrement)) {
/*---------------------------------------------------------------- if (! softfloat_isMaskedException(status, softfloat_flag_overflow)) {
*----------------------------------------------------------------*/ softfloat_raiseFlags(status, softfloat_flag_overflow);
roundMask = 0; exp -= 0x6000;
overflow: }
softfloat_raiseFlags(status, softfloat_flag_overflow | softfloat_flag_inexact); else {
if (roundNearEven /*----------------------------------------------------------------
|| (roundingMode == softfloat_round_near_maxMag) *----------------------------------------------------------------*/
|| (roundingMode == (sign ? softfloat_round_min : softfloat_round_max)) roundMask = 0;
) { overflow:
exp = 0x7FFF; softfloat_raiseFlags(status, softfloat_flag_overflow | softfloat_flag_inexact);
sig = UINT64_C(0x8000000000000000); if (roundNearEven
softfloat_setRoundingUp(status); || (roundingMode == softfloat_round_near_maxMag)
} else { || (roundingMode == (sign ? softfloat_round_min : softfloat_round_max))
exp = 0x7FFE; ) {
sig = ~roundMask; exp = 0x7FFF;
sig = UINT64_C(0x8000000000000000);
softfloat_setRoundingUp(status);
} else {
exp = 0x7FFE;
sig = ~roundMask;
}
return packToExtF80(sign, exp, sig);
} }
return packToExtF80(sign, exp, sig);
} }
} }
/*------------------------------------------------------------------------ /*------------------------------------------------------------------------
@ -211,19 +223,3 @@ extFloat80_t
} }
return packToExtF80(sign, exp, sig); return packToExtF80(sign, exp, sig);
} }
extFloat80_t
softfloat_roundPackToExtF80(bool sign, int32_t exp, uint64_t sig, uint64_t sigExtra, uint8_t roundingPrecision, struct softfloat_status_t *status)
{
extFloat80_t result = SoftFloat_roundPackToExtF80(sign, exp, sig, sigExtra, roundingPrecision, 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;
}
return result;
}