1/* Test double on x86. */ 2 3/* { dg-do run } */ 4/* { dg-options -O2 } */ 5 6extern void abort (void); 7 8static __inline double 9mypow (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 48const double E1 = 2.71828182845904523536028747135; 49 50double fact (double x) 51{ 52 double corr; 53 corr = 1.0; 54 return corr * mypow(x/E1, x); 55} 56 57int 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} 79