1 /******************************************************************\
3 * <math-68881.h> last modified: 18 May 1989. *
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. *
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. *
18 * Send bugs to Matthew Self (self@bayes.arc.nasa.gov). *
20 \******************************************************************/
29 __asm ("fmove%.d %#0x7ff0000000000000,%0" /* Infinity */ \
36 __inline static const double sin (double x)
40 __asm ("fsin%.x %1,%0"
46 __inline static const double cos (double x)
50 __asm ("fcos%.x %1,%0"
56 __inline static const double tan (double x)
60 __asm ("ftan%.x %1,%0"
66 __inline static const double asin (double x)
70 __asm ("fasin%.x %1,%0"
76 __inline static const double acos (double x)
80 __asm ("facos%.x %1,%0"
86 __inline static const double atan (double x)
90 __asm ("fatan%.x %1,%0"
96 __inline static const double atan2 (double y, double x)
100 __asm ("fmovecr%.x %#0,%0" /* extended precision pi */
103 __asm ("fscale%.b %#-1,%0" /* no loss of accuracy */
113 return pi_over_2 - atan (x / y);
120 return - pi_over_2 - atan (x / y);
128 return pi + atan (y / x);
130 return pi_over_2 - atan (x / y);
135 return - pi + atan (y / x);
137 return - pi_over_2 - atan (x / y);
143 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
152 __inline static const double sinh (double x)
156 __asm ("fsinh%.x %1,%0"
162 __inline static const double cosh (double x)
166 __asm ("fcosh%.x %1,%0"
172 __inline static const double tanh (double x)
176 __asm ("ftanh%.x %1,%0"
182 __inline static const double atanh (double x)
186 __asm ("fatanh%.x %1,%0"
192 __inline static const double exp (double x)
196 __asm ("fetox%.x %1,%0"
202 __inline static const double expm1 (double x)
206 __asm ("fetoxm1%.x %1,%0"
212 __inline static const double log (double x)
216 __asm ("flogn%.x %1,%0"
222 __inline static const double log1p (double x)
226 __asm ("flognp1%.x %1,%0"
232 __inline static const double log10 (double x)
236 __asm ("flog10%.x %1,%0"
242 __inline static const double sqrt (double x)
246 __asm ("fsqrt%.x %1,%0"
252 __inline static const double pow (const double x, const double y)
255 return exp (y * log (x));
265 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
275 __asm ("fintrz%.x %1,%0"
276 : "=f" (temp) /* integer-valued float */
282 if (i & 1 == 0) /* even */
283 return exp (y * log (x));
285 return - exp (y * log (x));
292 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
300 __inline static const double fabs (double x)
304 __asm ("fabs%.x %1,%0"
310 __inline static const double ceil (double x)
312 int rounding_mode, round_up;
315 __asm volatile ("fmove%.l %%fpcr,%0"
316 : "=dm" (rounding_mode)
318 round_up = rounding_mode | 0x30;
319 __asm volatile ("fmove%.l %0,%%fpcr"
322 __asm volatile ("fint%.x %1,%0"
325 __asm volatile ("fmove%.l %0,%%fpcr"
327 : "dmi" (rounding_mode));
331 __inline static const double floor (double x)
333 int rounding_mode, round_down;
336 __asm volatile ("fmove%.l %%fpcr,%0"
337 : "=dm" (rounding_mode)
339 round_down = (rounding_mode & ~0x10)
341 __asm volatile ("fmove%.l %0,%%fpcr"
343 : "dmi" (round_down));
344 __asm volatile ("fint%.x %1,%0"
347 __asm volatile ("fmove%.l %0,%%fpcr"
349 : "dmi" (rounding_mode));
353 __inline static const double rint (double x)
355 int rounding_mode, round_nearest;
358 __asm volatile ("fmove%.l %%fpcr,%0"
359 : "=dm" (rounding_mode)
361 round_nearest = rounding_mode & ~0x30;
362 __asm volatile ("fmove%.l %0,%%fpcr"
364 : "dmi" (round_nearest));
365 __asm volatile ("fint%.x %1,%0"
368 __asm volatile ("fmove%.l %0,%%fpcr"
370 : "dmi" (rounding_mode));
374 __inline static const double fmod (double x, double y)
378 __asm ("fmod%.x %2,%0"
385 __inline static const double drem (double x, double y)
389 __asm ("frem%.x %2,%0"
396 __inline static const double scalb (double x, int n)
400 __asm ("fscale%.l %2,%0"
407 __inline static double logb (double x)
411 __asm ("fgetexp%.x %1,%0"
417 __inline static const double ldexp (double x, int n)
421 __asm ("fscale%.l %2,%0"
428 __inline static double frexp (double x, int *exp)
430 double float_exponent;
434 __asm ("fgetexp%.x %1,%0"
435 : "=f" (float_exponent) /* integer-valued float */
437 int_exponent = (int) float_exponent;
438 __asm ("fgetman%.x %1,%0"
439 : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */
443 __asm ("fscale%.b %#-1,%0"
444 : "=f" (mantissa) /* mantissa /= 2.0 */
452 __inline static double modf (double x, double *ip)
456 __asm ("fintrz%.x %1,%0"
457 : "=f" (temp) /* integer-valued float */