home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / ginclude / math-68881.h < prev    next >
C/C++ Source or Header  |  1994-12-20  |  9KB  |  530 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. /* Changed by Jim Wilson:
  37.    September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif.  */
  38.  
  39. /* Changed by Ian Lance Taylor:
  40.    September 1994, use extern inline instead of static inline.  */
  41.  
  42. #ifndef __math_68881
  43. #define __math_68881
  44.  
  45. #include <errno.h>
  46.  
  47. #undef HUGE_VAL
  48. #ifdef __sun__
  49. /* The Sun assembler fails to handle the hex constant in the usual defn.  */
  50. #define HUGE_VAL                            \
  51. ({                                    \
  52.   static union { int i[2]; double d; } u = { {0x7ff00000, 0} };        \
  53.   u.d;                                    \
  54. })
  55. #else
  56. #define HUGE_VAL                            \
  57. ({                                    \
  58.   double huge_val;                            \
  59.                                     \
  60.   __asm ("fmove%.d %#0x7ff0000000000000,%0"    /* Infinity */        \
  61.      : "=f" (huge_val)                        \
  62.      : /* no inputs */);                        \
  63.   huge_val;                                \
  64. })
  65. #endif
  66.  
  67. __inline extern double
  68. sin (double x)
  69. {
  70.   double value;
  71.  
  72.   __asm ("fsin%.x %1,%0"
  73.      : "=f" (value)
  74.      : "f" (x));
  75.   return value;
  76. }
  77.  
  78. __inline extern double
  79. cos (double x)
  80. {
  81.   double value;
  82.  
  83.   __asm ("fcos%.x %1,%0"
  84.      : "=f" (value)
  85.      : "f" (x));
  86.   return value;
  87. }
  88.  
  89. __inline extern double
  90. tan (double x)
  91. {
  92.   double value;
  93.  
  94.   __asm ("ftan%.x %1,%0"
  95.      : "=f" (value)
  96.      : "f" (x));
  97.   return value;
  98. }
  99.  
  100. __inline extern double
  101. asin (double x)
  102. {
  103.   double value;
  104.  
  105.   __asm ("fasin%.x %1,%0"
  106.      : "=f" (value)
  107.      : "f" (x));
  108.   return value;
  109. }
  110.  
  111. __inline extern double
  112. acos (double x)
  113. {
  114.   double value;
  115.  
  116.   __asm ("facos%.x %1,%0"
  117.      : "=f" (value)
  118.      : "f" (x));
  119.   return value;
  120. }
  121.  
  122. __inline extern double
  123. atan (double x)
  124. {
  125.   double value;
  126.  
  127.   __asm ("fatan%.x %1,%0"
  128.      : "=f" (value)
  129.      : "f" (x));
  130.   return value;
  131. }
  132.  
  133. __inline extern double
  134. atan2 (double y, double x)
  135. {
  136.   double pi, pi_over_2;
  137.  
  138.   __asm ("fmovecr%.x %#0,%0"        /* extended precision pi */
  139.      : "=f" (pi)
  140.      : /* no inputs */ );
  141.   __asm ("fscale%.b %#-1,%0"        /* no loss of accuracy */
  142.      : "=f" (pi_over_2)
  143.      : "0" (pi));
  144.   if (x > 0)
  145.     {
  146.       if (y > 0)
  147.     {
  148.       if (x > y)
  149.         return atan (y / x);
  150.       else
  151.         return pi_over_2 - atan (x / y);
  152.     }
  153.       else
  154.     {
  155.       if (x > -y)
  156.         return atan (y / x);
  157.       else
  158.         return - pi_over_2 - atan (x / y);
  159.     }
  160.     }
  161.   else
  162.     {
  163.       if (y < 0)
  164.     {
  165.       if (-x > -y)
  166.         return - pi + atan (y / x);
  167.       else
  168.         return - pi_over_2 - atan (x / y);
  169.     }
  170.       else
  171.     {
  172.       if (-x > y)
  173.         return pi + atan (y / x);
  174.       else if (y > 0)
  175.         return pi_over_2 - atan (x / y);
  176.       else
  177.         {
  178.           double value;
  179.  
  180.           errno = EDOM;
  181.           __asm ("fmove%.d %#0x7fffffffffffffff,%0"     /* quiet NaN */
  182.              : "=f" (value)
  183.              : /* no inputs */);
  184.           return value;
  185.         }
  186.     }
  187.     }
  188. }
  189.  
  190. __inline extern double
  191. sinh (double x)
  192. {
  193.   double value;
  194.  
  195.   __asm ("fsinh%.x %1,%0"
  196.      : "=f" (value)
  197.      : "f" (x));
  198.   return value;
  199. }
  200.  
  201. __inline extern double
  202. cosh (double x)
  203. {
  204.   double value;
  205.  
  206.   __asm ("fcosh%.x %1,%0"
  207.      : "=f" (value)
  208.      : "f" (x));
  209.   return value;
  210. }
  211.  
  212. __inline extern double
  213. tanh (double x)
  214. {
  215.   double value;
  216.  
  217.   __asm ("ftanh%.x %1,%0"
  218.      : "=f" (value)
  219.      : "f" (x));
  220.   return value;
  221. }
  222.  
  223. __inline extern double
  224. atanh (double x)
  225. {
  226.   double value;
  227.  
  228.   __asm ("fatanh%.x %1,%0"
  229.      : "=f" (value)
  230.      : "f" (x));
  231.   return value;
  232. }
  233.  
  234. __inline extern double
  235. exp (double x)
  236. {
  237.   double value;
  238.  
  239.   __asm ("fetox%.x %1,%0"
  240.      : "=f" (value)
  241.      : "f" (x));
  242.   return value;
  243. }
  244.  
  245. __inline extern double
  246. expm1 (double x)
  247. {
  248.   double value;
  249.  
  250.   __asm ("fetoxm1%.x %1,%0"
  251.      : "=f" (value)
  252.      : "f" (x));
  253.   return value;
  254. }
  255.  
  256. __inline extern double
  257. log (double x)
  258. {
  259.   double value;
  260.  
  261.   __asm ("flogn%.x %1,%0"
  262.      : "=f" (value)
  263.      : "f" (x));
  264.   return value;
  265. }
  266.  
  267. __inline extern double
  268. log1p (double x)
  269. {
  270.   double value;
  271.  
  272.   __asm ("flognp1%.x %1,%0"
  273.      : "=f" (value)
  274.      : "f" (x));
  275.   return value;
  276. }
  277.  
  278. __inline extern double
  279. log10 (double x)
  280. {
  281.   double value;
  282.  
  283.   __asm ("flog10%.x %1,%0"
  284.      : "=f" (value)
  285.      : "f" (x));
  286.   return value;
  287. }
  288.  
  289. __inline extern double
  290. sqrt (double x)
  291. {
  292.   double value;
  293.  
  294.   __asm ("fsqrt%.x %1,%0"
  295.      : "=f" (value)
  296.      : "f" (x));
  297.   return value;
  298. }
  299.  
  300. __inline extern double
  301. hypot (double x, double y)
  302. {
  303.   return sqrt (x*x + y*y);
  304. }
  305.  
  306. __inline extern double
  307. pow (double x, double y)
  308. {
  309.   if (x > 0)
  310.     return exp (y * log (x));
  311.   else if (x == 0)
  312.     {
  313.       if (y > 0)
  314.     return 0.0;
  315.       else
  316.     {
  317.       double value;
  318.  
  319.       errno = EDOM;
  320.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  321.          : "=f" (value)
  322.          : /* no inputs */);
  323.       return value;
  324.     }
  325.     }
  326.   else
  327.     {
  328.       double temp;
  329.  
  330.       __asm ("fintrz%.x %1,%0"
  331.          : "=f" (temp)            /* integer-valued float */
  332.          : "f" (y));
  333.       if (y == temp)
  334.         {
  335.       int i = (int) y;
  336.       
  337.       if ((i & 1) == 0)            /* even */
  338.         return exp (y * log (-x));
  339.       else
  340.         return - exp (y * log (-x));
  341.         }
  342.       else
  343.         {
  344.       double value;
  345.  
  346.       errno = EDOM;
  347.       __asm ("fmove%.d %#0x7fffffffffffffff,%0"        /* quiet NaN */
  348.          : "=f" (value)
  349.          : /* no inputs */);
  350.       return value;
  351.         }
  352.     }
  353. }
  354.  
  355. __inline extern double
  356. fabs (double x)
  357. {
  358.   double value;
  359.  
  360.   __asm ("fabs%.x %1,%0"
  361.      : "=f" (value)
  362.      : "f" (x));
  363.   return value;
  364. }
  365.  
  366. __inline extern double
  367. ceil (double x)
  368. {
  369.   int rounding_mode, round_up;
  370.   double value;
  371.  
  372.   __asm volatile ("fmove%.l %!,%0"
  373.           : "=dm" (rounding_mode)
  374.           : /* no inputs */ );
  375.   round_up = rounding_mode | 0x30;
  376.   __asm volatile ("fmove%.l %0,%!"
  377.           : /* no outputs */
  378.           : "dmi" (round_up));
  379.   __asm volatile ("fint%.x %1,%0"
  380.           : "=f" (value)
  381.           : "f" (x));
  382.   __asm volatile ("fmove%.l %0,%!"
  383.           : /* no outputs */
  384.           : "dmi" (rounding_mode));
  385.   return value;
  386. }
  387.  
  388. __inline extern double
  389. floor (double x)
  390. {
  391.   int rounding_mode, round_down;
  392.   double value;
  393.  
  394.   __asm volatile ("fmove%.l %!,%0"
  395.           : "=dm" (rounding_mode)
  396.           : /* no inputs */ );
  397.   round_down = (rounding_mode & ~0x10)
  398.         | 0x20;
  399.   __asm volatile ("fmove%.l %0,%!"
  400.           : /* no outputs */
  401.           : "dmi" (round_down));
  402.   __asm volatile ("fint%.x %1,%0"
  403.           : "=f" (value)
  404.           : "f" (x));
  405.   __asm volatile ("fmove%.l %0,%!"
  406.           : /* no outputs */
  407.           : "dmi" (rounding_mode));
  408.   return value;
  409. }
  410.  
  411. __inline extern double
  412. rint (double x)
  413. {
  414.   int rounding_mode, round_nearest;
  415.   double value;
  416.  
  417.   __asm volatile ("fmove%.l %!,%0"
  418.           : "=dm" (rounding_mode)
  419.           : /* no inputs */ );
  420.   round_nearest = rounding_mode & ~0x30;
  421.   __asm volatile ("fmove%.l %0,%!"
  422.           : /* no outputs */
  423.           : "dmi" (round_nearest));
  424.   __asm volatile ("fint%.x %1,%0"
  425.           : "=f" (value)
  426.           : "f" (x));
  427.   __asm volatile ("fmove%.l %0,%!"
  428.           : /* no outputs */
  429.           : "dmi" (rounding_mode));
  430.   return value;
  431. }
  432.  
  433. __inline extern double
  434. fmod (double x, double y)
  435. {
  436.   double value;
  437.  
  438.   __asm ("fmod%.x %2,%0"
  439.      : "=f" (value)
  440.      : "0" (x),
  441.        "f" (y));
  442.   return value;
  443. }
  444.  
  445. __inline extern double
  446. drem (double x, double y)
  447. {
  448.   double value;
  449.  
  450.   __asm ("frem%.x %2,%0"
  451.      : "=f" (value)
  452.      : "0" (x),
  453.        "f" (y));
  454.   return value;
  455. }
  456.  
  457. __inline extern double
  458. scalb (double x, int n)
  459. {
  460.   double value;
  461.  
  462.   __asm ("fscale%.l %2,%0"
  463.      : "=f" (value)
  464.      : "0" (x),
  465.        "dmi" (n));
  466.   return value;
  467. }
  468.  
  469. __inline extern double
  470. logb (double x)
  471. {
  472.   double exponent;
  473.  
  474.   __asm ("fgetexp%.x %1,%0"
  475.      : "=f" (exponent)
  476.      : "f" (x));
  477.   return exponent;
  478. }
  479.  
  480. __inline extern double
  481. ldexp (double x, int n)
  482. {
  483.   double value;
  484.  
  485.   __asm ("fscale%.l %2,%0"
  486.      : "=f" (value)
  487.      : "0" (x),
  488.        "dmi" (n));
  489.   return value;
  490. }
  491.  
  492. __inline extern double
  493. frexp (double x, int *exp)
  494. {
  495.   double float_exponent;
  496.   int int_exponent;
  497.   double mantissa;
  498.  
  499.   __asm ("fgetexp%.x %1,%0"
  500.      : "=f" (float_exponent)     /* integer-valued float */
  501.      : "f" (x));
  502.   int_exponent = (int) float_exponent;
  503.   __asm ("fgetman%.x %1,%0"
  504.      : "=f" (mantissa)        /* 1.0 <= mantissa < 2.0 */
  505.      : "f" (x));
  506.   if (mantissa != 0)
  507.     {
  508.       __asm ("fscale%.b %#-1,%0"
  509.          : "=f" (mantissa)        /* mantissa /= 2.0 */
  510.          : "0" (mantissa));
  511.       int_exponent += 1;
  512.     }
  513.   *exp = int_exponent;
  514.   return mantissa;
  515. }
  516.  
  517. __inline extern double
  518. modf (double x, double *ip)
  519. {
  520.   double temp;
  521.  
  522.   __asm ("fintrz%.x %1,%0"
  523.      : "=f" (temp)            /* integer-valued float */
  524.      : "f" (x));
  525.   *ip = temp;
  526.   return x - temp;
  527. }
  528.  
  529. #endif /* not __math_68881 */
  530.