This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
rounding of soft-fp mul, div
- From: gkeating at apple dot com (Geoffrey Keating)
- To: gcc-patches at gcc dot gnu dot org, Michael Eager <eager at mvista dot com>
- Date: Mon, 10 Nov 2003 14:49:45 -0800 (PST)
- Subject: rounding of soft-fp mul, div
Hi Michael,
This should be exactly equivalent to your patch, but with a testcase
and with the formatting errors corrected.
Now, I'd appreciate it if you could check that this really works, with
a bootstrap & dejagnu testrun on some platform that showed the problem
before. Also, check that if you *don't* apply the change to fp-bit.c,
the testcase fails in dejagnu. (I have checked that the testcase
passes if you use hardware floating-point on powerpc.)
If all that works, then let me know and I'll check the patch and
testcase in.
--
- Geoffrey Keating <geoffk@apple.com>
===File ~/patches/meager-mulround.patch=====================
Index: ChangeLog
2003-11-10 Michael Eager <eager@mvista.com>
Geoffrey Keating <geoffk@apple.com>
* config/fp-bit.c (_fpdiv_parts, _fpmul_parts): Correct errors
in rounding logic.
Index: testsuite/ChangeLog
2003-11-10 Michael Eager <eager@mvista.com>
Geoffrey Keating <geoffk@apple.com>
* gcc.c-torture/execute/ieee/mul-round.c: New.
Index: config/fp-bit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/fp-bit.c,v
retrieving revision 1.43
diff -u -p -u -p -r1.43 fp-bit.c
--- config/fp-bit.c 22 Aug 2003 09:33:25 -0000 1.43
+++ config/fp-bit.c 10 Nov 2003 22:44:35 -0000
@@ -873,34 +873,9 @@ _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;
- }
- else if (low)
- {
- /* but we really weren't half way */
- high += GARDROUND + 1;
- }
- }
+ /* LSB of high is proxy for all bits in low. */
+ if (low)
+ high |= 0x1;
tmp->fraction.ll = high;
tmp->class = CLASS_NUMBER;
return tmp;
@@ -998,19 +973,9 @@ _fpdiv_parts (fp_number_type * a,
numerator *= 2;
}
- if (!ROUND_TOWARDS_ZERO && (quotient & GARDMASK) == GARDMSB)
- {
- if (quotient & (1 << NGARDS))
- {
- /* half way, so round to even */
- quotient += GARDROUND + 1;
- }
- else if (numerator)
- {
- /* but we really weren't half way, more bits exist */
- quotient += GARDROUND + 1;
- }
- }
+ /* LSB of quotient is proxy for all low order bits in numerator. */
+ if (numerator)
+ quotient |= 0x1;
a->fraction.ll = quotient;
return (a);
Index: testsuite/gcc.c-torture/execute/ieee/mul-round.c
===================================================================
RCS file: testsuite/gcc.c-torture/execute/ieee/mul-round.c
diff -N testsuite/gcc.c-torture/execute/ieee/mul-round.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ testsuite/gcc.c-torture/execute/ieee/mul-round.c 10 Nov 2003 22:44:36 -0000
@@ -0,0 +1,41 @@
+#define NUMTESTS 6
+
+typedef union {
+ int i;
+ float f;
+} FUNION;
+
+int main(void)
+{
+ FUNION argv1[NUMTESTS], argv2[NUMTESTS];
+ FUNION expres[NUMTESTS], actres[NUMTESTS];
+ int i;
+
+ argv1[0].i = 0xfff;
+ argv2[0].i = 0x3f800400;
+ expres[0].i = 0xfff;
+ argv1[1].i = 0x3f800400;
+ argv2[1].i = 0xfff;
+ expres[1].i = 0xfff;
+ argv1[2].i = 0xf;
+ argv2[2].i = 0x3fc88888;
+ expres[2].i = 0x17;
+ argv1[3].i = 0x3fc88888;
+ argv2[3].i = 0xf;
+ expres[3].i = 0x17;
+ argv1[4].i = 0xf;
+ argv2[4].i = 0x3f844444;
+ expres[4].i = 0xf;
+ argv1[5].i = 0xf;
+ argv2[5].i = 0x3fc88888;
+ expres[5].i = 0x17;
+
+ for (i = 0; i < NUMTESTS; i++)
+ {
+ actres[i].f = argv1[i].f * argv2[i].f;
+ if (actres[i].i != expres[i].i)
+ abort ();
+ }
+ exit (0);
+}
+
============================================================