diff options
-rw-r--r-- | include/complex.h | 107 | ||||
-rw-r--r-- | include/fpu_control.h | 98 | ||||
-rw-r--r-- | include/tgmath.h | 430 | ||||
-rw-r--r-- | libm/Makefile | 2 | ||||
-rw-r--r-- | libm/fpmacros.c | 108 | ||||
-rw-r--r-- | libm/nan.c | 48 |
6 files changed, 747 insertions, 46 deletions
diff --git a/include/complex.h b/include/complex.h new file mode 100644 index 000000000..f005a9391 --- /dev/null +++ b/include/complex.h @@ -0,0 +1,107 @@ +/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* + * ISO C99: 7.3 Complex arithmetic <complex.h> + */ + +#ifndef _COMPLEX_H +#define _COMPLEX_H 1 + +#include <features.h> + +/* Get general and ISO C99 specific information. */ +#include <bits/mathdef.h> + +__BEGIN_DECLS + +/* We might need to add support for more compilers here. But since ISO + C99 is out hopefully all maintained compilers will soon provide the data + types `float complex' and `double complex'. */ +#if __GNUC_PREREQ (2, 7) && !__GNUC_PREREQ (2, 97) +# define _Complex __complex__ +#endif + +#define complex _Complex + +/* Narrowest imaginary unit. This depends on the floating-point + evaluation method. + XXX This probably has to go into a gcc related file. */ +#define _Complex_I (__extension__ 1.0iF) + +/* Another more descriptive name is `I'. + XXX Once we have the imaginary support switch this to _Imaginary_I. */ +#undef I +#define I _Complex_I + +/* The file <bits/cmathcalls.h> contains the prototypes for all the + actual math functions. These macros are used for those prototypes, + so we can easily declare each function as both `name' and `__name', + and can declare the float versions `namef' and `__namef'. */ + +#define __MATHCALL(function, args) \ + __MATHDECL (_Mdouble_complex_,function, args) +#define __MATHDECL(type, function, args) \ + __MATHDECL_1(type, function, args); \ + __MATHDECL_1(type, __CONCAT(__,function), args) +#define __MATHDECL_1(type, function, args) \ + extern type __MATH_PRECNAME(function) args __THROW + +#define _Mdouble_ double +#define __MATH_PRECNAME(name) name +#include <bits/cmathcalls.h> +#undef _Mdouble_ +#undef __MATH_PRECNAME + +/* Now the float versions. */ +#ifndef _Mfloat_ +# define _Mfloat_ float +#endif +#define _Mdouble_ _Mfloat_ +#ifdef __STDC__ +# define __MATH_PRECNAME(name) name##f +#else +# define __MATH_PRECNAME(name) name/**/f +#endif +#include <bits/cmathcalls.h> +#undef _Mdouble_ +#undef __MATH_PRECNAME + +/* And the long double versions. It is non-critical to define them + here unconditionally since `long double' is required in ISO C99. */ +#if __STDC__ - 0 || __GNUC__ - 0 && !defined __NO_LONG_DOUBLE_MATH +# ifndef _Mlong_double_ +# define _Mlong_double_ long double +# endif +# define _Mdouble_ _Mlong_double_ +# ifdef __STDC__ +# define __MATH_PRECNAME(name) name##l +# else +# define __MATH_PRECNAME(name) name/**/l +# endif +# include <bits/cmathcalls.h> +#endif +#undef _Mdouble_ +#undef __MATH_PRECNAME +#undef __MATHDECL_1 +#undef __MATHDECL +#undef __MATHCALL + +__END_DECLS + +#endif /* complex.h */ diff --git a/include/fpu_control.h b/include/fpu_control.h new file mode 100644 index 000000000..ed9bf388a --- /dev/null +++ b/include/fpu_control.h @@ -0,0 +1,98 @@ +/* FPU control word bits. i387 version. + Copyright (C) 1993,1995,1996,1997,1998,2000,2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Olaf Flebbe. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H 1 + +/* Here is the dirty part. Set up your 387 through the control word + * (cw) register. + * + * 15-13 12 11-10 9-8 7-6 5 4 3 2 1 0 + * | reserved | IC | RC | PC | reserved | PM | UM | OM | ZM | DM | IM + * + * IM: Invalid operation mask + * DM: Denormalized operand mask + * ZM: Zero-divide mask + * OM: Overflow mask + * UM: Underflow mask + * PM: Precision (inexact result) mask + * + * Mask bit is 1 means no interrupt. + * + * PC: Precision control + * 11 - round to extended precision + * 10 - round to double precision + * 00 - round to single precision + * + * RC: Rounding control + * 00 - rounding to nearest + * 01 - rounding down (toward - infinity) + * 10 - rounding up (toward + infinity) + * 11 - rounding toward zero + * + * IC: Infinity control + * That is for 8087 and 80287 only. + * + * The hardware default is 0x037f which we use. + */ + +#include <features.h> + +/* masking of interrupts */ +#define _FPU_MASK_IM 0x01 +#define _FPU_MASK_DM 0x02 +#define _FPU_MASK_ZM 0x04 +#define _FPU_MASK_OM 0x08 +#define _FPU_MASK_UM 0x10 +#define _FPU_MASK_PM 0x20 + +/* precision control */ +#define _FPU_EXTENDED 0x300 /* libm requires double extended precision. */ +#define _FPU_DOUBLE 0x200 +#define _FPU_SINGLE 0x0 + +/* rounding control */ +#define _FPU_RC_NEAREST 0x0 /* RECOMMENDED */ +#define _FPU_RC_DOWN 0x400 +#define _FPU_RC_UP 0x800 +#define _FPU_RC_ZERO 0xC00 + +#define _FPU_RESERVED 0xF0C0 /* Reserved bits in cw */ + + +/* The fdlibm code requires strict IEEE double precision arithmetic, + and no interrupts for exceptions, rounding to nearest. */ + +#define _FPU_DEFAULT 0x037f + +/* IEEE: same as above. */ +#define _FPU_IEEE 0x037f + +/* Type of the control word. */ +typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__HI__))); + +/* Macros for accessing the hardware control word. */ +#define _FPU_GETCW(cw) __asm__ ("fnstcw %0" : "=m" (*&cw)) +#define _FPU_SETCW(cw) __asm__ ("fldcw %0" : : "m" (*&cw)) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif /* fpu_control.h */ diff --git a/include/tgmath.h b/include/tgmath.h new file mode 100644 index 000000000..5fb683fef --- /dev/null +++ b/include/tgmath.h @@ -0,0 +1,430 @@ +/* Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* + * ISO C99 Standard: 7.22 Type-generic math <tgmath.h> + */ + +#ifndef _TGMATH_H +#define _TGMATH_H 1 + +/* Include the needed headers. */ +#include <math.h> +#include <complex.h> + + +/* Since `complex' is currently not really implemented in most C compilers + and if it is implemented, the implementations differ. This makes it + quite difficult to write a generic implementation of this header. We + do not try this for now and instead concentrate only on GNU CC. Once + we have more information support for other compilers might follow. */ + +#if __GNUC_PREREQ (2, 7) + +# ifdef __NO_LONG_DOUBLE_MATH +# define __tgml(fct) fct +# else +# define __tgml(fct) fct ## l +# endif + +/* This is ugly but unless gcc gets appropriate builtins we have to do + something like this. Don't ask how it works. */ + +/* 1 if 'type' is a floating type, 0 if 'type' is an integer type. + Allows for _Bool. Expands to an integer constant expression. */ +# define __floating_type(type) (((type) 0.25) && ((type) 0.25 - 1)) + +/* The tgmath real type for T, where E is 0 if T is an integer type and + 1 for a floating type. */ +# define __tgmath_real_type_sub(T, E) \ + __typeof__(*(0 ? (__typeof__ (0 ? (double *) 0 : (void *) (E))) 0 \ + : (__typeof__ (0 ? (T *) 0 : (void *) (!(E)))) 0)) + +/* The tgmath real type of EXPR. */ +# define __tgmath_real_type(expr) \ + __tgmath_real_type_sub(__typeof__(expr), __floating_type(__typeof__(expr))) + + +/* We have two kinds of generic macros: to support functions which are + only defined on real valued parameters and those which are defined + for complex functions as well. */ +# define __TGMATH_UNARY_REAL_ONLY(Val, Fct) \ + (__extension__ ({ __tgmath_real_type (Val) __tgmres; \ + if (sizeof (Val) == sizeof (double) \ + || __builtin_classify_type (Val) != 8) \ + __tgmres = Fct (Val); \ + else if (sizeof (Val) == sizeof (float)) \ + __tgmres = Fct##f (Val); \ + else \ + __tgmres = __tgml(Fct) (Val); \ + __tgmres; })) + +# define __TGMATH_BINARY_FIRST_REAL_ONLY(Val1, Val2, Fct) \ + (__extension__ ({ __tgmath_real_type (Val1) __tgmres; \ + if (sizeof (Val1) == sizeof (double) \ + || __builtin_classify_type (Val1) != 8) \ + __tgmres = Fct (Val1, Val2); \ + else if (sizeof (Val1) == sizeof (float)) \ + __tgmres = Fct##f (Val1, Val2); \ + else \ + __tgmres = __tgml(Fct) (Val1, Val2); \ + __tgmres; })) + +# define __TGMATH_BINARY_REAL_ONLY(Val1, Val2, Fct) \ + (__extension__ ({ __tgmath_real_type ((Val1) + (Val2)) __tgmres; \ + if ((sizeof (Val1) > sizeof (double) \ + || sizeof (Val2) > sizeof (double)) \ + && __builtin_classify_type ((Val1) + (Val2)) == 8) \ + __tgmres = __tgml(Fct) (Val1, Val2); \ + else if (sizeof (Val1) == sizeof (double) \ + || sizeof (Val2) == sizeof (double) \ + || __builtin_classify_type (Val1) != 8 \ + || __builtin_classify_type (Val2) != 8) \ + __tgmres = Fct (Val1, Val2); \ + else \ + __tgmres = Fct##f (Val1, Val2); \ + __tgmres; })) + +# define __TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY(Val1, Val2, Val3, Fct) \ + (__extension__ ({ __tgmath_real_type ((Val1) + (Val2)) __tgmres; \ + if ((sizeof (Val1) > sizeof (double) \ + || sizeof (Val2) > sizeof (double)) \ + && __builtin_classify_type ((Val1) + (Val2)) == 8) \ + __tgmres = __tgml(Fct) (Val1, Val2, Val3); \ + else if (sizeof (Val1) == sizeof (double) \ + || sizeof (Val2) == sizeof (double) \ + || __builtin_classify_type (Val1) != 8 \ + || __builtin_classify_type (Val2) != 8) \ + __tgmres = Fct (Val1, Val2, Val3); \ + else \ + __tgmres = Fct##f (Val1, Val2, Val3); \ + __tgmres; })) + +# define __TGMATH_TERNARY_REAL_ONLY(Val1, Val2, Val3, Fct) \ + (__extension__ ({ __tgmath_real_type ((Val1) + (Val2) + (Val3)) __tgmres;\ + if ((sizeof (Val1) > sizeof (double) \ + || sizeof (Val2) > sizeof (double) \ + || sizeof (Val3) > sizeof (double)) \ + && __builtin_classify_type ((Val1) + (Val2) \ + + (Val3)) == 8) \ + __tgmres = __tgml(Fct) (Val1, Val2, Val3); \ + else if (sizeof (Val1) == sizeof (double) \ + || sizeof (Val2) == sizeof (double) \ + || sizeof (Val3) == sizeof (double) \ + || __builtin_classify_type (Val1) != 8 \ + || __builtin_classify_type (Val2) != 8 \ + || __builtin_classify_type (Val3) != 8) \ + __tgmres = Fct (Val1, Val2, Val3); \ + else \ + __tgmres = Fct##f (Val1, Val2, Val3); \ + __tgmres; })) + +/* XXX This definition has to be changed as soon as the compiler understands + the imaginary keyword. */ +# define __TGMATH_UNARY_REAL_IMAG(Val, Fct, Cfct) \ + (__extension__ ({ __tgmath_real_type (Val) __tgmres; \ + if (sizeof (__real__ (Val)) > sizeof (double) \ + && __builtin_classify_type (__real__ (Val)) == 8) \ + { \ + if (sizeof (__real__ (Val)) == sizeof (Val)) \ + __tgmres = __tgml(Fct) (Val); \ + else \ + __tgmres = __tgml(Cfct) (Val); \ + } \ + else if (sizeof (__real__ (Val)) == sizeof (double) \ + || __builtin_classify_type (__real__ (Val)) \ + != 8) \ + { \ + if (sizeof (__real__ (Val)) == sizeof (Val)) \ + __tgmres = Fct (Val); \ + else \ + __tgmres = Cfct (Val); \ + } \ + else \ + { \ + if (sizeof (__real__ (Val)) == sizeof (Val)) \ + __tgmres = Fct##f (Val); \ + else \ + __tgmres = Cfct##f (Val); \ + } \ + __tgmres; })) + +/* XXX This definition has to be changed as soon as the compiler understands + the imaginary keyword. */ +# define __TGMATH_UNARY_IMAG_ONLY(Val, Fct) \ + (__extension__ ({ __tgmath_real_type (Val) __tgmres; \ + if (sizeof (Val) == sizeof (__complex__ double) \ + || __builtin_classify_type (__real__ (Val)) != 8) \ + __tgmres = Fct (Val); \ + else if (sizeof (Val) == sizeof (__complex__ float)) \ + __tgmres = Fct##f (Val); \ + else \ + __tgmres = __tgml(Fct) (Val); \ + __tgmres; })) + +/* XXX This definition has to be changed as soon as the compiler understands + the imaginary keyword. */ +# define __TGMATH_BINARY_REAL_IMAG(Val1, Val2, Fct, Cfct) \ + (__extension__ ({ __tgmath_real_type ((Val1) + (Val2)) __tgmres; \ + if ((sizeof (__real__ (Val1)) > sizeof (double) \ + || sizeof (__real__ (Val2)) > sizeof (double)) \ + && __builtin_classify_type (__real__ (Val1) \ + + __real__ (Val2)) \ + == 8) \ + { \ + if (sizeof (__real__ (Val1)) == sizeof (Val1) \ + && sizeof (__real__ (Val2)) == sizeof (Val2)) \ + __tgmres = __tgml(Fct) (Val1, Val2); \ + else \ + __tgmres = __tgml(Cfct) (Val1, Val2); \ + } \ + else if (sizeof (__real__ (Val1)) == sizeof (double) \ + || sizeof (__real__ (Val2)) == sizeof(double) \ + || (__builtin_classify_type (__real__ (Val1)) \ + != 8) \ + || (__builtin_classify_type (__real__ (Val2)) \ + != 8)) \ + { \ + if (sizeof (__real__ (Val1)) == sizeof (Val1) \ + && sizeof (__real__ (Val2)) == sizeof (Val2)) \ + __tgmres = Fct (Val1, Val2); \ + else \ + __tgmres = Cfct (Val1, Val2); \ + } \ + else \ + { \ + if (sizeof (__real__ (Val1)) == sizeof (Val1) \ + && sizeof (__real__ (Val2)) == sizeof (Val2)) \ + __tgmres = Fct##f (Val1, Val2); \ + else \ + __tgmres = Cfct##f (Val1, Val2); \ + } \ + __tgmres; })) +#else +# error "Unsupported compiler; you cannot use <tgmath.h>" +#endif + + +/* Unary functions defined for real and complex values. */ + + +/* Trigonometric functions. */ + +/* Arc cosine of X. */ +#define acos(Val) __TGMATH_UNARY_REAL_IMAG (Val, acos, cacos) +/* Arc sine of X. */ +#define asin(Val) __TGMATH_UNARY_REAL_IMAG (Val, asin, casin) +/* Arc tangent of X. */ +#define atan(Val) __TGMATH_UNARY_REAL_IMAG (Val, atan, catan) +/* Arc tangent of Y/X. */ +#define atan2(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, atan2) + +/* Cosine of X. */ +#define cos(Val) __TGMATH_UNARY_REAL_IMAG (Val, cos, ccos) +/* Sine of X. */ +#define sin(Val) __TGMATH_UNARY_REAL_IMAG (Val, sin, csin) +/* Tangent of X. */ +#define tan(Val) __TGMATH_UNARY_REAL_IMAG (Val, tan, ctan) + + +/* Hyperbolic functions. */ + +/* Hyperbolic arc cosine of X. */ +#define acosh(Val) __TGMATH_UNARY_REAL_IMAG (Val, acosh, cacosh) +/* Hyperbolic arc sine of X. */ +#define asinh(Val) __TGMATH_UNARY_REAL_IMAG (Val, asinh, casinh) +/* Hyperbolic arc tangent of X. */ +#define atanh(Val) __TGMATH_UNARY_REAL_IMAG (Val, atanh, catanh) + +/* Hyperbolic cosine of X. */ +#define cosh(Val) __TGMATH_UNARY_REAL_IMAG (Val, cosh, ccosh) +/* Hyperbolic sine of X. */ +#define sinh(Val) __TGMATH_UNARY_REAL_IMAG (Val, sinh, csinh) +/* Hyperbolic tangent of X. */ +#define tanh(Val) __TGMATH_UNARY_REAL_IMAG (Val, tanh, ctanh) + + +/* Exponential and logarithmic functions. */ + +/* Exponential function of X. */ +#define exp(Val) __TGMATH_UNARY_REAL_IMAG (Val, exp, cexp) + +/* Break VALUE into a normalized fraction and an integral power of 2. */ +#define frexp(Val1, Val2) __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, frexp) + +/* X times (two to the EXP power). */ +#define ldexp(Val1, Val2) __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, ldexp) + +/* Natural logarithm of X. */ +#define log(Val) __TGMATH_UNARY_REAL_IMAG (Val, log, clog) + +/* Base-ten logarithm of X. */ +#ifdef __USE_GNU +# define log10(Val) __TGMATH_UNARY_REAL_IMAG (Val, log10, __clog10) +#else +# define log10(Val) __TGMATH_UNARY_REAL_ONLY (Val, log10) +#endif + +/* Return exp(X) - 1. */ +#define expm1(Val) __TGMATH_UNARY_REAL_ONLY (Val, expm1) + +/* Return log(1 + X). */ +#define log1p(Val) __TGMATH_UNARY_REAL_ONLY (Val, log1p) + +/* Return the base 2 signed integral exponent of X. */ +#define logb(Val) __TGMATH_UNARY_REAL_ONLY (Val, logb) + +/* Compute base-2 exponential of X. */ +#define exp2(Val) __TGMATH_UNARY_REAL_ONLY (Val, exp2) + +/* Compute base-2 logarithm of X. */ +#define log2(Val) __TGMATH_UNARY_REAL_ONLY (Val, log2) + + +/* Power functions. */ + +/* Return X to the Y power. */ +#define pow(Val1, Val2) __TGMATH_BINARY_REAL_IMAG (Val1, Val2, pow, cpow) + +/* Return the square root of X. */ +#define sqrt(Val) __TGMATH_UNARY_REAL_IMAG (Val, sqrt, csqrt) + +/* Return `sqrt(X*X + Y*Y)'. */ +#define hypot(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, hypot) + +/* Return the cube root of X. */ +#define cbrt(Val) __TGMATH_UNARY_REAL_ONLY (Val, cbrt) + + +/* Nearest integer, absolute value, and remainder functions. */ + +/* Smallest integral value not less than X. */ +#define ceil(Val) __TGMATH_UNARY_REAL_ONLY (Val, ceil) + +/* Absolute value of X. */ +#define fabs(Val) __TGMATH_UNARY_REAL_IMAG (Val, fabs, cabs) + +/* Largest integer not greater than X. */ +#define floor(Val) __TGMATH_UNARY_REAL_ONLY (Val, floor) + +/* Floating-point modulo remainder of X/Y. */ +#define fmod(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, fmod) + +/* Round X to integral valuein floating-point format using current + rounding direction, but do not raise inexact exception. */ +#define nearbyint(Val) __TGMATH_UNARY_REAL_ONLY (Val, nearbyint) + +/* Round X to nearest integral value, rounding halfway cases away from + zero. */ +#define round(Val) __TGMATH_UNARY_REAL_ONLY (Val, round) + +/* Round X to the integral value in floating-point format nearest but + not larger in magnitude. */ +#define trunc(Val) __TGMATH_UNARY_REAL_ONLY (Val, trunc) + +/* Compute remainder of X and Y and put in *QUO a value with sign of x/y + and magnitude congruent `mod 2^n' to the magnitude of the integral + quotient x/y, with n >= 3. */ +#define remquo(Val1, Val2, Val3) \ + __TGMATH_TERNARY_FIRST_SECOND_REAL_ONLY (Val1, Val2, Val3, remquo) + +/* Round X to nearest integral value according to current rounding + direction. */ +#define lrint(Val) __TGMATH_UNARY_REAL_ONLY (Val, lrint) +#define llrint(Val) __TGMATH_UNARY_REAL_ONLY (Val, llrint) + +/* Round X to nearest integral value, rounding halfway cases away from + zero. */ +#define lround(Val) __TGMATH_UNARY_REAL_ONLY (Val, lround) +#define llround(Val) __TGMATH_UNARY_REAL_ONLY (Val, llround) + + +/* Return X with its signed changed to Y's. */ +#define copysign(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, copysign) + +/* Error and gamma functions. */ +#define erf(Val) __TGMATH_UNARY_REAL_ONLY (Val, erf) +#define erfc(Val) __TGMATH_UNARY_REAL_ONLY (Val, erfc) +#define tgamma(Val) __TGMATH_UNARY_REAL_ONLY (Val, tgamma) +#define lgamma(Val) __TGMATH_UNARY_REAL_ONLY (Val, lgamma) + + +/* Return the integer nearest X in the direction of the + prevailing rounding mode. */ +#define rint(Val) __TGMATH_UNARY_REAL_ONLY (Val, rint) + +/* Return X + epsilon if X < Y, X - epsilon if X > Y. */ +#define nextafter(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, nextafter) +#define nexttoward(Val1, Val2) \ + __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, nexttoward) + +/* Return the remainder of integer divison X / Y with infinite precision. */ +#define remainder(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, remainder) + +/* Return X times (2 to the Nth power). */ +#if defined __USE_MISC || defined __USE_XOPEN_EXTENDED +# define scalb(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, scalb) +#endif + +/* Return X times (2 to the Nth power). */ +#define scalbn(Val1, Val2) __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, scalbn) + +/* Return X times (2 to the Nth power). */ +#define scalbln(Val1, Val2) \ + __TGMATH_BINARY_FIRST_REAL_ONLY (Val1, Val2, scalbln) + +/* Return the binary exponent of X, which must be nonzero. */ +#define ilogb(Val) __TGMATH_UNARY_REAL_ONLY (Val, ilogb) + + +/* Return positive difference between X and Y. */ +#define fdim(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, fdim) + +/* Return maximum numeric value from X and Y. */ +#define fmax(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, fmax) + +/* Return minimum numeric value from X and Y. */ +#define fmin(Val1, Val2) __TGMATH_BINARY_REAL_ONLY (Val1, Val2, fmin) + + +/* Multiply-add function computed as a ternary operation. */ +#define fma(Val1, Val2, Val3) \ + __TGMATH_TERNARY_REAL_ONLY (Val1, Val2, Val3, fma) + + +/* Absolute value, conjugates, and projection. */ + +/* Argument value of Z. */ +#define carg(Val) __TGMATH_UNARY_IMAG_ONLY (Val, carg) + +/* Complex conjugate of Z. */ +#define conj(Val) __TGMATH_UNARY_IMAG_ONLY (Val, conj) + +/* Projection of Z onto the Riemann sphere. */ +#define cproj(Val) __TGMATH_UNARY_IMAG_ONLY (Val, cproj) + + +/* Decomposing complex values. */ + +/* Imaginary part of Z. */ +#define cimag(Val) __TGMATH_UNARY_IMAG_ONLY (Val, cimag) + +/* Real part of Z. */ +#define creal(Val) __TGMATH_UNARY_IMAG_ONLY (Val, creal) + +#endif /* tgmath.h */ diff --git a/libm/Makefile b/libm/Makefile index b0821c82a..80ee30c4d 100644 --- a/libm/Makefile +++ b/libm/Makefile @@ -62,7 +62,7 @@ CSRC = e_acos.c e_acosh.c e_asin.c e_atan2.c e_atanh.c e_cosh.c\ w_cosh.c w_drem.c w_exp.c w_fmod.c w_gamma.c w_gamma_r.c\ w_hypot.c w_j0.c w_j1.c w_jn.c w_lgamma.c w_lgamma_r.c\ w_log.c w_log10.c w_pow.c w_remainder.c w_scalb.c w_sinh.c\ - w_sqrt.c w_sqrtf.c fpmacros.c + w_sqrt.c w_sqrtf.c fpmacros.c nan.c else # This list of math functions was taken from POSIX/IEEE 1003.1b-1993 CSRC = w_acos.c w_asin.c s_atan.c w_atan2.c s_ceil.c s_cos.c \ diff --git a/libm/fpmacros.c b/libm/fpmacros.c index a9f63df4b..3dbc8a13c 100644 --- a/libm/fpmacros.c +++ b/libm/fpmacros.c @@ -15,8 +15,8 @@ ** ** Change History (most recent first): ** -** 07 Jul 01 ram First created from fpfloatfunc.c, fp.c, -** classify.c and sign.c in MathLib v3 Mac OS9. +** 07 Jul 01 ram First created from fpfloatfunc.c, fp.c, +** classify.c and sign.c in MathLib v3 Mac OS9. ** ***********************************************************************/ @@ -148,7 +148,7 @@ long int __isnorma ( double x ) Calls: none ***********************************************************************/ -long int __isfinitef ( float x ) +long int __finitef ( float x ) { union { unsigned long int lval; @@ -159,13 +159,56 @@ long int __isfinitef ( float x ) return ((z.lval & FEXP_MASK) != FEXP_MASK); } -long int __isfinite ( double x ) +long int __finite ( double x ) { return ( __fpclassify ( x ) >= FP_ZERO ); } /*********************************************************************** + long int __signbitf(float x) returns nonzero if and only if the sign + bit of x is set and zero otherwise. + + Exceptions: INVALID is raised if x is a signaling NaN. + + Calls: none +***********************************************************************/ + +long int __signbitf ( float x ) +{ + union { + unsigned long int lval; + float fval; + } z; + + z.fval = x; + return ((z.lval & SIGN_MASK) != 0); +} + + +/*********************************************************************** + Function sign of a double. + Implementation of sign bit for the PowerPC. + + Calls: none +***********************************************************************/ + +long int __signbit ( double arg ) +{ + union + { + dHexParts hex; + double dbl; + } x; + long int sign; + + x.dbl = arg; + sign = ( ( x.hex.high & dSgnMask ) == dSgnMask ) ? 1 : 0; + return sign; +} + + +/*********************************************************************** * long int __isinff(float x) returns -1 if value represents negative * infinity, 1 if value represents positive infinity, * and 0 otherwise. @@ -190,6 +233,17 @@ long int __isinf ( double x ) return 0; } +#if 0 +long int __isinfl ( long double x ) +{ + long int class = __fpclassify(x); + if ( class == FP_INFINITE ) { + return ( (__signbit(x)) ? -1 : 1); + } + return 0; +} +#endif + /*********************************************************************** long int __isnanf(float x) returns nonzero if and only if x is a NaN and zero otherwise. @@ -217,47 +271,11 @@ long int __isnan ( double x ) return ( ( class == FP_SNAN ) || ( class == FP_QNAN ) ); } - -/*********************************************************************** - long int __signbitf(float x) returns nonzero if and only if the sign - bit of x is set and zero otherwise. - - Exceptions: INVALID is raised if x is a signaling NaN. - - Calls: none -***********************************************************************/ - -long int __signbitf ( float x ) -{ - union { - unsigned long int lval; - float fval; - } z; - - z.fval = x; - return ((z.lval & SIGN_MASK) != 0); -} - - -/*********************************************************************** - Function sign of a double. - Implementation of sign bit for the PowerPC. - - Calls: none -***********************************************************************/ - -long int __signbit ( double arg ) +#if 0 +long int __isnanl ( long double x ) { - union - { - dHexParts hex; - double dbl; - } x; - long int sign; - - x.dbl = arg; - sign = ( ( x.hex.high & dSgnMask ) == dSgnMask ) ? 1 : 0; - return sign; + long int class = __fpclassify(x); + return ( ( class == FP_SNAN ) || ( class == FP_QNAN ) ); } - +#endif diff --git a/libm/nan.c b/libm/nan.c new file mode 100644 index 000000000..8d7998896 --- /dev/null +++ b/libm/nan.c @@ -0,0 +1,48 @@ +/*********************************************************************** + nan, nanf, nanl - return quiet NaN + + These functions shall return a quiet NaN, if available, with content + indicated through tagp. + + If the implementation does not support quiet NaNs, these functions + shall return zero. + + Calls: strlen(), sprintf(), strtod() + +***********************************************************************/ +#include <math.h> +#include <string.h> +#include <stdlib.h> +#include <stdio.h> + +double nan (const char *tagp) +{ + if (tagp[0] != '\0') { + char buf[6 + strlen (tagp)]; + sprintf (buf, "NAN(%s)", tagp); + return strtod (buf, NULL); + } + return NAN; +} + +float nanf (const char *tagp) +{ + if (tagp[0] != '\0') { + char buf[6 + strlen (tagp)]; + sprintf (buf, "NAN(%s)", tagp); + return strtof (buf, NULL); + } + return NAN; +} + +#if 0 +long double nanl (const char *tagp) +{ + if (tagp[0] != '\0') { + char buf[6 + strlen (tagp)]; + sprintf (buf, "NAN(%s)", tagp); + return strtold (buf, NULL); + } + return NAN; +} +#endif |