diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-11 11:13:45 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2002-03-11 11:13:45 +0000 |
commit | 68d65858f49d338f6985a33ca1ae23d01c7797b3 (patch) | |
tree | b35783a3200c2c8aa44adc916c24401dfe49041e /gcc/config/fp-bit.c | |
parent | 7d3bbd11b28cbc892023fcf10699b9551a503136 (diff) | |
download | gcc-68d65858f49d338f6985a33ca1ae23d01c7797b3.tar.gz |
* defaults.h (LARGEST_EXPONENT_IS_NORMAL, ROUND_TOWARDS_ZERO): New.
(MODE_HAS_NANS, MODE_HAS_INFINITIES): Evaluate to false if
LARGEST_EXPONENT_IS_NORMAL for the given mode.
(MODE_HAS_SIGN_DEPENDENT_ROUNDING): False when ROUND_TOWARDS_ZERO.
* real.c (eadd1): Make rounding dependent on !ROUND_TOWARDS_ZERO.
(ediv, emul, eldexp, esqrt): Likewise.
(etoe113, etoe64, etoe53, etoe24, etodec, etoibm, etoc4x): Likewise.
(e24toe): Only check NaNs & infinities if !LARGEST_EXPONENT_IS_NORMAL.
(saturate): New function.
(toe53, toe24): Saturate on overflow if LARGEST_EXPONENT_IS_NORMAL.
(make_nan): Use a saturation value instead of a NaN if
LARGEST_EXPONENT_IS_NORMAL. Warn when this happens.
* fp-bit.c (pack_d): Saturate on NaN, infinite or overflowing
inputs if LARGEST_EXPONENT_IS_NORMAL. Represent subnormals as
zero if NO_DENORMALS. Only round to nearest if !ROUND_TOWARDS_ZERO.
(unpack_d): No NaNs or infinities if LARGEST_EXPONENT_IS_NORMAL.
(_fpmul_parts, _fpdiv_parts): Only round to nearest if
!ROUND_TOWARDS_ZERO.
* doc/tm.texi (LARGEST_EXPONENT_IS_NORMAL): Document.
(ROUND_TOWARDS_ZERO): Document.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@50569 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/fp-bit.c')
-rw-r--r-- | gcc/config/fp-bit.c | 69 |
1 files changed, 48 insertions, 21 deletions
diff --git a/gcc/config/fp-bit.c b/gcc/config/fp-bit.c index 4d39d912876..5da7a8efe13 100644 --- a/gcc/config/fp-bit.c +++ b/gcc/config/fp-bit.c @@ -1,6 +1,6 @@ /* This is a software floating point library which can be used for targets without hardware floating point. - Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001 + Copyright (C) 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002 Free Software Foundation, Inc. This file is free software; you can redistribute it and/or modify it @@ -181,7 +181,15 @@ pack_d ( fp_number_type * src) int sign = src->sign; int exp = 0; - if (isnan (src)) + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && (isnan (src) || isinf (src))) + { + /* We can't represent these values accurately. By using the + largest possible magnitude, we guarantee that the conversion + of infinity is at least as big as any finite number. */ + exp = EXPMAX; + fraction = ((fractype) 1 << FRACBITS) - 1; + } + else if (isnan (src)) { exp = EXPMAX; if (src->class == CLASS_QNAN || 1) @@ -207,6 +215,13 @@ pack_d ( fp_number_type * src) { if (src->normal_exp < NORMAL_EXPMIN) { +#ifdef NO_DENORMALS + /* Go straight to a zero representation if denormals are not + supported. The denormal handling would be harmless but + isn't unnecessary. */ + exp = 0; + fraction = 0; +#else /* NO_DENORMALS */ /* This number's exponent is too low to fit into the bits available in the number, so we'll store 0 in the exponent and shift the fraction to the right to make up for it. */ @@ -242,8 +257,10 @@ pack_d ( fp_number_type * src) exp += 1; } fraction >>= NGARDS; +#endif /* NO_DENORMALS */ } - else if (src->normal_exp > EXPBIAS) + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) + && src->normal_exp > EXPBIAS) { exp = EXPMAX; fraction = 0; @@ -251,25 +268,35 @@ pack_d ( fp_number_type * src) else { exp = src->normal_exp + EXPBIAS; - /* IF the gard bits are the all zero, but the first, then we're - half way between two numbers, choose the one which makes the - lsb of the answer 0. */ - if ((fraction & GARDMASK) == GARDMSB) - { - if (fraction & (1 << NGARDS)) - fraction += GARDROUND + 1; - } - else + if (!ROUND_TOWARDS_ZERO) { - /* Add a one to the guards to round up */ - fraction += GARDROUND; + /* IF the gard bits are the all zero, but the first, then we're + half way between two numbers, choose the one which makes the + lsb of the answer 0. */ + if ((fraction & GARDMASK) == GARDMSB) + { + if (fraction & (1 << NGARDS)) + fraction += GARDROUND + 1; + } + else + { + /* Add a one to the guards to round up */ + fraction += GARDROUND; + } + if (fraction >= IMPLICIT_2) + { + fraction >>= 1; + exp += 1; + } } - if (fraction >= IMPLICIT_2) + fraction >>= NGARDS; + + if (LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp > EXPMAX) { - fraction >>= 1; - exp += 1; + /* Saturate on overflow. */ + exp = EXPMAX; + fraction = ((fractype) 1 << FRACBITS) - 1; } - fraction >>= NGARDS; } } @@ -359,7 +386,7 @@ unpack_d (FLO_union_type * src, fp_number_type * dst) dst->fraction.ll = fraction; } } - else if (exp == EXPMAX) + else if (!LARGEST_EXPONENT_IS_NORMAL (FRAC_NBITS) && exp == EXPMAX) { /* Huge exponent*/ if (fraction == 0) @@ -729,7 +756,7 @@ _fpmul_parts ( fp_number_type * a, } } #endif - if ((high & GARDMASK) == GARDMSB) + if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB) { if (high & (1 << NGARDS)) { @@ -839,7 +866,7 @@ _fpdiv_parts (fp_number_type * a, numerator *= 2; } - if ((quotient & GARDMASK) == GARDMSB) + if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB) { if (quotient & (1 << NGARDS)) { |