summaryrefslogtreecommitdiff
path: root/gcc/config/fp-bit.c
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-11 11:13:45 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2002-03-11 11:13:45 +0000
commit68d65858f49d338f6985a33ca1ae23d01c7797b3 (patch)
treeb35783a3200c2c8aa44adc916c24401dfe49041e /gcc/config/fp-bit.c
parent7d3bbd11b28cbc892023fcf10699b9551a503136 (diff)
downloadgcc-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.c69
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))
{