convert floatx80_round_to_int to softfloat3e (#287)

Co-authored-by: Stanislav Shwartsman <sshwarts@users.sourceforge.net>
This commit is contained in:
Stanislav Shwartsman 2024-03-16 19:08:44 +02:00 committed by GitHub
parent 9fa35f4596
commit 8f7df199b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 11 additions and 119 deletions

View File

@ -1262,8 +1262,7 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FRNDINT(bxInstruction_c *i)
float_status_t status =
i387cw_to_softfloat_status_word(BX_CPU_THIS_PTR the_i387.get_control_word());
floatx80 result = floatx80_round_to_int(BX_READ_FPU_REG(0), status);
//floatx80 result = extF80_roundToInt(BX_READ_FPU_REG(0), &status);
floatx80 result = extF80_roundToInt(BX_READ_FPU_REG(0), &status);
if (! FPU_exception(i, status.float_exception_flags))
BX_WRITE_FPU_REG(result, 0);

View File

@ -75,93 +75,6 @@ floatx80 int32_to_floatx80(Bit32s a)
return packFloatx80(zSign, 0x403E - shiftCount, zSig<<shiftCount);
}
/*----------------------------------------------------------------------------
| Rounds the extended double-precision floating-point value `a' to an integer,
| and returns the result as an extended double-precision floating-point
| value. The operation is performed according to the IEC/IEEE Standard for
| Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
floatx80 floatx80_round_to_int(floatx80 a, float_status_t &status)
{
int aSign;
Bit64u lastBitMask, roundBitsMask;
int roundingMode = get_float_rounding_mode(status);
floatx80 z;
// handle unsupported extended double-precision floating encodings
if (floatx80_is_unsupported(a))
{
float_raise(status, float_flag_invalid);
return floatx80_default_nan;
}
Bit32s aExp = extractFloatx80Exp(a);
Bit64u aSig = extractFloatx80Frac(a);
if (0x403E <= aExp) {
if ((aExp == 0x7FFF) && (Bit64u) (aSig<<1)) {
return propagateFloatx80NaN(a, status);
}
return a;
}
if (aExp < 0x3FFF) {
if (aExp == 0) {
if ((aSig<<1) == 0) return a;
float_raise(status, float_flag_denormal);
}
float_raise(status, float_flag_inexact);
aSign = extractFloatx80Sign(a);
switch (roundingMode) {
case float_round_nearest_even:
if ((aExp == 0x3FFE) && (Bit64u) (aSig<<1)) {
set_float_rounding_up(status);
return packFloatx80(aSign, 0x3FFF, BX_CONST64(0x8000000000000000));
}
break;
case float_round_down:
if (aSign) {
set_float_rounding_up(status);
return packFloatx80(1, 0x3FFF, BX_CONST64(0x8000000000000000));
}
else {
return packFloatx80(0, 0, 0);
}
case float_round_up:
if (aSign) {
return packFloatx80(1, 0, 0);
}
else {
set_float_rounding_up(status);
return packFloatx80(0, 0x3FFF, BX_CONST64(0x8000000000000000));
}
}
return packFloatx80(aSign, 0, 0);
}
lastBitMask = 1;
lastBitMask <<= 0x403E - aExp;
roundBitsMask = lastBitMask - 1;
z = a;
if (roundingMode == float_round_nearest_even) {
z.fraction += lastBitMask>>1;
if ((z.fraction & roundBitsMask) == 0) z.fraction &= ~lastBitMask;
}
else if (roundingMode != float_round_to_zero) {
if (extractFloatx80Sign(z) ^ (roundingMode == float_round_up))
z.fraction += roundBitsMask;
}
z.fraction &= ~roundBitsMask;
if (z.fraction == 0) {
z.exp++;
z.fraction = BX_CONST64(0x8000000000000000);
}
if (z.fraction != a.fraction) {
float_raise(status, float_flag_inexact);
if (z.fraction > a.fraction || z.exp > a.exp)
set_float_rounding_up(status);
}
return z;
}
/*----------------------------------------------------------------------------
| Returns the result of adding the absolute values of the extended double-
| precision floating-point values `a' and `b'. If `zSign' is 1, the sum is

View File

@ -223,7 +223,6 @@ floatx80 int32_to_floatx80(Bit32s);
/*----------------------------------------------------------------------------
| Software IEC/IEEE extended double-precision operations.
*----------------------------------------------------------------------------*/
floatx80 floatx80_round_to_int(floatx80, float_status_t &status);
floatx80 floatx80_add(floatx80, floatx80, float_status_t &status);
floatx80 floatx80_sub(floatx80, floatx80, float_status_t &status);
floatx80 floatx80_mul(floatx80, floatx80, float_status_t &status);

View File

@ -47,7 +47,6 @@ extFloat80_t
uint64_t sigA;
uint16_t uiZ64;
uint64_t sigZ;
struct exp32_sig64 normExpSig;
struct uint128 uiZ;
uint64_t lastBitMask, roundBitsMask;
@ -65,30 +64,20 @@ extFloat80_t
sigA = a.signif;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (!(sigA & UINT64_C(0x8000000000000000)) && (exp != 0x7FFF)) {
if (!sigA) {
return packToExtF80(signUI64, 0, 0);
if (0x403E <= exp) {
if ((exp == 0x7FFF) && (uint64_t) (sigA<<1)) {
uiZ = softfloat_propagateNaNExtF80UI(uiA64, sigA, 0, 0, status);
return packToExtF80(uiZ.v64, uiZ.v0);
}
softfloat_raiseFlags(status, softfloat_flag_denormal);
normExpSig = softfloat_normSubnormalExtF80Sig(sigA);
exp += normExpSig.exp;
sigA = normExpSig.sig;
return a;
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
if (0x403E <= exp) {
if (exp == 0x7FFF) {
if (sigA & UINT64_C(0x7FFFFFFFFFFFFFFF)) {
uiZ = softfloat_propagateNaNExtF80UI(uiA64, sigA, 0, 0, status);
return packToExtF80(uiZ.v64, uiZ.v0);
}
sigZ = UINT64_C(0x8000000000000000);
} else {
sigZ = sigA;
}
return packToExtF80(signUI64, exp, sigZ);
}
if (exp <= 0x3FFE) {
if (! exp) {
if ((sigA<<1) == 0) return a;
softfloat_raiseFlags(status, softfloat_flag_denormal);
}
if (exact) softfloat_raiseFlags(status, softfloat_flag_inexact);
switch (roundingMode) {
case softfloat_round_near_even:

View File

@ -41,7 +41,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
uint32_t f32_to_ui32(float32_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint32_t uiA;
bool sign;
int16_t exp;
uint32_t sig;

View File

@ -42,7 +42,6 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
uint64_t f32_to_ui64(float32_t a, uint8_t roundingMode, bool exact, struct softfloat_status_t *status)
{
uint32_t uiA;
bool sign;
int16_t exp;
uint32_t sig;

View File

@ -46,7 +46,7 @@ int64_t f64_to_i64_r_minMag(float64_t a, bool exact, struct softfloat_status_t *
int16_t exp;
uint64_t sig;
int16_t shiftDist;
int64_t absZ;
uint64_t absZ;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/

View File

@ -51,7 +51,6 @@ extFloat80_t softfloat_addMagsExtF80(uint16_t uiA64, uint64_t uiA0, uint16_t uiB
int32_t expZ;
struct uint64_extra sig64Extra;
struct uint128 uiZ;
bool overflow;
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/

View File

@ -101,6 +101,5 @@ float16_t
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
packReturn:
return packToF16UI(sign, exp, sig);
}

View File

@ -105,6 +105,5 @@ float32_t
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
packReturn:
return packToF32UI(sign, exp, sig);
}

View File

@ -105,6 +105,5 @@ float64_t
}
/*------------------------------------------------------------------------
*------------------------------------------------------------------------*/
packReturn:
return packToF64UI(sign, exp, sig);
}

View File

@ -46,7 +46,6 @@ float32_t softfloat_subMagsF32(uint32_t uiA, uint32_t uiB, struct softfloat_stat
int16_t expB;
uint32_t sigB;
int16_t expDiff;
uint32_t uiZ;
int32_t sigDiff;
bool signZ;
int8_t shiftDist;

View File

@ -46,7 +46,6 @@ float64_t softfloat_subMagsF64(uint64_t uiA, uint64_t uiB, bool signZ, struct so
int16_t expB;
uint64_t sigB;
int16_t expDiff;
uint64_t uiZ;
int64_t sigDiff;
int8_t shiftDist;
int16_t expZ;