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 */