diff --git a/math/Makefile b/math/Makefile index 866bc0f..ea5e6e1 --- a/math/Makefile +++ b/math/Makefile @@ -26,7 +26,7 @@ headers := math.h bits/mathcalls.h bits/mathinline.h bits/huge_val.h \ bits/huge_valf.h bits/huge_vall.h bits/inf.h bits/nan.h \ fpu_control.h complex.h bits/cmathcalls.h fenv.h \ bits/fenv.h bits/fenvinline.h bits/mathdef.h tgmath.h \ - bits/math-finite.h + bits/math-finite.h bits/math-vector.h # FPU support code. aux := setfpucw fpu_control @@ -85,6 +85,22 @@ generated += $(foreach s,.c .S l.c l.S f.c f.S,$(calls:s_%=m_%$s)) routines = $(calls) $(calls:=f) $(long-c-$(long-double-fcts)) long-c-yes = $(calls:=l) +ifeq ($(build-mathvect),yes) +# We need to install libm.so as linker script +# for more comfortable use of vector math library. +subdir_install: $(inst_libdir)/libm.so.tmp +$(inst_libdir)/libm.so.tmp: $(common-objpfx)format.lds \ + $(common-objpfx)math/libm.so$(libm.so-version) \ + $(common-objpfx)mathvec/libmvec.so$(libmvec.so-version) \ + $(+force) + (echo '/* GNU ld script */';\ + cat $<; \ + echo 'GROUP ( $(slibdir)/libm.so$(libm.so-version) ' \ + 'AS_NEEDED ( $(slibdir)/libmvec.so$(libmvec.so-version) ) )' \ + ) > $@ + mv -f $@ $(inst_libdir)/libm.so +endif + # Rules for the test suite. tests = test-matherr test-fenv atest-exp atest-sincos atest-exp2 basic-test \ test-misc test-fpucw test-fpucw-ieee tst-definitions test-tgmath \ @@ -102,7 +118,7 @@ libm-tests = test-float test-double $(test-longdouble-$(long-double-fcts)) \ libm-tests.o = $(addsuffix .o,$(libm-tests)) tests += $(libm-tests) -libm-tests-generated = libm-test-ulps.h libm-test.c +libm-tests-generated = libm-test-ulps.h libm-have-vector.h libm-test.c generated += $(libm-tests-generated) libm-test.stmp # This is needed for dependencies @@ -113,9 +129,10 @@ ulps-file = $(firstword $(wildcard $(sysdirs:%=%/libm-test-ulps))) $(addprefix $(objpfx), $(libm-tests-generated)): $(objpfx)libm-test.stmp $(objpfx)libm-test.stmp: $(ulps-file) libm-test.inc gen-libm-test.pl \ - auto-libm-test-out + gen-libm-have-vector.sh auto-libm-test-out $(make-target-directory) $(PERL) gen-libm-test.pl -u $< -o "$(objpfx)" + $(BASH) gen-libm-have-vector.sh > $(objpfx)libm-have-vector.h @echo > $@ $(objpfx)test-float.o: $(objpfx)libm-test.stmp @@ -124,6 +141,14 @@ $(objpfx)test-double.o: $(objpfx)libm-test.stmp $(objpfx)test-idouble.o: $(objpfx)libm-test.stmp $(objpfx)test-ldouble.o: $(objpfx)libm-test.stmp $(objpfx)test-ildoubl.o: $(objpfx)libm-test.stmp + +$(objpfx)test-double-vlen4.o: $(objpfx)libm-test.stmp +#$(objpfx)test-float-vlen8.o: $(objpfx)libm-test.stmp + +$(objpfx)test-double-vlen4: $(common-objpfx)mathvec/libmvec.so \ + $(objpfx)init-arch.o +#$(objpfx)test-float-vlen8: $(common-objpfx)mathvec/libmvec.so \ + $(objpfx)init-arch.o endif CFLAGS-test-float.c = -fno-inline -ffloat-store -fno-builtin -frounding-math diff --git a/math/gen-libm-have-vector.sh b/math/gen-libm-have-vector.sh new file mode 100755 index 0000000..baf1368 --- /dev/null +++ b/math/gen-libm-have-vector.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# Copyright (C) 1999-2014 Free Software Foundation, Inc. +# This file is part of the GNU C Library. + +# The GNU C Library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. + +# The GNU C Library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. + +# You should have received a copy of the GNU Lesser General Public +# License along with the GNU C Library; if not, see +# . + +# Generate series of definitions used for vector math functions tests. +print_defs() +{ + echo "#ifdef __DECL_SIMD_$1" + echo "# define HAVE_VECTOR_$1 1" + echo "# define VEC_PREFIX_$1 WRAPPER_NAME($1)" + echo "#else" + echo "# define HAVE_VECTOR_$1 0" + echo "# define VEC_PREFIX_$1 $1" + echo "#endif" + echo +} + +for func in $(grep ALL_RM_TEST libm-test.inc | grep -v define | sed -r "s/.*\(//; s/,.*//"); do + print_defs ${func} + print_defs ${func}f + print_defs ${func}l +done + +print_defs jn +print_defs jnf +print_defs jnl + +print_defs cexp +print_defs cexpf +print_defs cexpl + +print_defs tgamma +print_defs tgammaf +print_defs tgammal diff --git a/math/libm-test.inc b/math/libm-test.inc index f86a4fa..e348ed4 100644 --- a/math/libm-test.inc +++ b/math/libm-test.inc @@ -126,6 +126,7 @@ #include #include #include +#include /* Structure for ulp data for a function, or the real or imaginary part of a function. */ @@ -678,13 +679,17 @@ test_exceptions (const char *test_name, int exception) feclearexcept (FE_ALL_EXCEPT); } +#ifndef TEST_MATHVEC +# define TEST_MATHVEC 0 +#endif + /* Test whether errno for TEST_NAME, set to ERRNO_VALUE, has value EXPECTED_VALUE (description EXPECTED_NAME). */ static void test_single_errno (const char *test_name, int errno_value, int expected_value, const char *expected_name) { -#ifndef TEST_INLINE +#if !defined TEST_INLINE && !TEST_MATHVEC if (errno_value == expected_value) { if (print_screen (1)) @@ -1295,16 +1300,17 @@ struct test_fFF_11_data /* Run an individual test, including any required setup and checking of results, or loop over all tests in an array. */ -#define RUN_TEST_f_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \ - EXCEPTIONS) \ - do \ - if (enable_test (EXCEPTIONS)) \ - { \ - COMMON_TEST_SETUP (ARG_STR); \ - check_float (test_name, FUNC (FUNC_NAME) (ARG), EXPECTED, \ - EXCEPTIONS); \ - COMMON_TEST_CLEANUP; \ - } \ +#define RUN_TEST_f_f(ARG_STR, FUNC_NAME, ARG, EXPECTED, \ + EXCEPTIONS) \ + do \ + if (enable_test (EXCEPTIONS)) \ + { \ + COMMON_TEST_SETUP (ARG_STR); \ + check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG), \ + EXPECTED, \ + EXCEPTIONS); \ + COMMON_TEST_CLEANUP; \ + } \ while (0) #define RUN_TEST_LOOP_f_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \ IF_ROUND_INIT_ ## ROUNDING_MODE \ @@ -1313,16 +1319,16 @@ struct test_fFF_11_data (ARRAY)[i].RM_##ROUNDING_MODE.expected, \ (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \ ROUND_RESTORE_ ## ROUNDING_MODE -#define RUN_TEST_2_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \ - EXCEPTIONS) \ - do \ - if (enable_test (EXCEPTIONS)) \ - { \ - COMMON_TEST_SETUP (ARG_STR); \ - check_float (test_name, FUNC (FUNC_NAME) (ARG1, ARG2), \ - EXPECTED, EXCEPTIONS); \ - COMMON_TEST_CLEANUP; \ - } \ +#define RUN_TEST_2_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \ + EXCEPTIONS) \ + do \ + if (enable_test (EXCEPTIONS)) \ + { \ + COMMON_TEST_SETUP (ARG_STR); \ + check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG1, ARG2), \ + EXPECTED, EXCEPTIONS); \ + COMMON_TEST_CLEANUP; \ + } \ while (0) #define RUN_TEST_LOOP_2_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \ IF_ROUND_INIT_ ## ROUNDING_MODE \ @@ -1340,16 +1346,16 @@ struct test_fFF_11_data #define RUN_TEST_LOOP_fl_f RUN_TEST_LOOP_2_f #define RUN_TEST_if_f RUN_TEST_2_f #define RUN_TEST_LOOP_if_f RUN_TEST_LOOP_2_f -#define RUN_TEST_fff_f(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \ - EXPECTED, EXCEPTIONS) \ - do \ - if (enable_test (EXCEPTIONS)) \ - { \ - COMMON_TEST_SETUP (ARG_STR); \ - check_float (test_name, FUNC (FUNC_NAME) (ARG1, ARG2, ARG3), \ - EXPECTED, EXCEPTIONS); \ - COMMON_TEST_CLEANUP; \ - } \ +#define RUN_TEST_fff_f(ARG_STR, FUNC_NAME, ARG1, ARG2, ARG3, \ + EXPECTED, EXCEPTIONS) \ + do \ + if (enable_test (EXCEPTIONS)) \ + { \ + COMMON_TEST_SETUP (ARG_STR); \ + check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG1, ARG2, ARG3), \ + EXPECTED, EXCEPTIONS); \ + COMMON_TEST_CLEANUP; \ + } \ while (0) #define RUN_TEST_LOOP_fff_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \ IF_ROUND_INIT_ ## ROUNDING_MODE \ @@ -1359,17 +1365,17 @@ struct test_fFF_11_data (ARRAY)[i].RM_##ROUNDING_MODE.expected, \ (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \ ROUND_RESTORE_ ## ROUNDING_MODE -#define RUN_TEST_c_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \ - EXCEPTIONS) \ - do \ - if (enable_test (EXCEPTIONS)) \ - { \ - COMMON_TEST_SETUP (ARG_STR); \ - check_float (test_name, \ - FUNC (FUNC_NAME) (BUILD_COMPLEX (ARG1, ARG2)), \ - EXPECTED, EXCEPTIONS); \ - COMMON_TEST_CLEANUP; \ - } \ +#define RUN_TEST_c_f(ARG_STR, FUNC_NAME, ARG1, ARG2, EXPECTED, \ + EXCEPTIONS) \ + do \ + if (enable_test (EXCEPTIONS)) \ + { \ + COMMON_TEST_SETUP (ARG_STR); \ + check_float (test_name, \ + FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARG1, ARG2)), \ + EXPECTED, EXCEPTIONS); \ + COMMON_TEST_CLEANUP; \ + } \ while (0) #define RUN_TEST_LOOP_c_f(FUNC_NAME, ARRAY, ROUNDING_MODE) \ IF_ROUND_INIT_ ## ROUNDING_MODE \ @@ -1387,7 +1393,7 @@ struct test_fFF_11_data { \ COMMON_TEST_SETUP (ARG_STR); \ (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \ - check_float (test_name, FUNC (FUNC_NAME) (ARG), EXPECTED, \ + check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \ EXCEPTIONS); \ EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \ if (EXTRA_TEST) \ @@ -1406,22 +1412,22 @@ struct test_fFF_11_data (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \ (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \ ROUND_RESTORE_ ## ROUNDING_MODE -#define RUN_TEST_fF_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \ - EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \ - EXTRA_EXPECTED) \ - do \ - if (enable_test (EXCEPTIONS)) \ - { \ - COMMON_TEST_SETUP (ARG_STR); \ - (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \ - check_float (test_name, FUNC (FUNC_NAME) (ARG, &(EXTRA_VAR)), \ - EXPECTED, EXCEPTIONS); \ - EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \ - if (EXTRA_TEST) \ - check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \ - EXTRA_OUTPUT_TEST_CLEANUP (1); \ - COMMON_TEST_CLEANUP; \ - } \ +#define RUN_TEST_fF_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \ + EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \ + EXTRA_EXPECTED) \ + do \ + if (enable_test (EXCEPTIONS)) \ + { \ + COMMON_TEST_SETUP (ARG_STR); \ + (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \ + check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA_VAR)), \ + EXPECTED, EXCEPTIONS); \ + EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \ + if (EXTRA_TEST) \ + check_float (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \ + EXTRA_OUTPUT_TEST_CLEANUP (1); \ + COMMON_TEST_CLEANUP; \ + } \ while (0) #define RUN_TEST_LOOP_fF_f1(FUNC_NAME, ARRAY, ROUNDING_MODE, EXTRA_VAR) \ IF_ROUND_INIT_ ## ROUNDING_MODE \ @@ -1433,22 +1439,22 @@ struct test_fFF_11_data (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \ (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \ ROUND_RESTORE_ ## ROUNDING_MODE -#define RUN_TEST_fI_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \ - EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \ - EXTRA_EXPECTED) \ - do \ - if (enable_test (EXCEPTIONS)) \ - { \ - COMMON_TEST_SETUP (ARG_STR); \ - (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \ - check_float (test_name, FUNC (FUNC_NAME) (ARG, &(EXTRA_VAR)), \ - EXPECTED, EXCEPTIONS); \ - EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \ - if (EXTRA_TEST) \ - check_int (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \ - EXTRA_OUTPUT_TEST_CLEANUP (1); \ - COMMON_TEST_CLEANUP; \ - } \ +#define RUN_TEST_fI_f1(ARG_STR, FUNC_NAME, ARG, EXPECTED, \ + EXCEPTIONS, EXTRA_VAR, EXTRA_TEST, \ + EXTRA_EXPECTED) \ + do \ + if (enable_test (EXCEPTIONS)) \ + { \ + COMMON_TEST_SETUP (ARG_STR); \ + (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \ + check_float (test_name, FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA_VAR)), \ + EXPECTED, EXCEPTIONS); \ + EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \ + if (EXTRA_TEST) \ + check_int (extra1_name, EXTRA_VAR, EXTRA_EXPECTED, 0); \ + EXTRA_OUTPUT_TEST_CLEANUP (1); \ + COMMON_TEST_CLEANUP; \ + } \ while (0) #define RUN_TEST_LOOP_fI_f1(FUNC_NAME, ARRAY, ROUNDING_MODE, EXTRA_VAR) \ IF_ROUND_INIT_ ## ROUNDING_MODE \ @@ -1469,7 +1475,7 @@ struct test_fFF_11_data COMMON_TEST_SETUP (ARG_STR); \ (EXTRA_VAR) = (EXTRA_EXPECTED) == 0 ? 1 : 0; \ check_float (test_name, \ - FUNC (FUNC_NAME) (ARG1, ARG2, &(EXTRA_VAR)), \ + FUNC_TEST (FUNC_NAME) (ARG1, ARG2, &(EXTRA_VAR)), \ EXPECTED, EXCEPTIONS); \ EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \ if (EXTRA_TEST) \ @@ -1490,17 +1496,17 @@ struct test_fFF_11_data (ARRAY)[i].RM_##ROUNDING_MODE.extra_test, \ (ARRAY)[i].RM_##ROUNDING_MODE.extra_expected); \ ROUND_RESTORE_ ## ROUNDING_MODE -#define RUN_TEST_c_c(ARG_STR, FUNC_NAME, ARGR, ARGC, EXPR, EXPC, \ - EXCEPTIONS) \ - do \ - if (enable_test (EXCEPTIONS)) \ - { \ - COMMON_TEST_SETUP (ARG_STR); \ - check_complex (test_name, \ - FUNC (FUNC_NAME) (BUILD_COMPLEX (ARGR, ARGC)), \ - BUILD_COMPLEX (EXPR, EXPC), EXCEPTIONS); \ - COMMON_TEST_CLEANUP; \ - } \ +#define RUN_TEST_c_c(ARG_STR, FUNC_NAME, ARGR, ARGC, EXPR, EXPC, \ + EXCEPTIONS) \ + do \ + if (enable_test (EXCEPTIONS)) \ + { \ + COMMON_TEST_SETUP (ARG_STR); \ + check_complex (test_name, \ + FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARGR, ARGC)), \ + BUILD_COMPLEX (EXPR, EXPC), EXCEPTIONS); \ + COMMON_TEST_CLEANUP; \ + } \ while (0) #define RUN_TEST_LOOP_c_c(FUNC_NAME, ARRAY, ROUNDING_MODE) \ IF_ROUND_INIT_ ## ROUNDING_MODE \ @@ -1511,18 +1517,18 @@ struct test_fFF_11_data (ARRAY)[i].RM_##ROUNDING_MODE.expc, \ (ARRAY)[i].RM_##ROUNDING_MODE.exceptions); \ ROUND_RESTORE_ ## ROUNDING_MODE -#define RUN_TEST_cc_c(ARG_STR, FUNC_NAME, ARG1R, ARG1C, ARG2R, ARG2C, \ - EXPR, EXPC, EXCEPTIONS) \ - do \ - if (enable_test (EXCEPTIONS)) \ - { \ - COMMON_TEST_SETUP (ARG_STR); \ - check_complex (test_name, \ - FUNC (FUNC_NAME) (BUILD_COMPLEX (ARG1R, ARG1C), \ - BUILD_COMPLEX (ARG2R, ARG2C)), \ - BUILD_COMPLEX (EXPR, EXPC), EXCEPTIONS); \ - COMMON_TEST_CLEANUP; \ - } \ +#define RUN_TEST_cc_c(ARG_STR, FUNC_NAME, ARG1R, ARG1C, ARG2R, ARG2C, \ + EXPR, EXPC, EXCEPTIONS) \ + do \ + if (enable_test (EXCEPTIONS)) \ + { \ + COMMON_TEST_SETUP (ARG_STR); \ + check_complex (test_name, \ + FUNC_TEST (FUNC_NAME) (BUILD_COMPLEX (ARG1R, ARG1C), \ + BUILD_COMPLEX (ARG2R, ARG2C)), \ + BUILD_COMPLEX (EXPR, EXPC), EXCEPTIONS); \ + COMMON_TEST_CLEANUP; \ + } \ while (0) #define RUN_TEST_LOOP_cc_c(FUNC_NAME, ARRAY, ROUNDING_MODE) \ IF_ROUND_INIT_ ## ROUNDING_MODE \ @@ -1539,7 +1545,7 @@ struct test_fFF_11_data if (enable_test (EXCEPTIONS)) \ { \ COMMON_TEST_SETUP (ARG_STR); \ - check_int (test_name, FUNC (FUNC_NAME) (ARG), EXPECTED, \ + check_int (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \ EXCEPTIONS); \ COMMON_TEST_CLEANUP; \ } \ @@ -1592,7 +1598,7 @@ struct test_fFF_11_data if (enable_test (EXCEPTIONS)) \ { \ COMMON_TEST_SETUP (ARG_STR); \ - check_bool (test_name, FUNC (FUNC_NAME) (ARG), EXPECTED, \ + check_bool (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \ EXCEPTIONS); \ COMMON_TEST_CLEANUP; \ } \ @@ -1626,7 +1632,7 @@ struct test_fFF_11_data if (enable_test (EXCEPTIONS)) \ { \ COMMON_TEST_SETUP (ARG_STR); \ - check_long (test_name, FUNC (FUNC_NAME) (ARG), EXPECTED, \ + check_long (test_name, FUNC_TEST (FUNC_NAME) (ARG), EXPECTED, \ EXCEPTIONS); \ COMMON_TEST_CLEANUP; \ } \ @@ -1643,8 +1649,8 @@ struct test_fFF_11_data if (enable_test (EXCEPTIONS)) \ { \ COMMON_TEST_SETUP (ARG_STR); \ - check_longlong (test_name, FUNC (FUNC_NAME) (ARG), EXPECTED, \ - EXCEPTIONS); \ + check_longlong (test_name, FUNC_TEST (FUNC_NAME) (ARG), \ + EXPECTED, EXCEPTIONS); \ COMMON_TEST_CLEANUP; \ } \ while (0) @@ -1663,7 +1669,7 @@ struct test_fFF_11_data if (enable_test (EXCEPTIONS)) \ { \ COMMON_TEST_SETUP (ARG_STR); \ - FUNC (FUNC_NAME) (ARG, &(EXTRA1_VAR), &(EXTRA2_VAR)); \ + FUNC_TEST (FUNC_NAME) (ARG, &(EXTRA1_VAR), &(EXTRA2_VAR)); \ EXTRA_OUTPUT_TEST_SETUP (ARG_STR, 1); \ if (EXTRA1_TEST) \ check_float (extra1_name, EXTRA1_VAR, EXTRA1_EXPECTED, \ @@ -1690,10 +1696,30 @@ struct test_fFF_11_data (ARRAY)[i].RM_##ROUNDING_MODE.extra2_expected); \ ROUND_RESTORE_ ## ROUNDING_MODE +#ifndef CHECK_ARCH_EXT +# define CHECK_ARCH_EXT +#endif + +#ifndef VEC_PREFIX +# define VEC_PREFIX +#endif + +#ifndef FUNC_TEST +# define FUNC_TEST FUNC +#endif + +#include "libm-have-vector.h" + +#define STR_CONCAT(a,b,c) __STRING(a##b##c) +#define STR_CON3(a,b,c) STR_CONCAT(a,b,c) + /* Start and end the tests for a given function. */ -#define START(FUNC, EXACT) \ - const char *this_func = #FUNC; \ +#define START(FUN, SUFF, EXACT) \ + CHECK_ARCH_EXT \ + if (TEST_MATHVEC && !HAVE_VECTOR_ ## FUN) return; \ + const char *this_func = STR_CON3(VEC_PREFIX, FUN, SUFF); \ init_max_error (this_func, EXACT) + #define END \ print_max_error (this_func) #define END_COMPLEX \ @@ -1705,28 +1731,28 @@ struct test_fFF_11_data { \ do \ { \ - START (FUNC, EXACT); \ + START (FUNC, , EXACT); \ LOOP_MACRO (FUNC, ARRAY, , ## __VA_ARGS__); \ END_MACRO; \ } \ while (0); \ do \ { \ - START (FUNC ## _downward, EXACT); \ + START (FUNC, _downward, EXACT); \ LOOP_MACRO (FUNC, ARRAY, FE_DOWNWARD, ## __VA_ARGS__); \ END_MACRO; \ } \ while (0); \ do \ { \ - START (FUNC ## _towardzero, EXACT); \ + START (FUNC, _towardzero, EXACT); \ LOOP_MACRO (FUNC, ARRAY, FE_TOWARDZERO, ## __VA_ARGS__); \ END_MACRO; \ } \ while (0); \ do \ { \ - START (FUNC ## _upward, EXACT); \ + START (FUNC, _upward, EXACT); \ LOOP_MACRO (FUNC, ARRAY, FE_UPWARD, ## __VA_ARGS__); \ END_MACRO; \ } \ @@ -1746,7 +1772,6 @@ matherr (struct exception *x __attribute__ ((unused))) Tests for single functions of libm. Please keep them alphabetically sorted! ****************************************************************************/ - static const struct test_f_f_data acos_test_data[] = { TEST_f_f (acos, plus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM), @@ -6034,7 +6059,7 @@ static const struct test_c_c_data cexp_test_data[] = static void cexp_test (void) { - START (cexp, 0); + START (cexp, , 0); RUN_TEST_LOOP_c_c (cexp, cexp_test_data, ); END_COMPLEX; } @@ -6245,7 +6270,6 @@ copysign_test (void) ALL_RM_TEST (copysign, 1, copysign_test_data, RUN_TEST_LOOP_ff_f, END); } - static const struct test_f_f_data cos_test_data[] = { TEST_f_f (cos, plus_infty, qnan_value, INVALID_EXCEPTION|ERRNO_EDOM), @@ -6261,7 +6285,6 @@ cos_test (void) ALL_RM_TEST (cos, 0, cos_test_data, RUN_TEST_LOOP_f_f, END); } - static const struct test_f_f_data cosh_test_data[] = { TEST_f_f (cosh, plus_infty, plus_infty, NO_TEST_INLINE), @@ -7548,7 +7571,7 @@ static const struct test_if_f_data jn_test_data[] = static void jn_test (void) { - START (jn, 0); + START (jn, , 0); RUN_TEST_LOOP_if_f (jn, jn_test_data, ); END; } @@ -9374,7 +9397,7 @@ static const struct test_f_f_data tgamma_test_data[] = static void tgamma_test (void) { - START (tgamma, 0); + START (tgamma, , 0); RUN_TEST_LOOP_f_f (tgamma, tgamma_test_data, ); END; } @@ -9628,7 +9651,6 @@ significand_test (void) ALL_RM_TEST (significand, 1, significand_test_data, RUN_TEST_LOOP_f_f, END); } - static void initialize (void) { @@ -9820,10 +9842,15 @@ main (int argc, char **argv) } } - initialize (); printf (TEST_MSG); +#if TEST_MATHVEC + static int avx2_usable = 0; + __init_cpu_features(); + avx2_usable = __cpu_features.feature[index_AVX2_Usable] & bit_AVX2_Usable; +#endif + check_ulp (); /* Keep the tests a wee bit ordered (according to ISO C99). */ diff --git a/math/test-double-vlen4.h b/math/test-double-vlen4.h new file mode 100644 index 0000000..be47e5a --- /dev/null +++ b/math/test-double-vlen4.h @@ -0,0 +1,26 @@ + +#define FLOAT double +#define FUNC(function) function +#define TEST_MSG "testing double vector math (without inline functions)\n" +#define MATHCONST(x) x +#define CHOOSE(Clongdouble,Cdouble,Cfloat,Cinlinelongdouble,Cinlinedouble,Cinlinefloat) Cdouble +#define PRINTF_EXPR "e" +#define PRINTF_XEXPR "a" +#define PRINTF_NEXPR "f" +#define TEST_DOUBLE 1 +#define TEST_MATHVEC 1 + +#ifndef __NO_MATH_INLINES +# define __NO_MATH_INLINES +#endif + +#define EXCEPTION_TESTS_double 0 +#define ROUNDING_TESTS_double(MODE) ((MODE) == FE_TONEAREST) + +#define VEC_PREFIX vlen4_ + +#define CONCAT(prefix,func) __CONCAT(prefix, func) + +#define WRAPPER_NAME(function) CONCAT(VEC_PREFIX, function) + +#define FUNC_TEST(function) CONCAT(VEC_PREFIX_ ## function, FUNC( )) diff --git a/sysdeps/x86_64/fpu/Makefile b/sysdeps/x86_64/fpu/Makefile new file mode 100755 index 0000000..9af2a20 --- /dev/null +++ b/sysdeps/x86_64/fpu/Makefile @@ -0,0 +1,19 @@ +ifeq ($(subdir),mathvec) +libmvec-support += svml_d_cos4_core svml_d_cos_data +endif + +# Rules for libmvec tests +ifeq ($(subdir),math) +ifeq ($(build-mathvec),yes) +libm-tests += test-double-vlen4 # test-float-vlen8 + +CFLAGS-test-double-vlen4.c = -fno-inline -ffloat-store -fno-builtin \ + -frounding-math -mavx2 -D__FAST_MATH__ \ + -DTEST_FAST_MATH -D_OPENMP=201307 + +#CFLAGS-test-float-vlen8.c = -fno-inline -ffloat-store -fno-builtin \ + -frounding-math -mavx2 -D__FAST_MATH__ \ + -DTEST_FAST_MATH -D_OPENMP=201307 + +endif +endif diff --git a/sysdeps/x86_64/fpu/test-double-vlen4.c b/sysdeps/x86_64/fpu/test-double-vlen4.c new file mode 100644 index 0000000..67e5fd1 --- /dev/null +++ b/sysdeps/x86_64/fpu/test-double-vlen4.c @@ -0,0 +1,44 @@ +/* Copyright (C) 2014 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include "test-double-vlen4.h" + +// Wrapper from scalar to vector function implemented in AVX2. +#define VECTOR_WRAPPER(scalar_func, vector_func) \ +extern __m256d vector_func(__m256d); \ +FLOAT scalar_func(FLOAT x)\ +{\ + int i;\ + __m256d mx = _mm256_set1_pd(x);\ + __m256d mr = vector_func(mx);\ + for(i=1;i<4;i++)\ + {\ + if (((FLOAT*)&mr)[0]!=((FLOAT*)&mr)[i])\ + {\ + return ((FLOAT*)&mr)[0]+0.1;\ + }\ + }\ + return ((FLOAT*)&mr)[0];\ +} + +#include + +VECTOR_WRAPPER (WRAPPER_NAME (cos), _ZGVdN4v_cos) + +#define CHECK_ARCH_EXT if (!avx2_usable) return; + +#include "libm-test.c"