summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2008-10-03 14:24:28 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2008-10-03 14:24:28 +0000
commitfeeb0301b31a5ad4ea0594b17e4720bbe3308a3b (patch)
treeae71a3f81309a3068335ec30f021333454bccbc6
parent2ba017a2d5af01cc3ef0dc554252a521e8d7c4f8 (diff)
- add long double math wrappers (Ned Ludd)
-rw-r--r--Rules.mak2
-rw-r--r--extra/Configs/Config.in.arch10
-rw-r--r--include/complex.h8
-rw-r--r--include/math.h18
-rw-r--r--include/tgmath.h2
-rw-r--r--libc/sysdeps/linux/alpha/bits/mathdef.h4
-rw-r--r--libc/sysdeps/linux/alpha/bits/wordsize.h4
-rw-r--r--libc/sysdeps/linux/arm/bits/mathdef.h8
-rw-r--r--libc/sysdeps/linux/common/bits/mathdef.h6
-rw-r--r--libc/sysdeps/linux/i386/bits/mathdef.h4
-rw-r--r--libc/sysdeps/linux/ia64/bits/mathdef.h4
-rw-r--r--libc/sysdeps/linux/m68k/bits/mathdef.h4
-rw-r--r--libc/sysdeps/linux/mips/bits/mathdef.h6
-rw-r--r--libc/sysdeps/linux/nios/bits/mathdef.h8
-rw-r--r--libc/sysdeps/linux/nios2/bits/mathdef.h8
-rw-r--r--libc/sysdeps/linux/powerpc/bits/mathdef.h8
-rw-r--r--libc/sysdeps/linux/powerpc/bits/wordsize.h4
-rw-r--r--libc/sysdeps/linux/sh/bits/mathdef.h6
-rw-r--r--libc/sysdeps/linux/sparc/bits/mathdef.h6
-rw-r--r--libc/sysdeps/linux/sparc/bits/mathinline.h12
-rw-r--r--libc/sysdeps/linux/sparc/bits/wordsize.h4
-rw-r--r--libc/sysdeps/linux/x86_64/bits/mathdef.h4
-rw-r--r--libc/sysdeps/linux/xtensa/bits/mathdef.h4
-rw-r--r--libm/Makefile.in30
-rw-r--r--libm/ldouble_wrappers.c523
-rw-r--r--libm/nan.c1
-rw-r--r--test/math/Makefile10
27 files changed, 603 insertions, 105 deletions
diff --git a/Rules.mak b/Rules.mak
index b5f9fc223..44be75c39 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -363,7 +363,7 @@ ifeq ($(TARGET_ARCH),powerpc)
PIEFLAG_NAME:=-fpie
PPC_HAS_REL16:=$(shell echo -e "\t.text\n\taddis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha" | $(CC) -c -x assembler -o /dev/null - 2> /dev/null && echo -n y || echo -n n)
CPU_CFLAGS-$(PPC_HAS_REL16)+= -DHAVE_ASM_PPC_REL16
- CPU_CFLAGS-$(CONFIG_E500) += "-D__NO_MATH_INLINES -D__NO_LONG_DOUBLE_MATH"
+ CPU_CFLAGS-$(CONFIG_E500) += "-D__NO_MATH_INLINES"
endif
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch
index 2a912a109..03d5e4e51 100644
--- a/extra/Configs/Config.in.arch
+++ b/extra/Configs/Config.in.arch
@@ -168,6 +168,16 @@ config UCLIBC_HAS_FENV
point environment, rounding and exception handling functions then
say Y here.
+config UCLIBC_HAS_LONG_DOUBLE_MATH
+ bool "Enable long double support"
+ depends on DO_C99_MATH
+ depends on TARGET_i386 || TARGET_m68k || TARGET_sparc || TARGET_x86_64 || TARGET_powerpc
+ default y
+ help
+ If you want the uClibc math library to contain the full set of C99
+ long double math library features, then answer Y. Don't enable it
+ for sparc w/ 32bit ABI.
+
config KERNEL_HEADERS
string "Linux kernel header location"
default "/usr/include"
diff --git a/include/complex.h b/include/complex.h
index f005a9391..94fb6ea44 100644
--- a/include/complex.h
+++ b/include/complex.h
@@ -62,7 +62,7 @@ __BEGIN_DECLS
#define __MATHDECL_1(type, function, args) \
extern type __MATH_PRECNAME(function) args __THROW
-#define _Mdouble_ double
+#define _Mdouble_ double
#define __MATH_PRECNAME(name) name
#include <bits/cmathcalls.h>
#undef _Mdouble_
@@ -72,7 +72,7 @@ __BEGIN_DECLS
#ifndef _Mfloat_
# define _Mfloat_ float
#endif
-#define _Mdouble_ _Mfloat_
+#define _Mdouble_ _Mfloat_
#ifdef __STDC__
# define __MATH_PRECNAME(name) name##f
#else
@@ -84,11 +84,11 @@ __BEGIN_DECLS
/* 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
+#if __STDC__ - 0 || __GNUC__ - 0 && defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
# ifndef _Mlong_double_
# define _Mlong_double_ long double
# endif
-# define _Mdouble_ _Mlong_double_
+# define _Mdouble_ _Mlong_double_
# ifdef __STDC__
# define __MATH_PRECNAME(name) name##l
# else
diff --git a/include/math.h b/include/math.h
index 34c042dc5..ae5d6ec70 100644
--- a/include/math.h
+++ b/include/math.h
@@ -64,7 +64,7 @@ __BEGIN_DECLS
#define __MATHDECL_1(type, function,suffix, args) \
extern type __MATH_PRECNAME(function,suffix) args __THROW
-#define _Mdouble_ double
+#define _Mdouble_ double
#define __MATH_PRECNAME(name,r) __CONCAT(name,r)
# define _Mdouble_BEGIN_NAMESPACE __BEGIN_NAMESPACE_STD
# define _Mdouble_END_NAMESPACE __END_NAMESPACE_STD
@@ -83,7 +83,7 @@ __BEGIN_DECLS
# ifndef _Mfloat_
# define _Mfloat_ float
# endif
-# define _Mdouble_ _Mfloat_
+# define _Mdouble_ _Mfloat_
# ifdef __STDC__
# define __MATH_PRECNAME(name,r) name##f##r
# else
@@ -98,7 +98,7 @@ __BEGIN_DECLS
# undef __MATH_PRECNAME
# if (__STDC__ - 0 || __GNUC__ - 0) \
- && (!defined __NO_LONG_DOUBLE_MATH || defined __LDBL_COMPAT)
+ && (defined __UCLIBC_HAS_LONG_DOUBLE_MATH__ || defined __LDBL_COMPAT)
# ifdef __LDBL_COMPAT
# ifdef __USE_ISOC99
@@ -130,7 +130,7 @@ extern long double __REDIRECT_NTH (nexttowardl,
# ifndef _Mlong_double_
# define _Mlong_double_ long double
# endif
-# define _Mdouble_ _Mlong_double_
+# define _Mdouble_ _Mlong_double_
# ifdef __STDC__
# define __MATH_PRECNAME(name,r) name##l##r
# else
@@ -210,7 +210,7 @@ enum
};
/* Return number of classification appropriate for X. */
-# ifdef __NO_LONG_DOUBLE_MATH
+# ifndef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# define fpclassify(x) \
(sizeof (x) == sizeof (float) ? __fpclassifyf (x) : __fpclassify (x))
# else
@@ -222,7 +222,7 @@ enum
# endif
/* Return nonzero value if sign of X is negative. */
-# ifdef __NO_LONG_DOUBLE_MATH
+# ifndef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# define signbit(x) \
(sizeof (x) == sizeof (float) ? __signbitf (x) : __signbit (x))
# else
@@ -234,7 +234,7 @@ enum
# endif
/* Return nonzero value if X is not +-Inf or NaN. */
-# ifdef __NO_LONG_DOUBLE_MATH
+# ifndef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# define isfinite(x) \
(sizeof (x) == sizeof (float) ? __finitef (x) : __finite (x))
# else
@@ -250,7 +250,7 @@ enum
/* Return nonzero value if X is a NaN. We could use `fpclassify' but
we already have this functions `__isnan' and it is faster. */
-# ifdef __NO_LONG_DOUBLE_MATH
+# ifndef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# define isnan(x) \
(sizeof (x) == sizeof (float) ? __isnanf (x) : __isnan (x))
# else
@@ -262,7 +262,7 @@ enum
# endif
/* Return nonzero value is X is positive or negative infinity. */
-# ifdef __NO_LONG_DOUBLE_MATH
+# ifndef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# define isinf(x) \
(sizeof (x) == sizeof (float) ? __isinff (x) : __isinf (x))
# else
diff --git a/include/tgmath.h b/include/tgmath.h
index 5fb683fef..685a34588 100644
--- a/include/tgmath.h
+++ b/include/tgmath.h
@@ -36,7 +36,7 @@
#if __GNUC_PREREQ (2, 7)
-# ifdef __NO_LONG_DOUBLE_MATH
+# ifndef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# define __tgml(fct) fct
# else
# define __tgml(fct) fct ## l
diff --git a/libc/sysdeps/linux/alpha/bits/mathdef.h b/libc/sysdeps/linux/alpha/bits/mathdef.h
index 3b52ec7d5..cbfaf68e2 100644
--- a/libc/sysdeps/linux/alpha/bits/mathdef.h
+++ b/libc/sysdeps/linux/alpha/bits/mathdef.h
@@ -78,7 +78,3 @@ typedef double double_t;
# endif /* GNUC before 3.4 */
#endif /* COMPLEX_H */
-
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/alpha/bits/wordsize.h b/libc/sysdeps/linux/alpha/bits/wordsize.h
index 22fc64109..029a7dfb2 100644
--- a/libc/sysdeps/linux/alpha/bits/wordsize.h
+++ b/libc/sysdeps/linux/alpha/bits/wordsize.h
@@ -18,13 +18,13 @@
#define __WORDSIZE 64
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
+#if defined __UCLIBC_HAS_LONG_DOUBLE_MATH__ && !defined __LONG_DOUBLE_MATH_OPTIONAL
/* Signal that we didn't used to have a `long double'. The changes all
the `long double' function variants to be redirects to the double
functions. */
# define __LONG_DOUBLE_MATH_OPTIONAL 1
# ifndef __LONG_DOUBLE_128__
-# define __NO_LONG_DOUBLE_MATH 1
+# undef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# endif
#endif
diff --git a/libc/sysdeps/linux/arm/bits/mathdef.h b/libc/sysdeps/linux/arm/bits/mathdef.h
index e013e74b7..22722e37a 100644
--- a/libc/sysdeps/linux/arm/bits/mathdef.h
+++ b/libc/sysdeps/linux/arm/bits/mathdef.h
@@ -34,11 +34,3 @@ typedef double double_t; /* `double' expressions are evaluated as
# define FP_ILOGBNAN (2147483647)
#endif /* ISO C99 */
-
-#ifndef __NO_LONG_DOUBLE_MATH
-/* Signal that we do not really have a `long double'. This disables the
- declaration of all the `long double' function variants. */
-/* XXX The FPA does support this but the patterns in GCC are currently
- turned off. */
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/common/bits/mathdef.h b/libc/sysdeps/linux/common/bits/mathdef.h
index 00c67241a..1927299f9 100644
--- a/libc/sysdeps/linux/common/bits/mathdef.h
+++ b/libc/sysdeps/linux/common/bits/mathdef.h
@@ -35,9 +35,3 @@ typedef double double_t; /* `double' expressions are evaluated as
# define FP_ILOGBNAN 2147483647
#endif /* ISO C99 */
-
-#ifndef __NO_LONG_DOUBLE_MATH
-/* Signal that we do not really have a `long double'. The disables the
- declaration of all the `long double' function variants. */
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/i386/bits/mathdef.h b/libc/sysdeps/linux/i386/bits/mathdef.h
index a3786fc81..ec42ed5df 100644
--- a/libc/sysdeps/linux/i386/bits/mathdef.h
+++ b/libc/sysdeps/linux/i386/bits/mathdef.h
@@ -44,7 +44,3 @@ typedef long double double_t; /* `double' expressions are evaluated as
# define FP_ILOGBNAN (-2147483647 - 1)
#endif /* ISO C99 */
-
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/ia64/bits/mathdef.h b/libc/sysdeps/linux/ia64/bits/mathdef.h
index 5da23cc8a..3dc286022 100644
--- a/libc/sysdeps/linux/ia64/bits/mathdef.h
+++ b/libc/sysdeps/linux/ia64/bits/mathdef.h
@@ -35,7 +35,3 @@ typedef double double_t; /* `double' expressions are evaluated as
# define FP_ILOGBNAN 2147483647
#endif /* ISO C99 */
-
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/m68k/bits/mathdef.h b/libc/sysdeps/linux/m68k/bits/mathdef.h
index a69e93089..65cf8d49f 100644
--- a/libc/sysdeps/linux/m68k/bits/mathdef.h
+++ b/libc/sysdeps/linux/m68k/bits/mathdef.h
@@ -36,7 +36,3 @@ typedef long double double_t; /* `double' expressions are evaluated as
# define FP_ILOGBNAN (2147483647)
#endif /* ISO C99 */
-
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/mips/bits/mathdef.h b/libc/sysdeps/linux/mips/bits/mathdef.h
index 331da13a9..b741f6551 100644
--- a/libc/sysdeps/linux/mips/bits/mathdef.h
+++ b/libc/sysdeps/linux/mips/bits/mathdef.h
@@ -39,10 +39,8 @@ typedef double double_t; /* `double' expressions are evaluated as
#endif /* ISO C99 */
-#if ! defined __NO_LONG_DOUBLE_MATH && _MIPS_SIM == _ABIO32
+#if defined __UCLIBC_HAS_LONG_DOUBLE_MATH__ && _MIPS_SIM == _ABIO32
/* Signal that we do not really have a `long double'. This disables the
declaration of all the `long double' function variants. */
-# define __NO_LONG_DOUBLE_MATH 1
-#elif !defined __NO_LONG_DOUBLE_MATH && !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
-# define __NO_LONG_DOUBLE_MATH 1
+# error defined __UCLIBC_HAS_LONG_DOUBLE_MATH__ and _MIPS_SIM == _ABIO32
#endif
diff --git a/libc/sysdeps/linux/nios/bits/mathdef.h b/libc/sysdeps/linux/nios/bits/mathdef.h
index e013e74b7..22722e37a 100644
--- a/libc/sysdeps/linux/nios/bits/mathdef.h
+++ b/libc/sysdeps/linux/nios/bits/mathdef.h
@@ -34,11 +34,3 @@ typedef double double_t; /* `double' expressions are evaluated as
# define FP_ILOGBNAN (2147483647)
#endif /* ISO C99 */
-
-#ifndef __NO_LONG_DOUBLE_MATH
-/* Signal that we do not really have a `long double'. This disables the
- declaration of all the `long double' function variants. */
-/* XXX The FPA does support this but the patterns in GCC are currently
- turned off. */
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/nios2/bits/mathdef.h b/libc/sysdeps/linux/nios2/bits/mathdef.h
index e013e74b7..22722e37a 100644
--- a/libc/sysdeps/linux/nios2/bits/mathdef.h
+++ b/libc/sysdeps/linux/nios2/bits/mathdef.h
@@ -34,11 +34,3 @@ typedef double double_t; /* `double' expressions are evaluated as
# define FP_ILOGBNAN (2147483647)
#endif /* ISO C99 */
-
-#ifndef __NO_LONG_DOUBLE_MATH
-/* Signal that we do not really have a `long double'. This disables the
- declaration of all the `long double' function variants. */
-/* XXX The FPA does support this but the patterns in GCC are currently
- turned off. */
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/powerpc/bits/mathdef.h b/libc/sysdeps/linux/powerpc/bits/mathdef.h
index f28bacece..81a46ddcd 100644
--- a/libc/sysdeps/linux/powerpc/bits/mathdef.h
+++ b/libc/sysdeps/linux/powerpc/bits/mathdef.h
@@ -65,13 +65,11 @@ typedef double double_t;
#endif /* ISO C99 */
-#ifndef __NO_LONG_DOUBLE_MATH
+#ifdef __UCLIBC_HAS_LONG_DOUBLE_MATH__
#include <bits/wordsize.h>
/* Signal that we do not really have a `long double'. The disables the
declaration of all the `long double' function variants. */
# if __WORDSIZE == 32
-# define __NO_LONG_DOUBLE_MATH 1
-# elif !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
-# define __NO_LONG_DOUBLE_MATH 1
+# undef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# endif /* __WORDSIZE == 32 */
-#endif /* __NO_LONG_DOUBLE_MATH */
+#endif /* __UCLIBC_HAS_LONG_DOUBLE_MATH__ */
diff --git a/libc/sysdeps/linux/powerpc/bits/wordsize.h b/libc/sysdeps/linux/powerpc/bits/wordsize.h
index cf934234f..dc19246d7 100644
--- a/libc/sysdeps/linux/powerpc/bits/wordsize.h
+++ b/libc/sysdeps/linux/powerpc/bits/wordsize.h
@@ -7,13 +7,13 @@
# define __WORDSIZE 32
#endif
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL
+#if defined __UCLIBC_HAS_LONG_DOUBLE_MATH__ && !defined __LONG_DOUBLE_MATH_OPTIONAL
/* Signal the glibc ABI didn't used to have a `long double'.
The changes all the `long double' function variants to be redirects
to the double functions. */
# define __LONG_DOUBLE_MATH_OPTIONAL 1
# ifndef __LONG_DOUBLE_128__
-# define __NO_LONG_DOUBLE_MATH 1
+# undef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# endif
#endif
diff --git a/libc/sysdeps/linux/sh/bits/mathdef.h b/libc/sysdeps/linux/sh/bits/mathdef.h
index 2b8caf194..c419fcd4a 100644
--- a/libc/sysdeps/linux/sh/bits/mathdef.h
+++ b/libc/sysdeps/linux/sh/bits/mathdef.h
@@ -61,9 +61,3 @@ typedef double double_t;
# define FP_ILOGBNAN 0x7fffffff
#endif /* ISO C99 */
-
-#ifndef __NO_LONG_DOUBLE_MATH
-/* Signal that we do not really have a `long double'. The disables the
- declaration of all the `long double' function variants. */
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/sparc/bits/mathdef.h b/libc/sysdeps/linux/sparc/bits/mathdef.h
index 7f9bbee81..b1a0d917c 100644
--- a/libc/sysdeps/linux/sparc/bits/mathdef.h
+++ b/libc/sysdeps/linux/sparc/bits/mathdef.h
@@ -57,15 +57,13 @@ typedef double double_t;
#endif /* ISO C99 */
-#ifndef __NO_LONG_DOUBLE_MATH
+#ifdef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# if __WORDSIZE == 32
/* Signal that in 32bit ABI we do not really have a `long double'.
The disables the declaration of all the `long double' function
variants. */
-# define __NO_LONG_DOUBLE_MATH 1
-# elif !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
-# define __NO_LONG_DOUBLE_MATH 1
+# undef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# endif
#endif
diff --git a/libc/sysdeps/linux/sparc/bits/mathinline.h b/libc/sysdeps/linux/sparc/bits/mathinline.h
index 729145e14..66ca0473d 100644
--- a/libc/sysdeps/linux/sparc/bits/mathinline.h
+++ b/libc/sysdeps/linux/sparc/bits/mathinline.h
@@ -37,7 +37,7 @@
# if __WORDSIZE == 32
-# ifndef __NO_LONG_DOUBLE_MATH
+# ifdef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# define __unordered_cmp(x, y) \
(__extension__ \
@@ -94,7 +94,7 @@
# define __unordered_v9cmp(x, y, op, qop) \
(__extension__ \
- ({ unsigned __r; \
+ ({ unsigned __r; \
if (sizeof (x) == 4 && sizeof (y) == 4) \
{ \
float __x = (x); float __y = (y); \
@@ -111,7 +111,7 @@
{ \
long double __x = (x); long double __y = (y); \
extern int _Qp_cmp (const long double *a, const long double *b); \
- __r = qop; \
+ __r = qop; \
} \
__r; }))
@@ -157,7 +157,7 @@ __NTH (__signbit (double __x))
return __u.__i[0] < 0;
}
-# ifndef __NO_LONG_DOUBLE_MATH
+# ifdef __UCLIBC_HAS_LONG_DOUBLE_MATH__
__MATH_INLINE int
__NTH (__signbitl (long double __x))
{
@@ -219,7 +219,7 @@ __NTH (sqrtl (long double __x))
_Qp_sqrt (&__r, &__x);
return __r;
}
-# elif !defined __NO_LONG_DOUBLE_MATH
+# elif defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
__MATH_INLINE long double
sqrtl (long double __x) __THROW
{
@@ -257,7 +257,7 @@ __ieee754_sqrtl (long double __x)
_Qp_sqrt(&__r, &__x);
return __r;
}
-# elif !defined __NO_LONG_DOUBLE_MATH
+# elif defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
__MATH_INLINE long double
__ieee754_sqrtl (long double __x)
{
diff --git a/libc/sysdeps/linux/sparc/bits/wordsize.h b/libc/sysdeps/linux/sparc/bits/wordsize.h
index c0e600ed5..c8e5bfdea 100644
--- a/libc/sysdeps/linux/sparc/bits/wordsize.h
+++ b/libc/sysdeps/linux/sparc/bits/wordsize.h
@@ -6,7 +6,7 @@
# define __WORDSIZE 32
#endif
-#if 0 /* uClibc: done in mathdefs.h: !defined __NO_LONG_DOUBLE_MATH && !defined __LONG_DOUBLE_MATH_OPTIONAL*/
+#if 0 /* uClibc: done in mathdefs.h: defined __UCLIBC_HAS_LONG_DOUBLE_MATH__ && !defined __LONG_DOUBLE_MATH_OPTIONAL*/
# if __WORDSIZE == 32
/* Signal that in 32bit ABI we didn't used to have a `long double'.
@@ -14,7 +14,7 @@
to the double functions. */
# define __LONG_DOUBLE_MATH_OPTIONAL 1
# ifndef __LONG_DOUBLE_128__
-# define __NO_LONG_DOUBLE_MATH 1
+# undef __UCLIBC_HAS_LONG_DOUBLE_MATH__
# endif
# endif
#endif
diff --git a/libc/sysdeps/linux/x86_64/bits/mathdef.h b/libc/sysdeps/linux/x86_64/bits/mathdef.h
index b0567e4d4..7b1618959 100644
--- a/libc/sysdeps/linux/x86_64/bits/mathdef.h
+++ b/libc/sysdeps/linux/x86_64/bits/mathdef.h
@@ -46,7 +46,3 @@ typedef long double double_t; /* `double' expressions are evaluated as
# define FP_ILOGBNAN (-2147483647 - 1)
#endif /* ISO C99 */
-
-#if !defined __NO_LONG_DOUBLE_MATH && !defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
-# define __NO_LONG_DOUBLE_MATH 1
-#endif
diff --git a/libc/sysdeps/linux/xtensa/bits/mathdef.h b/libc/sysdeps/linux/xtensa/bits/mathdef.h
index 0177fa9fc..99a4a318d 100644
--- a/libc/sysdeps/linux/xtensa/bits/mathdef.h
+++ b/libc/sysdeps/linux/xtensa/bits/mathdef.h
@@ -36,8 +36,8 @@ typedef double double_t; /* `double' expressions are evaluated as
#endif /* ISO C99 */
-#ifndef __NO_LONG_DOUBLE_MATH
+#if defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
/* Signal that we do not really have a `long double'. The disables the
declaration of all the `long double' function variants. */
-# define __NO_LONG_DOUBLE_MATH 1
+# undef __UCLIBC_HAS_LONG_DOUBLE_MATH__
#endif
diff --git a/libm/Makefile.in b/libm/Makefile.in
index 98e3aafe4..7e72d8add 100644
--- a/libm/Makefile.in
+++ b/libm/Makefile.in
@@ -52,6 +52,7 @@ endif
endif
FL_MSRC := float_wrappers.c
+LD_MSRC := ldouble_wrappers.c
ifeq ($(DO_C99_MATH),y)
libm_CSRC := \
@@ -84,6 +85,15 @@ FL_MOBJ := \
nextafterf.o powf.o remainderf.o remquof.o rintf.o roundf.o \
scalblnf.o scalbnf.o sinf.o sinhf.o sqrtf.o tanf.o tanhf.o \
tgammaf.o truncf.o cargf.o llrintf.o
+
+LD_MOBJ := acoshl.o acosl.o asinhl.o asinl.o atan2l.o atanhl.o atanl.o cbrtl.o \
+ ceill.o copysignl.o coshl.o cosl.o erfcl.o erfl.o exp2l.o expl.o \
+ expm1l.o fabsl.o fdiml.o floorl.o fmal.o fmaxl.o fminl.o fmodl.o \
+ frexpl.o gammal.o hypotl.o ilogbl.o ldexpl.o lgammal.o llrintl.o \
+ llroundl.o log10l.o log1pl.o XXXlog2l.o logbl.o logl.o lrintl.o lroundl.o \
+ modfl.o nearbyintl.o nextafterl.o XXXnexttowardl.o powl.o remainderl.o \
+ remquol.o rintl.o roundl.o scalblnl.o scalbnl.o sinhl.o sinl.o sqrtl.o \
+ tanhl.o tanl.o tgammal.o truncl.o
else
# This list of math functions was taken from POSIX/IEEE 1003.1b-1993
libm_CSRC := \
@@ -116,9 +126,11 @@ endif
# remove generic objects built from multi-sources, if arch specific version is present
FL_MOBJ := $(filter-out $(notdir $(libm_ARCH_OBJS)),$(FL_MOBJ))
+LD_MOBJ := $(filter-out $(notdir $(libm_ARCH_OBJS)),$(LD_MOBJ))
# we also try to remove % if s_% is in arch specific subdir
FL_MOBJ := $(filter-out $(patsubst s_%.o,%.o,$(notdir $(libm_ARCH_OBJS))),$(FL_MOBJ))
+LD_MOBJ := $(filter-out $(patsubst s_%.o,%.o,$(notdir $(libm_ARCH_OBJS))),$(LD_MOBJ))
endif
endif
endif
@@ -126,14 +138,22 @@ endif
libm_SRC := $(patsubst %.c,$(libm_DIR)/%.c,$(libm_CSRC))
libm_OBJ := $(patsubst $(libm_DIR)/%.c,$(libm_OUT)/%.o,$(libm_SRC))
+ifeq ($(strip $(UCLIBC_HAS_LONG_DOUBLE_MATH)),y)
+libm_MSRC2 := $(libm_DIR)/$(LD_MSRC)
+libm_MOBJ2 := $(patsubst %.o,$(libm_OUT)/%.o,$(LD_MOBJ))
+endif
libm_MSRC := $(libm_DIR)/$(FL_MSRC)
libm_MOBJ := $(patsubst %.o,$(libm_OUT)/%.o,$(FL_MOBJ))
+
ifneq ($(DOMULTI),n)
CFLAGS-libm += $(patsubst %,-DL_%,$(subst .o,,$(notdir $(libm_MOBJ))))
+ifeq ($(strip $(UCLIBC_HAS_LONG_DOUBLE_MATH)),y)
+CFLAGS-libm += $(patsubst %,-DL_%,$(subst .o,,$(notdir $(libm_MOBJ2))))
+endif
endif
-libm_OBJS := $(libm_OBJ) $(libm_MOBJ)
+libm_OBJS := $(libm_OBJ) $(libm_MOBJ) $(libm_MOBJ2)
ifeq ($(DOPIC),y)
libm-a-y += $(libm_OBJS:.o=.os)
@@ -162,7 +182,7 @@ $(libm_OUT)/libm_so.a: $(libm-so-y)
$(Q)$(RM) $@
$(do_ar)
-$(libm_OUT)/libm.oS: $(libm_SRC) $(libm_MSRC) $(libm_ARCH_SRC)
+$(libm_OUT)/libm.oS: $(libm_SRC) $(libm_MSRC) $(libm_MSRC2) $(libm_ARCH_SRC)
$(Q)$(RM) $@
$(compile-m)
@@ -174,8 +194,14 @@ $(top_builddir)lib/libm.a: $(libm-a-y)
$(libm_MOBJ): $(libm_MSRC)
$(compile.m)
+$(libm_MOBJ2): $(libm_MSRC2)
+ $(compile.m)
+
$(libm_MOBJ:.o=.os): $(libm_MSRC)
$(compile.m)
+$(libm_MOBJ2:.o=.os): $(libm_MSRC2)
+ $(compile.m)
+
libm_clean:
$(RM) $(libm_OUT)/{,*/,*/*/}*.{o,os,oS,a}
diff --git a/libm/ldouble_wrappers.c b/libm/ldouble_wrappers.c
new file mode 100644
index 000000000..d82436da4
--- /dev/null
+++ b/libm/ldouble_wrappers.c
@@ -0,0 +1,523 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Wrapper functions implementing all the long double math functions
+ * defined by SuSv3 by actually calling the double version of
+ * each function and then casting the result back to a long double
+ * to return to the user.
+ *
+ * Copyright (C) 2005 by Erik Andersen <andersen@uclibc.org>
+ *
+ * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+ */
+
+#include "math.h"
+
+/* Implement the following, as defined by SuSv3 */
+#if 0
+long double acoshl(long double);
+long double acosl(long double);
+long double asinhl(long double);
+long double asinl(long double);
+long double atan2l(long double, long double);
+long double atanhl(long double);
+long double atanl(long double);
+long double cbrtl(long double);
+long double ceill(long double);
+long double copysignl(long double, long double);
+long double coshl(long double);
+long double cosl(long double);
+long double erfcl(long double);
+long double erfl(long double);
+long double exp2l(long double);
+long double expl(long double);
+long double expm1l(long double);
+long double fabsl(long double);
+long double fdiml(long double, long double);
+long double floorl(long double);
+long double fmal(long double, long double, long double);
+long double fmaxl(long double, long double);
+long double fminl(long double, long double);
+long double fmodl(long double, long double);
+long double frexpl(long double value, int *);
+long double hypotl(long double, long double);
+int ilogbl(long double);
+long double ldexpl(long double, int);
+long double lgammal(long double);
+long long llrintl(long double);
+long long llroundl(long double);
+long double log10l(long double);
+long double log1pl(long double);
+long double log2l(long double);
+long double logbl(long double);
+long double logl(long double);
+long lrintl(long double);
+long lroundl(long double);
+long double modfl(long double, long double *);
+long double nearbyintl(long double);
+long double nextafterl(long double, long double);
+long double nexttowardl(long double, long double);
+long double powl(long double, long double);
+long double remainderl(long double, long double);
+long double remquol(long double, long double, int *);
+long double rintl(long double);
+long double roundl(long double);
+long double scalblnl(long double, long);
+long double scalbnl(long double, int);
+long double sinhl(long double);
+long double sinl(long double);
+long double sqrtl(long double);
+long double tanhl(long double);
+long double tanl(long double);
+long double tgammal(long double);
+long double truncl(long double);
+#endif
+
+#ifdef L_acoshl
+long double acoshl (long double x)
+{
+ return (long double) acosh( (double)x );
+}
+#endif
+
+
+#ifdef L_acosl
+long double acosl (long double x)
+{
+ return (long double) acos( (double)x );
+}
+#endif
+
+
+#ifdef L_asinhl
+long double asinhl (long double x)
+{
+ return (long double) asinh( (double)x );
+}
+#endif
+
+
+#ifdef L_asinl
+long double asinl (long double x)
+{
+ return (long double) asin( (double)x );
+}
+#endif
+
+
+#ifdef L_atan2l
+long double atan2l (long double x, long double y)
+{
+ return (long double) atan2( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_atanhl
+long double atanhl (long double x)
+{
+ return (long double) atanh( (double)x );
+}
+#endif
+
+
+#ifdef L_atanl
+long double atanl (long double x)
+{
+ return (long double) atan( (double)x );
+}
+#endif
+
+
+#ifdef L_cbrtl
+long double cbrtl (long double x)
+{
+ return (long double) cbrt( (double)x );
+}
+#endif
+
+
+#ifdef L_ceill
+long double ceill (long double x)
+{
+ return (long double) ceil( (double)x );
+}
+#endif
+
+
+#ifdef L_copysignl
+long double copysignl (long double x, long double y)
+{
+ return (long double) copysign( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_coshl
+long double coshl (long double x)
+{
+ return (long double) cosh( (double)x );
+}
+#endif
+
+
+#ifdef L_cosl
+long double cosl (long double x)
+{
+ return (long double) cos( (double)x );
+}
+#endif
+
+
+#ifdef L_erfcl
+long double erfcl (long double x)
+{
+ return (long double) erfc( (double)x );
+}
+#endif
+
+
+#ifdef L_erfl
+long double erfl (long double x)
+{
+ return (long double) erf( (double)x );
+}
+#endif
+
+
+#ifdef L_exp2l
+long double exp2l (long double x)
+{
+ return (long double) exp2( (double)x );
+}
+#endif
+
+
+#ifdef L_expl
+long double expl (long double x)
+{
+ return (long double) exp( (double)x );
+}
+#endif
+
+
+#ifdef L_expm1l
+long double expm1l (long double x)
+{
+ return (long double) expm1( (double)x );
+}
+#endif
+
+
+#ifdef L_fabsl
+long double fabsl (long double x)
+{
+ return (long double) fabs( (double)x );
+}
+#endif
+
+
+#ifdef L_fdiml
+long double fdiml (long double x, long double y)
+{
+ return (long double) fdim( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_floorl
+long double floorl (long double x)
+{
+ return (long double) floor( (double)x );
+}
+#endif
+
+
+#ifdef L_fmal
+long double fmal (long double x, long double y, long double z)
+{
+ return (long double) fma( (double)x, (double)y, (double)z );
+}
+#endif
+
+
+#ifdef L_fmaxl
+long double fmaxl (long double x, long double y)
+{
+ return (long double) fmax( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_fminl
+long double fminl (long double x, long double y)
+{
+ return (long double) fmin( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_fmodl
+long double fmodl (long double x, long double y)
+{
+ return (long double) fmod( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_frexpl
+long double frexpl (long double x, int *exp)
+{
+ return (long double) frexp( (double)x, exp );
+}
+#endif
+
+
+#ifdef L_hypotl
+long double hypotl (long double x, long double y)
+{
+ return (long double) hypot( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_ilogbl
+int ilogbl (long double x)
+{
+ return (long double) ilogb( (double)x );
+}
+#endif
+
+
+#ifdef L_ldexpl
+long double ldexpl (long double x, int exp)
+{
+ return (long double) ldexp( (double)x, exp );
+}
+#endif
+
+
+#ifdef L_lgammal
+long double lgammal (long double x)
+{
+ return (long double) lgamma( (double)x );
+}
+#endif
+
+
+#ifdef L_llrintl
+long long llrintl (long double x)
+{
+ return (long double) llrint( (double)x );
+}
+#endif
+
+
+#ifdef L_llroundl
+long long llroundl (long double x)
+{
+ return (long double) llround( (double)x );
+}
+#endif
+
+#ifdef L_log10l
+long double log10l (long double x)
+{
+ return (long double) log10( (double)x );
+}
+#endif
+
+
+#ifdef L_log1pl
+long double log1pl (long double x)
+{
+ return (long double) log1p( (double)x );
+}
+#endif
+
+
+#ifdef L_log2l
+long double log2l (long double x)
+{
+ return (long double) log2( (double)x );
+}
+#endif
+
+
+#ifdef L_logbl
+long double logbl (long double x)
+{
+ return (long double) logb( (double)x );
+}
+#endif
+
+
+#ifdef L_logl
+long double logl (long double x)
+{
+ return (long double) log( (double)x );
+}
+#endif
+
+
+#ifdef L_lrintl
+long lrintl (long double x)
+{
+ return (long double) lrint( (double)x );
+}
+#endif
+
+
+#ifdef L_lroundl
+long lroundl (long double x)
+{
+ return (long double) lround( (double)x );
+}
+#endif
+
+
+#ifdef L_modfl
+long double modfl (long double x, long double *iptr)
+{
+ double y, result;
+ result = modf ( x, &y );
+ *iptr = (long double)y;
+ return (long double) result;
+
+}
+#endif
+
+
+#ifdef L_nearbyintl
+long double nearbyintl (long double x)
+{
+ return (long double) nearbyint( (double)x );
+}
+#endif
+
+
+#ifdef L_nextafterl
+long double nextafterl (long double x, long double y)
+{
+ return (long double) nextafter( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_nexttowardl
+long double nexttowardl (long double x, long double y)
+{
+ return (long double) nexttoward( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_powl
+long double powl (long double x, long double y)
+{
+ return (long double) pow( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_remainderl
+long double remainderl (long double x, long double y)
+{
+ return (long double) remainder( (double)x, (double)y );
+}
+#endif
+
+
+#ifdef L_remquol
+long double remquol (long double x, long double y, int *quo)
+{
+ return (long double) remquo( (double)x, (double)y, quo );
+}
+#endif
+
+
+#ifdef L_rintl
+long double rintl (long double x)
+{
+ return (long double) rint( (double)x );
+}
+#endif
+
+
+#ifdef L_roundl
+long double roundl (long double x)
+{
+ return (long double) round( (double)x );
+}
+#endif
+
+
+#ifdef L_scalblnl
+long double scalblnl (long double x, long exp)
+{
+ return (long double) scalbln( (double)x, exp );
+}
+#endif
+
+
+#ifdef L_scalbnl
+long double scalbnl (long double x, int exp)
+{
+ return (long double) scalbn( (double)x, exp );
+}
+#endif
+
+
+#ifdef L_sinhl
+long double sinhl (long double x)
+{
+ return (long double) sinh( (double)x );
+}
+#endif
+
+
+#ifdef L_sinl
+long double sinl (long double x)
+{
+ return (long double) sin( (double)x );
+}
+#endif
+
+
+#ifdef L_sqrtl
+long double sqrtl (long double x)
+{
+ return (long double) sqrt( (double)x );
+}
+#endif
+
+
+#ifdef L_tanhl
+long double tanhl (long double x)
+{
+ return (long double) tanh( (double)x );
+}
+#endif
+
+
+#ifdef L_tanl
+long double tanl (long double x)
+{
+ return (long double) tan( (double)x );
+}
+#endif
+
+
+#ifdef L_tgammal
+long double tgammal (long double x)
+{
+ return (long double) tgamma( (double)x );
+}
+#endif
+
+
+#ifdef L_truncl
+long double truncl (long double x)
+{
+ return (long double) trunc( (double)x );
+}
+#endif
diff --git a/libm/nan.c b/libm/nan.c
index 662a25d33..ec221ea71 100644
--- a/libm/nan.c
+++ b/libm/nan.c
@@ -46,6 +46,7 @@ float nanf (const char *tagp)
libm_hidden_def(nanf)
#if defined __UCLIBC_HAS_LONG_DOUBLE_MATH__
+libm_hidden_proto(nanl)
long double nanl (const char *tagp)
{
if (tagp[0] != '\0') {
diff --git a/test/math/Makefile b/test/math/Makefile
index e65f1700e..09f5425a5 100644
--- a/test/math/Makefile
+++ b/test/math/Makefile
@@ -1,10 +1,10 @@
# uClibc math tests
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
-TESTS := basic-test rint tst-definitions test-fpucw
-# test-double test-idouble
-# test-float test-ifloat
-# test-ldouble test-ildouble
+TESTS := basic-test rint tst-definitions test-fpucw test-float test-ifloat test-double test-idouble
+ifeq ($(strip $(UCLIBC_HAS_LONG_DOUBLE_MATH)),y)
+TESTS += test-ldouble test-ildouble
+endif
include ../Test.mak
@@ -15,7 +15,7 @@ DODIFF_rint := 1
ifeq ($(TARGET_ARCH),sh)
CFLAGS_basic-test := -mieee
endif
-EXTRA_CFLAGS := -DNO_LONG_DOUBLE -fno-builtin
+EXTRA_CFLAGS := -fno-builtin
EXTRA_LDFLAGS := -lm
PERL := /usr/bin/perl