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

Reply via email to