summaryrefslogtreecommitdiff
path: root/test/math
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@uclibc-ng.org>2016-10-24 20:22:12 +0200
committerWaldemar Brodkorb <wbx@uclibc-ng.org>2016-10-24 20:22:12 +0200
commit7988979a722b4cdf287b2093956a76a3f19b9897 (patch)
treed35e251d0472ceca55a2eef61cff261c8ee68fab /test/math
add uClibc-ng test directory
Diffstat (limited to 'test/math')
-rw-r--r--test/math/Makefile8
-rw-r--r--test/math/Makefile.in46
-rw-r--r--test/math/basic-test.c161
-rw-r--r--test/math/c99_test.c116
-rw-r--r--test/math/compile_test.c141
-rw-r--r--test/math/fenv.h3
-rw-r--r--test/math/gamma.c73
-rwxr-xr-xtest/math/gen-libm-test.pl737
-rw-r--r--test/math/ilogb.c52
-rw-r--r--test/math/libm-test-ulps-arc145
-rw-r--r--test/math/libm-test-ulps-arm4989
-rw-r--r--test/math/libm-test-ulps-cris145
-rw-r--r--test/math/libm-test-ulps-generic5
-rw-r--r--test/math/libm-test-ulps-i3861261
-rw-r--r--test/math/libm-test-ulps-ia641146
-rw-r--r--test/math/libm-test-ulps-microblaze145
-rw-r--r--test/math/libm-test-ulps-mips32145
-rw-r--r--test/math/libm-test-ulps-mips649633
-rw-r--r--test/math/libm-test-ulps-nds32145
-rw-r--r--test/math/libm-test-ulps-powerpc1336
-rw-r--r--test/math/libm-test-ulps-sh1094
-rw-r--r--test/math/libm-test-ulps-sparc1338
-rw-r--r--test/math/libm-test-ulps-x86_641328
-rw-r--r--test/math/libm-test-ulps-xtensa145
-rw-r--r--test/math/libm-test.inc5096
-rw-r--r--test/math/rint.c33
-rw-r--r--test/math/signgam.c28
-rw-r--r--test/math/test-double.c33
-rw-r--r--test/math/test-float.c33
-rw-r--r--test/math/test-fpucw.c42
-rw-r--r--test/math/test-idouble.c34
-rw-r--r--test/math/test-ifloat.c34
-rw-r--r--test/math/test-ildoubl.c34
-rw-r--r--test/math/test-ldouble.c33
-rw-r--r--test/math/tst-definitions.c46
35 files changed, 29783 insertions, 0 deletions
diff --git a/test/math/Makefile b/test/math/Makefile
new file mode 100644
index 0000000..6194efa
--- /dev/null
+++ b/test/math/Makefile
@@ -0,0 +1,8 @@
+# uClibc math tests
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+top_builddir=../../
+top_srcdir=../../
+include ../Rules.mak
+-include Makefile.in
+include ../Test.mak
diff --git a/test/math/Makefile.in b/test/math/Makefile.in
new file mode 100644
index 0000000..3874001
--- /dev/null
+++ b/test/math/Makefile.in
@@ -0,0 +1,46 @@
+# uClibc math tests
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+
+# libm-test.c is a generated file used by the tests internally so skip it
+TESTS_DISABLED := libm-test
+
+# gamma (removed from TESTS, need to add "small errors are ok" machinery there)
+TESTS_DISABLED += gamma
+ifeq ($(UCLIBC_HAS_LONG_DOUBLE_MATH),)
+TESTS_DISABLED += test-ldouble test-ildoubl compile_test c99_test
+CFLAGS_basic-test := -DNO_LONG_DOUBLE
+endif
+ifeq ($(DO_C99_MATH),)
+TESTS_DISABLED += test-float test-ifloat test-double test-idouble rint signgam ilogb
+endif
+ifeq ($(UCLIBC_HAS_FPU),)
+TESTS_DISABLED += test-fpucw
+endif
+
+DODIFF_rint := 1
+DODIFF_signgam := 1
+
+# NOTE: For basic-test we must disable the floating point optimization.
+# Only for sh architecture because in the other architecture are disabled.
+ifeq ($(TARGET_ARCH),sh)
+CFLAGS_basic-test += -mieee
+endif
+EXTRA_CFLAGS := -fno-builtin
+EXTRA_LDFLAGS := -lm
+
+PERL := perl
+
+MDEPS := $(wildcard test-*.c)
+$(MDEPS): libm-test.c
+
+ULP_SUFFIX :=
+ifeq ($(TARGET_ARCH),mips)
+ULP_SUFFIX:=$(if $(CONFIG_MIPS_N64_ABI),64,32)
+endif
+
+TARGET_ULP := $(if $(wildcard libm-test-ulps-$(TARGET_ARCH)$(ULP_SUFFIX)),$(TARGET_ARCH)$(ULP_SUFFIX),generic)
+
+libm-test.c: libm-test-ulps-$(TARGET_ULP) libm-test.inc gen-libm-test.pl
+ $(Q)$(PERL) ./gen-libm-test.pl -u libm-test-ulps-$(TARGET_ULP) ./libm-test.inc -o "." 2>&1 > /dev/null
+
+EXTRA_CLEAN := libm-test.c libm-test-ulps.h
diff --git a/test/math/basic-test.c b/test/math/basic-test.c
new file mode 100644
index 0000000..d073abb
--- /dev/null
+++ b/test/math/basic-test.c
@@ -0,0 +1,161 @@
+/* Copyright (C) 1999 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+ 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, see
+ <http://www.gnu.org/licenses/>. */
+
+#define _ISOC99_SOURCE
+
+#include <math.h>
+#include <float.h>
+#include <stdio.h>
+
+static int errors = 0;
+
+
+static void
+check (const char *testname, int result)
+{
+ if (!result) {
+ printf ("Failure: %s\n", testname);
+ errors++;
+ }
+}
+
+#define TEST_FUNC(NAME, FLOAT, NANFUNC, EPSILON, HUGEVAL) \
+static void \
+NAME (void) \
+{ \
+ /* Variables are declared volatile to forbid some compiler \
+ optimizations. */ \
+ volatile FLOAT Inf_var, NaN_var, zero_var, one_var; \
+ FLOAT x1, x2; \
+ \
+ zero_var = 0.0; \
+ one_var = 1.0; \
+ NaN_var = zero_var/zero_var; \
+ Inf_var = one_var / zero_var; \
+ \
+ (void) &zero_var; \
+ (void) &one_var; \
+ (void) &NaN_var; \
+ (void) &Inf_var; \
+ \
+ \
+ check (#FLOAT " isinf (inf) == 1", isinf (Inf_var) == 1); \
+ check (#FLOAT " isinf (-inf) == -1", isinf (-Inf_var) == -1); \
+ check (#FLOAT " !isinf (1)", !(isinf (one_var))); \
+ check (#FLOAT " !isinf (NaN)", !(isinf (NaN_var))); \
+ \
+ check (#FLOAT " isnan (NaN)", isnan (NaN_var)); \
+ check (#FLOAT " isnan (-NaN)", isnan (-NaN_var)); \
+ check (#FLOAT " !isnan (1)", !(isnan (one_var))); \
+ check (#FLOAT " !isnan (inf)", !(isnan (Inf_var))); \
+ \
+ /* \
+ the same tests but this time with NAN from <bits/nan.h> \
+ NAN is a double const \
+ */ \
+ check (#FLOAT " isnan (NAN)", isnan (NAN)); \
+ check (#FLOAT " isnan (-NAN)", isnan (-NAN)); \
+ check (#FLOAT " !isinf (NAN)", !(isinf (NAN))); \
+ check (#FLOAT " !isinf (-NAN)", !(isinf (-NAN))); \
+ \
+ /* \
+ And again with the value returned by the `nan' function. \
+ */ \
+ check (#FLOAT " isnan (NAN)", isnan (NANFUNC (""))); \
+ check (#FLOAT " isnan (-NAN)", isnan (-NANFUNC (""))); \
+ check (#FLOAT " !isinf (NAN)", !(isinf (NANFUNC ("")))); \
+ check (#FLOAT " !isinf (-NAN)", !(isinf (-NANFUNC ("")))); \
+ check (#FLOAT " NAN != NAN", NANFUNC ("") != NANFUNC ("")); \
+ \
+ /* test if HUGE_VALx is ok */ \
+ x1 = HUGEVAL; \
+ check (#FLOAT " isinf (HUGE_VALx) == +1", isinf (x1) == +1); \
+ x1 = - HUGEVAL; \
+ check (#FLOAT " isinf (-HUGE_VALx) == -1", isinf (x1) == -1); \
+}
+#ifndef DO_C99_MATH
+# undef TEST_FUNC
+# define TEST_FUNC(NAME, FLOAT, NANFUNC, EPSILON, HUGEVAL) \
+static void \
+NAME(void) \
+{ /* nothing */ }
+#endif
+
+#define TEST_VAL(NAME, FLOAT, NANFUNC, EPSILON, HUGEVAL) \
+static void \
+NAME (void) \
+{ \
+ /* Variables are declared volatile to forbid some compiler \
+ optimizations. */ \
+ volatile FLOAT Inf_var, NaN_var, zero_var, one_var; \
+ FLOAT x1, x2; \
+ \
+ zero_var = 0.0; \
+ one_var = 1.0; \
+ NaN_var = zero_var/zero_var; \
+ Inf_var = one_var / zero_var; \
+ \
+ (void) &zero_var; \
+ (void) &one_var; \
+ (void) &NaN_var; \
+ (void) &Inf_var; \
+ \
+ \
+ check (#FLOAT " inf == inf", Inf_var == Inf_var); \
+ check (#FLOAT " -inf == -inf", -Inf_var == -Inf_var); \
+ check (#FLOAT " inf != -inf", Inf_var != -Inf_var); \
+ check (#FLOAT " NaN != NaN", NaN_var != NaN_var); \
+ \
+ check (#FLOAT " NAN != NAN", NAN != NAN); \
+ \
+ \
+ /* test if EPSILON is ok */ \
+ x1 = 1.0; \
+ x2 = x1 + EPSILON; \
+ check (#FLOAT " 1 != 1+EPSILON", x1 != x2); \
+ \
+ x1 = 1.0; \
+ x2 = x1 - EPSILON; \
+ check (#FLOAT " 1 != 1-EPSILON", x1 != x2); \
+ \
+}
+
+TEST_VAL (float_test_value, float, nanf, FLT_EPSILON, HUGE_VALF)
+TEST_FUNC (float_test_call, float, nanf, FLT_EPSILON, HUGE_VALF)
+TEST_VAL (double_test_value, double, nan, DBL_EPSILON, HUGE_VAL)
+TEST_FUNC (double_test_call, double, nan, DBL_EPSILON, HUGE_VAL)
+#ifndef NO_LONG_DOUBLE
+TEST_VAL (ldouble_test_value, long double, nanl, LDBL_EPSILON, HUGE_VALL)
+TEST_FUNC (ldouble_test_call, long double, nanl, LDBL_EPSILON, HUGE_VALL)
+#endif
+
+int
+main (void)
+{
+ float_test_value ();
+ float_test_call ();
+ double_test_value ();
+ double_test_call ();
+
+#ifndef NO_LONG_DOUBLE
+ ldouble_test_value ();
+ ldouble_test_call ();
+#endif
+
+ return errors != 0;
+}
diff --git a/test/math/c99_test.c b/test/math/c99_test.c
new file mode 100644
index 0000000..73382e4
--- /dev/null
+++ b/test/math/c99_test.c
@@ -0,0 +1,116 @@
+#include <math.h>
+#include <float.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <limits.h>
+#include <stdio.h>
+
+#define check_d1(func, param, expected) \
+do { \
+ int err; hex_union ur; hex_union up; \
+ double result = func(param); up.f = param; ur.f = result; \
+ errors += (err = (result != (expected))); \
+ err \
+ ? printf("FAIL: %s(%g/"HEXFMT")=%g/"HEXFMT" (expected %g)\n", \
+ #func, (double)(param), (long long)up.hex, result, (long long)ur.hex, (double)(expected)) \
+ : printf("PASS: %s(%g)=%g\n", #func, (double)(param), result); \
+} while (0)
+
+#define check_i1(func, param, expected) \
+do { \
+ int err; hex_union up; \
+ long long result = func(param); up.f = param; \
+ errors += (err = (result != (expected))); \
+ err \
+ ? printf("FAIL: %s(%g/"HEXFMT")=%lld/%llu (expected %llu)\n", \
+ #func, (double)(param), (long long)up.hex, result, result, (long long)(expected)) \
+ : printf("PASS: %s(%g)=%lld/%llu\n", #func, (double)(param), result, result); \
+} while (0)
+
+#define HEXFMT "%08llx"
+typedef union {
+ double f;
+ uint64_t hex;
+} hex_union;
+
+double zero = 0.0;
+double minus_zero = 0.0;
+double nan_value = 0.0;
+int errors = 0;
+
+int main(void)
+{
+ nan_value /= nan_value;
+ minus_zero = copysign(zero, -1.0);
+
+ check_i1(isfinite, 1.0, 1);
+ check_i1(isfinite, 2.0, 1);
+ check_i1(isfinite, 3.0, 1);
+ check_i1(isfinite, DBL_MAX, 1);
+ check_i1(isfinite, FLT_MAX, 1);
+ check_i1(isfinite, HUGE_VAL, 0);
+ check_i1(isfinite, HUGE_VALF, 0);
+ check_i1(isfinite, HUGE_VALL, 0);
+ check_i1(isfinite, nan_value, 0);
+ check_i1(isfinite, nan_value, 0);
+ check_i1(isfinite, nan_value, 0);
+
+ check_i1(isnan, 1.0, 0);
+ check_i1(isnan, 2.0, 0);
+ check_i1(isnan, 3.0, 0);
+ check_i1(isnan, DBL_MAX, 0);
+ check_i1(isnan, FLT_MAX, 0);
+ check_i1(isnan, HUGE_VAL, 0);
+ check_i1(isnan, HUGE_VALF, 0);
+ check_i1(isnan, HUGE_VALL, 0);
+ check_i1(isnan, (float)HUGE_VALL, 0);
+ check_i1(isnan, nan_value, 1);
+ check_i1(isnan, nan_value, 1);
+ check_i1(isnan, nan_value, 1);
+
+ check_i1(isinf, 1.0, 0);
+ check_i1(isinf, 2.0, 0);
+ check_i1(isinf, 3.0, 0);
+ check_i1(isinf, DBL_MAX, 0);
+ check_i1(isinf, FLT_MAX, 0);
+ check_i1(isinf, (float)DBL_MAX, 1);
+ check_i1(isinf, HUGE_VAL, 1);
+ check_i1(isinf, HUGE_VALF, 1);
+ check_i1(isinf, HUGE_VALL, 1);
+ check_i1(isinf, (float)HUGE_VALL, 1);
+ check_i1(isinf, nan_value, 0);
+ check_i1(isinf, nan_value, 0);
+ check_i1(isinf, nan_value, 0);
+
+ check_i1(fpclassify, minus_zero, FP_ZERO);
+ check_i1(fpclassify, 0.0, FP_ZERO);
+ check_i1(fpclassify, 1.0, FP_NORMAL);
+ check_i1(fpclassify, 2.0, FP_NORMAL);
+ check_i1(fpclassify, 3.0, FP_NORMAL);
+ check_i1(fpclassify, DBL_MIN/1.01, FP_SUBNORMAL);
+ check_i1(fpclassify, DBL_MIN, FP_NORMAL);
+ check_i1(fpclassify, DBL_MAX, FP_NORMAL);
+ check_i1(fpclassify, FLT_MAX, FP_NORMAL);
+ check_i1(fpclassify, DBL_MAX, FP_NORMAL);
+ check_i1(fpclassify, DBL_MAX*1.01, FP_INFINITE);
+ check_i1(fpclassify, HUGE_VAL, FP_INFINITE);
+ check_i1(fpclassify, HUGE_VALF, FP_INFINITE);
+ check_i1(fpclassify, HUGE_VALL, FP_INFINITE);
+ check_i1(fpclassify, (float)HUGE_VALL, FP_INFINITE);
+ check_i1(fpclassify, nan_value, FP_NAN);
+ check_i1(fpclassify, nan_value, FP_NAN);
+ check_i1(fpclassify, nan_value, FP_NAN);
+
+ check_i1(!!signbit, -1.0, 1);
+ check_i1(!!signbit, minus_zero, 1);
+ check_i1(!!signbit, 0.0, 0);
+ check_i1(!!signbit, HUGE_VAL, 0);
+ check_i1(!!signbit, HUGE_VALF, 0);
+ check_i1(!!signbit, HUGE_VALL, 0);
+ check_i1(!!signbit, -HUGE_VAL, 1);
+ check_i1(!!signbit, -HUGE_VALF, 1);
+ check_i1(!!signbit, -HUGE_VALL, 1);
+
+ printf("Errors: %d\n", errors);
+ return errors;
+}
diff --git a/test/math/compile_test.c b/test/math/compile_test.c
new file mode 100644
index 0000000..aedfde6
--- /dev/null
+++ b/test/math/compile_test.c
@@ -0,0 +1,141 @@
+#include <math.h>
+
+static int testf(float float_x, long double long_double_x, /*float complex float_complex_x,*/ int int_x, long long_x)
+{
+int r = 0;
+r += acosf(float_x);
+r += acoshf(float_x);
+r += asinf(float_x);
+r += asinhf(float_x);
+r += atan2f(float_x, float_x);
+r += atanf(float_x);
+r += atanhf(float_x);
+/*r += cargf(float_complex_x); - will fight with complex numbers later */
+r += cbrtf(float_x);
+r += ceilf(float_x);
+r += copysignf(float_x, float_x);
+r += cosf(float_x);
+r += coshf(float_x);
+r += erfcf(float_x);
+r += erff(float_x);
+r += exp2f(float_x);
+r += expf(float_x);
+r += expm1f(float_x);
+r += fabsf(float_x);
+r += fdimf(float_x, float_x);
+r += floorf(float_x);
+r += fmaf(float_x, float_x, float_x);
+r += fmaxf(float_x, float_x);
+r += fminf(float_x, float_x);
+r += fmodf(float_x, float_x);
+r += frexpf(float_x, &int_x);
+r += gammaf(float_x);
+r += hypotf(float_x, float_x);
+r += ilogbf(float_x);
+r += ldexpf(float_x, int_x);
+r += lgammaf(float_x);
+r += llrintf(float_x);
+r += llroundf(float_x);
+r += log10f(float_x);
+r += log1pf(float_x);
+r += log2f(float_x);
+r += logbf(float_x);
+r += logf(float_x);
+r += lrintf(float_x);
+r += lroundf(float_x);
+r += modff(float_x, &float_x);
+r += nearbyintf(float_x);
+r += nexttowardf(float_x, long_double_x);
+r += powf(float_x, float_x);
+r += remainderf(float_x, float_x);
+r += remquof(float_x, float_x, &int_x);
+r += rintf(float_x);
+r += roundf(float_x);
+#ifdef __UCLIBC_SUSV3_LEGACY__
+r += scalbf(float_x, float_x);
+#endif
+r += scalblnf(float_x, long_x);
+r += scalbnf(float_x, int_x);
+r += significandf(float_x);
+r += sinf(float_x);
+r += sinhf(float_x);
+r += sqrtf(float_x);
+r += tanf(float_x);
+r += tanhf(float_x);
+r += tgammaf(float_x);
+r += truncf(float_x);
+return r;
+}
+
+static int testl(long double long_double_x, int int_x, long long_x)
+{
+int r = 0;
+r += __finitel(long_double_x);
+r += __fpclassifyl(long_double_x);
+r += __isinfl(long_double_x);
+r += __isnanl(long_double_x);
+r += __signbitl(long_double_x);
+r += acoshl(long_double_x);
+r += acosl(long_double_x);
+r += asinhl(long_double_x);
+r += asinl(long_double_x);
+r += atan2l(long_double_x, long_double_x);
+r += atanhl(long_double_x);
+r += atanl(long_double_x);
+r += cbrtl(long_double_x);
+r += ceill(long_double_x);
+r += copysignl(long_double_x, long_double_x);
+r += coshl(long_double_x);
+r += cosl(long_double_x);
+r += erfcl(long_double_x);
+r += erfl(long_double_x);
+r += exp2l(long_double_x);
+r += expl(long_double_x);
+r += expm1l(long_double_x);
+r += fabsl(long_double_x);
+r += fdiml(long_double_x, long_double_x);
+r += floorl(long_double_x);
+r += fmal(long_double_x, long_double_x, long_double_x);
+r += fmaxl(long_double_x, long_double_x);
+r += fminl(long_double_x, long_double_x);
+r += fmodl(long_double_x, long_double_x);
+r += frexpl(long_double_x, &int_x);
+r += hypotl(long_double_x, long_double_x);
+r += ilogbl(long_double_x);
+r += ldexpl(long_double_x, int_x);
+r += lgammal(long_double_x);
+r += llrintl(long_double_x);
+r += llroundl(long_double_x);
+r += log10l(long_double_x);
+r += log1pl(long_double_x);
+r += log2l(long_double_x);
+r += logbl(long_double_x);
+r += logl(long_double_x);
+r += lrintl(long_double_x);
+r += lroundl(long_double_x);
+r += modfl(long_double_x, &long_double_x);
+r += nearbyintl(long_double_x);
+r += nextafterl(long_double_x, long_double_x);
+r += nexttowardl(long_double_x, long_double_x);
+r += powl(long_double_x, long_double_x);
+r += remainderl(long_double_x, long_double_x);
+r += remquol(long_double_x, long_double_x, &int_x);
+r += rintl(long_double_x);
+r += roundl(long_double_x);
+r += scalblnl(long_double_x, long_x);
+r += scalbnl(long_double_x, int_x);
+r += sinhl(long_double_x);
+r += sinl(long_double_x);
+r += sqrtl(long_double_x);
+r += tanhl(long_double_x);
+r += tanl(long_double_x);
+r += tgammal(long_double_x);
+r += truncl(long_double_x);
+return r;
+}
+
+int main(int argc, char **argv)
+{
+ /* Always 0 but gcc hopefully won't be able to notice */
+ return 5 & ((long)&testf) & ((long)&testl) & 2;
+}
diff --git a/test/math/fenv.h b/test/math/fenv.h
new file mode 100644
index 0000000..0025a62
--- /dev/null
+++ b/test/math/fenv.h
@@ -0,0 +1,3 @@
+/* until we support fenv ... */
+#define feclearexcept(X)
+#define fetestexcept(X) (0)
diff --git a/test/math/gamma.c b/test/math/gamma.c
new file mode 100644
index 0000000..69c10af
--- /dev/null
+++ b/test/math/gamma.c
@@ -0,0 +1,73 @@
+#include <math.h>
+#include <float.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <stdio.h>
+
+#define check_d1(func, param, expected) \
+do { \
+ int err; hex_union ur; hex_union up; \
+ double result = func(param); up.f = param; ur.f = result; \
+ errors += (err = (result != (expected))); \
+ err \
+ ? printf("FAIL: %s(%g/"HEXFMT")=%g/"HEXFMT" (expected %g)\n", \
+ #func, (double)(param), (long long)up.hex, result, (long long)ur.hex, (double)(expected)) \
+ : printf("PASS: %s(%g)=%g\n", #func, (double)(param), result); \
+} while (0)
+
+#define HEXFMT "%08llx"
+typedef union {
+ double f;
+ uint64_t hex;
+} hex_union;
+double result;
+
+#define M_2_SQRT_PIl 3.5449077018110320545963349666822903L /* 2 sqrt (M_PIl) */
+#define M_SQRT_PIl 1.7724538509055160272981674833411451L /* sqrt (M_PIl) */
+
+double zero = 0.0;
+double minus_zero = 0.0;
+double nan_value = 0.0;
+int errors = 0;
+
+int main(void)
+{
+ nan_value /= nan_value;
+ minus_zero = copysign(zero, -1.0);
+
+ //check_d1(tgamma, HUGE_VAL, NAN);
+ //check_d1(tgamma, negative_integer, NAN);
+ check_d1(tgamma, 0.0, HUGE_VAL); /* pole */
+ check_d1(tgamma, minus_zero, -HUGE_VAL); /* pole */
+ check_d1(tgamma, DBL_MAX/2, HUGE_VAL); /* overflow to inf */
+ check_d1(tgamma, DBL_MAX, HUGE_VAL); /* overflow to inf */
+ check_d1(tgamma, HUGE_VAL, HUGE_VAL); /* overflow to inf */
+ check_d1(tgamma, 7, 2*3*4*5*6); /* normal value */
+ check_d1(tgamma, -0.5, -M_2_SQRT_PIl); /* normal value (testing negative points) */
+
+ check_d1(lgamma, -HUGE_VAL, HUGE_VAL);
+ //check_d1(lgamma, HUGE_VAL, NAN);
+ check_d1(lgamma, 0.0, HUGE_VAL); /* pole */
+ check_d1(lgamma, minus_zero, HUGE_VAL); /* pole */
+ check_d1(lgamma, 1.0, 0.0);
+ check_d1(lgamma, 2.0, 0.0);
+ check_d1(lgamma, DBL_MAX/2, HUGE_VAL); /* overflow to inf */
+ check_d1(lgamma, DBL_MAX, HUGE_VAL); /* overflow to inf */
+ check_d1(lgamma, HUGE_VAL, HUGE_VAL); /* overflow to inf */
+ check_d1(lgamma, 7, log(2*3*4*5*6)); /* normal value */
+
+ /* In glibc, gamma == lgamma. (In BSD, it's == tgamma */
+ check_d1(gamma, -HUGE_VAL, HUGE_VAL);
+ //check_d1(gamma, HUGE_VAL, NAN);
+ check_d1(gamma, 0.0, HUGE_VAL); /* pole */
+ check_d1(gamma, minus_zero, HUGE_VAL); /* pole */
+ check_d1(gamma, 1.0, 0.0);
+ check_d1(gamma, 2.0, 0.0);
+ check_d1(gamma, DBL_MAX/2, HUGE_VAL); /* overflow to inf */
+ check_d1(gamma, DBL_MAX, HUGE_VAL); /* overflow to inf */
+ check_d1(gamma, HUGE_VAL, HUGE_VAL); /* overflow to inf */
+ check_d1(gamma, 7, log(2*3*4*5*6)); /* normal value */
+
+ printf("Errors: %d\n", errors);
+ return errors;
+}
diff --git a/test/math/gen-libm-test.pl b/test/math/gen-libm-test.pl
new file mode 100755
index 0000000..118f352
--- /dev/null
+++ b/test/math/gen-libm-test.pl
@@ -0,0 +1,737 @@
+#!/usr/bin/env perl
+# Copyright (C) 1999 Free Software Foundation, Inc.
+# This file is part of the GNU C Library.
+# Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+# 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; see the file COPYING.LIB. If
+# not, see <http://www.gnu.org/licenses/>.
+
+# This file needs to be tidied up
+# Note that functions and tests share the same namespace.
+
+# Information about tests are stored in: %results
+# $results{$test}{"kind"} is either "fct" or "test" and flags whether this
+# is a maximal error of a function or a single test.
+# $results{$test}{"type"} is the result type, e.g. normal or complex.
+# $results{$test}{"has_ulps"} is set if deltas exist.
+# $results{$test}{"has_fails"} is set if exptected failures exist.
+# In the following description $type and $float are:
+# - $type is either "normal", "real" (for the real part of a complex number)
+# or "imag" (for the imaginary part # of a complex number).
+# - $float is either of float, ifloat, double, idouble, ldouble, ildouble;
+# It represents the underlying floating point type (float, double or long
+# double) and if inline functions (the leading i stands for inline)
+# are used.
+# $results{$test}{$type}{"fail"}{$float} is defined and has a 1 if
+# the test is expected to fail
+# $results{$test}{$type}{"ulp"}{$float} is defined and has a delta as value
+
+
+use Getopt::Std;
+
+use strict;
+
+use vars qw ($input $output);
+use vars qw (%results);
+use vars qw (@tests @functions);
+use vars qw ($count);
+use vars qw (%beautify @all_floats);
+use vars qw ($output_dir $ulps_file);
+
+# all_floats is sorted and contains all recognised float types
+@all_floats = ('double', 'float', 'idouble',
+ 'ifloat', 'ildouble', 'ldouble');
+
+%beautify =
+ ( "minus_zero" => "-0",
+ "plus_zero" => "+0",
+ "minus_infty" => "-inf",
+ "plus_infty" => "inf",
+ "nan_value" => "NaN",
+ "M_El" => "e",
+ "M_E2l" => "e^2",
+ "M_E3l" => "e^3",
+ "M_LOG10El", "log10(e)",
+ "M_PIl" => "pi",
+ "M_PI_34l" => "3/4 pi",
+ "M_PI_2l" => "pi/2",
+ "M_PI_4l" => "pi/4",
+ "M_PI_6l" => "pi/6",
+ "M_PI_34_LOG10El" => "3/4 pi*log10(e)",
+ "M_PI_LOG10El" => "pi*log10(e)",
+ "M_PI2_LOG10El" => "pi/2*log10(e)",
+ "M_PI4_LOG10El" => "pi/4*log10(e)",
+ "M_LOG_SQRT_PIl" => "log(sqrt(pi))",
+ "M_LOG_2_SQRT_PIl" => "log(2*sqrt(pi))",
+ "M_2_SQRT_PIl" => "2 sqrt (pi)",
+ "M_SQRT_PIl" => "sqrt (pi)",
+ "INVALID_EXCEPTION" => "invalid exception",
+ "DIVIDE_BY_ZERO_EXCEPTION" => "division by zero exception",
+ "INVALID_EXCEPTION_OK" => "invalid exception allowed",
+ "DIVIDE_BY_ZERO_EXCEPTION_OK" => "division by zero exception allowed",
+ "EXCEPTIONS_OK" => "exceptions allowed",
+ "IGNORE_ZERO_INF_SIGN" => "sign of zero/inf not specified",
+"INVALID_EXCEPTION|IGNORE_ZERO_INF_SIGN" => "invalid exception and sign of zero/inf not specified"
+ );
+
+
+# get Options
+# Options:
+# u: ulps-file
+# h: help
+# o: output-directory
+# n: generate new ulps file
+use vars qw($opt_u $opt_h $opt_o $opt_n);
+getopts('u:o:nh');
+
+$ulps_file = 'libm-test-ulps';
+$output_dir = '';
+
+if ($opt_h) {
+ print "Usage: gen-libm-test.pl [OPTIONS]\n";
+ print " -h print this help, then exit\n";
+ print " -o DIR directory where generated files will be placed\n";
+ print " -n only generate sorted file NewUlps from libm-test-ulps\n";
+ print " -u FILE input file with ulps\n";
+ exit 0;
+}
+
+$ulps_file = $opt_u if ($opt_u);
+$output_dir = $opt_o if ($opt_o);
+
+$input = "libm-test.inc";
+$output = "${output_dir}libm-test.c";
+
+$count = 0;
+
+&parse_ulps ($ulps_file);
+&generate_testfile ($input, $output) unless ($opt_n);
+&output_ulps ("${output_dir}libm-test-ulps.h", $ulps_file) unless ($opt_n);
+&print_ulps_file ("${output_dir}NewUlps") if ($opt_n);
+
+# Return a nicer representation
+sub beautify {
+ my ($arg) = @_;
+ my ($tmp);
+
+ if (exists $beautify{$arg}) {
+ return $beautify{$arg};
+ }
+ if ($arg =~ /^-/) {
+ $tmp = $arg;
+ $tmp =~ s/^-//;
+ if (exists $beautify{$tmp}) {
+ return '-' . $beautify{$tmp};
+ }
+ }
+ if ($arg =~ /[0-9]L$/) {
+ $arg =~ s/L$//;
+ }
+ return $arg;
+}
+
+# Return a nicer representation of a complex number
+sub build_complex_beautify {
+ my ($r, $i) = @_;
+ my ($str1, $str2);
+
+ $str1 = &beautify ($r);
+ $str2 = &beautify ($i);
+ if ($str2 =~ /^-/) {
+ $str2 =~ s/^-//;
+ $str1 .= ' - ' . $str2;
+ } else {
+ $str1 .= ' + ' . $str2;
+ }
+ $str1 .= ' i';
+ return $str1;
+}
+
+# Return name of a variable
+sub get_variable {
+ my ($number) = @_;
+
+ return "x" if ($number == 1);
+ return "y" if ($number == 2);
+ return "z" if ($number == 3);
+ # return x1,x2,...
+ $number =-3;
+ return "x$number";
+}
+
+# Add a new test to internal data structures and fill in the
+# ulps, failures and exception information for the C line.
+sub new_test {
+ my ($test, $exception) = @_;
+ my $rest;
+
+ # Add ulp, xfail
+ if (exists $results{$test}{'has_ulps'}) {
+ $rest = ", DELTA$count";
+ } else {
+ $rest = ', 0';
+ }
+ if (exists $results{$test}{'has_fails'}) {
+ $rest .= ", FAIL$count";
+ } else {
+ $rest .= ', 0';
+ }
+ if (defined $exception) {
+ $rest .= ", $exception";
+ } else {
+ $rest .= ', 0';
+ }
+ $rest .= ");\n";
+ # We must increment here to keep @tests and count in sync
+ push @tests, $test;
+ ++$count;
+ return $rest;
+}
+
+# Treat some functions especially.
+# Currently only sincos needs extra treatment.
+sub special_functions {
+ my ($file, $args) = @_;
+ my (@args, $str, $test, $cline);
+
+ @args = split /,\s*/, $args;
+
+ unless ($args[0] =~ /sincos/) {
+ die ("Don't know how to handle $args[0] extra.");
+ }
+ print $file " FUNC (sincos) ($args[1], &sin_res, &cos_res);\n";
+
+ $str = 'sincos (' . &beautify ($args[1]) . ', &sin_res, &cos_res)';
+ # handle sin
+ $test = $str . ' puts ' . &beautify ($args[2]) . ' in sin_res';
+ if ($#args == 4) {
+ $test .= " plus " . &beautify ($args[4]);
+ }
+
+ $cline = " check_float (\"$test\", sin_res, $args[2]";
+ $cline .= &new_test ($test, $args[4]);
+ print $file $cline;
+
+ # handle cos
+ $test = $