1*0a6a1f1dSLionel Sambuc /* $NetBSD: t_libm.h,v 1.6 2014/03/25 17:30:14 joerg Exp $ */ 2*0a6a1f1dSLionel Sambuc 3*0a6a1f1dSLionel Sambuc /* 4*0a6a1f1dSLionel Sambuc * Check result of fn(arg) is correct within the bounds. 5*0a6a1f1dSLionel Sambuc * Should be ok to do the checks using 'double' for 'float' functions. 6*0a6a1f1dSLionel Sambuc * On i386 float and double values are returned on the x87 stack and might 7*0a6a1f1dSLionel Sambuc * be out of range for the function - so save and print as 'long double'. 8*0a6a1f1dSLionel Sambuc * (otherwise you can get 'inf != inf' reported!) 9*0a6a1f1dSLionel Sambuc */ 10*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK(subtest, fn, arg, expect_, epsilon_) do { \ 11*0a6a1f1dSLionel Sambuc long double epsilon = epsilon_; \ 12*0a6a1f1dSLionel Sambuc long double expect = expect_; \ 13*0a6a1f1dSLionel Sambuc long double r = fn(arg); \ 14*0a6a1f1dSLionel Sambuc long double e = fabsl(r - expect); \ 15*0a6a1f1dSLionel Sambuc if (r != expect && e > epsilon) \ 16*0a6a1f1dSLionel Sambuc atf_tc_fail_nonfatal( \ 17*0a6a1f1dSLionel Sambuc "subtest %u: " #fn "(%g) is %Lg (%.14La) " \ 18*0a6a1f1dSLionel Sambuc "not %Lg (%.13La), error %Lg (%.6La) > %Lg", \ 19*0a6a1f1dSLionel Sambuc subtest, arg, r, r, expect, expect, e, e, epsilon); \ 20*0a6a1f1dSLionel Sambuc } while (0) 21*0a6a1f1dSLionel Sambuc 22*0a6a1f1dSLionel Sambuc /* Check that the result of fn(arg) is NaN */ 23*0a6a1f1dSLionel Sambuc #ifndef __vax__ 24*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK_NAN(subtest, fn, arg) do { \ 25*0a6a1f1dSLionel Sambuc double r = fn(arg); \ 26*0a6a1f1dSLionel Sambuc if (!isnan(r)) \ 27*0a6a1f1dSLionel Sambuc atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not NaN", \ 28*0a6a1f1dSLionel Sambuc subtest, arg, r); \ 29*0a6a1f1dSLionel Sambuc } while (0) 30*0a6a1f1dSLionel Sambuc #else 31*0a6a1f1dSLionel Sambuc /* vax doesn't support NaN */ 32*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK_NAN(subtest, fn, arg) (void)(arg) 33*0a6a1f1dSLionel Sambuc #endif 34*0a6a1f1dSLionel Sambuc 35*0a6a1f1dSLionel Sambuc /* Check that the result of fn(arg) is +0.0 */ 36*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK_PLUS_ZERO(subtest, fn, arg) do { \ 37*0a6a1f1dSLionel Sambuc double r = fn(arg); \ 38*0a6a1f1dSLionel Sambuc if (fabs(r) > 0.0 || signbit(r) != 0) \ 39*0a6a1f1dSLionel Sambuc atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not +0.0", \ 40*0a6a1f1dSLionel Sambuc subtest, arg, r); \ 41*0a6a1f1dSLionel Sambuc } while (0) 42*0a6a1f1dSLionel Sambuc 43*0a6a1f1dSLionel Sambuc /* Check that the result of fn(arg) is -0.0 */ 44*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK_MINUS_ZERO(subtest, fn, arg) do { \ 45*0a6a1f1dSLionel Sambuc double r = fn(arg); \ 46*0a6a1f1dSLionel Sambuc if (fabs(r) > 0.0 || signbit(r) == 0) \ 47*0a6a1f1dSLionel Sambuc atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not -0.0", \ 48*0a6a1f1dSLionel Sambuc subtest, arg, r); \ 49*0a6a1f1dSLionel Sambuc } while (0) 50*0a6a1f1dSLionel Sambuc 51*0a6a1f1dSLionel Sambuc /* Some useful constants (for test vectors) */ 52*0a6a1f1dSLionel Sambuc #ifndef __vax__ /* no NAN nor +/- INF on vax */ 53*0a6a1f1dSLionel Sambuc #define T_LIBM_NAN (0.0 / 0.0) 54*0a6a1f1dSLionel Sambuc #define T_LIBM_PLUS_INF (+1.0 / 0.0) 55*0a6a1f1dSLionel Sambuc #define T_LIBM_MINUS_INF (-1.0 / 0.0) 56*0a6a1f1dSLionel Sambuc #endif 57*0a6a1f1dSLionel Sambuc 58*0a6a1f1dSLionel Sambuc /* One line definition of a simple test */ 59*0a6a1f1dSLionel Sambuc #define ATF_LIBM_TEST(name, description) \ 60*0a6a1f1dSLionel Sambuc ATF_TC(name); \ 61*0a6a1f1dSLionel Sambuc ATF_TC_HEAD(name, tc) { atf_tc_set_md_var(tc, "descr", description); } \ 62*0a6a1f1dSLionel Sambuc ATF_TC_BODY(name, tc) 63