diff --git a/bochs/cpu/fpu/f2xm1.cc b/bochs/cpu/fpu/f2xm1.cc index 3cfc3d2c6..00b1679e8 100644 --- a/bochs/cpu/fpu/f2xm1.cc +++ b/bochs/cpu/fpu/f2xm1.cc @@ -130,14 +130,14 @@ floatx80 f2xm1(floatx80 a, float_status_t &status) int aSign = extF80_sign(a); if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1)) + if (aSig << 1) return propagateFloatx80NaN(a, status); return (aSign) ? floatx80_negone : a; } - if (aExp == 0) { - if (aSig == 0) return a; + if (! aExp) { + if (! aSig) return a; softfloat_raiseFlags(&status, softfloat_flag_denormal | softfloat_flag_inexact); normalizeFloatx80Subnormal(aSig, &aExp, &aSig); diff --git a/bochs/cpu/fpu/fpatan.cc b/bochs/cpu/fpu/fpatan.cc index c7756f36e..aa5c5dd98 100644 --- a/bochs/cpu/fpu/fpatan.cc +++ b/bochs/cpu/fpu/fpatan.cc @@ -159,19 +159,17 @@ floatx80 fpatan(floatx80 a, floatx80 b, float_status_t &status) if (aSig<<1) return propagateFloatx80NaN(a, b, status); - if (aSign) { /* return 3PI/4 */ - return roundAndPackFloatx80(80, bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, status); - } - else { /* return PI/4 */ - return roundAndPackFloatx80(80, bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); - } + if (aSign) /* return 3PI/4 */ + return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80, &status); + else /* return PI/4 */ + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); } if (aSig && ! aExp) softfloat_raiseFlags(&status, softfloat_flag_denormal); /* return PI/2 */ - return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); } if (aExp == 0x7FFF) { @@ -183,11 +181,10 @@ floatx80 fpatan(floatx80 a, floatx80 b, float_status_t &status) return_PI_or_ZERO: - if (aSign) { /* return PI */ - return roundAndPackFloatx80(80, bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); - } else { /* return 0 */ - return packFloatx80(bSign, 0, 0); - } + if (aSign) /* return PI */ + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); + else /* return 0 */ + return packToExtF80(bSign, 0, 0); } if (! bExp) { @@ -202,7 +199,7 @@ return_PI_or_ZERO: if (! aExp) { if (! aSig) /* return PI/2 */ - return roundAndPackFloatx80(80, bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI2_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); softfloat_raiseFlags(&status, softfloat_flag_denormal); normalizeFloatx80Subnormal(aSig, &aExp, &aSig); @@ -213,9 +210,9 @@ return_PI_or_ZERO: /* |a| = |b| ==> return PI/4 */ if (aSig == bSig && aExp == bExp) { if (aSign) - return roundAndPackFloatx80(80, bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, status); + return softfloat_roundPackToExtF80(bSign, FLOATX80_3PI4_EXP, FLOAT_3PI4_HI, FLOAT_3PI4_LO, 80, &status); else - return roundAndPackFloatx80(80, bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, status); + return softfloat_roundPackToExtF80(bSign, FLOATX80_PI4_EXP, FLOAT_PI_HI, FLOAT_PI_LO, 80, &status); } /* ******************************** */ diff --git a/bochs/cpu/fpu/fprem.cc b/bochs/cpu/fpu/fprem.cc index 2f44d7bf1..7a0869b87 100644 --- a/bochs/cpu/fpu/fprem.cc +++ b/bochs/cpu/fpu/fprem.cc @@ -24,92 +24,101 @@ these four paragraphs for those parts of this code that are retained. * ==========================================================================*/ #include "softfloatx80.h" -#include "softfloat-round-pack.h" #define USE_estimateDiv128To64 -#include "softfloat-macros.h" #include "softfloat-helpers.h" +#include "../softfloat3e/include/specialize.h" // for softfloat_propagateNaNExtF80UI + /* executes single exponent reduction cycle */ static Bit64u remainder_kernel(Bit64u aSig0, Bit64u bSig, int expDiff, Bit64u *zSig0, Bit64u *zSig1) { - Bit64u term0, term1; + uint128 term, z; Bit64u aSig1 = 0; - shortShift128Left(aSig1, aSig0, expDiff, &aSig1, &aSig0); Bit64u q = estimateDiv128To64(aSig1, aSig0, bSig); - mul64To128(bSig, q, &term0, &term1); - sub128(aSig1, aSig0, term0, term1, zSig1, zSig0); - while ((Bit64s)(*zSig1) < 0) { + term = softfloat_mul64To128(bSig, q); + z = softfloat_sub128(aSig1, aSig0, term.v64, term.v0); + while ((int64_t) z.v64 < 0) { --q; - add128(*zSig1, *zSig0, 0, bSig, zSig1, zSig0); + z = softfloat_add128(z.v64, z.v0, 0, bSig); } + *zSig0 = z.v0; + *zSig1 = z.v64; return q; } -static int do_fprem(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, int rounding_mode, float_status_t &status) +static int do_fprem(extFloat80_t a, extFloat80_t b, extFloat80_t &r, Bit64u &q, int rounding_mode, struct softfloat_status_t *status) { Bit32s aExp, bExp, zExp, expDiff; - Bit64u aSig0, aSig1, bSig; + Bit64u aSig0, aSig1 = 0, bSig; int aSign; + struct exp32_sig64 normExpSig; + uint128 term; + q = 0; // handle unsupported extended double-precision floating encodings if (extF80_isUnsupported(a) || extF80_isUnsupported(b)) { - softfloat_raiseFlags(&status, softfloat_flag_invalid); + softfloat_raiseFlags(status, softfloat_flag_invalid); r = floatx80_default_nan; return -1; } - aSig0 = extractFloatx80Frac(a); - aExp = extractFloatx80Exp(a); - aSign = extractFloatx80Sign(a); - bSig = extractFloatx80Frac(b); - bExp = extractFloatx80Exp(b); + aSig0 = extF80_fraction(a); + aExp = extF80_exp(a); + aSign = extF80_sign(a); + bSig = extF80_fraction(b); + bExp = extF80_exp(b); if (aExp == 0x7FFF) { - if ((Bit64u) (aSig0<<1) || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) { - r = propagateFloatx80NaN(a, b, status); + if ((aSig0<<1) || ((bExp == 0x7FFF) && (bSig<<1))) { + r = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif, status); return -1; } - softfloat_raiseFlags(&status, softfloat_flag_invalid); + softfloat_raiseFlags(status, softfloat_flag_invalid); r = floatx80_default_nan; return -1; } if (bExp == 0x7FFF) { - if ((Bit64u) (bSig<<1)) { - r = propagateFloatx80NaN(a, b, status); + if (bSig << 1) { + r = softfloat_propagateNaNExtF80UI(a.signExp, a.signif, b.signExp, b.signif, status); return -1; } - if (aExp == 0 && aSig0) { - softfloat_raiseFlags(&status, softfloat_flag_denormal); - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); - r = (a.fraction & BX_CONST64(0x8000000000000000)) ? packFloatx80(aSign, aExp, aSig0) : a; + if (! aExp && aSig0) { + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(aSig0); + aExp = normExpSig.exp + 1; + aSig0 = normExpSig.sig; + r = (a.signif & BX_CONST64(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a; return 0; } r = a; return 0; } - if (bExp == 0) { - if (bSig == 0) { - softfloat_raiseFlags(&status, softfloat_flag_invalid); + if (! bExp) { + if (! bSig) { + softfloat_raiseFlags(status, softfloat_flag_invalid); r = floatx80_default_nan; return -1; } - softfloat_raiseFlags(&status, softfloat_flag_denormal); - normalizeFloatx80Subnormal(bSig, &bExp, &bSig); + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(bSig); + bExp = normExpSig.exp + 1; + bSig = normExpSig.sig; } - if (aExp == 0) { - if (aSig0 == 0) { + if (! aExp) { + if (! aSig0) { r = a; return 0; } - softfloat_raiseFlags(&status, softfloat_flag_denormal); - normalizeFloatx80Subnormal(aSig0, &aExp, &aSig0); + softfloat_raiseFlags(status, softfloat_flag_denormal); + normExpSig = softfloat_normSubnormalExtF80Sig(aSig0); + aExp = normExpSig.exp + 1; + aSig0 = normExpSig.sig; } - expDiff = aExp - bExp; - aSig1 = 0; + expDiff = aExp - bExp; int overflow = 0; if (expDiff >= 64) { @@ -123,8 +132,7 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, int rounding if (expDiff < 0) { if (expDiff < -1) { - r = (a.fraction & BX_CONST64(0x8000000000000000)) ? - packFloatx80(aSign, aExp, aSig0) : a; + r = (a.signif & BX_CONST64(0x8000000000000000)) ? packToExtF80(aSign, aExp, aSig0) : a; return 0; } shortShift128Right(aSig0, 0, 1, &aSig0, &aSig1); @@ -141,26 +149,28 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, int rounding } } - if (rounding_mode == softfloat_round_near_even) - { + if (rounding_mode == softfloat_round_near_even) { Bit64u term0, term1; shortShift128Right(bSig, 0, 1, &term0, &term1); - if (! lt128(aSig0, aSig1, term0, term1)) - { - int lt = lt128(term0, term1, aSig0, aSig1); - int eq = eq128(aSig0, aSig1, term0, term1); + if (! softfloat_lt128(aSig0, aSig1, term0, term1)) { + int lt = softfloat_lt128(term0, term1, aSig0, aSig1); + int eq = softfloat_eq128(aSig0, aSig1, term0, term1); - if ((eq && (q & 1)) || lt) { - aSign = !aSign; - ++q; - } - if (lt) sub128(bSig, 0, aSig0, aSig1, &aSig0, &aSig1); + if ((eq && (q & 1)) || lt) { + aSign = !aSign; + ++q; + } + if (lt) { + term = softfloat_sub128(bSig, 0, aSig0, aSig1); + aSig0 = term.v64; + aSig1 = term.v0; + } } } } - r = normalizeRoundAndPackFloatx80(80, aSign, zExp, aSig0, aSig1, status); + r = softfloat_normRoundPackToExtF80(aSign, zExp, aSig0, aSig1, 80, status); return overflow; } @@ -170,7 +180,7 @@ static int do_fprem(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, int rounding | according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic. *----------------------------------------------------------------------------*/ -int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, float_status_t &status) +int floatx80_ieee754_remainder(extFloat80_t a, extFloat80_t b, extFloat80_t &r, Bit64u &q, struct softfloat_status_t *status) { return do_fprem(a, b, r, q, softfloat_round_near_even, status); } @@ -184,7 +194,7 @@ int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, f | quotient of 'a' divided by 'b' to an integer. *----------------------------------------------------------------------------*/ -int floatx80_remainder(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, float_status_t &status) +int floatx80_remainder(extFloat80_t a, extFloat80_t b, extFloat80_t &r, Bit64u &q, struct softfloat_status_t *status) { return do_fprem(a, b, r, q, softfloat_round_to_zero, status); } diff --git a/bochs/cpu/fpu/fpu_trans.cc b/bochs/cpu/fpu/fpu_trans.cc index 91b7c3bbe..06361fdbb 100644 --- a/bochs/cpu/fpu/fpu_trans.cc +++ b/bochs/cpu/fpu/fpu_trans.cc @@ -233,11 +233,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FPREM1(bxInstruction_c *i) Bit64u quotient; - floatx80 a = BX_READ_FPU_REG(0); - floatx80 b = BX_READ_FPU_REG(1); - floatx80 result; + extFloat80_t a = BX_READ_FPU_REG(0); + extFloat80_t b = BX_READ_FPU_REG(1); + extFloat80_t result; - int flags = floatx80_ieee754_remainder(a, b, result, quotient, status); + int flags = floatx80_ieee754_remainder(a, b, result, quotient, &status); if (! FPU_exception(i, status.float_exception_flags)) { if (flags >= 0) { @@ -276,11 +276,11 @@ void BX_CPP_AttrRegparmN(1) BX_CPU_C::FPREM(bxInstruction_c *i) Bit64u quotient; - floatx80 a = BX_READ_FPU_REG(0); - floatx80 b = BX_READ_FPU_REG(1); - floatx80 result; + extFloat80_t a = BX_READ_FPU_REG(0); + extFloat80_t b = BX_READ_FPU_REG(1); + extFloat80_t result; - int flags = floatx80_remainder(a, b, result, quotient, status); + int flags = floatx80_remainder(a, b, result, quotient, &status); if (! FPU_exception(i, status.float_exception_flags)) { if (flags >= 0) { diff --git a/bochs/cpu/fpu/fyl2x.cc b/bochs/cpu/fpu/fyl2x.cc index 3724503b4..9114d4e65 100644 --- a/bochs/cpu/fpu/fyl2x.cc +++ b/bochs/cpu/fpu/fyl2x.cc @@ -154,9 +154,7 @@ invalid: int zSign = bSign ^ 1; if (aExp == 0x7FFF) { - if ((Bit64u) (aSig<<1) - || ((bExp == 0x7FFF) && (Bit64u) (bSig<<1))) - { + if ((aSig<<1) || ((bExp == 0x7FFF) && (bSig<<1))) { return propagateFloatx80NaN(a, b, status); } if (aSign) goto invalid; @@ -168,16 +166,15 @@ invalid: return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } } - if (bExp == 0x7FFF) - { - if (bSig<<1) return propagateFloatx80NaN(a, b, status); + if (bExp == 0x7FFF) { + if (bSig << 1) return propagateFloatx80NaN(a, b, status); if (aSign && (Bit64u)(aExp | aSig)) goto invalid; if (aSig && ! aExp) softfloat_raiseFlags(&status, softfloat_flag_denormal); if (aExp < 0x3FFF) { return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } - if (aExp == 0x3FFF && ((Bit64u) (aSig<<1) == 0)) goto invalid; + if (aExp == 0x3FFF && ! (aSig<<1)) goto invalid; return packFloatx80(bSign, 0x7FFF, BX_CONST64(0x8000000000000000)); } if (! aExp) { @@ -199,7 +196,7 @@ invalid: softfloat_raiseFlags(&status, softfloat_flag_denormal); normalizeFloatx80Subnormal(bSig, &bExp, &bSig); } - if (aExp == 0x3FFF && ((aSig<<1) == 0)) + if (aExp == 0x3FFF && ! (aSig<<1)) return packFloatx80(bSign, 0, 0); softfloat_raiseFlags(&status, softfloat_flag_inexact); @@ -339,8 +336,7 @@ invalid: --zExp; } - return - roundAndPackFloatx80(80, aSign ^ bSign, zExp, zSig0, zSig1, status); + return softfloat_roundPackToExtF80(aSign ^ bSign, zExp, zSig0, zSig1, 80, &status); } /* ******************************** */ diff --git a/bochs/cpu/fpu/softfloat-helpers.h b/bochs/cpu/fpu/softfloat-helpers.h index 5d948e9d6..6708eebed 100644 --- a/bochs/cpu/fpu/softfloat-helpers.h +++ b/bochs/cpu/fpu/softfloat-helpers.h @@ -81,4 +81,35 @@ BX_CPP_INLINE void shortShift128Right(Bit64u a0, Bit64u a1, int count, Bit64u *z *z0Ptr = z0; } +/*---------------------------------------------------------------------------- +| Returns an approximation to the 64-bit integer quotient obtained by dividing +| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The +| divisor `b' must be at least 2^63. If q is the exact quotient truncated +| toward zero, the approximation returned lies between q and q + 2 inclusive. +| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit +| unsigned integer is returned. +*----------------------------------------------------------------------------*/ + +#ifdef USE_estimateDiv128To64 +static Bit64u estimateDiv128To64(Bit64u a0, Bit64u a1, Bit64u b) +{ + uint128 term, rem; + Bit64u b0, b1; + Bit64u z; + if (b <= a0) return BX_CONST64(0xFFFFFFFFFFFFFFFF); + b0 = b>>32; + z = (b0<<32 <= a0) ? BX_CONST64(0xFFFFFFFF00000000) : (a0 / b0)<<32; + term = softfloat_mul64To128(b, z); + rem = softfloat_sub128(a0, a1, term.v64, term.v0); + while (((int64_t) rem.v64) < 0) { + z -= UINT64_C(0x100000000); + b1 = b<<32; + rem = softfloat_add128(rem.v64, rem.v0, b0, b1); + } + rem.v64 = (rem.v64<<32) | (rem.v0>>32); + z |= (b0<<32 <= rem.v64) ? 0xFFFFFFFF : rem.v64 / b0; + return z; +} +#endif + #endif diff --git a/bochs/cpu/fpu/softfloat-macros.h b/bochs/cpu/fpu/softfloat-macros.h index 953b16976..23573a77a 100644 --- a/bochs/cpu/fpu/softfloat-macros.h +++ b/bochs/cpu/fpu/softfloat-macros.h @@ -103,20 +103,6 @@ BX_CPP_INLINE void shift64ExtraRightJamming(Bit64u a0, Bit64u a1, int count, Bit *z0Ptr = z0; } -/*---------------------------------------------------------------------------- -| Adds the 128-bit value formed by concatenating `a0' and `a1' to the 128-bit -| value formed by concatenating `b0' and `b1'. Addition is modulo 2^128, so -| any carry out is lost. The result is broken into two 64-bit pieces which -| are stored at the locations pointed to by `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void add128(Bit64u a0, Bit64u a1, Bit64u b0, Bit64u b1, Bit64u *z0Ptr, Bit64u *z1Ptr) -{ - Bit64u z1 = a1 + b1; - *z1Ptr = z1; - *z0Ptr = a0 + b0 + (z1 < a1); -} - /*---------------------------------------------------------------------------- | Subtracts the 128-bit value formed by concatenating `b0' and `b1' from the | 128-bit value formed by concatenating `a0' and `a1'. Subtraction is modulo @@ -132,66 +118,6 @@ BX_CPP_INLINE void *z0Ptr = a0 - b0 - (a1 < b1); } -/*---------------------------------------------------------------------------- -| Multiplies `a' by `b' to obtain a 128-bit product. The product is broken -| into two 64-bit pieces which are stored at the locations pointed to by -| `z0Ptr' and `z1Ptr'. -*----------------------------------------------------------------------------*/ - -BX_CPP_INLINE void mul64To128(Bit64u a, Bit64u b, Bit64u *z0Ptr, Bit64u *z1Ptr) -{ - Bit32u aHigh, aLow, bHigh, bLow; - Bit64u z0, zMiddleA, zMiddleB, z1; - - aLow = (Bit32u) a; - aHigh = (Bit32u)(a>>32); - bLow = (Bit32u) b; - bHigh = (Bit32u)(b>>32); - z1 = ((Bit64u) aLow) * bLow; - zMiddleA = ((Bit64u) aLow) * bHigh; - zMiddleB = ((Bit64u) aHigh) * bLow; - z0 = ((Bit64u) aHigh) * bHigh; - zMiddleA += zMiddleB; - z0 += (((Bit64u) (zMiddleA < zMiddleB))<<32) + (zMiddleA>>32); - zMiddleA <<= 32; - z1 += zMiddleA; - z0 += (z1 < zMiddleA); - *z1Ptr = z1; - *z0Ptr = z0; -} - -/*---------------------------------------------------------------------------- -| Returns an approximation to the 64-bit integer quotient obtained by dividing -| `b' into the 128-bit value formed by concatenating `a0' and `a1'. The -| divisor `b' must be at least 2^63. If q is the exact quotient truncated -| toward zero, the approximation returned lies between q and q + 2 inclusive. -| If the exact quotient q is larger than 64 bits, the maximum positive 64-bit -| unsigned integer is returned. -*----------------------------------------------------------------------------*/ - -#ifdef USE_estimateDiv128To64 -static Bit64u estimateDiv128To64(Bit64u a0, Bit64u a1, Bit64u b) -{ - Bit64u b0, b1; - Bit64u rem0, rem1, term0, term1; - Bit64u z; - - if (b <= a0) return BX_CONST64(0xFFFFFFFFFFFFFFFF); - b0 = b>>32; - z = (b0<<32 <= a0) ? BX_CONST64(0xFFFFFFFF00000000) : (a0 / b0)<<32; - mul64To128(b, z, &term0, &term1); - sub128(a0, a1, term0, term1, &rem0, &rem1); - while (((Bit64s) rem0) < 0) { - z -= BX_CONST64(0x100000000); - b1 = b<<32; - add128(rem0, rem1, b0, b1, &rem0, &rem1); - } - rem0 = (rem0<<32) | (rem1>>32); - z |= (b0<<32 <= rem0) ? 0xFFFFFFFF : rem0 / b0; - return z; -} -#endif - static const int countLeadingZeros8[] = { 8, 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, diff --git a/bochs/cpu/fpu/softfloat-round-pack.cc b/bochs/cpu/fpu/softfloat-round-pack.cc index 121105357..8cb2d2288 100644 --- a/bochs/cpu/fpu/softfloat-round-pack.cc +++ b/bochs/cpu/fpu/softfloat-round-pack.cc @@ -270,30 +270,6 @@ floatx80 roundAndPackFloatx80(int roundingPrecision, return result; } -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent -| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1', -| and returns the proper extended double-precision floating-point value -| corresponding to the abstract input. This routine is just like -| `roundAndPackFloatx80' except that the input significand does not have to be -| normalized. -*----------------------------------------------------------------------------*/ - -floatx80 normalizeRoundAndPackFloatx80(int roundingPrecision, - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, float_status_t &status) -{ - if (zSig0 == 0) { - zSig0 = zSig1; - zSig1 = 0; - zExp -= 64; - } - int shiftCount = countLeadingZeros64(zSig0); - shortShift128Left(zSig0, zSig1, shiftCount, &zSig0, &zSig1); - zExp -= shiftCount; - return - roundAndPackFloatx80(roundingPrecision, zSign, zExp, zSig0, zSig1, status); -} - #endif #ifdef FLOAT128 diff --git a/bochs/cpu/fpu/softfloat-round-pack.h b/bochs/cpu/fpu/softfloat-round-pack.h index 80087d1ca..e1017e7ad 100644 --- a/bochs/cpu/fpu/softfloat-round-pack.h +++ b/bochs/cpu/fpu/softfloat-round-pack.h @@ -75,18 +75,6 @@ void normalizeFloatx80Subnormal(Bit64u aSig, Bit32s *zExpPtr, Bit64u *zSigPtr); floatx80 roundAndPackFloatx80(int roundingPrecision, int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, float_status_t &status); -/*---------------------------------------------------------------------------- -| Takes an abstract floating-point value having sign `zSign', exponent -| `zExp', and significand formed by the concatenation of `zSig0' and `zSig1', -| and returns the proper extended double-precision floating-point value -| corresponding to the abstract input. This routine is just like -| `roundAndPackFloatx80' except that the input significand does not have to be -| normalized. -*----------------------------------------------------------------------------*/ - -floatx80 normalizeRoundAndPackFloatx80(int roundingPrecision, - int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, float_status_t &status); - #endif // FLOATX80 #ifdef FLOAT128 diff --git a/bochs/cpu/fpu/softfloatx80.h b/bochs/cpu/fpu/softfloatx80.h index 89d8108ac..c41b0b86a 100644 --- a/bochs/cpu/fpu/softfloatx80.h +++ b/bochs/cpu/fpu/softfloatx80.h @@ -33,8 +33,9 @@ these four paragraphs for those parts of this code that are retained. | Software IEC/IEEE extended double-precision operations. *----------------------------------------------------------------------------*/ -int floatx80_remainder(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, float_status_t &status); -int floatx80_ieee754_remainder(floatx80 a, floatx80 b, floatx80 &r, Bit64u &q, float_status_t &status); +int floatx80_remainder(extFloat80_t a, extFloat80_t b, extFloat80_t &r, Bit64u &q, struct softfloat_status_t *status); +int floatx80_ieee754_remainder(extFloat80_t a, extFloat80_t b, extFloat80_t &r, Bit64u &q, struct softfloat_status_t *status); + floatx80 f2xm1(floatx80 a, float_status_t &status); floatx80 fyl2x(floatx80 a, floatx80 b, float_status_t &status); floatx80 fyl2xp1(floatx80 a, floatx80 b, float_status_t &status); diff --git a/bochs/cpu/softfloat3e/s_roundPackToExtF80.c b/bochs/cpu/softfloat3e/s_roundPackToExtF80.c index 596ba9495..daceeee17 100644 --- a/bochs/cpu/softfloat3e/s_roundPackToExtF80.c +++ b/bochs/cpu/softfloat3e/s_roundPackToExtF80.c @@ -197,6 +197,9 @@ extFloat80_t if (sig > sigExact) softfloat_setRoundingUp(status); } + else { + if (! sig) exp = 0; + } return packToExtF80(sign, exp, sig); }