This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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);
+}
+
============================================================


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]