1 /******************************************************************\
3 * <math-68881.h> last modified: 23 May 1992. *
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 \******************************************************************/
22 /* This file is NOT a part of GCC, just distributed with it. */
24 /* If you find this in GCC,
25 please send bug reports to bug-gcc@prep.ai.mit.edu. */
27 /* Changed by Richard Stallman:
28 May 1993, add conditional to prevent multiple inclusion.
29 % inserted before a #.
30 New function `hypot' added.
31 Nans written in hex to avoid 0rnan.
32 May 1992, use %! for fpcr register. Break lines before function names.
33 December 1989, add parens around `&' in pow.
34 November 1990, added alternate definition of HUGE_VAL for Sun. */
36 /* Changed by Jim Wilson:
37 September 1993, Use #undef before HUGE_VAL instead of #ifdef/#endif. */
39 /* Changed by Ian Lance Taylor:
40 September 1994, use extern inline instead of static inline. */
49 /* The Sun assembler fails to handle the hex constant in the usual defn. */
52 static union { int i[2]; double d; } u = { {0x7ff00000, 0} }; \
60 __asm ("fmove%.d #0x7ff0000000000000,%0" /* Infinity */ \
67 __inline
extern double
72 __asm ("fsin%.x %1,%0"
78 __inline
extern double
83 __asm ("fcos%.x %1,%0"
89 __inline
extern double
94 __asm ("ftan%.x %1,%0"
100 __inline
extern double
105 __asm ("fasin%.x %1,%0"
111 __inline
extern double
116 __asm ("facos%.x %1,%0"
122 __inline
extern double
127 __asm ("fatan%.x %1,%0"
133 __inline
extern double
134 atan2 (double y
, double x
)
136 double pi
, pi_over_2
;
138 __asm ("fmovecr%.x #0,%0" /* extended precision pi */
141 __asm ("fscale%.b #-1,%0" /* no loss of accuracy */
151 return pi_over_2
- atan (x
/ y
);
158 return - pi_over_2
- atan (x
/ y
);
166 return - pi
+ atan (y
/ x
);
168 return - pi_over_2
- atan (x
/ y
);
173 return pi
+ atan (y
/ x
);
175 return pi_over_2
- atan (x
/ y
);
181 __asm ("fmove%.d #0x7fffffffffffffff,%0" /* quiet NaN */
190 __inline
extern double
195 __asm ("fsinh%.x %1,%0"
201 __inline
extern double
206 __asm ("fcosh%.x %1,%0"
212 __inline
extern double
217 __asm ("ftanh%.x %1,%0"
223 __inline
extern double
228 __asm ("fatanh%.x %1,%0"
234 __inline
extern double
239 __asm ("fetox%.x %1,%0"
245 __inline
extern double
250 __asm ("fetoxm1%.x %1,%0"
256 __inline
extern double
261 __asm ("flogn%.x %1,%0"
267 __inline
extern double
272 __asm ("flognp1%.x %1,%0"
278 __inline
extern double
283 __asm ("flog10%.x %1,%0"
289 __inline
extern double
294 __asm ("fsqrt%.x %1,%0"
300 __inline
extern double
301 hypot (double x
, double y
)
303 return sqrt (x
*x
+ y
*y
);
306 __inline
extern double
307 pow (double x
, double y
)
310 return exp (y
* log (x
));
320 __asm ("fmove%.d #0x7fffffffffffffff,%0" /* quiet NaN */
330 __asm ("fintrz%.x %1,%0"
331 : "=f" (temp
) /* integer-valued float */
337 if ((i
& 1) == 0) /* even */
338 return exp (y
* log (-x
));
340 return - exp (y
* log (-x
));
347 __asm ("fmove%.d #0x7fffffffffffffff,%0" /* quiet NaN */
355 __inline
extern double
360 __asm ("fabs%.x %1,%0"
366 __inline
extern double
369 int rounding_mode
, round_up
;
372 __asm
volatile ("fmove%.l %!,%0"
373 : "=dm" (rounding_mode
)
375 round_up
= rounding_mode
| 0x30;
376 __asm
volatile ("fmove%.l %0,%!"
379 __asm
volatile ("fint%.x %1,%0"
382 __asm
volatile ("fmove%.l %0,%!"
384 : "dmi" (rounding_mode
));
388 __inline
extern double
391 int rounding_mode
, round_down
;
394 __asm
volatile ("fmove%.l %!,%0"
395 : "=dm" (rounding_mode
)
397 round_down
= (rounding_mode
& ~0x10)
399 __asm
volatile ("fmove%.l %0,%!"
401 : "dmi" (round_down
));
402 __asm
volatile ("fint%.x %1,%0"
405 __asm
volatile ("fmove%.l %0,%!"
407 : "dmi" (rounding_mode
));
411 __inline
extern double
414 int rounding_mode
, round_nearest
;
417 __asm
volatile ("fmove%.l %!,%0"
418 : "=dm" (rounding_mode
)
420 round_nearest
= rounding_mode
& ~0x30;
421 __asm
volatile ("fmove%.l %0,%!"
423 : "dmi" (round_nearest
));
424 __asm
volatile ("fint%.x %1,%0"
427 __asm
volatile ("fmove%.l %0,%!"
429 : "dmi" (rounding_mode
));
433 __inline
extern double
434 fmod (double x
, double y
)
438 __asm ("fmod%.x %2,%0"
445 __inline
extern double
446 drem (double x
, double y
)
450 __asm ("frem%.x %2,%0"
457 __inline
extern double
458 scalb (double x
, int n
)
462 __asm ("fscale%.l %2,%0"
469 __inline
extern double
474 __asm ("fgetexp%.x %1,%0"
480 __inline
extern double
481 ldexp (double x
, int n
)
485 __asm ("fscale%.l %2,%0"
492 __inline
extern double
493 frexp (double x
, int *exp
)
495 double float_exponent
;
499 __asm ("fgetexp%.x %1,%0"
500 : "=f" (float_exponent
) /* integer-valued float */
502 int_exponent
= (int) float_exponent
;
503 __asm ("fgetman%.x %1,%0"
504 : "=f" (mantissa
) /* 1.0 <= mantissa < 2.0 */
508 __asm ("fscale%.b #-1,%0"
509 : "=f" (mantissa
) /* mantissa /= 2.0 */
517 __inline
extern double
518 modf (double x
, double *ip
)
522 __asm ("fintrz%.x %1,%0"
523 : "=f" (temp
) /* integer-valued float */
529 #endif /* not __math_68881 */