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