backport some softfloat changes to CVS

This commit is contained in:
Stanislav Shwartsman 2004-03-19 18:11:10 +00:00
parent b7b0b604ef
commit 78a2976b49
3 changed files with 7 additions and 201 deletions

View File

@ -1039,108 +1039,6 @@ float32 float32_div(float32 a, float32 b, float_status_t &status)
return roundAndPackFloat32(zSign, zExp, zSig, status);
}
/*----------------------------------------------------------------------------
| Returns the remainder of the single-precision floating-point value `a'
| with respect to the corresponding value `b'. The operation is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float32 float32_rem(float32 a, float32 b, float_status_t &status)
{
int aSign, bSign, zSign;
Bit16s aExp, bExp, expDiff;
Bit32u aSig, bSig;
Bit32u q;
Bit64u aSig64, bSig64, q64;
Bit32u alternateASig;
Bit32s sigMean;
aSig = extractFloat32Frac(a);
aExp = extractFloat32Exp(a);
aSign = extractFloat32Sign(a);
bSig = extractFloat32Frac(b);
bExp = extractFloat32Exp(b);
bSign = extractFloat32Sign(b);
if (aExp == 0xFF) {
if (aSig || ((bExp == 0xFF) && bSig)) {
return propagateFloat32NaN(a, b, status);
}
float_raise(status, float_flag_invalid);
return float32_default_nan;
}
if (bExp == 0xFF) {
if (bSig) return propagateFloat32NaN(a, b, status);
if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
return a;
}
if (bExp == 0) {
if (bSig == 0) {
float_raise(status, float_flag_invalid);
return float32_default_nan;
}
float_raise(status, float_flag_denormal);
normalizeFloat32Subnormal(bSig, &bExp, &bSig);
}
if (aExp == 0) {
if (aSig == 0) return packFloat32(aSign, 0, 0);
float_raise(status, float_flag_denormal);
normalizeFloat32Subnormal(aSig, &aExp, &aSig);
}
expDiff = aExp - bExp;
aSig |= 0x00800000;
bSig |= 0x00800000;
if (expDiff < 32) {
aSig <<= 8;
bSig <<= 8;
if (expDiff < 0) {
if (expDiff < -1) return a;
aSig >>= 1;
}
q = (bSig <= aSig);
if (q) aSig -= bSig;
if (0 < expDiff) {
q = (((Bit64u) aSig)<<32) / bSig;
q >>= 32 - expDiff;
bSig >>= 2;
aSig = ((aSig>>1)<<(expDiff - 1)) - bSig * q;
}
else {
aSig >>= 2;
bSig >>= 2;
}
}
else {
if (bSig <= aSig) aSig -= bSig;
aSig64 = ((Bit64u) aSig)<<40;
bSig64 = ((Bit64u) bSig)<<40;
expDiff -= 64;
while (0 < expDiff) {
q64 = estimateDiv128To64(aSig64, 0, bSig64);
q64 = (2 < q64) ? q64 - 2 : 0;
aSig64 = -((bSig * q64)<<38);
expDiff -= 62;
}
expDiff += 64;
q64 = estimateDiv128To64(aSig64, 0, bSig64);
q64 = (2 < q64) ? q64 - 2 : 0;
q = q64>>(64 - expDiff);
bSig <<= 6;
aSig = ((aSig64>>33)<<(expDiff - 1)) - bSig * q;
}
do {
alternateASig = aSig;
++q;
aSig -= bSig;
} while (0 <= (Bit32s) aSig);
sigMean = aSig + alternateASig;
if ((sigMean < 0) || ((sigMean == 0) && (q & 1))) {
aSig = alternateASig;
}
zSign = ((Bit32s) aSig < 0);
if (zSign) aSig = -aSig;
return normalizeRoundAndPackFloat32(aSign ^ zSign, bExp, aSig, status);
}
/*----------------------------------------------------------------------------
| Returns the square root of the single-precision floating-point value `a'.
| The operation is performed according to the IEC/IEEE Standard for Binary
@ -2051,93 +1949,6 @@ float64 float64_div(float64 a, float64 b, float_status_t &status)
return roundAndPackFloat64(zSign, zExp, zSig, status);
}
/*----------------------------------------------------------------------------
| Returns the remainder of the double-precision floating-point value `a'
| with respect to the corresponding value `b'. The operation is performed
| according to the IEC/IEEE Standard for Binary Floating-Point Arithmetic.
*----------------------------------------------------------------------------*/
float64 float64_rem(float64 a, float64 b, float_status_t &status)
{
int aSign, bSign, zSign;
Bit16s aExp, bExp, expDiff;
Bit64u aSig, bSig;
Bit64u q, alternateASig;
Bit64s sigMean;
aSig = extractFloat64Frac(a);
aExp = extractFloat64Exp(a);
aSign = extractFloat64Sign(a);
bSig = extractFloat64Frac(b);
bExp = extractFloat64Exp(b);
bSign = extractFloat64Sign(b);
if (aExp == 0x7FF) {
if (aSig || ((bExp == 0x7FF) && bSig)) {
return propagateFloat64NaN(a, b, status);
}
float_raise(status, float_flag_invalid);
return float64_default_nan;
}
if (bExp == 0x7FF) {
if (bSig) return propagateFloat64NaN(a, b, status);
if (aSig && (aExp == 0)) float_raise(status, float_flag_denormal);
return a;
}
if (bExp == 0) {
if (bSig == 0) {
float_raise(status, float_flag_invalid);
return float64_default_nan;
}
float_raise(status, float_flag_denormal);
normalizeFloat64Subnormal(bSig, &bExp, &bSig);
}
if (aExp == 0) {
if (aSig == 0) return packFloat64(aSign, 0, 0);
float_raise(status, float_flag_denormal);
normalizeFloat64Subnormal(aSig, &aExp, &aSig);
}
expDiff = aExp - bExp;
aSig = (aSig | BX_CONST64(0x0010000000000000))<<11;
bSig = (bSig | BX_CONST64(0x0010000000000000))<<11;
if (expDiff < 0) {
if (expDiff < -1) return a;
aSig >>= 1;
}
q = (bSig <= aSig);
if (q) aSig -= bSig;
expDiff -= 64;
while (0 < expDiff) {
q = estimateDiv128To64(aSig, 0, bSig);
q = (2 < q) ? q - 2 : 0;
aSig = -((bSig>>2) * q);
expDiff -= 62;
}
expDiff += 64;
if (0 < expDiff) {
q = estimateDiv128To64(aSig, 0, bSig);
q = (2 < q) ? q - 2 : 0;
q >>= 64 - expDiff;
bSig >>= 2;
aSig = ((aSig>>1)<<(expDiff - 1)) - bSig * q;
}
else {
aSig >>= 2;
bSig >>= 2;
}
do {
alternateASig = aSig;
++q;
aSig -= bSig;
} while (0 <= (Bit64s) aSig);
sigMean = aSig + alternateASig;
if ((sigMean < 0) || ((sigMean == 0) && (q & 1))) {
aSig = alternateASig;
}
zSign = ((Bit64s) aSig < 0);
if (zSign) aSig = -aSig;
return normalizeRoundAndPackFloat64(aSign ^ zSign, bExp, aSig, status);
}
/*----------------------------------------------------------------------------
| Returns the square root of the double-precision floating-point value `a'.
| The operation is performed according to the IEC/IEEE Standard for Binary
@ -2536,12 +2347,11 @@ float_class_t floatx80_class(floatx80 a)
static floatx80 roundAndPackFloatx80(int roundingPrecision,
int zSign, Bit32s zExp, Bit64u zSig0, Bit64u zSig1, float_status_t &status)
{
Bit8u roundingMode;
int roundNearestEven, increment, isTiny;
Bit64s roundIncrement, roundMask, roundBits;
Bit64u roundIncrement, roundMask, roundBits;
int increment;
roundingMode = get_float_rounding_mode(status);
roundNearestEven = (roundingMode == float_round_nearest_even);
Bit8u roundingMode = get_float_rounding_mode(status);
int roundNearestEven = (roundingMode == float_round_nearest_even);
if (roundingPrecision == 64) {
roundIncrement = BX_CONST64(0x0000000000000400);
roundMask = BX_CONST64(0x00000000000007FF);
@ -2575,7 +2385,7 @@ static floatx80 roundAndPackFloatx80(int roundingPrecision,
goto overflow;
}
if (zExp <= 0) {
isTiny =
int isTiny =
(status.float_detect_tininess == float_tininess_before_rounding)
|| (zExp < 0)
|| (zSig0 <= zSig0 + roundIncrement);
@ -2639,7 +2449,7 @@ static floatx80 roundAndPackFloatx80(int roundingPrecision,
return packFloatx80(zSign, 0x7FFF, BX_CONST64(0x8000000000000000));
}
if (zExp <= 0) {
isTiny =
int isTiny =
(status.float_detect_tininess == float_tininess_before_rounding)
|| (zExp < 0)
|| ! increment

View File

@ -158,7 +158,6 @@ float32 float32_add(float32, float32, float_status_t &status);
float32 float32_sub(float32, float32, float_status_t &status);
float32 float32_mul(float32, float32, float_status_t &status);
float32 float32_div(float32, float32, float_status_t &status);
float32 float32_rem(float32, float32, float_status_t &status);
float32 float32_sqrt(float32, float_status_t &status);
typedef int (*float32_compare_method)(float32, float32, float_status_t &status);
@ -192,7 +191,6 @@ float64 float64_add(float64, float64, float_status_t &status);
float64 float64_sub(float64, float64, float_status_t &status);
float64 float64_mul(float64, float64, float_status_t &status);
float64 float64_div(float64, float64, float_status_t &status);
float64 float64_rem(float64, float64, float_status_t &status);
float64 float64_sqrt(float64, float_status_t &status);
typedef int (*float64_compare_method)(float64, float64, float_status_t &status);
@ -214,7 +212,7 @@ int float64_is_signaling_nan(float64);
/*----------------------------------------------------------------------------
| Software IEC/IEEE floating-point types.
*----------------------------------------------------------------------------*/
#ifdef BIG_ENDIAN
#ifdef BX_BIG_ENDIAN
struct floatx80 { // do not allow 16-byte extension of the structure
Bit16u exp;
Bit64u fraction;
@ -261,7 +259,6 @@ 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);
floatx80 floatx80_div(floatx80, floatx80, float_status_t &status);
floatx80 floatx80_rem(floatx80, floatx80, float_status_t &status);
floatx80 floatx80_sqrt(floatx80, float_status_t &status);
int floatx80_eq(floatx80, floatx80, float_status_t &status);
int floatx80_le(floatx80, floatx80, float_status_t &status);

View File

@ -98,7 +98,6 @@ extern int isNaN(FPU_REG const *ptr) BX_CPP_AttrRegparmN(1);
extern void FPU_pop(void);
extern int FPU_empty_i(int stnr) BX_CPP_AttrRegparmN(1);
extern int FPU_stackoverflow(FPU_REG **st_new_ptr);
extern void FPU_sync_tags(void);
extern void FPU_copy_to_regi(FPU_REG const *r, u_char tag, int stnr) BX_CPP_AttrRegparmN(3);
extern void FPU_copy_to_reg1(FPU_REG const *r, u_char tag) BX_CPP_AttrRegparmN(2);
extern void FPU_copy_to_reg0(FPU_REG const *r, u_char tag) BX_CPP_AttrRegparmN(2);