public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* egcs 1.0.2 is broken on x86
@ 1998-04-14 17:34 H.J. Lu
  0 siblings, 0 replies; only message in thread
From: H.J. Lu @ 1998-04-14 17:34 UTC (permalink / raw)
  To: egcs

egcs 1.0.2 seems broken on x86. Here is a test case. The problem is
egcs is confused about the register stack. At certain point, the
register stack looks like:

	st0: value
	st1: dead
	st2: 1

We want to change it to

	st0: value
	st1: 1

We can do

	fstp %st(1)

or
	fxch %st(1)
	fstp %st(0)

But egcs 1.0.2 emits

	fxch %st(1)
	fstp %st(1)

As the result, the register stack is screwed up. I think we should
make egcs 1.0.3 to fix this bug plus a few others.

Thanks.


-- 
H.J. Lu (hjl@gnu.org)
----
Tue Apr 14 17:22:35 1998  H.J. Lu  (hjl@gnu.org)

	* gcc.dg/980414-1.c: New to test double on x86.

--- /dev/null	Wed Dec 31 16:00:00 1969
+++ gcc.dg/980414-1.c	Tue Apr 14 17:20:42 1998
@@ -0,0 +1,76 @@
+/* Test double on x86. */
+
+/* { dg-do run { target i?86-*-* } } */
+/* { dg-options -O2 } */
+
+static __inline  double
+mypow (double __x, double __y)
+{
+  register double __value, __exponent;
+  long __p = (long) __y;
+  if (__y == (double) __p)
+    {
+      double __r = 1.0;
+      if (__p == 0)
+	return 1.0;
+      if (__p < 0)
+	{
+	  __p = -__p;
+	  __x = 1.0 / __x;
+	}
+      while (1)
+	{
+	  if (__p & 1)
+	    __r *= __x;
+	  __p >>= 1;
+	  if (__p == 0)
+	    return __r;
+	  __x *= __x;
+	}
+    }
+  __asm __volatile__
+    ("fmul	%%st(1)		# y * log2(x)\n\t"
+     "fstl	%%st(1)\n\t"
+     "frndint			# int(y * log2(x))\n\t"
+     "fxch\n\t"
+     "fsub	%%st(1)		# fract(y * log2(x))\n\t"
+     "f2xm1			# 2^(fract(y * log2(x))) - 1\n\t"
+     : "=t" (__value), "=u" (__exponent) :  "0" (__x), "1" (__y));
+  __value += 1.0;
+  __asm __volatile__
+    ("fscale"
+     : "=t" (__value) : "0" (__value), "u" (__exponent));
+  return __value;
+}
+
+const double E1 = 2.71828182845904523536028747135;
+
+double fact (double x)
+{
+  double corr;
+  corr = 1.0;
+  return corr * mypow(x/E1, x);
+}
+
+int main ()
+{
+  double y, z;
+
+  y = fact (46.2);
+  z = mypow (46.2/E1, 46.2);
+
+#if 0
+  printf ("%26.19e, %26.19e\n", y, z);
+#endif
+
+  if (y > z)
+    y -= z;
+  else
+    y = z - y;
+
+  y /= z;
+  if (y > 0.1)
+    abort ();
+ 
+  return 0;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~1998-04-14 17:34 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-04-14 17:34 egcs 1.0.2 is broken on x86 H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).