home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 2 / FFMCD02.bin / useful / include / math-68881.h < prev    next >
C/C++ Source or Header  |  1993-09-05  |  10KB  |  550 lines

  1. /******************************************************************\
  2. *                                   *
  3. *  <math-68881.h>        last modified: 18 May 1989.       *
  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. /* Dec 1991  - mw - added support for -traditional mode */
  23.  
  24. #include <errno.h>
  25.  
  26. #if defined(__STDC__) || defined(__cplusplus)
  27. #define _DEFUN(name, args1, args2) name ( args2 )
  28. #define _AND ,
  29. #define _CONST const
  30. #else
  31. #define _DEFUN(name, args1, args2) name args1 args2;
  32. #define _AND ;
  33. #define _CONST
  34. #endif
  35.  
  36. #ifndef HUGE_VAL
  37. #define HUGE_VAL                            \
  38. ({                                    \
  39.   double huge_val;                            \
  40.                                     \
  41.   __asm ("fmove%.d #0x7ff0000000000000,%0"    /* Infinity */        \
  42.      : "=f" (huge_val)                        \
  43.      : /* no inputs */);                        \
  44.   huge_val;                                \
  45. })
  46. #endif
  47.  
  48. __inline static _CONST double 
  49. _DEFUN(sin, (x),
  50.     double x)
  51. {
  52.   double value;
  53.  
  54.   __asm ("fsin%.x %1,%0"
  55.      : "=f" (value)
  56.      : "f" (x));
  57.   return value;
  58. }
  59.  
  60. __inline static _CONST double 
  61. _DEFUN(cos, (x),
  62.     double x)
  63. {
  64.   double value;
  65.  
  66.   __asm ("fcos%.x %1,%0"
  67.      : "=f" (value)
  68.      : "f" (x));
  69.   return value;
  70. }
  71.  
  72. __inline static _CONST double 
  73. _DEFUN(tan, (x),
  74.     double x)
  75. {
  76.   double value;
  77.  
  78.   __asm ("ftan%.x %1,%0"
  79.      : "=f" (value)
  80.      : "f" (x));
  81.   return value;
  82. }
  83.  
  84. __inline static _CONST double 
  85. _DEFUN(asin, (x),
  86.     double x)
  87. {
  88.   double value;
  89.  
  90.   __asm ("fasin%.x %1,%0"
  91.      : "=f" (value)
  92.      : "f" (x));
  93.   return value;
  94. }
  95.  
  96. __inline static _CONST double 
  97. _DEFUN(acos, (x),
  98.     double x)
  99. {
  100.   double value;
  101.  
  102.   __asm ("facos%.x %1,%0"
  103.      : "=f" (value)
  104.      : "f" (x));
  105.   return value;
  106. }
  107.  
  108. __inline static _CONST double 
  109. _DEFUN(atan, (x),
  110.     double x)
  111. {
  112.   double value;
  113.  
  114.   __asm ("fatan%.x %1,%0"
  115.      : "=f" (value)
  116.      : "f" (x));
  117.   return value;
  118. }
  119.  
  120. __inline static _CONST double 
  121. _DEFUN(atan2, (y, x),
  122.     double y _AND
  123.     double x)
  124. {
  125.   double pi, pi_over_2;
  126.  
  127.   __asm ("fmovecr%.x %#0,%0"        /* extended precision pi */
  128.      : "=f" (pi)
  129.      : /* no inputs */ );
  130.   __asm ("fscale%.b %#-1,%0"        /* no loss of accuracy */
  131.      : "=f" (pi_over_2)
  132.      : "0" (pi));
  133.   if (x > 0)
  134.     {
  135.       if (y > 0)
  136.     {
  137.       if (x > y)
  138.         return atan (y / x);
  139.       else
  140.         return pi_over_2 - atan (x / y);
  141.     }
  142.       else
  143.     {
  144.       if (x > -y)
  145.         return atan (y / x);
  146.       else
  147.         return - pi_over_2 - atan (x / y);
  148.     }
  149.     }
  150.   else
  151.     {
  152.       if (y > 0)
  153.     {
  154.       if (-x > y)
  155.         return pi + atan (y / x);
  156.       else
  157.         return pi_over_2 - atan (x / y);
  158.     }
  159.       else
  160.     {
  161.       if (-x > -y)
  162.         return - pi + atan (y / x);
  163.       else if (y < 0)
  164.         return - pi_over_2 - atan (x / y);
  165.       else
  166.         {
  167.           double value;
  168.  
  169.           errno = EDOM;
  170.           __asm ("fmove%.d %#0rnan,%0"     /* quiet NaN */
  171.              : "=f" (value)
  172.              : /* no inputs */);
  173.           return value;
  174.         }
  175.     }
  176.     }
  177. }
  178.  
  179. __inline static _CONST double 
  180. _DEFUN(sinh, (x),
  181.     double x)
  182. {
  183.   double value;
  184.  
  185.   __asm ("fsinh%.x %1,%0"
  186.      : "=f" (value)
  187.      : "f" (x));
  188.   return value;
  189. }
  190.  
  191. __inline static _CONST double 
  192. _DEFUN(cosh, (x),
  193.     double x)
  194. {
  195.   double value;
  196.  
  197.   __asm ("fcosh%.x %1,%0"
  198.      : "=f" (value)
  199.      : "f" (x));
  200.   return value;
  201. }
  202.  
  203. __inline static _CONST double 
  204. _DEFUN(tanh, (x),
  205.     double x)
  206. {
  207.   double value;
  208.  
  209.   __asm ("ftanh%.x %1,%0"
  210.      : "=f" (value)
  211.      : "f" (x));
  212.   return value;
  213. }
  214.  
  215. __inline static _CONST double 
  216. _DEFUN(atanh, (x),
  217.     double x)
  218. {
  219.   double value;
  220.  
  221.   __asm ("fatanh%.x %1,%0"
  222.      : "=f" (value)
  223.      : "f" (x));
  224.   return value;
  225. }
  226.  
  227. __inline static _CONST double 
  228. _DEFUN(exp, (x),
  229.     double x)
  230. {
  231.   double value;
  232.  
  233.   __asm ("fetox%.x %1,%0"
  234.      : "=f" (value)
  235.      : "f" (x));
  236.   return value;
  237. }
  238.  
  239. __inline static _CONST double 
  240. _DEFUN(expm1, (x),
  241.     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. _DEFUN(log, (x),
  253.     double x)
  254. {
  255.   double value;
  256.  
  257.   __asm ("flogn%.x %1,%0"
  258.      : "=f" (value)
  259.      : "f" (x));
  260.   return value;
  261. }
  262.  
  263. __inline static _CONST double 
  264. _DEFUN(log1p, (x),
  265.     double x)
  266. {
  267.   double value;
  268.  
  269.   __asm ("flognp1%.x %1,%0"
  270.      : "=f" (value)
  271.      : "f" (x));
  272.   return value;
  273. }
  274.  
  275. __inline static _CONST double 
  276. _DEFUN(log10, (x),
  277.     double x)
  278. {
  279.   double value;
  280.  
  281.   __asm ("flog10%.x %1,%0"
  282.      : "=f" (value)
  283.      : "f" (x));
  284.   return value;
  285. }
  286.  
  287. __inline static _CONST double 
  288. _DEFUN(sqrt, (x),
  289.     double x)
  290. {
  291.   double value;
  292.  
  293.   __asm ("fsqrt%.x %1,%0"
  294.      : "=f" (value)
  295.      : "f" (x));
  296.   return value;
  297. }
  298.  
  299. __inline static _CONST double
  300. hypot (_CONST double x, _CONST double y)
  301. {
  302.   return sqrt (x*x + y*y);
  303. }
  304.  
  305. __inline static _CONST double 
  306. _DEFUN(pow, (x, y),
  307.     _CONST double x _AND
  308.     _CONST double y)
  309. {
  310.   if (x > 0)
  311.     return exp (y * log (x));
  312.   else if (x == 0)
  313.     {
  314.       if (y > 0)
  315.     return 0.0;
  316.       else
  317.     {
  318.       double value;
  319.  
  320.       errno = EDOM;
  321.       __asm ("fmove%.d %#0rnan,%0"        /* quiet NaN */
  322.          : "=f" (value)
  323.          : /* no inputs */);
  324.       return value;
  325.     }
  326.     }
  327.   else
  328.     {
  329.       double temp;
  330.  
  331.       __asm ("fintrz%.x %1,%0"
  332.          : "=f" (temp)            /* integer-valued float */
  333.          : "f" (y));
  334.       if (y == temp)
  335.         {
  336.       int i = (int) y;
  337.       
  338.       if ((i & 1) == 0)            /* even */
  339.         return exp (y * log (x));
  340.       else
  341.         return - exp (y * log (x));
  342.         }
  343.       else
  344.         {
  345.       double value;
  346.  
  347.       errno = EDOM;
  348.       __asm ("fmove%.d %#0rnan,%0"        /* quiet NaN */
  349.          : "=f" (value)
  350.          : /* no inputs */);
  351.       return value;
  352.         }
  353.     }
  354. }
  355.  
  356. __inline static _CONST double 
  357. _DEFUN(fabs, (x),
  358.     double x)
  359. {
  360.   double value;
  361.  
  362.   __asm ("fabs%.x %1,%0"
  363.      : "=f" (value)
  364.      : "f" (x));
  365.   return value;
  366. }
  367.  
  368. __inline static _CONST double 
  369. _DEFUN(ceil, (x),
  370.     double x)
  371. {
  372.   int rounding_mode, round_up;
  373.   double value;
  374.  
  375.   __asm __volatile ("fmove%.l fpcr,%0"
  376.           : "=dm" (rounding_mode)
  377.           : /* no inputs */ );
  378.   round_up = rounding_mode | 0x30;
  379.   __asm __volatile ("fmove%.l %0,fpcr"
  380.           : /* no outputs */
  381.           : "dmi" (round_up));
  382.   __asm __volatile ("fint%.x %1,%0"
  383.           : "=f" (value)
  384.           : "f" (x));
  385.   __asm __volatile ("fmove%.l %0,fpcr"
  386.           : /* no outputs */
  387.           : "dmi" (rounding_mode));
  388.   return value;
  389. }
  390.  
  391. __inline static _CONST double 
  392. _DEFUN(floor, (x),
  393.     double x)
  394. {
  395.   int rounding_mode, round_down;
  396.   double value;
  397.  
  398.   __asm __volatile ("fmove%.l fpcr,%0"
  399.           : "=dm" (rounding_mode)
  400.           : /* no inputs */ );
  401.   round_down = (rounding_mode & ~0x10)
  402.         | 0x20;
  403.   __asm __volatile ("fmove%.l %0,fpcr"
  404.           : /* no outputs */
  405.           : "dmi" (round_down));
  406.   __asm __volatile ("fint%.x %1,%0"
  407.           : "=f" (value)
  408.           : "f" (x));
  409.   __asm __volatile ("fmove%.l %0,fpcr"
  410.           : /* no outputs */
  411.           : "dmi" (rounding_mode));
  412.   return value;
  413. }
  414.  
  415. __inline static _CONST double 
  416. _DEFUN(rint, (x),
  417.     double x)
  418. {
  419.   int rounding_mode, round_nearest;
  420.   double value;
  421.  
  422.   __asm __volatile ("fmove%.l fpcr,%0"
  423.           : "=dm" (rounding_mode)
  424.           : /* no inputs */ );
  425.   round_nearest = rounding_mode & ~0x30;
  426.   __asm __volatile ("fmove%.l %0,fpcr"
  427.           : /* no outputs */
  428.           : "dmi" (round_nearest));
  429.   __asm __volatile ("fint%.x %1,%0"
  430.           : "=f" (value)
  431.           : "f" (x));
  432.   __asm __volatile ("fmove%.l %0,fpcr"
  433.           : /* no outputs */
  434.           : "dmi" (rounding_mode));
  435.   return value;
  436. }
  437.  
  438. __inline static _CONST double 
  439. _DEFUN(fmod, (x, y),
  440.     double x _AND
  441.     double y)
  442. {
  443.   double value;
  444.  
  445.   __asm ("fmod%.x %2,%0"
  446.      : "=f" (value)
  447.      : "0" (x),
  448.        "f" (y));
  449.   return value;
  450. }
  451.  
  452. __inline static _CONST double 
  453. _DEFUN(drem, (x, y),
  454.     double x _AND
  455.     double y)
  456. {
  457.   double value;
  458.  
  459.   __asm ("frem%.x %2,%0"
  460.      : "=f" (value)
  461.      : "0" (x),
  462.        "f" (y));
  463.   return value;
  464. }
  465.  
  466. __inline static _CONST double 
  467. _DEFUN(scalb, (x, n),
  468.     double x