OSDN Git Service

PR c/17844
[pf3gnuchains/gcc-fork.git] / gcc / testsuite / gcc.dg / 980414-1.c
1 /* Test double on x86. */
2
3 /* { dg-do run { target i?86-*-* } } */
4 /* { dg-options -O2 } */
5
6 extern void abort (void);
7
8 static __inline  double
9 mypow (double __x, double __y)
10 {
11   register double __value, __exponent;
12   long __p = (long) __y;
13   if (__y == (double) __p)
14     {
15       double __r = 1.0;
16       if (__p == 0)
17         return 1.0;
18       if (__p < 0)
19         {
20           __p = -__p;
21           __x = 1.0 / __x;
22         }
23       while (1)
24         {
25           if (__p & 1)
26             __r *= __x;
27           __p >>= 1;
28           if (__p == 0)
29             return __r;
30           __x *= __x;
31         }
32     }
33   __asm __volatile__
34     ("fmul      %%st(1),%%st\n\t"       /* y * log2(x) */
35      "fst       %%st(1)\n\t"
36      "frndint\n\t"                      /* int(y * log2(x)) */
37      "fxch  %%st(1)\n\t"
38      "fsub      %%st(1),%%st\n\t"       /* fract(y * log2(x)) */
39      "f2xm1\n\t"                        /* 2^(fract(y * log2(x))) - 1 */
40      : "=t" (__value), "=u" (__exponent) :  "0" (__x), "1" (__y));
41   __value += 1.0;
42   __asm __volatile__
43     ("fscale"
44      : "=t" (__value) : "0" (__value), "u" (__exponent));
45   return __value;
46 }
47
48 const double E1 = 2.71828182845904523536028747135;
49
50 double fact (double x)
51 {
52   double corr;
53   corr = 1.0;
54   return corr * mypow(x/E1, x);
55 }
56
57 int main ()
58 {
59   double y, z;
60
61   y = fact (46.2);
62   z = mypow (46.2/E1, 46.2);
63
64 #if 0
65   printf ("%26.19e, %26.19e\n", y, z);
66 #endif
67
68   if (y > z)
69     y -= z;
70   else
71     y = z - y;
72
73   y /= z;
74   if (y > 0.1)
75     abort ();
76  
77   return 0;
78 }