aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans-Peter Nilsson <hp@axis.com>2004-03-05 00:27:56 +0000
committerHans-Peter Nilsson <hp@gcc.gnu.org>2004-03-05 00:27:56 +0000
commitfc7b80e449142f24b52c3c0bc07ef6f9cc9fd885 (patch)
treeab74d69e13d3cadd84e08112a07e4556de4d9a09
parent5fd200f17fa09d56e1972a1d8dbfb913df4f601c (diff)
downloadgcc-fc7b80e449142f24b52c3c0bc07ef6f9cc9fd885.zip
gcc-fc7b80e449142f24b52c3c0bc07ef6f9cc9fd885.tar.gz
gcc-fc7b80e449142f24b52c3c0bc07ef6f9cc9fd885.tar.bz2
fp-bit.c (_fpdiv_parts): Do not round when pack_d would round the same.
* config/fp-bit.c (_fpdiv_parts): Do not round when pack_d would round the same. When rounding, clear bits that would cause a second rounding in pack_d. (_fpmul_parts): Ditto. Remove #if 0:d code. From-SVN: r78951
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/fp-bit.c46
2 files changed, 32 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2495b33..73f0f1f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2004-03-05 Hans-Peter Nilsson <hp@axis.com>
+
+ * config/fp-bit.c (_fpdiv_parts): Do not round when pack_d would
+ round the same. When rounding, clear bits that would cause a
+ second rounding in pack_d.
+ (_fpmul_parts): Ditto. Remove #if 0:d code.
+
2004-03-04 Ziemowit Laski <zlaski@apple.com>
PR c++/14425, c++/14426
diff --git a/gcc/config/fp-bit.c b/gcc/config/fp-bit.c
index e7556c4..0de191d 100644
--- a/gcc/config/fp-bit.c
+++ b/gcc/config/fp-bit.c
@@ -899,32 +899,28 @@ _fpmul_parts ( fp_number_type * a,
high |= 1;
low <<= 1;
}
- /* rounding is tricky. if we only round if it won't make us round later. */
-#if 0
- if (low & FRACHIGH2)
- {
- if (((high & GARDMASK) != GARDMSB)
- && (((high + 1) & GARDMASK) == GARDMSB))
- {
- /* don't round, it gets done again later. */
- }
- else
- {
- high++;
- }
- }
-#endif
+
if (!ROUND_TOWARDS_ZERO && (high & GARDMASK) == GARDMSB)
{
if (high & (1 << NGARDS))
{
- /* half way, so round to even */
- high += GARDROUND + 1;
+ /* Because we're half way, we would round to even by adding
+ GARDROUND + 1, except that's also done in the packing
+ function, and rounding twice will lose precision and cause
+ the result to be too far off. Example: 32-bit floats with
+ bit patterns 0xfff * 0x3f800400 ~= 0xfff (less than 0.5ulp
+ off), not 0x1000 (more than 0.5ulp off). */
}
else if (low)
{
- /* but we really weren't half way */
+ /* We're a further than half way by a small amount corresponding
+ to the bits set in "low". Knowing that, we round here and
+ not in pack_d, because there we don't have "low" avaliable
+ anymore. */
high += GARDROUND + 1;
+
+ /* Avoid further rounding in pack_d. */
+ high &= ~(fractype) GARDMASK;
}
}
tmp->fraction.ll = high;
@@ -1028,13 +1024,21 @@ _fpdiv_parts (fp_number_type * a,
{
if (quotient & (1 << NGARDS))
{
- /* half way, so round to even */
- quotient += GARDROUND + 1;
+ /* Because we're half way, we would round to even by adding
+ GARDROUND + 1, except that's also done in the packing
+ function, and rounding twice will lose precision and cause
+ the result to be too far off. */
}
else if (numerator)
{
- /* but we really weren't half way, more bits exist */
+ /* We're a further than half way by the small amount
+ corresponding to the bits set in "numerator". Knowing
+ that, we round here and not in pack_d, because there we
+ don't have "numerator" avaliable anymore. */
quotient += GARDROUND + 1;
+
+ /* Avoid further rounding in pack_d. */
+ quotient &= ~(fractype) GARDMASK;
}
}