Module Name: src Committed By: martin Date: Sun Dec 21 15:37:03 UTC 2014
Modified Files: src/tests/lib/libm: Makefile Added Files: src/tests/lib/libm: t_fenv.c Log Message: Add a test program for basic fenv.h rounding mode/exception mask testing. To generate a diff of this commit: cvs rdiff -u -r1.26 -r1.27 src/tests/lib/libm/Makefile cvs rdiff -u -r0 -r1.1 src/tests/lib/libm/t_fenv.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/lib/libm/Makefile diff -u src/tests/lib/libm/Makefile:1.26 src/tests/lib/libm/Makefile:1.27 --- src/tests/lib/libm/Makefile:1.26 Sun Aug 10 11:30:51 2014 +++ src/tests/lib/libm/Makefile Sun Dec 21 15:37:03 2014 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.26 2014/08/10 11:30:51 martin Exp $ +# $NetBSD: Makefile,v 1.27 2014/12/21 15:37:03 martin Exp $ .include <bsd.own.mk> @@ -23,6 +23,7 @@ TESTS_C+= t_cos TESTS_C+= t_cosh TESTS_C+= t_erf TESTS_C+= t_exp +TESTS_C+= t_fenv TESTS_C+= t_fmod TESTS_C+= t_infinity TESTS_C+= t_ldexp Added files: Index: src/tests/lib/libm/t_fenv.c diff -u /dev/null src/tests/lib/libm/t_fenv.c:1.1 --- /dev/null Sun Dec 21 15:37:03 2014 +++ src/tests/lib/libm/t_fenv.c Sun Dec 21 15:37:03 2014 @@ -0,0 +1,205 @@ +/* $NetBSD: t_fenv.c,v 1.1 2014/12/21 15:37:03 martin Exp $ */ + +/*- + * Copyright (c) 2014 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Martin Husemann. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ +#include <sys/cdefs.h> +__RCSID("$NetBSD: t_fenv.c,v 1.1 2014/12/21 15:37:03 martin Exp $"); + +#include <atf-c.h> + +#ifdef HAVE_FENV_H + +#include <ieeefp.h> +#include <stdlib.h> +#include <fenv.h> + + +#if __arm__ && !__SOFTFP__ + /* + * Some NEON fpus do not implement IEEE exception handling, + * skip these tests if running on them and compiled for + * hard float. + */ +#define FPU_PREREQ() \ + if (0 == fpsetmask(fpsetmask(FP_X_INV))) \ + atf_tc_skip("FPU does not implement exception handling"); +#endif + +#ifndef FPU_PREREQ +#define FPU_PREREQ() /* nothing */ +#endif + + +ATF_TC(fegetround); + +ATF_TC_HEAD(fegetround, tc) +{ + atf_tc_set_md_var(tc, "descr", + "verify the fegetround() function agrees with the legacy " + "fpsetround"); +} + +ATF_TC_BODY(fegetround, tc) +{ + fpsetround(FP_RZ); + ATF_CHECK(fegetround() == FE_TOWARDZERO); + fpsetround(FP_RM); + ATF_CHECK(fegetround() == FE_DOWNWARD); + fpsetround(FP_RN); + ATF_CHECK(fegetround() == FE_TONEAREST); + fpsetround(FP_RP); + ATF_CHECK(fegetround() == FE_UPWARD); +} + +ATF_TC(fesetround); + +ATF_TC_HEAD(fesetround, tc) +{ + atf_tc_set_md_var(tc, "descr", + "verify the fesetround() function agrees with the legacy " + "fpgetround"); +} + +ATF_TC_BODY(fesetround, tc) +{ + fesetround(FE_TOWARDZERO); + ATF_CHECK(fpgetround() == FP_RZ); + fesetround(FE_DOWNWARD); + ATF_CHECK(fpgetround() == FP_RM); + fesetround(FE_TONEAREST); + ATF_CHECK(fpgetround() == FP_RN); + fesetround(FE_UPWARD); + ATF_CHECK(fpgetround() == FP_RP); +} + +ATF_TC(fegetexcept); + +ATF_TC_HEAD(fegetexcept, tc) +{ + atf_tc_set_md_var(tc, "descr", + "verify the fegetexcept() function agrees with the legacy " + "fpsetmask()"); +} + +ATF_TC_BODY(fegetexcept, tc) +{ + FPU_PREREQ(); + + fpsetmask(0); + ATF_CHECK(fegetexcept() == 0); + + fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); + ATF_CHECK(fegetexcept() == (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW + |FE_UNDERFLOW|FE_INEXACT)); + + fpsetmask(FP_X_INV); + ATF_CHECK(fegetexcept() == FE_INVALID); + + fpsetmask(FP_X_DZ); + ATF_CHECK(fegetexcept() == FE_DIVBYZERO); + + fpsetmask(FP_X_OFL); + ATF_CHECK(fegetexcept() == FE_OVERFLOW); + + fpsetmask(FP_X_UFL); + ATF_CHECK(fegetexcept() == FE_UNDERFLOW); + + fpsetmask(FP_X_IMP); + ATF_CHECK(fegetexcept() == FE_INEXACT); +} + +ATF_TC(feenableexcept); + +ATF_TC_HEAD(feenableexcept, tc) +{ + atf_tc_set_md_var(tc, "descr", + "verify the feenableexcept() function agrees with the legacy " + "fpgetmask()"); +} + +ATF_TC_BODY(feenableexcept, tc) +{ + FPU_PREREQ(); + + fedisableexcept(FE_ALL_EXCEPT); + ATF_CHECK(fpgetmask() == 0); + + feenableexcept(FE_UNDERFLOW); + ATF_CHECK(fpgetmask() == FP_X_UFL); + + fedisableexcept(FE_ALL_EXCEPT); + feenableexcept(FE_OVERFLOW); + ATF_CHECK(fpgetmask() == FP_X_OFL); + + fedisableexcept(FE_ALL_EXCEPT); + feenableexcept(FE_DIVBYZERO); + ATF_CHECK(fpgetmask() == FP_X_DZ); + + fedisableexcept(FE_ALL_EXCEPT); + feenableexcept(FE_INEXACT); + ATF_CHECK(fpgetmask() == FP_X_IMP); + + fedisableexcept(FE_ALL_EXCEPT); + feenableexcept(FE_INVALID); + ATF_CHECK(fpgetmask() == FP_X_INV); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, fegetround); + ATF_TP_ADD_TC(tp, fesetround); + ATF_TP_ADD_TC(tp, fegetexcept); + ATF_TP_ADD_TC(tp, feenableexcept); + + return atf_no_error(); +} + +#else /* no fenv.h support */ + +ATF_TC(t_nofenv); + +ATF_TC_HEAD(t_nofenv, tc) +{ + atf_tc_set_md_var(tc, "descr", + "dummy test case - no fenv.h support"); +} + + +ATF_TC_BODY(t_nofenv, tc) +{ + atf_tc_skip("no fenv.h support on this architecture"); +} + +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, t_nofenv); + return atf_no_error(); +} + +#endif