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 */ \
35 __inline static const double sin (double x)
39 __asm ("fsin%.x %1,%0"
45 __inline static const double cos (double x)
49 __asm ("fcos%.x %1,%0"
55 __inline static const double tan (double x)
59 __asm ("ftan%.x %1,%0"
65 __inline static const double asin (double x)
69 __asm ("fasin%.x %1,%0"
75 __inline static const double acos (double x)
79 __asm ("facos%.x %1,%0"
85 __inline static const double atan (double x)
89 __asm ("fatan%.x %1,%0"
95 __inline static const double atan2 (double y, double x)
99 __asm ("fmovecr%.x %#0,%0" /* extended precision pi */
102 __asm ("fscale%.b %#-1,%0" /* no loss of accuracy */
112 return pi_over_2 - atan (x / y);
119 return - pi_over_2 - atan (x / y);
127 return pi + atan (y / x);
129 return pi_over_2 - atan (x / y);
134 return - pi + atan (y / x);
136 return - pi_over_2 - atan (x / y);
142 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
151 __inline static const double sinh (double x)
155 __asm ("fsinh%.x %1,%0"
161 __inline static const double cosh (double x)
165 __asm ("fcosh%.x %1,%0"
171 __inline static const double tanh (double x)
175 __asm ("ftanh%.x %1,%0"
181 __inline static const double atanh (double x)
185 __asm ("fatanh%.x %1,%0"
191 __inline static const double exp (double x)
195 __asm ("fetox%.x %1,%0"
201 __inline static const double expm1 (double x)
205 __asm ("fetoxm1%.x %1,%0"
211 __inline static const double log (double x)
215 __asm ("flogn%.x %1,%0"
221 __inline static const double log1p (double x)
225 __asm ("flognp1%.x %1,%0"
231 __inline static const double log10 (double x)
235 __asm ("flog10%.x %1,%0"
241 __inline static const double sqrt (double x)
245 __asm ("fsqrt%.x %1,%0"
251 __inline static const double pow (const double x, const double y)
254 return exp (y * log (x));
264 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
274 __asm ("fintrz%.x %1,%0"
275 : "=f" (temp) /* integer-valued float */
281 if (i & 1 == 0) /* even */
282 return exp (y * log (x));
284 return - exp (y * log (x));
291 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
299 __inline static const double fabs (double x)
303 __asm ("fabs%.x %1,%0"
309 __inline static const double ceil (double x)
311 int rounding_mode, round_up;
314 __asm volatile ("fmove%.l %%fpcr,%0"
315 : "=dm" (rounding_mode)
317 round_up = rounding_mode | 0x30;
318 __asm volatile ("fmove%.l %0,%%fpcr"
321 __asm volatile ("fint%.x %1,%0"
324 __asm volatile ("fmove%.l %0,%%fpcr"
326 : "dmi" (rounding_mode));
330 __inline static const double floor (double x)
332 int rounding_mode, round_down;
335 __asm volatile ("fmove%.l %%fpcr,%0"
336 : "=dm" (rounding_mode)
338 round_down = (rounding_mode & ~0x10)
340 __asm volatile ("fmove%.l %0,%%fpcr"
342 : "dmi" (round_down));
343 __asm volatile ("fint%.x %1,%0"
346 __asm volatile ("fmove%.l %0,%%fpcr"
348 : "dmi" (rounding_mode));
352 __inline static const double rint (double x)
354 int rounding_mode, round_nearest;
357 __asm volatile ("fmove%.l %%fpcr,%0"
358 : "=dm" (rounding_mode)
360 round_nearest = rounding_mode & ~0x30;
361 __asm volatile ("fmove%.l %0,%%fpcr"
363 : "dmi" (round_nearest));
364 __asm volatile ("fint%.x %1,%0"
367 __asm volatile ("fmove%.l %0,%%fpcr"
369 : "dmi" (rounding_mode));
373 __inline static const double fmod (double x, double y)
377 __asm ("fmod%.x %2,%0"
384 __inline static const double drem (double x, double y)
388 __asm ("frem%.x %2,%0"
395 __inline static const double scalb (double x, int n)
399 __asm ("fscale%.l %2,%0"
406 __inline static double logb (double x)
410 __asm ("fgetexp%.x %1,%0"
416 __inline static const double ldexp (double x, int n)
420 __asm ("fscale%.l %2,%0"
427 __inline static double frexp (double x, int *exp)
429 double float_exponent;
433 __asm ("fgetexp%.x %1,%0"
434 : "=f" (float_exponent) /* integer-valued float */
436 int_exponent = (int) float_exponent;
437 __asm ("fgetman%.x %1,%0"
438 : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */
442 __asm ("fscale%.b %#-1,%0"
443 : "=f" (mantissa) /* mantissa /= 2.0 */
451 __inline static double modf (double x, double *ip)
455 __asm ("fintrz%.x %1,%0"
456 : "=f" (temp) /* integer-valued float */