summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/regression/lib/msun/Makefile2
-rw-r--r--tools/regression/lib/msun/test-cexp.c213
-rw-r--r--tools/regression/lib/msun/test-conj.c23
-rw-r--r--tools/regression/lib/msun/test-csqrt.c102
-rw-r--r--tools/regression/lib/msun/test-ctrig.c285
-rw-r--r--tools/regression/lib/msun/test-exponential.c16
-rw-r--r--tools/regression/lib/msun/test-fma.c27
-rw-r--r--tools/regression/lib/msun/test-fmaxmin.c16
-rw-r--r--tools/regression/lib/msun/test-invctrig.c78
-rw-r--r--tools/regression/lib/msun/test-invtrig.c38
-rw-r--r--tools/regression/lib/msun/test-logarithm.c16
-rw-r--r--tools/regression/lib/msun/test-nearbyint.c26
-rw-r--r--tools/regression/lib/msun/test-next.c6
-rw-r--r--tools/regression/lib/msun/test-trig.c18
-rw-r--r--tools/regression/lib/msun/test-utils.h174
15 files changed, 412 insertions, 628 deletions
diff --git a/tools/regression/lib/msun/Makefile b/tools/regression/lib/msun/Makefile
index 9559bb1..dbf582f 100644
--- a/tools/regression/lib/msun/Makefile
+++ b/tools/regression/lib/msun/Makefile
@@ -5,7 +5,7 @@ TESTS= test-cexp test-conj test-csqrt test-ctrig \
test-fmaxmin test-ilogb test-invtrig test-invctrig \
test-logarithm test-lrint \
test-lround test-nan test-nearbyint test-next test-rem test-trig
-CFLAGS+= -O0 -lm
+CFLAGS+= -O0 -lm -Wno-unknown-pragmas
.PHONY: tests
tests: ${TESTS}
diff --git a/tools/regression/lib/msun/test-cexp.c b/tools/regression/lib/msun/test-cexp.c
index 51e9144..78c3f1a 100644
--- a/tools/regression/lib/msun/test-cexp.c
+++ b/tools/regression/lib/msun/test-cexp.c
@@ -38,11 +38,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
-#define FLT_ULP() ldexpl(1.0, 1 - FLT_MANT_DIG)
-#define DBL_ULP() ldexpl(1.0, 1 - DBL_MANT_DIG)
-#define LDBL_ULP() ldexpl(1.0, 1 - LDBL_MANT_DIG)
+#include "test-utils.h"
#define N(i) (sizeof(i) / sizeof((i)[0]))
@@ -50,23 +46,6 @@ __FBSDID("$FreeBSD$");
#pragma STDC CX_LIMITED_RANGE OFF
/*
- * XXX gcc implements complex multiplication incorrectly. In
- * particular, it implements it as if the CX_LIMITED_RANGE pragma
- * were ON. Consequently, we need this function to form numbers
- * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
- * NaN + INFINITY * I.
- */
-static inline long double complex
-cpackl(long double x, long double y)
-{
- long double complex z;
-
- __real__ z = x;
- __imag__ z = y;
- return (z);
-}
-
-/*
* 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
@@ -83,14 +62,15 @@ cpackl(long double x, long double y)
#define test(func, z, result, exceptmask, excepts, checksign) do { \
volatile long double complex _d = z; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(cfpequal((func)(_d), (result), (checksign))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ 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))); \
+ assert(cfpequal_tol((func)(_d), (result), (tol), \
+ FPE_ABS_ZERO | CS_BOTH)); \
} while (0)
/* Test all the functions that compute cexp(x). */
@@ -112,67 +92,6 @@ cpackl(long double x, long double y)
static const float finites[] =
{ -42.0e20, -1.0, -1.0e-10, -0.0, 0.0, 1.0e-10, 1.0, 42.0e20 };
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- * If checksign is 0, we compare the absolute values instead.
- */
-static int
-fpequal(long double x, long double y, int checksign)
-{
- if (isnan(x) || isnan(y))
- return (1);
- if (checksign)
- return (x == y && !signbit(x) == !signbit(y));
- else
- return (fabsl(x) == fabsl(y));
-}
-
-static int
-fpequal_tol(long double x, long double y, long double tol)
-{
- fenv_t env;
- int ret;
-
- if (isnan(x) && isnan(y))
- return (1);
- if (!signbit(x) != !signbit(y))
- return (0);
- if (x == y)
- return (1);
- if (tol == 0)
- return (0);
-
- /* Hard case: need to check the tolerance. */
- feholdexcept(&env);
- /*
- * For our purposes here, if y=0, we interpret tol as an absolute
- * tolerance. This is to account for roundoff in the input, e.g.,
- * cos(Pi/2) ~= 0.
- */
- if (y == 0.0)
- ret = fabsl(x - y) <= fabsl(tol);
- else
- ret = fabsl(x - y) <= fabsl(y * tol);
- fesetenv(&env);
- return (ret);
-}
-
-static int
-cfpequal(long double complex x, long double complex y, int checksign)
-{
- return (fpequal(creal(x), creal(y), checksign)
- && fpequal(cimag(x), cimag(y), checksign));
-}
-
-static int
-cfpequal_tol(long double complex x, long double complex y, long double tol)
-{
- return (fpequal_tol(creal(x), creal(y), tol)
- && fpequal_tol(cimag(x), cimag(y), tol));
-}
-
/* Tests for 0 */
void
@@ -182,8 +101,8 @@ 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(cpackl(0.0, -0.0), cpackl(1.0, -0.0), ALL_STD_EXCEPT, 0, 1);
- testall(cpackl(-0.0, -0.0), cpackl(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);
+ testall(CMPLXL(-0.0, -0.0), CMPLXL(1.0, -0.0), ALL_STD_EXCEPT, 0, 1);
}
/*
@@ -198,27 +117,27 @@ test_nan()
/* cexp(x + NaNi) = NaN + NaNi and optionally raises invalid */
/* cexp(NaN + yi) = NaN + NaNi and optionally raises invalid (|y|>0) */
for (i = 0; i < N(finites); i++) {
- testall(cpackl(finites[i], NAN), cpackl(NAN, NAN),
+ 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(cpackl(NAN, finites[i]), cpackl(NAN, NAN),
+ testall(CMPLXL(NAN, finites[i]), CMPLXL(NAN, NAN),
ALL_STD_EXCEPT & ~(FE_INVALID | FE_INEXACT), 0, 0);
}
/* cexp(NaN +- 0i) = NaN +- 0i */
- testall(cpackl(NAN, 0.0), cpackl(NAN, 0.0), ALL_STD_EXCEPT, 0, 1);
- testall(cpackl(NAN, -0.0), cpackl(NAN, -0.0), ALL_STD_EXCEPT, 0, 1);
+ 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(cpackl(INFINITY, NAN), cpackl(INFINITY, NAN),
+ testall(CMPLXL(INFINITY, NAN), CMPLXL(INFINITY, NAN),
ALL_STD_EXCEPT, 0, 0);
/* cexp(-inf + NaN i) = 0 */
- testall(cpackl(-INFINITY, NAN), cpackl(0.0, 0.0),
+ testall(CMPLXL(-INFINITY, NAN), CMPLXL(0.0, 0.0),
ALL_STD_EXCEPT, 0, 0);
/* cexp(NaN + NaN i) = NaN + NaN i */
- testall(cpackl(NAN, NAN), cpackl(NAN, NAN),
+ testall(CMPLXL(NAN, NAN), CMPLXL(NAN, NAN),
ALL_STD_EXCEPT, 0, 0);
}
@@ -229,37 +148,37 @@ test_inf(void)
/* cexp(x + inf i) = NaN + NaNi and raises invalid */
for (i = 0; i < N(finites); i++) {
- testall(cpackl(finites[i], INFINITY), cpackl(NAN, NAN),
+ 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(cpackl(-INFINITY, M_PI_4), cpackl(0.0, 0.0),
+ testall(CMPLXL(-INFINITY, M_PI_4), CMPLXL(0.0, 0.0),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- testall(cpackl(-INFINITY, 3 * M_PI_4), cpackl(-0.0, 0.0),
+ testall(CMPLXL(-INFINITY, 3 * M_PI_4), CMPLXL(-0.0, 0.0),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- testall(cpackl(-INFINITY, 5 * M_PI_4), cpackl(-0.0, -0.0),
+ testall(CMPLXL(-INFINITY, 5 * M_PI_4), CMPLXL(-0.0, -0.0),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- testall(cpackl(-INFINITY, 7 * M_PI_4), cpackl(0.0, -0.0),
+ testall(CMPLXL(-INFINITY, 7 * M_PI_4), CMPLXL(0.0, -0.0),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- testall(cpackl(-INFINITY, 0.0), cpackl(0.0, 0.0),
+ testall(CMPLXL(-INFINITY, 0.0), CMPLXL(0.0, 0.0),
ALL_STD_EXCEPT, 0, 1);
- testall(cpackl(-INFINITY, -0.0), cpackl(0.0, -0.0),
+ 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(cpackl(INFINITY, M_PI_4), cpackl(INFINITY, INFINITY),
+ testall(CMPLXL(INFINITY, M_PI_4), CMPLXL(INFINITY, INFINITY),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- testall(cpackl(INFINITY, 3 * M_PI_4), cpackl(-INFINITY, INFINITY),
+ testall(CMPLXL(INFINITY, 3 * M_PI_4), CMPLXL(-INFINITY, INFINITY),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- testall(cpackl(INFINITY, 5 * M_PI_4), cpackl(-INFINITY, -INFINITY),
+ testall(CMPLXL(INFINITY, 5 * M_PI_4), CMPLXL(-INFINITY, -INFINITY),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- testall(cpackl(INFINITY, 7 * M_PI_4), cpackl(INFINITY, -INFINITY),
+ testall(CMPLXL(INFINITY, 7 * M_PI_4), CMPLXL(INFINITY, -INFINITY),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
/* cexp(inf + 0i) = inf + 0i */
- testall(cpackl(INFINITY, 0.0), cpackl(INFINITY, 0.0),
+ testall(CMPLXL(INFINITY, 0.0), CMPLXL(INFINITY, 0.0),
ALL_STD_EXCEPT, 0, 1);
- testall(cpackl(INFINITY, -0.0), cpackl(INFINITY, -0.0),
+ testall(CMPLXL(INFINITY, -0.0), CMPLXL(INFINITY, -0.0),
ALL_STD_EXCEPT, 0, 1);
}
@@ -270,17 +189,17 @@ test_reals(void)
for (i = 0; i < N(finites); i++) {
/* XXX could check exceptions more meticulously */
- test(cexp, cpackl(finites[i], 0.0),
- cpackl(exp(finites[i]), 0.0),
+ test(cexp, CMPLXL(finites[i], 0.0),
+ CMPLXL(exp(finites[i]), 0.0),
FE_INVALID | FE_DIVBYZERO, 0, 1);
- test(cexp, cpackl(finites[i], -0.0),
- cpackl(exp(finites[i]), -0.0),
+ test(cexp, CMPLXL(finites[i], -0.0),
+ CMPLXL(exp(finites[i]), -0.0),
FE_INVALID | FE_DIVBYZERO, 0, 1);
- test(cexpf, cpackl(finites[i], 0.0),
- cpackl(expf(finites[i]), 0.0),
+ test(cexpf, CMPLXL(finites[i], 0.0),
+ CMPLXL(expf(finites[i]), 0.0),
FE_INVALID | FE_DIVBYZERO, 0, 1);
- test(cexpf, cpackl(finites[i], -0.0),
- cpackl(expf(finites[i]), -0.0),
+ test(cexpf, CMPLXL(finites[i], -0.0),
+ CMPLXL(expf(finites[i]), -0.0),
FE_INVALID | FE_DIVBYZERO, 0, 1);
}
}
@@ -291,17 +210,17 @@ test_imaginaries(void)
int i;
for (i = 0; i < N(finites); i++) {
- test(cexp, cpackl(0.0, finites[i]),
- cpackl(cos(finites[i]), sin(finites[i])),
+ test(cexp, CMPLXL(0.0, finites[i]),
+ CMPLXL(cos(finites[i]), sin(finites[i])),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- test(cexp, cpackl(-0.0, finites[i]),
- cpackl(cos(finites[i]), sin(finites[i])),
+ test(cexp, CMPLXL(-0.0, finites[i]),
+ CMPLXL(cos(finites[i]), sin(finites[i])),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- test(cexpf, cpackl(0.0, finites[i]),
- cpackl(cosf(finites[i]), sinf(finites[i])),
+ test(cexpf, CMPLXL(0.0, finites[i]),
+ CMPLXL(cosf(finites[i]), sinf(finites[i])),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
- test(cexpf, cpackl(-0.0, finites[i]),
- cpackl(cosf(finites[i]), sinf(finites[i])),
+ test(cexpf, CMPLXL(-0.0, finites[i]),
+ CMPLXL(cosf(finites[i]), sinf(finites[i])),
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
}
}
@@ -326,12 +245,12 @@ test_small(void)
b = tests[i + 1];
x = tests[i + 2];
y = tests[i + 3];
- test_tol(cexp, cpackl(a, b), cpackl(x, y), 3 * DBL_ULP());
+ 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, cpackl(a, b), cpackl(x, y), 1 * FLT_ULP());
+ test_tol(cexpf, CMPLXL(a, b), CMPLXL(x, y), 1 * FLT_ULP());
}
}
@@ -340,27 +259,27 @@ void
test_large(void)
{
- test_tol(cexp, cpackl(709.79, 0x1p-1074),
- cpackl(INFINITY, 8.94674309915433533273e-16), DBL_ULP());
- test_tol(cexp, cpackl(1000, 0x1p-1074),
- cpackl(INFINITY, 9.73344457300016401328e+110), DBL_ULP());
- test_tol(cexp, cpackl(1400, 0x1p-1074),
- cpackl(INFINITY, 5.08228858149196559681e+284), DBL_ULP());
- test_tol(cexp, cpackl(900, 0x1.23456789abcdep-1020),
- cpackl(INFINITY, 7.42156649354218408074e+83), DBL_ULP());
- test_tol(cexp, cpackl(1300, 0x1.23456789abcdep-1020),
- cpackl(INFINITY, 3.87514844965996756704e+257), DBL_ULP());
-
- test_tol(cexpf, cpackl(88.73, 0x1p-149),
- cpackl(INFINITY, 4.80265603e-07), 2 * FLT_ULP());
- test_tol(cexpf, cpackl(90, 0x1p-149),
- cpackl(INFINITY, 1.7101492622e-06f), 2 * FLT_ULP());
- test_tol(cexpf, cpackl(192, 0x1p-149),
- cpackl(INFINITY, 3.396809344e+38f), 2 * FLT_ULP());
- test_tol(cexpf, cpackl(120, 0x1.234568p-120),
- cpackl(INFINITY, 1.1163382522e+16f), 2 * FLT_ULP());
- test_tol(cexpf, cpackl(170, 0x1.234568p-120),
- cpackl(INFINITY, 5.7878851079e+37f), 2 * FLT_ULP());
+ 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
diff --git a/tools/regression/lib/msun/test-conj.c b/tools/regression/lib/msun/test-conj.c
index 909e810..c261f60 100644
--- a/tools/regression/lib/msun/test-conj.c
+++ b/tools/regression/lib/msun/test-conj.c
@@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
#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. */
@@ -50,27 +52,6 @@ static float (*libcimagf)(float complex) = cimagf;
static double (*libcimag)(double complex) = cimag;
static long double (*libcimagl)(long double complex) = cimagl;
-/*
- * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
- * Fail an assertion if they differ.
- */
-static int
-fpequal(long double d1, long double d2)
-{
-
- if (d1 != d2)
- return (isnan(d1) && isnan(d2));
- return (copysignl(1.0, d1) == copysignl(1.0, d2));
-}
-
-static int
-cfpequal(long double complex d1, long double complex d2)
-{
-
- return (fpequal(creall(d1), creall(d2)) &&
- fpequal(cimagl(d1), cimagl(d2)));
-}
-
static const double tests[] = {
/* a + bI */
0.0, 0.0,
diff --git a/tools/regression/lib/msun/test-csqrt.c b/tools/regression/lib/msun/test-csqrt.c
index 9877b9d..39176eb 100644
--- a/tools/regression/lib/msun/test-csqrt.c
+++ b/tools/regression/lib/msun/test-csqrt.c
@@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
+#include "test-utils.h"
+
#define N(i) (sizeof(i) / sizeof((i)[0]))
/*
@@ -63,23 +65,6 @@ _csqrt(long double complex d)
#pragma STDC CX_LIMITED_RANGE off
/*
- * XXX gcc implements complex multiplication incorrectly. In
- * particular, it implements it as if the CX_LIMITED_RANGE pragma
- * were ON. Consequently, we need this function to form numbers
- * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
- * NaN + INFINITY * I.
- */
-static inline long double complex
-cpackl(long double x, long double y)
-{
- long double complex z;
-
- __real__ z = x;
- __imag__ z = y;
- return (z);
-}
-
-/*
* Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
* Fail an assertion if they differ.
*/
@@ -87,20 +72,7 @@ static void
assert_equal(long double complex d1, long double complex d2)
{
- if (isnan(creall(d1))) {
- assert(isnan(creall(d2)));
- } else {
- assert(creall(d1) == creall(d2));
- assert(copysignl(1.0, creall(d1)) ==
- copysignl(1.0, creall(d2)));
- }
- if (isnan(cimagl(d1))) {
- assert(isnan(cimagl(d2)));
- } else {
- assert(cimagl(d1) == cimagl(d2));
- assert(copysignl(1.0, cimagl(d1)) ==
- copysignl(1.0, cimagl(d2)));
- }
+ assert(cfpequal(d1, d2));
}
/*
@@ -161,7 +133,7 @@ test_finite()
b = tests[i + 1] * mults[j] * mults[j];
x = tests[i + 2] * mults[j];
y = tests[i + 3] * mults[j];
- assert(t_csqrt(cpackl(a, b)) == cpackl(x, y));
+ assert(t_csqrt(CMPLXL(a, b)) == CMPLXL(x, y));
}
}
@@ -174,10 +146,10 @@ static void
test_zeros()
{
- assert_equal(t_csqrt(cpackl(0.0, 0.0)), cpackl(0.0, 0.0));
- assert_equal(t_csqrt(cpackl(-0.0, 0.0)), cpackl(0.0, 0.0));
- assert_equal(t_csqrt(cpackl(0.0, -0.0)), cpackl(0.0, -0.0));
- assert_equal(t_csqrt(cpackl(-0.0, -0.0)), cpackl(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));
+ assert_equal(t_csqrt(CMPLXL(-0.0, -0.0)), CMPLXL(0.0, -0.0));
}
/*
@@ -199,15 +171,15 @@ test_infinities()
for (i = 0; i < N(vals); i++) {
if (isfinite(vals[i])) {
- assert_equal(t_csqrt(cpackl(-INFINITY, vals[i])),
- cpackl(0.0, copysignl(INFINITY, vals[i])));
- assert_equal(t_csqrt(cpackl(INFINITY, vals[i])),
- cpackl(INFINITY, copysignl(0.0, 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(cpackl(vals[i], INFINITY)),
- cpackl(INFINITY, INFINITY));
- assert_equal(t_csqrt(cpackl(vals[i], -INFINITY)),
- cpackl(INFINITY, -INFINITY));
+ assert_equal(t_csqrt(CMPLXL(vals[i], INFINITY)),
+ CMPLXL(INFINITY, INFINITY));
+ assert_equal(t_csqrt(CMPLXL(vals[i], -INFINITY)),
+ CMPLXL(INFINITY, -INFINITY));
}
}
@@ -218,26 +190,26 @@ static void
test_nans()
{
- assert(creall(t_csqrt(cpackl(INFINITY, NAN))) == INFINITY);
- assert(isnan(cimagl(t_csqrt(cpackl(INFINITY, NAN)))));
-
- assert(isnan(creall(t_csqrt(cpackl(-INFINITY, NAN)))));
- assert(isinf(cimagl(t_csqrt(cpackl(-INFINITY, NAN)))));
-
- assert_equal(t_csqrt(cpackl(NAN, INFINITY)),
- cpackl(INFINITY, INFINITY));
- assert_equal(t_csqrt(cpackl(NAN, -INFINITY)),
- cpackl(INFINITY, -INFINITY));
-
- assert_equal(t_csqrt(cpackl(0.0, NAN)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(-0.0, NAN)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(42.0, NAN)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(-42.0, NAN)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, 0.0)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, -0.0)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, 42.0)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, -42.0)), cpackl(NAN, NAN));
- assert_equal(t_csqrt(cpackl(NAN, NAN)), cpackl(NAN, NAN));
+ 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));
}
/*
@@ -254,7 +226,7 @@ test_overflow(int maxexp)
a = ldexpl(115 * 0x1p-8, maxexp);
b = ldexpl(252 * 0x1p-8, maxexp);
- result = t_csqrt(cpackl(a, b));
+ result = t_csqrt(CMPLXL(a, b));
assert(creall(result) == ldexpl(14 * 0x1p-4, maxexp / 2));
assert(cimagl(result) == ldexpl(9 * 0x1p-4, maxexp / 2));
}
diff --git a/tools/regression/lib/msun/test-ctrig.c b/tools/regression/lib/msun/test-ctrig.c
index ed78661..e12bb48 100644
--- a/tools/regression/lib/msun/test-ctrig.c
+++ b/tools/regression/lib/msun/test-ctrig.c
@@ -38,46 +38,12 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
-#define OPT_INVALID (ALL_STD_EXCEPT & ~FE_INVALID)
-#define OPT_INEXACT (ALL_STD_EXCEPT & ~FE_INEXACT)
-#define FLT_ULP() ldexpl(1.0, 1 - FLT_MANT_DIG)
-#define DBL_ULP() ldexpl(1.0, 1 - DBL_MANT_DIG)
-#define LDBL_ULP() ldexpl(1.0, 1 - LDBL_MANT_DIG)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
#pragma STDC CX_LIMITED_RANGE OFF
/*
- * XXX gcc implements complex multiplication incorrectly. In
- * particular, it implements it as if the CX_LIMITED_RANGE pragma
- * were ON. Consequently, we need this function to form numbers
- * such as x + INFINITY * I, since gcc evalutes INFINITY * I as
- * NaN + INFINITY * I.
- */
-static inline long double complex
-cpackl(long double x, long double y)
-{
- long double complex z;
-
- __real__ z = x;
- __imag__ z = y;
- return (z);
-}
-
-/* Flags that determine whether to check the signs of the result. */
-#define CS_REAL 1
-#define CS_IMAG 2
-#define CS_BOTH (CS_REAL | CS_IMAG)
-
-#ifdef DEBUG
-#define debug(...) printf(__VA_ARGS__)
-#else
-#define debug(...) (void)0
-#endif
-
-/*
* 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
@@ -95,8 +61,8 @@ cpackl(long double x, long double y)
debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(cfpequal((func)(_d), (result), (checksign))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(cfpequal_cs((func)(_d), (result), (checksign))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
/*
@@ -108,7 +74,7 @@ cpackl(long double x, long double y)
volatile long double complex _d = z; \
debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \
- assert(cfpequal_tol((func)(_d), (result), (tol))); \
+ assert(cfpequal_tol((func)(_d), (result), (tol), FPE_ABS_ZERO)); \
} while (0)
/* These wrappers apply the identities f(conj(z)) = conj(f(z)). */
@@ -152,79 +118,18 @@ cpackl(long double x, long double y)
test_tol(func, -x, result, tol * DBL_ULP()); \
} while (0)
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- * If checksign is 0, we compare the absolute values instead.
- */
-static int
-fpequal(long double x, long double y, int checksign)
-{
- if (isnan(x) && isnan(y))
- return (1);
- if (checksign)
- return (x == y && !signbit(x) == !signbit(y));
- else
- return (fabsl(x) == fabsl(y));
-}
-
-static int
-fpequal_tol(long double x, long double y, long double tol)
-{
- fenv_t env;
- int ret;
-
- if (isnan(x) && isnan(y))
- return (1);
- if (!signbit(x) != !signbit(y) && tol == 0)
- return (0);
- if (x == y)
- return (1);
- if (tol == 0)
- return (0);
-
- /* Hard case: need to check the tolerance. */
- feholdexcept(&env);
- /*
- * For our purposes here, if y=0, we interpret tol as an absolute
- * tolerance. This is to account for roundoff in the input, e.g.,
- * cos(Pi/2) ~= 0.
- */
- if (y == 0.0)
- ret = fabsl(x - y) <= fabsl(tol);
- else
- ret = fabsl(x - y) <= fabsl(y * tol);
- fesetenv(&env);
- return (ret);
-}
-
-static int
-cfpequal(long double complex x, long double complex y, int checksign)
-{
- return (fpequal(creal(x), creal(y), checksign & CS_REAL)
- && fpequal(cimag(x), cimag(y), checksign & CS_IMAG));
-}
-
-static int
-cfpequal_tol(long double complex x, long double complex y, long double tol)
-{
- return (fpequal_tol(creal(x), creal(y), tol)
- && fpequal_tol(cimag(x), cimag(y), tol));
-}
-
/* Tests for 0 */
void
test_zero(void)
{
- long double complex zero = cpackl(0.0, 0.0);
+ long double complex zero = CMPLXL(0.0, 0.0);
/* csinh(0) = ctanh(0) = 0; ccosh(0) = 1 (no exceptions raised) */
testall_odd(csinh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
testall_odd(csin, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
testall_even(ccosh, zero, 1.0, ALL_STD_EXCEPT, 0, CS_BOTH);
- testall_even(ccos, zero, cpackl(1.0, -0.0), ALL_STD_EXCEPT, 0, CS_BOTH);
+ testall_even(ccos, zero, CMPLXL(1.0, -0.0), ALL_STD_EXCEPT, 0, CS_BOTH);
testall_odd(ctanh, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
testall_odd(ctan, zero, zero, ALL_STD_EXCEPT, 0, CS_BOTH);
}
@@ -235,7 +140,7 @@ test_zero(void)
void
test_nan()
{
- long double complex nan_nan = cpackl(NAN, NAN);
+ long double complex nan_nan = CMPLXL(NAN, NAN);
long double complex z;
/*
@@ -256,7 +161,7 @@ test_nan()
testall_even(ccos, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
testall_odd(ctan, z, nan_nan, ALL_STD_EXCEPT, 0, 0);
- z = cpackl(42, NAN);
+ z = CMPLXL(42, NAN);
testall_odd(csinh, z, nan_nan, OPT_INVALID, 0, 0);
testall_even(ccosh, z, nan_nan, OPT_INVALID, 0, 0);
/* XXX We allow a spurious inexact exception here. */
@@ -265,7 +170,7 @@ test_nan()
testall_even(ccos, z, nan_nan, OPT_INVALID, 0, 0);
testall_odd(ctan, z, nan_nan, OPT_INVALID, 0, 0);
- z = cpackl(NAN, 42);
+ z = CMPLXL(NAN, 42);
testall_odd(csinh, z, nan_nan, OPT_INVALID, 0, 0);
testall_even(ccosh, z, nan_nan, OPT_INVALID, 0, 0);
testall_odd(ctanh, z, nan_nan, OPT_INVALID, 0, 0);
@@ -274,38 +179,38 @@ test_nan()
/* XXX We allow a spurious inexact exception here. */
testall_odd(ctan, z, nan_nan, OPT_INVALID & ~FE_INEXACT, 0, 0);
- z = cpackl(NAN, INFINITY);
+ z = CMPLXL(NAN, INFINITY);
testall_odd(csinh, z, nan_nan, OPT_INVALID, 0, 0);
testall_even(ccosh, z, nan_nan, OPT_INVALID, 0, 0);
testall_odd(ctanh, z, nan_nan, OPT_INVALID, 0, 0);
- testall_odd(csin, z, cpackl(NAN, INFINITY), ALL_STD_EXCEPT, 0, 0);
- testall_even(ccos, z, cpackl(INFINITY, NAN), ALL_STD_EXCEPT, 0,
+ testall_odd(csin, z, CMPLXL(NAN, INFINITY), ALL_STD_EXCEPT, 0, 0);
+ testall_even(ccos, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0,
CS_IMAG);
- testall_odd(ctan, z, cpackl(0, 1), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall_odd(ctan, z, CMPLXL(0, 1), ALL_STD_EXCEPT, 0, CS_IMAG);
- z = cpackl(INFINITY, NAN);
- testall_odd(csinh, z, cpackl(INFINITY, NAN), ALL_STD_EXCEPT, 0, 0);
- testall_even(ccosh, z, cpackl(INFINITY, NAN), ALL_STD_EXCEPT, 0,
+ z = CMPLXL(INFINITY, NAN);
+ testall_odd(csinh, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0, 0);
+ testall_even(ccosh, z, CMPLXL(INFINITY, NAN), ALL_STD_EXCEPT, 0,
CS_REAL);
- testall_odd(ctanh, z, cpackl(1, 0), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_odd(ctanh, z, CMPLXL(1, 0), ALL_STD_EXCEPT, 0, CS_REAL);
testall_odd(csin, z, nan_nan, OPT_INVALID, 0, 0);
testall_even(ccos, z, nan_nan, OPT_INVALID, 0, 0);
testall_odd(ctan, z, nan_nan, OPT_INVALID, 0, 0);
- z = cpackl(0, NAN);
- testall_odd(csinh, z, cpackl(0, NAN), ALL_STD_EXCEPT, 0, 0);
- testall_even(ccosh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ z = CMPLXL(0, NAN);
+ testall_odd(csinh, z, CMPLXL(0, NAN), ALL_STD_EXCEPT, 0, 0);
+ testall_even(ccosh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
testall_odd(ctanh, z, nan_nan, OPT_INVALID, 0, 0);
- testall_odd(csin, z, cpackl(0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
- testall_even(ccos, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
- testall_odd(ctan, z, cpackl(0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
-
- z = cpackl(NAN, 0);
- testall_odd(csinh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
- testall_even(ccosh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
- testall_odd(ctanh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
- testall_odd(csin, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
- testall_even(ccos, z, cpackl(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ testall_odd(csin, z, CMPLXL(0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_even(ccos, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ testall_odd(ctan, z, CMPLXL(0, NAN), ALL_STD_EXCEPT, 0, CS_REAL);
+
+ z = CMPLXL(NAN, 0);
+ testall_odd(csinh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall_even(ccosh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ testall_odd(ctanh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, CS_IMAG);
+ testall_odd(csin, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
+ testall_even(ccos, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, 0, 0);
testall_odd(ctan, z, nan_nan, OPT_INVALID, 0, 0);
}
@@ -325,53 +230,53 @@ test_inf(void)
* 0,Inf +-0,NaN inval NaN,+-0 inval NaN,NaN inval
* finite,Inf NaN,NaN inval NaN,NaN inval NaN,NaN inval
*/
- z = cpackl(INFINITY, INFINITY);
- testall_odd(csinh, z, cpackl(INFINITY, NAN),
+ z = CMPLXL(INFINITY, INFINITY);
+ testall_odd(csinh, z, CMPLXL(INFINITY, NAN),
ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccosh, z, cpackl(INFINITY, NAN),
+ testall_even(ccosh, z, CMPLXL(INFINITY, NAN),
ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_odd(ctanh, z, cpackl(1, 0), ALL_STD_EXCEPT, 0, CS_REAL);
- testall_odd(csin, z, cpackl(NAN, INFINITY),
+ testall_odd(ctanh, z, CMPLXL(1, 0), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_odd(csin, z, CMPLXL(NAN, INFINITY),
ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccos, z, cpackl(INFINITY, NAN),
+ testall_even(ccos, z, CMPLXL(INFINITY, NAN),
ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_odd(ctan, z, cpackl(0, 1), ALL_STD_EXCEPT, 0, CS_REAL);
+ testall_odd(ctan, z, CMPLXL(0, 1), ALL_STD_EXCEPT, 0, CS_REAL);
/* XXX We allow spurious inexact exceptions here (hard to avoid). */
for (i = 0; i < sizeof(finites) / sizeof(finites[0]); i++) {
- z = cpackl(INFINITY, finites[i]);
+ z = CMPLXL(INFINITY, finites[i]);
c = INFINITY * cosl(finites[i]);
s = finites[i] == 0 ? finites[i] : INFINITY * sinl(finites[i]);
- testall_odd(csinh, z, cpackl(c, s), OPT_INEXACT, 0, CS_BOTH);
- testall_even(ccosh, z, cpackl(c, s), OPT_INEXACT, 0, CS_BOTH);
- testall_odd(ctanh, z, cpackl(1, 0 * sin(finites[i] * 2)),
+ testall_odd(csinh, z, CMPLXL(c, s), OPT_INEXACT, 0, CS_BOTH);
+ testall_even(ccosh, z, CMPLXL(c, s), OPT_INEXACT, 0, CS_BOTH);
+ testall_odd(ctanh, z, CMPLXL(1, 0 * sin(finites[i] * 2)),
OPT_INEXACT, 0, CS_BOTH);
- z = cpackl(finites[i], INFINITY);
- testall_odd(csin, z, cpackl(s, c), OPT_INEXACT, 0, CS_BOTH);
- testall_even(ccos, z, cpackl(c, -s), OPT_INEXACT, 0, CS_BOTH);
- testall_odd(ctan, z, cpackl(0 * sin(finites[i] * 2), 1),
+ z = CMPLXL(finites[i], INFINITY);
+ testall_odd(csin, z, CMPLXL(s, c), OPT_INEXACT, 0, CS_BOTH);
+ testall_even(ccos, z, CMPLXL(c, -s), OPT_INEXACT, 0, CS_BOTH);
+ testall_odd(ctan, z, CMPLXL(0 * sin(finites[i] * 2), 1),
OPT_INEXACT, 0, CS_BOTH);
}
- z = cpackl(0, INFINITY);
- testall_odd(csinh, z, cpackl(0, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccosh, z, cpackl(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_odd(ctanh, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
- z = cpackl(INFINITY, 0);
- testall_odd(csin, z, cpackl(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccos, z, cpackl(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_odd(ctan, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
-
- z = cpackl(42, INFINITY);
- testall_odd(csinh, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccosh, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ z = CMPLXL(0, INFINITY);
+ testall_odd(csinh, z, CMPLXL(0, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_even(ccosh, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_odd(ctanh, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ z = CMPLXL(INFINITY, 0);
+ testall_odd(csin, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_even(ccos, z, CMPLXL(NAN, 0), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_odd(ctan, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+
+ z = CMPLXL(42, INFINITY);
+ testall_odd(csinh, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_even(ccosh, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
/* XXX We allow a spurious inexact exception here. */
- testall_odd(ctanh, z, cpackl(NAN, NAN), OPT_INEXACT, FE_INVALID, 0);
- z = cpackl(INFINITY, 42);
- testall_odd(csin, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
- testall_even(ccos, z, cpackl(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_odd(ctanh, z, CMPLXL(NAN, NAN), OPT_INEXACT, FE_INVALID, 0);
+ z = CMPLXL(INFINITY, 42);
+ testall_odd(csin, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
+ testall_even(ccos, z, CMPLXL(NAN, NAN), ALL_STD_EXCEPT, FE_INVALID, 0);
/* XXX We allow a spurious inexact exception here. */
- testall_odd(ctan, z, cpackl(NAN, NAN), OPT_INEXACT, FE_INVALID, 0);
+ testall_odd(ctan, z, CMPLXL(NAN, NAN), OPT_INEXACT, FE_INVALID, 0);
}
/* Tests along the real and imaginary axes. */
@@ -387,26 +292,26 @@ test_axes(void)
for (i = 0; i < sizeof(nums) / sizeof(nums[0]); i++) {
/* Real axis */
- z = cpackl(nums[i], 0.0);
- testall_odd_tol(csinh, z, cpackl(sinh(nums[i]), 0), 0);
- testall_even_tol(ccosh, z, cpackl(cosh(nums[i]), 0), 0);
- testall_odd_tol(ctanh, z, cpackl(tanh(nums[i]), 0), 1);
- testall_odd_tol(csin, z, cpackl(sin(nums[i]),
+ z = CMPLXL(nums[i], 0.0);
+ testall_odd_tol(csinh, z, CMPLXL(sinh(nums[i]), 0), 0);
+ testall_even_tol(ccosh, z, CMPLXL(cosh(nums[i]), 0), 0);
+ testall_odd_tol(ctanh, z, CMPLXL(tanh(nums[i]), 0), 1);
+ testall_odd_tol(csin, z, CMPLXL(sin(nums[i]),
copysign(0, cos(nums[i]))), 0);
- testall_even_tol(ccos, z, cpackl(cos(nums[i]),
+ testall_even_tol(ccos, z, CMPLXL(cos(nums[i]),
-copysign(0, sin(nums[i]))), 0);
- testall_odd_tol(ctan, z, cpackl(tan(nums[i]), 0), 1);
+ testall_odd_tol(ctan, z, CMPLXL(tan(nums[i]), 0), 1);
/* Imaginary axis */
- z = cpackl(0.0, nums[i]);
- testall_odd_tol(csinh, z, cpackl(copysign(0, cos(nums[i])),
+ z = CMPLXL(0.0, nums[i]);
+ testall_odd_tol(csinh, z, CMPLXL(copysign(0, cos(nums[i])),
sin(nums[i])), 0);
- testall_even_tol(ccosh, z, cpackl(cos(nums[i]),
+ testall_even_tol(ccosh, z, CMPLXL(cos(nums[i]),
copysign(0, sin(nums[i]))), 0);
- testall_odd_tol(ctanh, z, cpackl(0, tan(nums[i])), 1);
- testall_odd_tol(csin, z, cpackl(0, sinh(nums[i])), 0);
- testall_even_tol(ccos, z, cpackl(cosh(nums[i]), -0.0), 0);
- testall_odd_tol(ctan, z, cpackl(0, tanh(nums[i])), 1);
+ testall_odd_tol(ctanh, z, CMPLXL(0, tan(nums[i])), 1);
+ testall_odd_tol(csin, z, CMPLXL(0, sinh(nums[i])), 0);
+ testall_even_tol(ccos, z, CMPLXL(cosh(nums[i]), -0.0), 0);
+ testall_odd_tol(ctan, z, CMPLXL(0, tanh(nums[i])), 1);
}
}
@@ -462,13 +367,13 @@ test_small(void)
int i;
for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++) {
- z = cpackl(tests[i].a, tests[i].b);
+ z = CMPLXL(tests[i].a, tests[i].b);
testall_odd_tol(csinh, z,
- cpackl(tests[i].sinh_a, tests[i].sinh_b), 1.1);
+ CMPLXL(tests[i].sinh_a, tests[i].sinh_b), 1.1);
testall_even_tol(ccosh, z,
- cpackl(tests[i].cosh_a, tests[i].cosh_b), 1.1);
+ CMPLXL(tests[i].cosh_a, tests[i].cosh_b), 1.1);
testall_odd_tol(ctanh, z,
- cpackl(tests[i].tanh_a, tests[i].tanh_b), 1.1);
+ CMPLXL(tests[i].tanh_a, tests[i].tanh_b), 1.1);
}
}
@@ -479,36 +384,36 @@ test_large(void)
long double complex z;
/* tanh() uses a threshold around x=22, so check both sides. */
- z = cpackl(21, 0.78539816339744830961566084581987572L);
+ z = CMPLXL(21, 0.78539816339744830961566084581987572L);
testall_odd_tol(ctanh, z,
- cpackl(1.0, 1.14990445285871196133287617611468468e-18L), 1);
+ CMPLXL(1.0, 1.14990445285871196133287617611468468e-18L), 1);
z++;
testall_odd_tol(ctanh, z,
- cpackl(1.0, 1.55622644822675930314266334585597964e-19L), 1);
+ CMPLXL(1.0, 1.55622644822675930314266334585597964e-19L), 1);
- z = cpackl(355, 0.78539816339744830961566084581987572L);
+ z = CMPLXL(355, 0.78539816339744830961566084581987572L);
testall_odd_tol(ctanh, z,
- cpackl(1.0, 8.95257245135025991216632140458264468e-309L), 1);
- z = cpackl(30, 0x1p1023L);
+ CMPLXL(1.0, 8.95257245135025991216632140458264468e-309L), 1);
+ z = CMPLXL(30, 0x1p1023L);
testall_odd_tol(ctanh, z,
- cpackl(1.0, -1.62994325413993477997492170229268382e-26L), 1);
- z = cpackl(1, 0x1p1023L);
+ CMPLXL(1.0, -1.62994325413993477997492170229268382e-26L), 1);
+ z = CMPLXL(1, 0x1p1023L);
testall_odd_tol(ctanh, z,
- cpackl(0.878606311888306869546254022621986509L,
+ CMPLXL(0.878606311888306869546254022621986509L,
-0.225462792499754505792678258169527424L), 1);
- z = cpackl(710.6, 0.78539816339744830961566084581987572L);
+ z = CMPLXL(710.6, 0.78539816339744830961566084581987572L);
testall_odd_tol(csinh, z,
- cpackl(1.43917579766621073533185387499658944e308L,
+ CMPLXL(1.43917579766621073533185387499658944e308L,
1.43917579766621073533185387499658944e308L), 1);
testall_even_tol(ccosh, z,
- cpackl(1.43917579766621073533185387499658944e308L,
+ CMPLXL(1.43917579766621073533185387499658944e308L,
1.43917579766621073533185387499658944e308L), 1);
- z = cpackl(1500, 0.78539816339744830961566084581987572L);
- testall_odd(csinh, z, cpackl(INFINITY, INFINITY), OPT_INEXACT,
+ z = CMPLXL(1500, 0.78539816339744830961566084581987572L);
+ testall_odd(csinh, z, CMPLXL(INFINITY, INFINITY), OPT_INEXACT,
FE_OVERFLOW, CS_BOTH);
- testall_even(ccosh, z, cpackl(INFINITY, INFINITY), OPT_INEXACT,
+ testall_even(ccosh, z, CMPLXL(INFINITY, INFINITY), OPT_INEXACT,
FE_OVERFLOW, CS_BOTH);
}
diff --git a/tools/regression/lib/msun/test-exponential.c b/tools/regression/lib/msun/test-exponential.c
index 53a6116..010e0fd 100644
--- a/tools/regression/lib/msun/test-exponential.c
+++ b/tools/regression/lib/msun/test-exponential.c
@@ -41,8 +41,7 @@ __FBSDID("$FreeBSD$");
#include <ieeefp.h>
#endif
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
@@ -63,7 +62,7 @@ __FBSDID("$FreeBSD$");
volatile long double _d = x; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
assert(fpequal((func)(_d), (result))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
/* Test all the functions that compute b^x. */
@@ -81,17 +80,6 @@ __FBSDID("$FreeBSD$");
test(expm1f, x, result, exceptmask, excepts); \
} while (0)
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y)
-{
- return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
-}
-
void
run_generic_tests(void)
{
diff --git a/tools/regression/lib/msun/test-fma.c b/tools/regression/lib/msun/test-fma.c
index c17ef45..1fcf889 100644
--- a/tools/regression/lib/msun/test-fma.c
+++ b/tools/regression/lib/msun/test-fma.c
@@ -37,8 +37,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
@@ -53,14 +52,17 @@ __FBSDID("$FreeBSD$");
* meaningful error messages.
*/
#define test(func, x, y, z, result, exceptmask, excepts) do { \
+ volatile long double _vx = (x), _vy = (y), _vz = (z); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(fpequal((func)((x), (y), (z)), (result))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(fpequal((func)(_vx, _vy, _vz), (result))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
#define testall(x, y, z, result, exceptmask, excepts) do { \
- test(fma, (x), (y), (z), (double)(result), (exceptmask), (excepts)); \
- test(fmaf, (x), (y), (z), (float)(result), (exceptmask), (excepts)); \
+ test(fma, (double)(x), (double)(y), (double)(z), \
+ (double)(result), (exceptmask), (excepts)); \
+ test(fmaf, (float)(x), (float)(y), (float)(z), \
+ (float)(result), (exceptmask), (excepts)); \
test(fmal, (x), (y), (z), (result), (exceptmask), (excepts)); \
} while (0)
@@ -82,19 +84,6 @@ __FBSDID("$FreeBSD$");
*/
volatile double one = 1.0;
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y)
-{
-
- return ((x == y && !signbit(x) == !signbit(y))
- || (isnan(x) && isnan(y)));
-}
-
static void
test_zeroes(void)
{
diff --git a/tools/regression/lib/msun/test-fmaxmin.c b/tools/regression/lib/msun/test-fmaxmin.c
index fdba529..7ddcc87 100644
--- a/tools/regression/lib/msun/test-fmaxmin.c
+++ b/tools/regression/lib/msun/test-fmaxmin.c
@@ -36,25 +36,11 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
/*
- * Test for equality with two special rules:
- * fpequal(NaN, NaN) is true
- * fpequal(+0.0, -0.0) is false
- */
-static inline int
-fpequal(long double x, long double y)
-{
-
- return ((x == y && !signbit(x) == !signbit(y))
- || (isnan(x) && isnan(y)));
-}
-
-/*
* Test whether func(x, y) has the expected result, and make sure no
* exceptions are raised.
*/
diff --git a/tools/regression/lib/msun/test-invctrig.c b/tools/regression/lib/msun/test-invctrig.c
index 6f0fe58..e78c26b 100644
--- a/tools/regression/lib/msun/test-invctrig.c
+++ b/tools/regression/lib/msun/test-invctrig.c
@@ -38,28 +38,11 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
-#define OPT_INVALID (ALL_STD_EXCEPT & ~FE_INVALID)
-#define OPT_INEXACT (ALL_STD_EXCEPT & ~FE_INEXACT)
-#define FLT_ULP() ldexpl(1.0, 1 - FLT_MANT_DIG)
-#define DBL_ULP() ldexpl(1.0, 1 - DBL_MANT_DIG)
-#define LDBL_ULP() ldexpl(1.0, 1 - LDBL_MANT_DIG)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
#pragma STDC CX_LIMITED_RANGE OFF
-/* Flags that determine whether to check the signs of the result. */
-#define CS_REAL 1
-#define CS_IMAG 2
-#define CS_BOTH (CS_REAL | CS_IMAG)
-
-#ifdef DEBUG
-#define debug(...) printf(__VA_ARGS__)
-#else
-#define debug(...) (void)0
-#endif
-
/*
* Test that a function returns the correct value and sets the
* exception flags correctly. The exceptmask specifies which
@@ -78,8 +61,8 @@ __FBSDID("$FreeBSD$");
debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(cfpequal((func)(_d), (result), (checksign))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(cfpequal_cs((func)(_d), (result), (checksign))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
/*
@@ -90,7 +73,7 @@ __FBSDID("$FreeBSD$");
volatile long double complex _d = z; \
debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \
- assert(cfpequal_tol((func)(_d), (result), (tol))); \
+ assert(cfpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \
} while (0)
/* These wrappers apply the identities f(conj(z)) = conj(f(z)). */
@@ -138,59 +121,6 @@ static const long double
pi = 3.14159265358979323846264338327950280L,
c3pi = 9.42477796076937971538793014983850839L;
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- * If checksign is 0, we compare the absolute values instead.
- */
-static int
-fpequal(long double x, long double y, int checksign)
-{
- if (isnan(x) && isnan(y))
- return (1);
- if (checksign)
- return (x == y && !signbit(x) == !signbit(y));
- else
- return (fabsl(x) == fabsl(y));
-}
-
-static int
-fpequal_tol(long double x, long double y, long double tol)
-{
- fenv_t env;
- int ret;
-
- if (isnan(x) && isnan(y))
- return (1);
- if (!signbit(x) != !signbit(y))
- return (0);
- if (x == y)
- return (1);
- if (tol == 0 || y == 0.0)
- return (0);
-
- /* Hard case: need to check the tolerance. */
- feholdexcept(&env);
- ret = fabsl(x - y) <= fabsl(y * tol);
- fesetenv(&env);
- return (ret);
-}
-
-static int
-cfpequal(long double complex x, long double complex y, int checksign)
-{
- return (fpequal(creal(x), creal(y), checksign & CS_REAL)
- && fpequal(cimag(x), cimag(y), checksign & CS_IMAG));
-}
-
-static int
-cfpequal_tol(long double complex x, long double complex y, long double tol)
-{
- return (fpequal_tol(creal(x), creal(y), tol)
- && fpequal_tol(cimag(x), cimag(y), tol));
-}
-
/* Tests for 0 */
void
diff --git a/tools/regression/lib/msun/test-invtrig.c b/tools/regression/lib/msun/test-invtrig.c
index 05d310f..2523d59 100644
--- a/tools/regression/lib/msun/test-invtrig.c
+++ b/tools/regression/lib/msun/test-invtrig.c
@@ -39,8 +39,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#define LEN(a) (sizeof(a) / sizeof((a)[0]))
@@ -58,8 +57,8 @@ __FBSDID("$FreeBSD$");
#define test_tol(func, x, result, tol, excepts) do { \
volatile long double _in = (x), _out = (result); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(fpequal(func(_in), _out, (tol))); \
- assert((func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
+ assert(fpequal_tol(func(_in), _out, (tol), CS_BOTH)); \
+ assert(((void)func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
} while (0)
#define test(func, x, result, excepts) \
test_tol(func, (x), (result), 0, (excepts))
@@ -78,8 +77,8 @@ __FBSDID("$FreeBSD$");
#define test2_tol(func, y, x, result, tol, excepts) do { \
volatile long double _iny = (y), _inx = (x), _out = (result); \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
- assert(fpequal(func(_iny, _inx), _out, (tol))); \
- assert((func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
+ assert(fpequal_tol(func(_iny, _inx), _out, (tol), CS_BOTH)); \
+ assert(((void)func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
} while (0)
#define test2(func, y, x, result, excepts) \
test2_tol(func, (y), (x), (result), 0, (excepts))
@@ -104,33 +103,6 @@ c7pi = 2.19911485751285526692385036829565196e+01L,
c5pio3 = 5.23598775598298873077107230546583851e+00L,
sqrt2m1 = 4.14213562373095048801688724209698081e-01L;
-/*
- * Determine whether x and y are equal to within a relative error of tol,
- * with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y, long double tol)
-{
- fenv_t env;
- int ret;
-
- if (isnan(x) && isnan(y))
- return (1);
- if (!signbit(x) != !signbit(y))
- return (0);
- if (x == y)
- return (1);
- if (tol == 0)
- return (0);
-
- /* Hard case: need to check the tolerance. */
- feholdexcept(&env);
- ret = fabsl(x - y) <= fabsl(y * tol);
- fesetenv(&env);
- return (ret);
-}
/*
* Test special case inputs in asin(), acos() and atan(): signed
diff --git a/tools/regression/lib/msun/test-logarithm.c b/tools/regression/lib/msun/test-logarithm.c
index 258c514..c5f23b8 100644
--- a/tools/regression/lib/msun/test-logarithm.c
+++ b/tools/regression/lib/msun/test-logarithm.c
@@ -41,8 +41,7 @@ __FBSDID("$FreeBSD$");
#include <ieeefp.h>
#endif
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#pragma STDC FENV_ACCESS ON
@@ -63,7 +62,7 @@ __FBSDID("$FreeBSD$");
volatile long double _d = x; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
assert(fpequal((func)(_d), (result))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
/* Test all the functions that compute log(x). */
@@ -82,17 +81,6 @@ __FBSDID("$FreeBSD$");
test(log1pf, x, result, exceptmask, excepts); \
} while (0)
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y)
-{
- return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
-}
-
void
run_generic_tests(void)
{
diff --git a/tools/regression/lib/msun/test-nearbyint.c b/tools/regression/lib/msun/test-nearbyint.c
index 7251acb..602ea2a 100644
--- a/tools/regression/lib/msun/test-nearbyint.c
+++ b/tools/regression/lib/msun/test-nearbyint.c
@@ -40,8 +40,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
static int testnum;
@@ -49,6 +48,14 @@ static const int rmodes[] = {
FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO,
};
+/* Make sure we're testing the library, not some broken compiler built-ins. */
+double (*libnearbyint)(double) = nearbyint;
+float (*libnearbyintf)(float) = nearbyintf;
+long double (*libnearbyintl)(long double) = nearbyintl;
+#define nearbyintf libnearbyintf
+#define nearbyint libnearbyint
+#define nearbyintl libnearbyintl
+
static const struct {
float in;
float out[3]; /* one answer per rounding mode except towardzero */
@@ -64,19 +71,6 @@ static const struct {
static const int ntests = sizeof(tests) / sizeof(tests[0]);
-/*
- * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
- * Fail an assertion if they differ.
- */
-static int
-fpequal(long double d1, long double d2)
-{
-
- if (d1 != d2)
- return (isnan(d1) && isnan(d2));
- return (copysignl(1.0, d1) == copysignl(1.0, d2));
-}
-
/* Get the appropriate result for the current rounding mode. */
static float
get_output(int testindex, int rmodeindex, int negative)
@@ -107,7 +101,7 @@ test_nearby(int testindex)
in = tests[testindex].in;
out = get_output(testindex, i, 0);
- assert(fpequal(out, nearbyintf(in)));
+ assert(fpequal(out, libnearbyintf(in)));
assert(fpequal(out, nearbyint(in)));
assert(fpequal(out, nearbyintl(in)));
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
diff --git a/tools/regression/lib/msun/test-next.c b/tools/regression/lib/msun/test-next.c
index 68e4361..d16fa77 100644
--- a/tools/regression/lib/msun/test-next.c
+++ b/tools/regression/lib/msun/test-next.c
@@ -41,8 +41,8 @@ __FBSDID("$FreeBSD$");
#include <ieeefp.h>
#endif
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID |\
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
+
#define test(exp, ans, ex) do { \
double __ans = (ans); \
feclearexcept(ALL_STD_EXCEPT); \
@@ -235,7 +235,7 @@ _testl(const char *exp, int line, long double actual, long double expected,
int actual_except;
actual_except = fetestexcept(ALL_STD_EXCEPT);
- if (actual != expected && !(isnan(actual) && isnan(expected))) {
+ if (!fpequal(actual, expected)) {
fprintf(stderr, "%d: %s returned %La, expecting %La\n",
line, exp, actual, expected);
abort();
diff --git a/tools/regression/lib/msun/test-trig.c b/tools/regression/lib/msun/test-trig.c
index 1ac7873..80f1aef 100644
--- a/tools/regression/lib/msun/test-trig.c
+++ b/tools/regression/lib/msun/test-trig.c
@@ -42,8 +42,7 @@ __FBSDID("$FreeBSD$");
#include <math.h>
#include <stdio.h>
-#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
- FE_OVERFLOW | FE_UNDERFLOW)
+#include "test-utils.h"
#define LEN(a) (sizeof(a) / sizeof((a)[0]))
@@ -66,7 +65,7 @@ __FBSDID("$FreeBSD$");
volatile long double _d = x; \
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
assert(fpequal((func)(_d), (result))); \
- assert(((func), fetestexcept(exceptmask) == (excepts))); \
+ assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
} while (0)
#define testall(prefix, x, result, exceptmask, excepts) do { \
@@ -80,19 +79,6 @@ __FBSDID("$FreeBSD$");
test(prefix##f, x, (float)result, exceptmask, excepts); \
} while (0)
-
-
-/*
- * Determine whether x and y are equal, with two special rules:
- * +0.0 != -0.0
- * NaN == NaN
- */
-int
-fpequal(long double x, long double y)
-{
- return ((x == y && !signbit(x) == !signbit(y)) || isnan(x) && isnan(y));
-}
-
/*
* Test special cases in sin(), cos(), and tan().
*/
diff --git a/tools/regression/lib/msun/test-utils.h b/tools/regression/lib/msun/test-utils.h
new file mode 100644
index 0000000..bf0d6de
--- /dev/null
+++ b/tools/regression/lib/msun/test-utils.h
@@ -0,0 +1,174 @@
+/*-
+ * Copyright (c) 2005-2013 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _TEST_UTILS_H_
+#define _TEST_UTILS_H_
+
+#include <complex.h>
+#include <fenv.h>
+
+/*
+ * Implementations are permitted to define additional exception flags
+ * not specified in the standard, so it is not necessarily true that
+ * FE_ALL_EXCEPT == ALL_STD_EXCEPT.
+ */
+#define ALL_STD_EXCEPT (FE_DIVBYZERO | FE_INEXACT | FE_INVALID | \
+ FE_OVERFLOW | FE_UNDERFLOW)
+#define OPT_INVALID (ALL_STD_EXCEPT & ~FE_INVALID)
+#define OPT_INEXACT (ALL_STD_EXCEPT & ~FE_INEXACT)
+#define FLT_ULP() ldexpl(1.0, 1 - FLT_MANT_DIG)
+#define DBL_ULP() ldexpl(1.0, 1 - DBL_MANT_DIG)
+#define LDBL_ULP() ldexpl(1.0, 1 - LDBL_MANT_DIG)
+
+/*
+ * Flags that control the behavior of various fpequal* functions.
+ * XXX This is messy due to merging various notions of "close enough"
+ * that are best suited for different functions.
+ *
+ * CS_REAL
+ * CS_IMAG
+ * CS_BOTH
+ * (cfpequal_cs, fpequal_tol, cfpequal_tol) Whether to check the sign of
+ * the real part of the result, the imaginary part, or both.
+ *
+ * FPE_ABS_ZERO
+ * (fpequal_tol, cfpequal_tol) If set, treats the tolerance as an absolute
+ * tolerance when the expected value is 0. This is useful when there is
+ * round-off error in the input, e.g., cos(Pi/2) ~= 0.
+ */
+#define CS_REAL 0x01
+#define CS_IMAG 0x02
+#define CS_BOTH (CS_REAL | CS_IMAG)
+#define FPE_ABS_ZERO 0x04
+
+#ifdef DEBUG
+#define debug(...) printf(__VA_ARGS__)
+#else
+#define debug(...) (void)0
+#endif
+
+/*
+ * XXX The ancient version of gcc in the base system doesn't support CMPLXL,
+ * but we can fake it most of the time.
+ */
+#ifndef CMPLXL
+static inline long double complex
+CMPLXL(long double x, long double y)
+{
+ long double complex z;
+
+ __real__ z = x;
+ __imag__ z = y;
+ return (z);
+}
+#endif
+
+/*
+ * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
+ * Fail an assertion if they differ.
+ */
+static int
+fpequal(long double d1, long double d2)
+{
+
+ if (d1 != d2)
+ return (isnan(d1) && isnan(d2));
+ return (copysignl(1.0, d1) == copysignl(1.0, d2));
+}
+
+/*
+ * Determine whether x and y are equal, with two special rules:
+ * +0.0 != -0.0
+ * NaN == NaN
+ * If checksign is 0, we compare the absolute values instead.
+ */
+static int
+fpequal_cs(long double x, long double y, int checksign)
+{
+ if (isnan(x) && isnan(y))
+ return (1);
+ if (checksign)
+ return (x == y && !signbit(x) == !signbit(y));
+ else
+ return (fabsl(x) == fabsl(y));
+}
+
+static int
+fpequal_tol(long double x, long double y, long double tol, unsigned int flags)
+{
+ fenv_t env;
+ int ret;
+
+ if (isnan(x) && isnan(y))
+ return (1);
+ if (!signbit(x) != !signbit(y) && (flags & CS_BOTH))
+ return (0);
+ if (x == y)
+ return (1);
+ if (tol == 0)
+ return (0);
+
+ /* Hard case: need to check the tolerance. */
+ feholdexcept(&env);
+ /*
+ * For our purposes here, if y=0, we interpret tol as an absolute
+ * tolerance. This is to account for roundoff in the input, e.g.,
+ * cos(Pi/2) ~= 0.
+ */
+ if ((flags & FPE_ABS_ZERO) && y == 0.0)
+ ret = fabsl(x - y) <= fabsl(tol);
+ else
+ ret = fabsl(x - y) <= fabsl(y * tol);
+ fesetenv(&env);
+ return (ret);
+}
+
+static int
+cfpequal(long double complex d1, long double complex d2)
+{
+
+ return (fpequal(creall(d1), creall(d2)) &&
+ fpequal(cimagl(d1), cimagl(d2)));
+}
+
+static int
+cfpequal_cs(long double complex x, long double complex y, int checksign)
+{
+ return (fpequal_cs(creal(x), creal(y), checksign)
+ && fpequal_cs(cimag(x), cimag(y), checksign));
+}
+
+static int
+cfpequal_tol(long double complex x, long double complex y, long double tol,
+ unsigned int flags)
+{
+ return (fpequal_tol(creal(x), creal(y), tol, flags)
+ && fpequal_tol(cimag(x), cimag(y), tol, flags));
+}
+
+#endif /* _TEST_UTILS_H_ */
OpenPOWER on IntegriCloud