convert floatx80_round_to_int to softfloat3e (#287)
Co-authored-by: Stanislav Shwartsman <sshwarts@users.sourceforge.net>
This commit is contained in:
parent
9fa35f4596
commit
8f7df199b9
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
|
@ -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;
|
||||
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
|
@ -101,6 +101,5 @@ float16_t
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
packReturn:
|
||||
return packToF16UI(sign, exp, sig);
|
||||
}
|
||||
|
@ -105,6 +105,5 @@ float32_t
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
packReturn:
|
||||
return packToF32UI(sign, exp, sig);
|
||||
}
|
||||
|
@ -105,6 +105,5 @@ float64_t
|
||||
}
|
||||
/*------------------------------------------------------------------------
|
||||
*------------------------------------------------------------------------*/
|
||||
packReturn:
|
||||
return packToF64UI(sign, exp, sig);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user