From ab3b0e51e9f71696232c49745bc6b7c027f39d73 Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Thu, 2 May 1991 18:44:28 +0000 Subject: [PATCH] Initial revision From-SVN: r19 --- gcc/ginclude/math-68881.h | 482 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 482 insertions(+) create mode 100644 gcc/ginclude/math-68881.h diff --git a/gcc/ginclude/math-68881.h b/gcc/ginclude/math-68881.h new file mode 100644 index 00000000000..e51cdf8c511 --- /dev/null +++ b/gcc/ginclude/math-68881.h @@ -0,0 +1,482 @@ +/******************************************************************\ +* * +* last modified: 18 May 1989. * +* * +* Copyright (C) 1989 by Matthew Self. * +* You may freely distribute verbatim copies of this software * +* provided that this copyright notice is retained in all copies. * +* You may distribute modifications to this software under the * +* conditions above if you also clearly note such modifications * +* with their author and date. * +* * +* Note: errno is not set to EDOM when domain errors occur for * +* most of these functions. Rather, it is assumed that the * +* 68881's OPERR exception will be enabled and handled * +* appropriately by the operating system. Similarly, overflow * +* and underflow do not set errno to ERANGE. * +* * +* Send bugs to Matthew Self (self@bayes.arc.nasa.gov). * +* * +\******************************************************************/ + +/* Changed by Richard Stallman: % inserted before a #. + New function `hypot' added. + Nans written in hex to avoid 0rnan. + December 1989, add parens around `&' in pow. + November 1990, added alternate definition of HUGE_VAL for Sun. */ + +#include + +#ifndef HUGE_VAL +#ifdef __sun__ +/* The Sun assembler fails to handle the hex constant in the usual defn. */ +#define HUGE_VAL \ +({ \ + static union { int i[2]; double d; } u = { {0x7ff00000, 0} }; \ + u.d; \ +}) +#else +#define HUGE_VAL \ +({ \ + double huge_val; \ + \ + __asm ("fmove%.d %#0x7ff0000000000000,%0" /* Infinity */ \ + : "=f" (huge_val) \ + : /* no inputs */); \ + huge_val; \ +}) +#endif +#endif + +__inline static const double sin (double x) +{ + double value; + + __asm ("fsin%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double cos (double x) +{ + double value; + + __asm ("fcos%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double tan (double x) +{ + double value; + + __asm ("ftan%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double asin (double x) +{ + double value; + + __asm ("fasin%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double acos (double x) +{ + double value; + + __asm ("facos%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double atan (double x) +{ + double value; + + __asm ("fatan%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double atan2 (double y, double x) +{ + double pi, pi_over_2; + + __asm ("fmovecr%.x %#0,%0" /* extended precision pi */ + : "=f" (pi) + : /* no inputs */ ); + __asm ("fscale%.b %#-1,%0" /* no loss of accuracy */ + : "=f" (pi_over_2) + : "0" (pi)); + if (x > 0) + { + if (y > 0) + { + if (x > y) + return atan (y / x); + else + return pi_over_2 - atan (x / y); + } + else + { + if (x > -y) + return atan (y / x); + else + return - pi_over_2 - atan (x / y); + } + } + else + { + if (y > 0) + { + if (-x > y) + return pi + atan (y / x); + else + return pi_over_2 - atan (x / y); + } + else + { + if (-x > -y) + return - pi + atan (y / x); + else if (y < 0) + return - pi_over_2 - atan (x / y); + else + { + double value; + + errno = EDOM; + __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */ + : "=f" (value) + : /* no inputs */); + return value; + } + } + } +} + +__inline static const double sinh (double x) +{ + double value; + + __asm ("fsinh%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double cosh (double x) +{ + double value; + + __asm ("fcosh%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double tanh (double x) +{ + double value; + + __asm ("ftanh%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double atanh (double x) +{ + double value; + + __asm ("fatanh%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double exp (double x) +{ + double value; + + __asm ("fetox%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double expm1 (double x) +{ + double value; + + __asm ("fetoxm1%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double log (double x) +{ + double value; + + __asm ("flogn%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double log1p (double x) +{ + double value; + + __asm ("flognp1%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double log10 (double x) +{ + double value; + + __asm ("flog10%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double sqrt (double x) +{ + double value; + + __asm ("fsqrt%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double hypot (const double x, const double y) +{ + return sqrt (x*x + y*y); +} + +__inline static const double pow (const double x, const double y) +{ + if (x > 0) + return exp (y * log (x)); + else if (x == 0) + { + if (y > 0) + return 0.0; + else + { + double value; + + errno = EDOM; + __asm ("fmove%.d %#07fffffffffffffff,%0" /* quiet NaN */ + : "=f" (value) + : /* no inputs */); + return value; + } + } + else + { + double temp; + + __asm ("fintrz%.x %1,%0" + : "=f" (temp) /* integer-valued float */ + : "f" (y)); + if (y == temp) + { + int i = (int) y; + + if (i & 1 == 0) /* even */ + return exp (y * log (-x)); + else + return - exp (y * log (-x)); + } + else + { + double value; + + errno = EDOM; + __asm ("fmove%.d %#0x7fffffffffffffff,%0" /* quiet NaN */ + : "=f" (value) + : /* no inputs */); + return value; + } + } +} + +__inline static const double fabs (double x) +{ + double value; + + __asm ("fabs%.x %1,%0" + : "=f" (value) + : "f" (x)); + return value; +} + +__inline static const double ceil (double x) +{ + int rounding_mode, round_up; + double value; + + __asm volatile ("fmove%.l fpcr,%0" + : "=dm" (rounding_mode) + : /* no inputs */ ); + round_up = rounding_mode | 0x30; + __asm volatile ("fmove%.l %0,fpcr" + : /* no outputs */ + : "dmi" (round_up)); + __asm volatile ("fint%.x %1,%0" + : "=f" (value) + : "f" (x)); + __asm volatile ("fmove%.l %0,fpcr" + : /* no outputs */ + : "dmi" (rounding_mode)); + return value; +} + +__inline static const double floor (double x) +{ + int rounding_mode, round_down; + double value; + + __asm volatile ("fmove%.l fpcr,%0" + : "=dm" (rounding_mode) + : /* no inputs */ ); + round_down = (rounding_mode & ~0x10) + | 0x20; + __asm volatile ("fmove%.l %0,fpcr" + : /* no outputs */ + : "dmi" (round_down)); + __asm volatile ("fint%.x %1,%0" + : "=f" (value) + : "f" (x)); + __asm volatile ("fmove%.l %0,fpcr" + : /* no outputs */ + : "dmi" (rounding_mode)); + return value; +} + +__inline static const double rint (double x) +{ + int rounding_mode, round_nearest; + double value; + + __asm volatile ("fmove%.l fpcr,%0" + : "=dm" (rounding_mode) + : /* no inputs */ ); + round_nearest = rounding_mode & ~0x30; + __asm volatile ("fmove%.l %0,fpcr" + : /* no outputs */ + : "dmi" (round_nearest)); + __asm volatile ("fint%.x %1,%0" + : "=f" (value) + : "f" (x)); + __asm volatile ("fmove%.l %0,fpcr" + : /* no outputs */ + : "dmi" (rounding_mode)); + return value; +} + +__inline static const double fmod (double x, double y) +{ + double value; + + __asm ("fmod%.x %2,%0" + : "=f" (value) + : "0" (x), + "f" (y)); + return value; +} + +__inline static const double drem (double x, double y) +{ + double value; + + __asm ("frem%.x %2,%0" + : "=f" (value) + : "0" (x), + "f" (y)); + return value; +} + +__inline static const double scalb (double x, int n) +{ + double value; + + __asm ("fscale%.l %2,%0" + : "=f" (value) + : "0" (x), + "dmi" (n)); + return value; +} + +__inline static double logb (double x) +{ + double exponent; + + __asm ("fgetexp%.x %1,%0" + : "=f" (exponent) + : "f" (x)); + return exponent; +} + +__inline static const double ldexp (double x, int n) +{ + double value; + + __asm ("fscale%.l %2,%0" + : "=f" (value) + : "0" (x), + "dmi" (n)); + return value; +} + +__inline static double frexp (double x, int *exp) +{ + double float_exponent; + int int_exponent; + double mantissa; + + __asm ("fgetexp%.x %1,%0" + : "=f" (float_exponent) /* integer-valued float */ + : "f" (x)); + int_exponent = (int) float_exponent; + __asm ("fgetman%.x %1,%0" + : "=f" (mantissa) /* 1.0 <= mantissa < 2.0 */ + : "f" (x)); + if (mantissa != 0) + { + __asm ("fscale%.b %#-1,%0" + : "=f" (mantissa) /* mantissa /= 2.0 */ + : "0" (mantissa)); + int_exponent += 1; + } + *exp = int_exponent; + return mantissa; +} + +__inline static double modf (double x, double *ip) +{ + double temp; + + __asm ("fintrz%.x %1,%0" + : "=f" (temp) /* integer-valued float */ + : "f" (x)); + *ip = temp; + return x - temp; +} + -- 2.30.2