home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / gcc-2.4.5 / math-68881.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-06-07  |  9.2 KB  |  525 lines

  1. /******************************************************************\
  2. *                                   *
  3. *  <math-68881.h>        last modified: 23 May 1992.       *
  4. *                                   *
  5. *  Copyright (C) 1989 by Matthew Self.                   *
  6. *  You may freely distribute verbatim copies of this software       *
  7. *  provided that this copyright notice is retained in all copies.  *
  8. *  You may distribute modifications to this software under the     *
  9. *  conditions above if you also clearly note such modifications    *
  10. *  with their author and date.                               *
  11. *                                   *
  12. *  Note:  errno is not set to EDOM when domain errors occur for    *
  13. *  most of these functions.  Rather, it is assumed that the       *
  14. *  68881's OPERR exception will be enabled and handled           *
  15. *  appropriately by the    operating system.  Similarly, overflow       *
  16. *  and underflow do not set errno to ERANGE.               *
  17. *                                   *
  18. *  Send bugs to Matthew Self (self@bayes.arc.nasa.gov).           *
  19. *                                   *
  20. \******************************************************************/
  21.  
  22. /* This file is NOT a part of GCC, just distributed with it.  */
  23.  
  24. /* If you find this in GCC,
  25.    please send bug reports to bug-gcc@prep.ai.mit.edu.  */
  26.  
  27. /* Changed by Richard Stallman:
  28.    May 1993, add conditional to prevent multiple inclusion.
  29.    % inserted before a #.
  30.    New function `hypot' added.
  31.    Nans written in hex to avoid 0rnan.
  32.    May 1992, use %! for fpcr register.  Break lines before function names.
  33.    December 1989, add parens around `&' in pow.
  34.    November 1990, added alternate definition of HUGE_VAL for Sun.  */
  35.  
  36. #ifndef __math_68881
  37. #define __math_68881
  38.  
  39. #include <errno.h>
  40.  
  41. #ifndef HUGE_VAL
  42. #ifdef __sun__
  43. /* The Sun assembler fails to handle the hex constant in the usual defn.  */
  44. #define HUGE_VAL                            \
  45. ({                                    \
  46.   static union { int i[2]; double d; } u = { {0x7ff00000, 0} };        \
  47.   u.d;                                    \
  48. })
  49. #else
  50. #define HUGE_VAL                            \
  51. ({                                    \
  52.   double huge_val;                            \
  53.                                     \
  54.   __asm ("fmove%.d %#0x7ff0000000000000,%0"    /* Infinity */        \
  55.      : "=f" (huge_val)                        \
  56.      : /* no inputs */);                        \
  57.   huge_val;                                \
  58. })
  59. #endif
  60. #endif
  61.  
  62. __inline static const double
  63. sin (double x)
  64. {
  65.   double value;
  66.  
  67.   __asm ("fsin%.x %1,%0"
  68.      : "=f" (value)
  69.      : "f" (x));
  70.   return value;
  71. }
  72.  
  73. __inline static const double
  74. cos (double x)
  75. {
  76.   double value;
  77.  
  78.   __asm ("fcos%.x %1,%0"
  79.      : "=f" (value)
  80.      : "f" (x));
  81.   return value;
  82. }
  83.  
  84. __inline static const double
  85. tan (double x)
  86. {
  87.   double value;
  88.  
  89.   __asm ("ftan%.x %1,%0"
  90.      : "=f" (value)
  91.      : "f" (x));
  92.   return value;
  93. }
  94.  
  95. __inline static const double
  96. asin (double x)
  97. {
  98.   double value;
  99.  
  100.   __asm ("fasin%.x %1,%0"
  101.      : "=f" (value)
  102.      : "f" (x));
  103.   return value;
  104. }
  105.  
  106. __inline static const double
  107. acos (double x)
  108. {
  109.   double value;
  110.  
  111.   __asm ("facos%.x %1,%0"
  112.      : "=f" (value)
  113.      : "f" (x));
  114.   return value;
  115. }
  116.  
  117. __inline static const double
  118. atan (double x)
  119. {
  120.   double value;
  121.  
  122.   __asm ("fatan%.x %1,%0"
  123.      : "=f" (value)
  124.      : "f" (x));
  125.   return value;
  126. }
  127.  
  128. __inline static const double
  129. atan2 (double y, double x)
  130. {
  131.   double pi, pi_over_2;
  132.  
  133.   __asm ("fmovecr%.x %#0,%0"        /* extended precision pi */
  134.      : "=f" (pi)
  135.      : /* no inputs */ );
  136.   __asm ("fscale%.b %#-1,%0"        /* no loss of accuracy */
  137.      : "=f" (pi_over_2)
  138.      : "0" (pi));
  139.   if (x > 0)
  140.     {
  141.       if (y > 0)
  142.     {
  143.       if (x > y)
  144.         return atan (y / x);
  145.       else
  146.         return pi_over_2 - atan (x / y);
  147.     }
  148.       else
  149.     {
  150.       if (x > -y)
  151.         return atan (y / x);
  152.       else
  153.         return - pi_over_2 - atan (x / y);
  154.     }
  155.     }
  156.   else
  157.     {
  158.       if (y < 0)
  159.     {
  160.       if (-x > -y)
  161.         return - pi + atan (y / x);
  162.       else
  163.         return - pi_over_2 - atan (x / y);
  164.     }
  165.       else
  166.     {
  167.       if (-x > y)
  168.         return pi + atan (y / x);
  169.       else if (y > 0)
  170.         return pi_over_2 - atan (x / y);
  171.       else
  172.         {
  173.           double value;
  174.  
  175.           errno = EDOM;
  176.           __asm ("fmove%.d %#0x7fffffffffffffff,%0"     /* quiet NaN */
  177.              : "=f" (value)
  178.              : /* no inputs */);
  179.           return value;
  180.         }
  181.     }
  182.     }
  183. }
  184.  
  185. __inline static const double
  186. sinh (double x)
  187. {
  188.   double value;
  189.  
  190.   __asm ("fsinh%.x %1,%0"
  191.      : "=f" (value)
  192.      : "f" (x));
  193.   return value;
  194. }
  195.  
  196. __inline static const double
  197. cosh (double x)
  198. {
  199.   double value;
  200.  
  201.   __asm ("fcosh%.x %1,%0"
  202.      : "=f" (value)
  203.      : "f" (x));
  204.   return value;
  205. }
  206.  
  207. __inline static const double
  208. tanh (double x)
  209. {
  210.   double value;
  211.  
  212.   __asm ("ftanh%.x %1,%0"
  213.      : "=f" (value)
  214.      : "f" (x));
  215.   return value;
  216. }
  217.  
  218. __inline static const double
  219. atanh (double x)
  220. {
  221.   double value;
  222.  
  223.   __asm ("fatanh%.x %1,%0"
  224.      : "=f" (value)
  225.      : "f" (x));
  226.   return value;
  227. }
  228.  
  229. __inline static const double
  230. exp (double x)
  231. {
  232.   double value;
  233.  
  234.   __asm ("fetox%.x %1,%0"
  235.      : "=f" (value)
  236.      : "f" (x));
  237.   return value;
  238. }
  239.  
  240. __inline static const double
  241. expm1 (double x)
  242. {
  243.   double value;
  244.  
  245.   __asm ("fetoxm1%.x %1,%0"
  246.      : "=f" (value)
  247.      : "f" (x));
  248.   return value;
  249. }
  250.  
  251. __inline static const double
  252. log (double x)
  253. {
  254.   double value;
  255.  
  256.   __asm ("flogn%.x %1,%0"
  257.      : "=f" (value)
  258.      : "f" (x));
  259.   return value;
  260. }
  261.  
  262. __inline static const double
  263. log1p (double x)
  264. {
  265.   double value;
  266.  
  267.   __asm ("flognp1%.x %1,%0"
  268.      : "=f" (value)
  269.      : "f" (x));
  270.   return value;
  271. }
  272.  
  273. __inline static const double
  274. log10 (double x)
  275. {
  276.   double value;
  277.  
  278.   __asm ("flog10%.x %1,%0"
  279.      : "=f" (value)
  280.      : "f" (x));
  281.   return value;
  282. }
  283.  
  284. __inline static const double
  285. sqrt (double x)
  286. {
  287.   double value;
  288.  
  289.   __asm ("fsqrt%.x %1,%0"
  290.      : "=f" (value)
  291.      : "f" (x));
  292.   return value;
  293. }
  294.  
  295. __inline static const double
  296. hypot (const double x, const double y)
  297. {
  298.   return sqrt (x*x + y*y);
  299. }
  300.  
  301. __inline static const double
  302. pow (const double x, const double y)
  303. {
  304.   if (x > 0)
  305.     return exp (y * log (x));
  306.   else if (x == 0)
  307.     {
  308.       if (y > 0)
  309.     return 0.0;
  310.       else
  311.     {
  312.       double value;
  313.  
  314.       errno = EDOM;
  315.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  316.          : "=f" (value)
  317.          : /* no inputs */);
  318.       return value;
  319.     }
  320.     }
  321.   else
  322.     {
  323.       double temp;
  324.  
  325.       __asm ("fintrz%.x %1,%0"
  326.          : "=f" (temp)            /* integer-valued float */
  327.          : "f" (y));
  328.       if (y == temp)
  329.         {
  330.       int i = (int) y;
  331.       
  332.       if ((i & 1) == 0)            /* even */
  333.         return exp (y * log (-x));
  334.       else
  335.         return - exp (y * log (-x));
  336.         }
  337.       else
  338.         {
  339.       double value;
  340.  
  341.       errno = EDOM;
  342.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  343.          : "=f" (value)
  344.          : /* no inputs */);
  345.       return value;
  346.         }
  347.     }
  348. }
  349.  
  350. __inline static const double
  351. fabs (double x)
  352. {
  353.   double value;
  354.  
  355.   __asm ("fabs%.x %1,%0"
  356.      : "=f" (value)
  357.      : "f" (x));
  358.   return value;
  359. }
  360.  
  361. __inline static const double
  362. ceil (double x)
  363. {
  364.   int rounding_mode, round_up;
  365.   double value;
  366.  
  367.   __asm volatile ("fmove%.l %!,%0"
  368.           : "=dm" (rounding_mode)
  369.           : /* no inputs */ );
  370.   round_up = rounding_mode | 0x30;
  371.   __asm volatile ("fmove%.l %0,%!"
  372.           : /* no outputs */
  373.           : "dmi" (round_up));
  374.   __asm volatile ("fint%.x %1,%0"
  375.           : "=f" (value)
  376.           : "f" (x));
  377.   __asm volatile ("fmove%.l %0,%!"
  378.           : /* no outputs */
  379.           : "dmi" (rounding_mode));
  380.   return value;
  381. }
  382.  
  383. __inline static const double
  384. floor (double x)
  385. {
  386.   int rounding_mode, round_down;
  387.   double value;
  388.  
  389.   __asm volatile ("fmove%.l %!,%0"
  390.           : "=dm" (rounding_mode)
  391.           : /* no inputs */ );
  392.   round_down = (rounding_mode & ~0x10)
  393.         | 0x20;
  394.   __asm volatile ("fmove%.l %0,%!"
  395.           : /* no outputs */
  396.           : "dmi" (round_down));
  397.   __asm volatile ("fint%.x %1,%0"
  398.           : "=f" (value)
  399.           : "f" (x));
  400.   __asm volatile ("fmove%.l %0,%!"
  401.           : /* no outputs */
  402.           : "dmi" (rounding_mode));
  403.   return value;
  404. }
  405.  
  406. __inline static const double
  407. rint (double x)
  408. {
  409.   int rounding_mode, round_nearest;
  410.   double value;
  411.  
  412.   __asm volatile ("fmove%.l %!,%0"
  413.           : "=dm" (rounding_mode)
  414.           : /* no inputs */ );
  415.   round_nearest = rounding_mode & ~0x30;
  416.   __asm volatile ("fmove%.l %0,%!"
  417.           : /* no outputs */
  418.           : "dmi" (round_nearest));
  419.   __asm volatile ("fint%.x %1,%0"
  420.           : "=f" (value)
  421.           : "f" (x));
  422.   __asm volatile ("fmove%.l %0,%!"
  423.           : /* no outputs */
  424.           : "dmi" (rounding_mode));
  425.   return value;
  426. }
  427.  
  428. __inline static const double
  429. fmod (double x, double y)
  430. {
  431.   double value;
  432.  
  433.   __asm ("fmod%.x %2,%0"
  434.      : "=f" (value)
  435.      : "0" (x),
  436.        "f" (y));
  437.   return value;
  438. }
  439.  
  440. __inline static const double
  441. drem (double x, double y)
  442. {
  443.   double value;
  444.  
  445.   __asm ("frem%.x %2,%0"
  446.      : "=f" (value)
  447.      : "0" (x),
  448.        "f" (y));
  449.   return value;
  450. }
  451.  
  452. __inline static const double
  453. scalb (double x, int n)
  454. {
  455.   double value;
  456.  
  457.   __asm ("fscale%.l %2,%0"
  458.      : "=f" (value)
  459.      : "0" (x),
  460.        "dmi" (n));
  461.   return value;
  462. }
  463.  
  464. __inline static double
  465. logb (double x)
  466. {
  467.   double exponent;
  468.  
  469.   __asm ("fgetexp%.x %1,%0"
  470.      : "=f" (exponent)
  471.      : "f" (x));
  472.   return exponent;
  473. }
  474.  
  475. __inline static const double
  476. ldexp (double x, int n)
  477. {
  478.   double value;
  479.  
  480.   __asm ("fscale%.l %2,%0"
  481.      : "=f" (value)
  482.      : "0" (x),
  483.        "dmi" (n));
  484.   return value;
  485. }
  486.  
  487. __inline static double
  488. frexp (double x, int *exp)
  489. {
  490.   double float_exponent;
  491.   int int_exponent;
  492.   double mantissa;
  493.  
  494.   __asm ("fgetexp%.x %1,%0"
  495.      : "=f" (float_exponent)     /* integer-valued float */
  496.      : "f" (x));
  497.   int_exponent = (int) float_exponent;
  498.   __asm ("fgetman%.x %1,%0"
  499.      : "=f" (mantissa)        /* 1.0 <= mantissa < 2.0 */
  500.      : "f" (x));
  501.   if (mantissa != 0)
  502.     {
  503.       __asm ("fscale%.b %#-1,%0"
  504.          : "=f" (mantissa)        /* mantissa /= 2.0 */
  505.          : "0" (mantissa));
  506.       int_exponent += 1;
  507.     }
  508.   *exp = int_exponent;
  509.   return mantissa;
  510. }
  511.  
  512. __inline static double
  513. modf (double x, double *ip)
  514. {
  515.   double temp;
  516.  
  517.   __asm ("fintrz%.x %1,%0"
  518.      : "=f" (temp)            /* integer-valued float */
  519.      : "f" (x));
  520.   *ip = temp;
  521.   return x - temp;
  522. }
  523.  
  524. #endif /* not __math_68881 */
  525.