(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.target/
i386/
980414-1.c
       1  /* Test double on x86. */
       2  
       3  /* { dg-do run } */
       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  }