home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 4 / FreshFish_May-June1994.bin / gnu / lib / gcc-lib / amigados / 2.5.8 / include / math-68881.h < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  9.4 KB  |  556 lines

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