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 /* If you find this in GCC,
23 please send bug reports to bug-gcc@prep.ai.mit.edu. */
25 /* Changed by Richard Stallman: % inserted before a #.
26 New function `hypot' added.
27 Nans written in hex to avoid 0rnan.
28 May 1992, use %! for fpcr register. Break lines before function names.
29 December 1989, add parens around `&' in pow.
30 November 1990, added alternate definition of HUGE_VAL for Sun. */
36 /* The Sun assembler fails to handle the hex constant in the usual defn. */
39 static union { int i[2]; double d; } u = { {0x7ff00000, 0} }; \
47 __asm ("fmove%.d %#0x7ff0000000000000,%0" /* Infinity */ \
55 __inline static const double
60 __asm ("fsin%.x %1,%0"
66 __inline static const double
71 __asm ("fcos%.x %1,%0"
77 __inline static const double
82 __asm ("ftan%.x %1,%0"
88 __inline static const double
93 __asm ("fasin%.x %1,%0"
99 __inline static const double
104 __asm ("facos%.x %1,%0"
110 __inline static const double
115 __asm ("fatan%.x %1,%0"
121 __inline static const double
122 atan2 (double y, double x)
124 double pi, pi_over_2;
126 __asm ("fmovecr%.x %#0,%0" /* extended precision pi */
129 __asm ("fscale%.b %#-1,%0" /* no loss of accuracy */
139 return pi_over_2 - atan (x / y);
146 return - pi_over_2 - atan (x / y);
154 return pi + atan (y / x);
156 return pi_over_2 - atan (x / y);
161 return - pi + atan (y / x);
163 return - pi_over_2 - atan (x / y);
169 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
178 __inline static const double
183 __asm ("fsinh%.x %1,%0"
189 __inline static const double
194 __asm ("fcosh%.x %1,%0"
200 __inline static const double
205 __asm ("ftanh%.x %1,%0"
211 __inline static const double
216 __asm ("fatanh%.x %1,%0"
222 __inline static const double
227 __asm ("fetox%.x %1,%0"
233 __inline static const double
238 __asm ("fetoxm1%.x %1,%0"
244 __inline static const double
249 __asm ("flogn%.x %1,%0"
255 __inline static const double
260 __asm ("flognp1%.x %1,%0"
266 __inline static const double
271 __asm ("flog10%.x %1,%0"
277 __inline static const double
282 __asm ("fsqrt%.x %1,%0"
288 __inline static const double
289 hypot (const double x, const double y)
291 return sqrt (x*x + y*y);
294 __inline static const double
295 pow (const double x, const double y)
298 return exp (y * log (x));
308 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
318 __asm ("fintrz%.x %1,%0"
319 : "=f" (temp) /* integer-valued float */
325 if ((i & 1) == 0) /* even */
326 return exp (y * log (-x));
328 return - exp (y * log (-x));
335 __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */
343 __inline static const double
348 __asm ("fabs%.x %1,%0"
354 __inline static const double
357 int rounding_mode, round_up;
360 __asm volatile ("fmove%.l %!,%0"
361 : "=dm" (rounding_mode)
363 round_up = rounding_mode | 0x30;
364 __asm volatile ("fmove%.l %0,%!"
367 __asm volatile ("fint%.x %1,%0"
370 __asm volatile ("fmove%.l %0,%!"
372 : "dmi" (rounding_mode));
376 __inline static const double
379 int rounding_mode, round_down;
382 __asm volatile ("fmove%.l %!,%0"
383 : "=dm" (rounding_mode)
385 round_down = (rounding_mode & ~0x10)
387 __asm volatile ("fmove%.l %0,%!"
389 : "dmi" (round_down));
390 __asm volatile ("fint%.x %1,%0"
393 __asm volatile ("fmove%.l %0,%!"
395 : "dmi" (rounding_mode));
399 __inline static const double
402 int rounding_mode, round_nearest;
405 __asm volatile ("fmove%.l %!,%0"
406 : "=dm" (rounding_mode)
408 round_nearest = rounding_mode & ~0x30;
409 __asm volatile ("fmove%.l %0,%!"
411 : "dmi" (round_nearest));
412 __asm volatile ("fint%.x %1,%0"
415 __asm volatile ("fmove%.l %0,%!"
417 : "dmi" (rounding_mode));
421 __inline static const double
422 fmod (double x, double y)
426 __asm ("fmod%.x %2,%0"
433 __inline static const double
434 drem (double x, double y)
438 __asm ("frem%.x %2,%0"
445 __inline static const double
446 scalb (double x, int n)
450 __asm ("fscale%.l %2,%0"
457 __inline static double
462 __asm ("fgetexp%.x %1,%0"
468 __inline static const double
469 ldexp (double x, int n)
473 __asm ("fscale%.l %2,%0"
480 __inline static double
481 frexp (double x, int *exp)
483 double float_exponent;
487 __asm ("fgetexp%.x %1,%0"
488 : "=f" (float_exponent) /* integer-valued float */
490 int_exponent = (int) float_exponent;
491 __asm ("fgetman%.x %1,%0"
492 : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */
496 __asm ("fscale%.b %#-1,%0"
497 : "=f" (mantissa) /* mantissa /= 2.0 */
505 __inline static double
506 modf (double x, double *ip)
510 __asm ("fintrz%.x %1,%0"
511 : "=f" (temp) /* integer-valued float */