summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorngie <ngie@FreeBSD.org>2016-01-06 20:21:40 +0000
committerngie <ngie@FreeBSD.org>2016-01-06 20:21:40 +0000
commitd42686c8e06e5c0ff53de7112114f4d98755baa6 (patch)
tree99daa019cfcfe018bc200e270d3c2cecf5cb0d3d
parent03aed74e9c37f31301d107b9678a5e10a1f1dd9e (diff)
downloadFreeBSD-src-d42686c8e06e5c0ff53de7112114f4d98755baa6.zip
FreeBSD-src-d42686c8e06e5c0ff53de7112114f4d98755baa6.tar.gz
MFC r292328:
Integrate a number of testcases from tools/regression/lib/msun into the FreeBSD test suite There's no functional change with these testcases; they're purposely being left in TAP format for the time being Other testcases which crash on amd64/i386 as-is have not been integrated yet (they need to be retested on a later version of CURRENT, as I haven't used i386 in some time)
-rw-r--r--lib/msun/tests/Makefile22
-rw-r--r--lib/msun/tests/cexp_test.c322
-rw-r--r--lib/msun/tests/conj_test.c139
-rw-r--r--lib/msun/tests/csqrt_test.c295
-rw-r--r--lib/msun/tests/fenv_test.c (renamed from tools/regression/lib/msun/test-fenv.c)0
-rw-r--r--lib/msun/tests/fmaxmin_test.c (renamed from tools/regression/lib/msun/test-fmaxmin.c)0
-rw-r--r--lib/msun/tests/ilogb_test.c (renamed from tools/regression/lib/msun/test-ilogb.c)0
-rw-r--r--lib/msun/tests/invctrig_test.c (renamed from tools/regression/lib/msun/test-invctrig.c)0
-rw-r--r--lib/msun/tests/logarithm_test.c (renamed from tools/regression/lib/msun/test-logarithm.c)0
-rw-r--r--lib/msun/tests/lrint_test.c (renamed from tools/regression/lib/msun/test-lrint.c)0
-rw-r--r--lib/msun/tests/nan_test.c (renamed from tools/regression/lib/msun/test-nan.c)0
-rw-r--r--lib/msun/tests/nearbyint_test.c (renamed from tools/regression/lib/msun/test-nearbyint.c)0
-rw-r--r--lib/msun/tests/next_test.c (renamed from tools/regression/lib/msun/test-next.c)0
-rw-r--r--lib/msun/tests/rem_test.c (renamed from tools/regression/lib/msun/test-rem.c)0
-rw-r--r--lib/msun/tests/trig_test.c280
-rw-r--r--tools/regression/lib/msun/Makefile8
-rw-r--r--tools/regression/lib/msun/test-cexp.t10
-rw-r--r--tools/regression/lib/msun/test-conj.t10
-rw-r--r--tools/regression/lib/msun/test-csqrt.t10
-rw-r--r--tools/regression/lib/msun/test-fenv.t10
-rw-r--r--tools/regression/lib/msun/test-fmaxmin.t10
-rw-r--r--tools/regression/lib/msun/test-ilogb.t10
-rw-r--r--tools/regression/lib/msun/test-logarithm.t10
-rw-r--r--tools/regression/lib/msun/test-lrint.t10
-rw-r--r--tools/regression/lib/msun/test-nan.t10
-rw-r--r--tools/regression/lib/msun/test-nearbyint.t10
-rw-r--r--tools/regression/lib/msun/test-next.t10
-rw-r--r--tools/regression/lib/msun/test-rem.t10
-rw-r--r--tools/regression/lib/msun/test-trig.t10
29 files changed, 1061 insertions, 135 deletions
diff --git a/lib/msun/tests/Makefile b/lib/msun/tests/Makefile
index 7199ea7..ffa1765 100644
--- a/lib/msun/tests/Makefile
+++ b/lib/msun/tests/Makefile
@@ -36,12 +36,34 @@ NETBSD_ATF_TESTS_C+= sqrt_test
NETBSD_ATF_TESTS_C+= tan_test
NETBSD_ATF_TESTS_C+= tanh_test
+TAP_TESTS_C+= cexp_test
+TAP_TESTS_C+= conj_test
+TAP_TESTS_C+= csqrt_test
+TAP_TESTS_C+= fenv_test
+TAP_TESTS_C+= fmaxmin_test
+TAP_TESTS_C+= ilogb_test
+TAP_TESTS_C+= invctrig_test
+TAP_TESTS_C+= logarithm_test
+TAP_TESTS_C+= lrint_test
+TAP_TESTS_C+= nan_test
+TAP_TESTS_C+= nearbyint_test
+TAP_TESTS_C+= next_test
+TAP_TESTS_C+= rem_test
+TAP_TESTS_C+= trig_test
+
+.for t in ${TAP_TESTS_C}
+CFLAGS.$t+= -O0
+CFLAGS.$t+= -I${SRCTOP}/tools/regression/lib/msun
+.endfor
+
CSTD= c99
LDADD+= -lm
DPADD+= ${LIBM}
#COPTS+= -Wfloat-equal
+IGNORE_PRAGMA=
+
# Copied from lib/msun/Makefile
.if ${MACHINE_CPUARCH} == "i386"
ARCH_SUBDIR= i387
diff --git a/lib/msun/tests/cexp_test.c b/lib/msun/tests/cexp_test.c
new file mode 100644
index 0000000..6be71ad
--- /dev/null
+++ b/lib/msun/tests/cexp_test.c
@@ -0,0 +1,322 @@
+/*-
+ * Copyright (c) 2008-2011 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Tests for corner cases in cexp*().
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <assert.h>
+#include <complex.h>
+#include <fenv.h>
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "test-utils.h"
+
+#pragma STDC FENV_ACCESS ON
+#pragma STDC CX_LIMITED_RANGE OFF
+
+/*
+ * Test that a function returns the correct value and sets the
+ * exception flags correctly. The exceptmask specifies which
+ * exceptions we should check. We need to be lenient for several
+ * reasons, but mainly because on some architectures it's impossible
+ * to raise FE_OVERFLOW without raising FE_INEXACT. In some cases,
+ * whether cexp() raises an invalid exception is unspecified.
+ *
+ * These are macros instead of functions so that assert provides more
+ * meaningful error messages.
+ *
+ * XXX The volatile here is to avoid gcc's bogus constant folding and work
+ * around the lack of support for the FENV_ACCESS pragma.
+ */
+#define test(func, z, result, exceptmask, excepts, checksign) do { \
+ volatile long double complex _d = z; \
+ assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
+ assert(cfpequal_cs((func)(_d), (result), (checksign))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
+} while (0)
+
+/* Test within a given tolerance. */
+#define test_tol(func, z, result, tol) do { \
+ volatile long double complex _d = z; \
+ assert(cfpequal_tol((func)(_d), (result), (tol), \
+ FPE_ABS_ZERO | CS_BOTH)); \
+} while (0)
+
+/* Test all the functions that compute cexp(x). */
+#define testall(x, result, exceptmask, excepts, checksign) do { \
+ test(cexp, x, result, exceptmask, excepts, checksign); \
+ test(cexpf, x, result, exceptmask, excepts, checksign); \
+} while (0)
+
+/*
+ * Test all the functions that compute cexp(x), within a given tolerance.
+ * The tolerance is specified in ulps.
+ */
+#define testall_tol(x, result, tol) do { \
+ test_tol(cexp, x, result, tol * DBL_ULP()); \
+ test_tol(cexpf, x, result, tol * FLT_ULP()); \
+} while (0)
+
+/* Various finite non-zero numbers to test. */
+static const float finites[] =
+{ -42.0e20, -1.0, -1.0e-10, -0.0, 0.0, 1.0e-10, 1.0, 42.0e20 };
+
+
+/* Tests for 0 */
+void
+test_zero(void)
+{
+
+ /* cexp(0) = 1, no exceptions raised */
+ testall(0.0, 1.0, ALL_STD_EXCEPT, 0, 1);
+ testall(-0.0, 1.0, ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(0.0, -0.0), CMPLXL(1.0, -0.0), ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(-0.0, -0.0), CMPLXL(1.0, -0.0), ALL_STD_EXCEPT, 0, 1);
+}
+
+/*
+ * Tests for NaN. The signs of the results are indeterminate unless the
+ * imaginary part is 0.
+ */
+void
+test_nan()
+{
+ int i;
+
+ /* cexp(x + NaNi) = NaN + NaNi and optionally raises invalid */
+ /* cexp(NaN + yi) = NaN + NaNi and optionally raises invalid (|y|>0) */
+ for (i = 0; i < nitems(finites); i++) {
+ printf("# Run %d..\n", i);
+ testall(CMPLXL(finites[i], NAN), CMPLXL(NAN, NAN),
+ ALL_STD_EXCEPT & ~FE_INVALID, 0, 0);
+ if (finites[i] == 0.0)
+ continue;
+ /* XXX FE_INEXACT shouldn't be raised here */
+ testall(CMPLXL(NAN, finites[i]), CMPLXL(NAN, NAN),
+ ALL_STD_EXCEPT & ~(FE_INVALID | FE_INEXACT), 0, 0);
+ }
+
+ /* cexp(NaN +- 0i) = NaN +- 0i */
+ testall(CMPLXL(NAN, 0.0), CMPLXL(NAN, 0.0), ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(NAN, -0.0), CMPLXL(NAN, -0.0), ALL_STD_EXCEPT, 0, 1);
+
+ /* cexp(inf + NaN i) = inf + nan i */
+ testall(CMPLXL(INFINITY, NAN), CMPLXL(INFINITY, NAN),
+ ALL_STD_EXCEPT, 0, 0);
+ /* cexp(-inf + NaN i) = 0 */
+ testall(CMPLXL(-INFINITY, NAN), CMPLXL(0.0, 0.0),
+ ALL_STD_EXCEPT, 0, 0);
+ /* cexp(NaN + NaN i) = NaN + NaN i */
+ testall(CMPLXL(NAN, NAN), CMPLXL(NAN, NAN),
+ ALL_STD_EXCEPT, 0, 0);
+}
+
+void
+test_inf(void)
+{
+ int i;
+
+ /* cexp(x + inf i) = NaN + NaNi and raises invalid */
+ for (i = 0; i < nitems(finites); i++) {
+ printf("# Run %d..\n", i);
+ testall(CMPLXL(finites[i], INFINITY), CMPLXL(NAN, NAN),
+ ALL_STD_EXCEPT, FE_INVALID, 1);
+ }
+ /* cexp(-inf + yi) = 0 * (cos(y) + sin(y)i) */
+ /* XXX shouldn't raise an inexact exception */
+ testall(CMPLXL(-INFINITY, M_PI_4), CMPLXL(0.0, 0.0),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(-INFINITY, 3 * M_PI_4), CMPLXL(-0.0, 0.0),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(-INFINITY, 5 * M_PI_4), CMPLXL(-0.0, -0.0),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(-INFINITY, 7 * M_PI_4), CMPLXL(0.0, -0.0),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(-INFINITY, 0.0), CMPLXL(0.0, 0.0),
+ ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(-INFINITY, -0.0), CMPLXL(0.0, -0.0),
+ ALL_STD_EXCEPT, 0, 1);
+ /* cexp(inf + yi) = inf * (cos(y) + sin(y)i) (except y=0) */
+ /* XXX shouldn't raise an inexact exception */
+ testall(CMPLXL(INFINITY, M_PI_4), CMPLXL(INFINITY, INFINITY),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(INFINITY, 3 * M_PI_4), CMPLXL(-INFINITY, INFINITY),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(INFINITY, 5 * M_PI_4), CMPLXL(-INFINITY, -INFINITY),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ testall(CMPLXL(INFINITY, 7 * M_PI_4), CMPLXL(INFINITY, -INFINITY),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ /* cexp(inf + 0i) = inf + 0i */
+ testall(CMPLXL(INFINITY, 0.0), CMPLXL(INFINITY, 0.0),
+ ALL_STD_EXCEPT, 0, 1);
+ testall(CMPLXL(INFINITY, -0.0), CMPLXL(INFINITY, -0.0),
+ ALL_STD_EXCEPT, 0, 1);
+}
+
+void
+test_reals(void)
+{
+ int i;
+
+ for (i = 0; i < nitems(finites); i++) {
+ /* XXX could check exceptions more meticulously */
+ printf("# Run %d..\n", i);
+ test(cexp, CMPLXL(finites[i], 0.0),
+ CMPLXL(exp(finites[i]), 0.0),
+ FE_INVALID | FE_DIVBYZERO, 0, 1);
+ test(cexp, CMPLXL(finites[i], -0.0),
+ CMPLXL(exp(finites[i]), -0.0),
+ FE_INVALID | FE_DIVBYZERO, 0, 1);
+ test(cexpf, CMPLXL(finites[i], 0.0),
+ CMPLXL(expf(finites[i]), 0.0),
+ FE_INVALID | FE_DIVBYZERO, 0, 1);
+ test(cexpf, CMPLXL(finites[i], -0.0),
+ CMPLXL(expf(finites[i]), -0.0),
+ FE_INVALID | FE_DIVBYZERO, 0, 1);
+ }
+}
+
+void
+test_imaginaries(void)
+{
+ int i;
+
+ for (i = 0; i < nitems(finites); i++) {
+ printf("# Run %d..\n", i);
+ test(cexp, CMPLXL(0.0, finites[i]),
+ CMPLXL(cos(finites[i]), sin(finites[i])),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ test(cexp, CMPLXL(-0.0, finites[i]),
+ CMPLXL(cos(finites[i]), sin(finites[i])),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ test(cexpf, CMPLXL(0.0, finites[i]),
+ CMPLXL(cosf(finites[i]), sinf(finites[i])),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ test(cexpf, CMPLXL(-0.0, finites[i]),
+ CMPLXL(cosf(finites[i]), sinf(finites[i])),
+ ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
+ }
+}
+
+void
+test_small(void)
+{
+ static const double tests[] = {
+ /* csqrt(a + bI) = x + yI */
+ /* a b x y */
+ 1.0, M_PI_4, M_SQRT2 * 0.5 * M_E, M_SQRT2 * 0.5 * M_E,
+ -1.0, M_PI_4, M_SQRT2 * 0.5 / M_E, M_SQRT2 * 0.5 / M_E,
+ 2.0, M_PI_2, 0.0, M_E * M_E,
+ M_LN2, M_PI, -2.0, 0.0,
+ };
+ double a, b;
+ double x, y;
+ int i;
+
+ for (i = 0; i < nitems(tests); i += 4) {
+ printf("# Run %d..\n", i);
+ a = tests[i];
+ b = tests[i + 1];
+ x = tests[i + 2];
+ y = tests[i + 3];
+ test_tol(cexp, CMPLXL(a, b), CMPLXL(x, y), 3 * DBL_ULP());
+
+ /* float doesn't have enough precision to pass these tests */
+ if (x == 0 || y == 0)
+ continue;
+ test_tol(cexpf, CMPLXL(a, b), CMPLXL(x, y), 1 * FLT_ULP());
+ }
+}
+
+/* Test inputs with a real part r that would overflow exp(r). */
+void
+test_large(void)
+{
+
+ test_tol(cexp, CMPLXL(709.79, 0x1p-1074),
+ CMPLXL(INFINITY, 8.94674309915433533273e-16), DBL_ULP());
+ test_tol(cexp, CMPLXL(1000, 0x1p-1074),
+ CMPLXL(INFINITY, 9.73344457300016401328e+110), DBL_ULP());
+ test_tol(cexp, CMPLXL(1400, 0x1p-1074),
+ CMPLXL(INFINITY, 5.08228858149196559681e+284), DBL_ULP());
+ test_tol(cexp, CMPLXL(900, 0x1.23456789abcdep-1020),
+ CMPLXL(INFINITY, 7.42156649354218408074e+83), DBL_ULP());
+ test_tol(cexp, CMPLXL(1300, 0x1.23456789abcdep-1020),
+ CMPLXL(INFINITY, 3.87514844965996756704e+257), DBL_ULP());
+
+ test_tol(cexpf, CMPLXL(88.73, 0x1p-149),
+ CMPLXL(INFINITY, 4.80265603e-07), 2 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(90, 0x1p-149),
+ CMPLXL(INFINITY, 1.7101492622e-06f), 2 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(192, 0x1p-149),
+ CMPLXL(INFINITY, 3.396809344e+38f), 2 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(120, 0x1.234568p-120),
+ CMPLXL(INFINITY, 1.1163382522e+16f), 2 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(170, 0x1.234568p-120),
+ CMPLXL(INFINITY, 5.7878851079e+37f), 2 * FLT_ULP());
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ printf("1..7\n");
+
+ test_zero();
+ printf("ok 1 - cexp zero\n");
+
+ test_nan();
+ printf("ok 2 - cexp nan\n");
+
+ test_inf();
+ printf("ok 3 - cexp inf\n");
+
+#if defined(__i386__)
+ printf("not ok 4 - cexp reals # TODO: PR # 191676 fails assertion on i386\n");
+#else
+ test_reals();
+ printf("ok 4 - cexp reals\n");
+#endif
+
+ test_imaginaries();
+ printf("ok 5 - cexp imaginaries\n");
+
+ test_small();
+ printf("ok 6 - cexp small\n");
+
+ test_large();
+ printf("ok 7 - cexp large\n");
+
+ return (0);
+}
diff --git a/lib/msun/tests/conj_test.c b/lib/msun/tests/conj_test.c
new file mode 100644
index 0000000..7426f9e
--- /dev/null
+++ b/lib/msun/tests/conj_test.c
@@ -0,0 +1,139 @@
+/*-
+ * Copyright (c) 2008 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Tests for conj{,f,l}()
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <assert.h>
+#include <complex.h>
+#include <fenv.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "test-utils.h"
+
+#pragma STDC CX_LIMITED_RANGE OFF
+
+/* Make sure gcc doesn't use builtin versions of these or honor __pure2. */
+static float complex (*libconjf)(float complex) = conjf;
+static double complex (*libconj)(double complex) = conj;
+static long double complex (*libconjl)(long double complex) = conjl;
+static float (*libcrealf)(float complex) = crealf;
+static double (*libcreal)(double complex) = creal;
+static long double (*libcreall)(long double complex) = creall;
+static float (*libcimagf)(float complex) = cimagf;
+static double (*libcimag)(double complex) = cimag;
+static long double (*libcimagl)(long double complex) = cimagl;
+
+static const double tests[] = {
+ /* a + bI */
+ 0.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 0.0,
+ -1.0, 0.0,
+ 1.0, -0.0,
+ 0.0, -1.0,
+ 2.0, 4.0,
+ 0.0, INFINITY,
+ 0.0, -INFINITY,
+ INFINITY, 0.0,
+ NAN, 1.0,
+ 1.0, NAN,
+ NAN, NAN,
+ -INFINITY, INFINITY,
+};
+
+int
+main(int argc, char *argv[])
+{
+ static const int ntests = sizeof(tests) / sizeof(tests[0]) / 2;
+ complex float in;
+ complex long double expected;
+ int i;
+
+ printf("1..%d\n", ntests * 3);
+
+ for (i = 0; i < ntests; i++) {
+ __real__ expected = __real__ in = tests[2 * i];
+ __imag__ in = tests[2 * i + 1];
+ __imag__ expected = -cimag(in);
+
+ assert(fpequal(libcrealf(in), __real__ in));
+ assert(fpequal(libcreal(in), __real__ in));
+ assert(fpequal(libcreall(in), __real__ in));
+ assert(fpequal(libcimagf(in), __imag__ in));
+ assert(fpequal(libcimag(in), __imag__ in));
+ assert(fpequal(libcimagl(in), __imag__ in));
+
+ feclearexcept(FE_ALL_EXCEPT);
+ if (!cfpequal(libconjf(in), expected)) {
+ printf("not ok %d\t# conjf(%#.2g + %#.2gI): "
+ "wrong value\n",
+ 3 * i + 1, creal(in), cimag(in));
+ } else if (fetestexcept(FE_ALL_EXCEPT)) {
+ printf("not ok %d\t# conjf(%#.2g + %#.2gI): "
+ "threw an exception\n",
+ 3 * i + 1, creal(in), cimag(in));
+ } else {
+ printf("ok %d\t\t# conjf(%#.2g + %#.2gI)\n",
+ 3 * i + 1, creal(in), cimag(in));
+ }
+
+ feclearexcept(FE_ALL_EXCEPT);
+ if (!cfpequal(libconj(in), expected)) {
+ printf("not ok %d\t# conj(%#.2g + %#.2gI): "
+ "wrong value\n",
+ 3 * i + 2, creal(in), cimag(in));
+ } else if (fetestexcept(FE_ALL_EXCEPT)) {
+ printf("not ok %d\t# conj(%#.2g + %#.2gI): "
+ "threw an exception\n",
+ 3 * i + 2, creal(in), cimag(in));
+ } else {
+ printf("ok %d\t\t# conj(%#.2g + %#.2gI)\n",
+ 3 * i + 2, creal(in), cimag(in));
+ }
+
+ feclearexcept(FE_ALL_EXCEPT);
+ if (!cfpequal(libconjl(in), expected)) {
+ printf("not ok %d\t# conjl(%#.2g + %#.2gI): "
+ "wrong value\n",
+ 3 * i + 3, creal(in), cimag(in));
+ } else if (fetestexcept(FE_ALL_EXCEPT)) {
+ printf("not ok %d\t# conjl(%#.2g + %#.2gI): "
+ "threw an exception\n",
+ 3 * i + 3, creal(in), cimag(in));
+ } else {
+ printf("ok %d\t\t# conjl(%#.2g + %#.2gI)\n",
+ 3 * i + 3, creal(in), cimag(in));
+ }
+ }
+
+ return (0);
+}
diff --git a/lib/msun/tests/csqrt_test.c b/lib/msun/tests/csqrt_test.c
new file mode 100644
index 0000000..aa119d1
--- /dev/null
+++ b/lib/msun/tests/csqrt_test.c
@@ -0,0 +1,295 @@
+/*-
+ * Copyright (c) 2007 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Tests for csqrt{,f}()
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <assert.h>
+#include <complex.h>
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "test-utils.h"
+
+/*
+ * This is a test hook that can point to csqrtl(), _csqrt(), or to _csqrtf().
+ * The latter two convert to float or double, respectively, and test csqrtf()
+ * and csqrt() with the same arguments.
+ */
+long double complex (*t_csqrt)(long double complex);
+
+static long double complex
+_csqrtf(long double complex d)
+{
+
+ return (csqrtf((float complex)d));
+}
+
+static long double complex
+_csqrt(long double complex d)
+{
+
+ return (csqrt((double complex)d));
+}
+
+#pragma STDC CX_LIMITED_RANGE OFF
+
+/*
+ * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
+ * Fail an assertion if they differ.
+ */
+static void
+assert_equal(long double complex d1, long double complex d2)
+{
+
+ assert(cfpequal(d1, d2));
+}
+
+/*
+ * Test csqrt for some finite arguments where the answer is exact.
+ * (We do not test if it produces correctly rounded answers when the
+ * result is inexact, nor do we check whether it throws spurious
+ * exceptions.)
+ */
+static void
+test_finite()
+{
+ static const double tests[] = {
+ /* csqrt(a + bI) = x + yI */
+ /* a b x y */
+ 0, 8, 2, 2,
+ 0, -8, 2, -2,
+ 4, 0, 2, 0,
+ -4, 0, 0, 2,
+ 3, 4, 2, 1,
+ 3, -4, 2, -1,
+ -3, 4, 1, 2,
+ -3, -4, 1, -2,
+ 5, 12, 3, 2,
+ 7, 24, 4, 3,
+ 9, 40, 5, 4,
+ 11, 60, 6, 5,
+ 13, 84, 7, 6,
+ 33, 56, 7, 4,
+ 39, 80, 8, 5,
+ 65, 72, 9, 4,
+ 987, 9916, 74, 67,
+ 5289, 6640, 83, 40,
+ 460766389075.0, 16762287900.0, 678910, 12345
+ };
+ /*
+ * We also test some multiples of the above arguments. This
+ * array defines which multiples we use. Note that these have
+ * to be small enough to not cause overflow for float precision
+ * with all of the constants in the above table.
+ */
+ static const double mults[] = {
+ 1,
+ 2,
+ 3,
+ 13,
+ 16,
+ 0x1.p30,
+ 0x1.p-30,
+ };
+
+ double a, b;
+ double x, y;
+ int i, j;
+
+ for (i = 0; i < nitems(tests); i += 4) {
+ for (j = 0; j < nitems(mults); j++) {
+ a = tests[i] * mults[j] * mults[j];
+ b = tests[i + 1] * mults[j] * mults[j];
+ x = tests[i + 2] * mults[j];
+ y = tests[i + 3] * mults[j];
+ assert(t_csqrt(CMPLXL(a, b)) == CMPLXL(x, y));
+ }
+ }
+
+}
+
+/*
+ * Test the handling of +/- 0.
+ */
+static void
+test_zeros()
+{
+
+ assert_equal(t_csqrt(CMPLXL(0.0, 0.0)), CMPLXL(0.0, 0.0));
+ assert_equal(t_csqrt(CMPLXL(-0.0, 0.0)), CMPLXL(0.0, 0.0));
+ assert_equal(t_csqrt(CMPLXL(0.0, -0.0)), CMPLXL(0.0, -0.0));
+ assert_equal(t_csqrt(CMPLXL(-0.0, -0.0)), CMPLXL(0.0, -0.0));
+}
+
+/*
+ * Test the handling of infinities when the other argument is not NaN.
+ */
+static void
+test_infinities()
+{
+ static const double vals[] = {
+ 0.0,
+ -0.0,
+ 42.0,
+ -42.0,
+ INFINITY,
+ -INFINITY,
+ };
+
+ int i;
+
+ for (i = 0; i < nitems(vals); i++) {
+ if (isfinite(vals[i])) {
+ assert_equal(t_csqrt(CMPLXL(-INFINITY, vals[i])),
+ CMPLXL(0.0, copysignl(INFINITY, vals[i])));
+ assert_equal(t_csqrt(CMPLXL(INFINITY, vals[i])),
+ CMPLXL(INFINITY, copysignl(0.0, vals[i])));
+ }
+ assert_equal(t_csqrt(CMPLXL(vals[i], INFINITY)),
+ CMPLXL(INFINITY, INFINITY));
+ assert_equal(t_csqrt(CMPLXL(vals[i], -INFINITY)),
+ CMPLXL(INFINITY, -INFINITY));
+ }
+}
+
+/*
+ * Test the handling of NaNs.
+ */
+static void
+test_nans()
+{
+
+ assert(creall(t_csqrt(CMPLXL(INFINITY, NAN))) == INFINITY);
+ assert(isnan(cimagl(t_csqrt(CMPLXL(INFINITY, NAN)))));
+
+ assert(isnan(creall(t_csqrt(CMPLXL(-INFINITY, NAN)))));
+ assert(isinf(cimagl(t_csqrt(CMPLXL(-INFINITY, NAN)))));
+
+ assert_equal(t_csqrt(CMPLXL(NAN, INFINITY)),
+ CMPLXL(INFINITY, INFINITY));
+ assert_equal(t_csqrt(CMPLXL(NAN, -INFINITY)),
+ CMPLXL(INFINITY, -INFINITY));
+
+ assert_equal(t_csqrt(CMPLXL(0.0, NAN)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(-0.0, NAN)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(42.0, NAN)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(-42.0, NAN)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, 0.0)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, -0.0)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, 42.0)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, -42.0)), CMPLXL(NAN, NAN));
+ assert_equal(t_csqrt(CMPLXL(NAN, NAN)), CMPLXL(NAN, NAN));
+}
+
+/*
+ * Test whether csqrt(a + bi) works for inputs that are large enough to
+ * cause overflow in hypot(a, b) + a. In this case we are using
+ * csqrt(115 + 252*I) == 14 + 9*I
+ * scaled up to near MAX_EXP.
+ */
+static void
+test_overflow(int maxexp)
+{
+ long double a, b;
+ long double complex result;
+
+ a = ldexpl(115 * 0x1p-8, maxexp);
+ b = ldexpl(252 * 0x1p-8, maxexp);
+ result = t_csqrt(CMPLXL(a, b));
+ assert(creall(result) == ldexpl(14 * 0x1p-4, maxexp / 2));
+ assert(cimagl(result) == ldexpl(9 * 0x1p-4, maxexp / 2));
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ printf("1..15\n");
+
+ /* Test csqrt() */
+ t_csqrt = _csqrt;
+
+ test_finite();
+ printf("ok 1 - csqrt\n");
+
+ test_zeros();
+ printf("ok 2 - csqrt\n");
+
+ test_infinities();
+ printf("ok 3 - csqrt\n");
+
+ test_nans();
+ printf("ok 4 - csqrt\n");
+
+ test_overflow(DBL_MAX_EXP);
+ printf("ok 5 - csqrt\n");
+
+ /* Now test csqrtf() */
+ t_csqrt = _csqrtf;
+
+ test_finite();
+ printf("ok 6 - csqrt\n");
+
+ test_zeros();
+ printf("ok 7 - csqrt\n");
+
+ test_infinities();
+ printf("ok 8 - csqrt\n");
+
+ test_nans();
+ printf("ok 9 - csqrt\n");
+
+ test_overflow(FLT_MAX_EXP);
+ printf("ok 10 - csqrt\n");
+
+ /* Now test csqrtl() */
+ t_csqrt = csqrtl;
+
+ test_finite();
+ printf("ok 11 - csqrt\n");
+
+ test_zeros();
+ printf("ok 12 - csqrt\n");
+
+ test_infinities();
+ printf("ok 13 - csqrt\n");
+
+ test_nans();
+ printf("ok 14 - csqrt\n");
+
+ test_overflow(LDBL_MAX_EXP);
+ printf("ok 15 - csqrt\n");
+
+ return (0);
+}
diff --git a/tools/regression/lib/msun/test-fenv.c b/lib/msun/tests/fenv_test.c
index 0ea6e42..0ea6e42 100644
--- a/tools/regression/lib/msun/test-fenv.c
+++ b/lib/msun/tests/fenv_test.c
diff --git a/tools/regression/lib/msun/test-fmaxmin.c b/lib/msun/tests/fmaxmin_test.c
index 7ddcc87..7ddcc87 100644
--- a/tools/regression/lib/msun/test-fmaxmin.c
+++ b/lib/msun/tests/fmaxmin_test.c
diff --git a/tools/regression/lib/msun/test-ilogb.c b/lib/msun/tests/ilogb_test.c
index a1440c4..a1440c4 100644
--- a/tools/regression/lib/msun/test-ilogb.c
+++ b/lib/msun/tests/ilogb_test.c
diff --git a/tools/regression/lib/msun/test-invctrig.c b/lib/msun/tests/invctrig_test.c
index 34e78a1..34e78a1 100644
--- a/tools/regression/lib/msun/test-invctrig.c
+++ b/lib/msun/tests/invctrig_test.c
diff --git a/tools/regression/lib/msun/test-logarithm.c b/lib/msun/tests/logarithm_test.c
index 18b9ebe..18b9ebe 100644
--- a/tools/regression/lib/msun/test-logarithm.c
+++ b/lib/msun/tests/logarithm_test.c
diff --git a/tools/regression/lib/msun/test-lrint.c b/lib/msun/tests/lrint_test.c
index ba099aa..ba099aa 100644
--- a/tools/regression/lib/msun/test-lrint.c
+++ b/lib/msun/tests/lrint_test.c
diff --git a/tools/regression/lib/msun/test-nan.c b/lib/msun/tests/nan_test.c
index c12926b..c12926b 100644
--- a/tools/regression/lib/msun/test-nan.c
+++ b/lib/msun/tests/nan_test.c
diff --git a/tools/regression/lib/msun/test-nearbyint.c b/lib/msun/tests/nearbyint_test.c
index 602ea2a..602ea2a 100644
--- a/tools/regression/lib/msun/test-nearbyint.c
+++ b/lib/msun/tests/nearbyint_test.c
diff --git a/tools/regression/lib/msun/test-next.c b/lib/msun/tests/next_test.c
index d16fa77..d16fa77 100644
--- a/tools/regression/lib/msun/test-next.c
+++ b/lib/msun/tests/next_test.c
diff --git a/tools/regression/lib/msun/test-rem.c b/lib/msun/tests/rem_test.c
index 36e3476..36e3476 100644
--- a/tools/regression/lib/msun/test-rem.c
+++ b/lib/msun/tests/rem_test.c
diff --git a/lib/msun/tests/trig_test.c b/lib/msun/tests/trig_test.c
new file mode 100644
index 0000000..1dcce1f
--- /dev/null
+++ b/lib/msun/tests/trig_test.c
@@ -0,0 +1,280 @@
+/*-
+ * Copyright (c) 2008 David Schultz <das@FreeBSD.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Tests for corner cases in trigonometric functions. Some accuracy tests
+ * are included as well, but these are very basic sanity checks, not
+ * intended to be comprehensive.
+ *
+ * The program for generating representable numbers near multiples of pi is
+ * available at http://www.cs.berkeley.edu/~wkahan/testpi/ .
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+
+#include <assert.h>
+#include <fenv.h>
+#include <float.h>
+#include <math.h>
+#include <stdio.h>
+
+#include "test-utils.h"
+
+#pragma STDC FENV_ACCESS ON
+
+/*
+ * Test that a function returns the correct value and sets the
+ * exception flags correctly. The exceptmask specifies which
+ * exceptions we should check. We need to be lenient for several
+ * reasons, but mainly because on some architectures it's impossible
+ * to raise FE_OVERFLOW without raising FE_INEXACT.
+ *
+ * These are macros instead of functions so that assert provides more
+ * meaningful error messages.
+ *
+ * XXX The volatile here is to avoid gcc's bogus constant folding and work
+ * around the lack of support for the FENV_ACCESS pragma.
+ */
+#define test(func, x, result, exceptmask, excepts) do { \
+ volatile long double _d = x; \
+ assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
+ assert(fpequal((func)(_d), (result))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
+} while (0)
+
+#define testall(prefix, x, result, exceptmask, excepts) do { \
+ test(prefix, x, (double)result, exceptmask, excepts); \
+ test(prefix##f, x, (float)result, exceptmask, excepts); \
+ test(prefix##l, x, result, exceptmask, excepts); \
+} while (0)
+
+#define testdf(prefix, x, result, exceptmask, excepts) do { \
+ test(prefix, x, (double)result, exceptmask, excepts); \
+ test(prefix##f, x, (float)result, exceptmask, excepts); \
+} while (0)
+
+/*
+ * Test special cases in sin(), cos(), and tan().
+ */
+static void
+run_special_tests(void)
+{
+
+ /* Values at 0 should be exact. */
+ testall(tan, 0.0, 0.0, ALL_STD_EXCEPT, 0);
+ testall(tan, -0.0, -0.0, ALL_STD_EXCEPT, 0);
+ testall(cos, 0.0, 1.0, ALL_STD_EXCEPT, 0);
+ testall(cos, -0.0, 1.0, ALL_STD_EXCEPT, 0);
+ testall(sin, 0.0, 0.0, ALL_STD_EXCEPT, 0);
+ testall(sin, -0.0, -0.0, ALL_STD_EXCEPT, 0);
+
+ /* func(+-Inf) == NaN */
+ testall(tan, INFINITY, NAN, ALL_STD_EXCEPT, FE_INVALID);
+ testall(sin, INFINITY, NAN, ALL_STD_EXCEPT, FE_INVALID);
+ testall(cos, INFINITY, NAN, ALL_STD_EXCEPT, FE_INVALID);
+ testall(tan, -INFINITY, NAN, ALL_STD_EXCEPT, FE_INVALID);
+ testall(sin, -INFINITY, NAN, ALL_STD_EXCEPT, FE_INVALID);
+ testall(cos, -INFINITY, NAN, ALL_STD_EXCEPT, FE_INVALID);
+
+ /* func(NaN) == NaN */
+ testall(tan, NAN, NAN, ALL_STD_EXCEPT, 0);
+ testall(sin, NAN, NAN, ALL_STD_EXCEPT, 0);
+ testall(cos, NAN, NAN, ALL_STD_EXCEPT, 0);
+}
+
+/*
+ * Tests to ensure argument reduction for large arguments is accurate.
+ */
+static void
+run_reduction_tests(void)
+{
+ /* floats very close to odd multiples of pi */
+ static const float f_pi_odd[] = {
+ 85563208.0f,
+ 43998769152.0f,
+ 9.2763667655669323e+25f,
+ 1.5458357838905804e+29f,
+ };
+ /* doubles very close to odd multiples of pi */
+ static const double d_pi_odd[] = {
+ 3.1415926535897931,
+ 91.106186954104004,
+ 642615.9188844458,
+ 3397346.5699258847,
+ 6134899525417045.0,
+ 3.0213551960457761e+43,
+ 1.2646209897993783e+295,
+ 6.2083625380677099e+307,
+ };
+ /* long doubles very close to odd multiples of pi */
+#if LDBL_MANT_DIG == 64
+ static const long double ld_pi_odd[] = {
+ 1.1891886960373841596e+101L,
+ 1.07999475322710967206e+2087L,
+ 6.522151627890431836e+2147L,
+ 8.9368974898260328229e+2484L,
+ 9.2961044110572205863e+2555L,
+ 4.90208421886578286e+3189L,
+ 1.5275546401232615884e+3317L,
+ 1.7227465626338900093e+3565L,
+ 2.4160090594000745334e+3808L,
+ 9.8477555741888350649e+4314L,
+ 1.6061597222105160737e+4326L,
+ };
+#elif LDBL_MANT_DIG == 113
+ static const long double ld_pi_odd[] = {
+ /* XXX */
+ };
+#endif
+
+ int i;
+
+ for (i = 0; i < nitems(f_pi_odd); i++) {
+ assert(fabs(sinf(f_pi_odd[i])) < FLT_EPSILON);
+ assert(cosf(f_pi_odd[i]) == -1.0);
+ assert(fabs(tan(f_pi_odd[i])) < FLT_EPSILON);
+
+ assert(fabs(sinf(-f_pi_odd[i])) < FLT_EPSILON);
+ assert(cosf(-f_pi_odd[i]) == -1.0);
+ assert(fabs(tanf(-f_pi_odd[i])) < FLT_EPSILON);
+
+ assert(fabs(sinf(f_pi_odd[i] * 2)) < FLT_EPSILON);
+ assert(cosf(f_pi_odd[i] * 2) == 1.0);
+ assert(fabs(tanf(f_pi_odd[i] * 2)) < FLT_EPSILON);
+
+ assert(fabs(sinf(-f_pi_odd[i] * 2)) < FLT_EPSILON);
+ assert(cosf(-f_pi_odd[i] * 2) == 1.0);
+ assert(fabs(tanf(-f_pi_odd[i] * 2)) < FLT_EPSILON);
+ }
+
+ for (i = 0; i < nitems(d_pi_odd); i++) {
+ assert(fabs(sin(d_pi_odd[i])) < 2 * DBL_EPSILON);
+ assert(cos(d_pi_odd[i]) == -1.0);
+ assert(fabs(tan(d_pi_odd[i])) < 2 * DBL_EPSILON);
+
+ assert(fabs(sin(-d_pi_odd[i])) < 2 * DBL_EPSILON);
+ assert(cos(-d_pi_odd[i]) == -1.0);
+ assert(fabs(tan(-d_pi_odd[i])) < 2 * DBL_EPSILON);
+
+ assert(fabs(sin(d_pi_odd[i] * 2)) < 2 * DBL_EPSILON);
+ assert(cos(d_pi_odd[i] * 2) == 1.0);
+ assert(fabs(tan(d_pi_odd[i] * 2)) < 2 * DBL_EPSILON);
+
+ assert(fabs(sin(-d_pi_odd[i] * 2)) < 2 * DBL_EPSILON);
+ assert(cos(-d_pi_odd[i] * 2) == 1.0);
+ assert(fabs(tan(-d_pi_odd[i] * 2)) < 2 * DBL_EPSILON);
+ }
+
+#if LDBL_MANT_DIG > 53
+ for (i = 0; i < nitems(ld_pi_odd); i++) {
+ assert(fabsl(sinl(ld_pi_odd[i])) < LDBL_EPSILON);
+ assert(cosl(ld_pi_odd[i]) == -1.0);
+ assert(fabsl(tanl(ld_pi_odd[i])) < LDBL_EPSILON);
+
+ assert(fabsl(sinl(-ld_pi_odd[i])) < LDBL_EPSILON);
+ assert(cosl(-ld_pi_odd[i]) == -1.0);
+ assert(fabsl(tanl(-ld_pi_odd[i])) < LDBL_EPSILON);
+
+ assert(fabsl(sinl(ld_pi_odd[i] * 2)) < LDBL_EPSILON);
+ assert(cosl(ld_pi_odd[i] * 2) == 1.0);
+ assert(fabsl(tanl(ld_pi_odd[i] * 2)) < LDBL_EPSILON);
+
+ assert(fabsl(sinl(-ld_pi_odd[i] * 2)) < LDBL_EPSILON);
+ assert(cosl(-ld_pi_odd[i] * 2) == 1.0);
+ assert(fabsl(tanl(-ld_pi_odd[i] * 2)) < LDBL_EPSILON);
+ }
+#endif
+}
+
+/*
+ * Tests the accuracy of these functions over the primary range.
+ */
+static void
+run_accuracy_tests(void)
+{
+
+ /* For small args, sin(x) = tan(x) = x, and cos(x) = 1. */
+ testall(sin, 0xd.50ee515fe4aea16p-114L, 0xd.50ee515fe4aea16p-114L,
+ ALL_STD_EXCEPT, FE_INEXACT);
+ testall(tan, 0xd.50ee515fe4aea16p-114L, 0xd.50ee515fe4aea16p-114L,
+ ALL_STD_EXCEPT, FE_INEXACT);
+ testall(cos, 0xd.50ee515fe4aea16p-114L, 1.0,
+ ALL_STD_EXCEPT, FE_INEXACT);
+
+ /*
+ * These tests should pass for f32, d64, and ld80 as long as
+ * the error is <= 0.75 ulp (round to nearest)
+ */
+#if LDBL_MANT_DIG <= 64
+#define testacc testall
+#else
+#define testacc testdf
+#endif
+ testacc(sin, 0.17255452780841205174L, 0.17169949801444412683L,
+ ALL_STD_EXCEPT, FE_INEXACT);
+ testacc(sin, -0.75431944555904520893L, -0.68479288156557286353L,
+ ALL_STD_EXCEPT, FE_INEXACT);
+ testacc(cos, 0.70556358769838947292L, 0.76124620693117771850L,
+ ALL_STD_EXCEPT, FE_INEXACT);
+ testacc(cos, -0.34061437849088045332L, 0.94254960031831729956L,
+ ALL_STD_EXCEPT, FE_INEXACT);
+ testacc(tan, -0.15862817413325692897L, -0.15997221861309522115L,
+ ALL_STD_EXCEPT, FE_INEXACT);
+ testacc(tan, 0.38374784931303813530L, 0.40376500259976759951L,
+ ALL_STD_EXCEPT, FE_INEXACT);
+
+ /*
+ * XXX missing:
+ * - tests for ld128
+ * - tests for other rounding modes (probably won't pass for now)
+ * - tests for large numbers that get reduced to hi+lo with lo!=0
+ */
+}
+
+int
+main(int argc, char *argv[])
+{
+
+ printf("1..3\n");
+
+ run_special_tests();
+ printf("ok 1 - trig\n");
+
+#ifndef __i386__
+ run_reduction_tests();
+#endif
+ printf("ok 2 - trig\n");
+
+#ifndef __i386__
+ run_accuracy_tests();
+#endif
+ printf("ok 3 - trig\n");
+
+ return (0);
+}
diff --git a/tools/regression/lib/msun/Makefile b/tools/regression/lib/msun/Makefile
index dbf582f..8b301cb 100644
--- a/tools/regression/lib/msun/Makefile
+++ b/tools/regression/lib/msun/Makefile
@@ -1,10 +1,8 @@
# $FreeBSD$
-TESTS= test-cexp test-conj test-csqrt test-ctrig \
- test-exponential test-fenv test-fma \
- test-fmaxmin test-ilogb test-invtrig test-invctrig \
- test-logarithm test-lrint \
- test-lround test-nan test-nearbyint test-next test-rem test-trig
+TESTS= test-ctrig \
+ test-exponential test-fma \
+ test-lround test-nearbyint test-next test-rem test-trig
CFLAGS+= -O0 -lm -Wno-unknown-pragmas
.PHONY: tests
diff --git a/tools/regression/lib/msun/test-cexp.t b/tools/regression/lib/msun/test-cexp.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-cexp.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-conj.t b/tools/regression/lib/msun/test-conj.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-conj.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-csqrt.t b/tools/regression/lib/msun/test-csqrt.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-csqrt.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-fenv.t b/tools/regression/lib/msun/test-fenv.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-fenv.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-fmaxmin.t b/tools/regression/lib/msun/test-fmaxmin.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-fmaxmin.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-ilogb.t b/tools/regression/lib/msun/test-ilogb.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-ilogb.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-logarithm.t b/tools/regression/lib/msun/test-logarithm.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-logarithm.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-lrint.t b/tools/regression/lib/msun/test-lrint.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-lrint.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-nan.t b/tools/regression/lib/msun/test-nan.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-nan.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-nearbyint.t b/tools/regression/lib/msun/test-nearbyint.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-nearbyint.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-next.t b/tools/regression/lib/msun/test-next.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-next.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-rem.t b/tools/regression/lib/msun/test-rem.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-rem.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
diff --git a/tools/regression/lib/msun/test-trig.t b/tools/regression/lib/msun/test-trig.t
deleted file mode 100644
index 8bdfd03..0000000
--- a/tools/regression/lib/msun/test-trig.t
+++ /dev/null
@@ -1,10 +0,0 @@
-#!/bin/sh
-# $FreeBSD$
-
-cd `dirname $0`
-
-executable=`basename $0 .t`
-
-make $executable 2>&1 > /dev/null
-
-exec ./$executable
OpenPOWER on IntegriCloud