diff options
Diffstat (limited to 'math/test')
36 files changed, 633 insertions, 349 deletions
diff --git a/math/test/mathbench.c b/math/test/mathbench.c index 0c17826..6e18e36 100644 --- a/math/test/mathbench.c +++ b/math/test/mathbench.c @@ -1,8 +1,8 @@ /* * Microbenchmark for math functions. * - * Copyright (c) 2018-2020, Arm Limited. - * SPDX-License-Identifier: MIT + * Copyright (c) 2018-2022, Arm Limited. + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #undef _GNU_SOURCE @@ -66,6 +66,43 @@ v_float_dup (float x) { return (v_float){x, x, x, x}; } +#if WANT_SVE_MATH +#include <arm_sve.h> +typedef svbool_t sv_bool; +typedef svfloat64_t sv_double; + +#define sv_double_len() svcntd() + +static inline sv_double +sv_double_load (const double *p) +{ + svbool_t pg = svptrue_b64(); + return svld1(pg, p); +} + +static inline sv_double +sv_double_dup (double x) +{ + return svdup_n_f64(x); +} + +typedef svfloat32_t sv_float; + +#define sv_float_len() svcntw() + +static inline sv_float +sv_float_load (const float *p) +{ + svbool_t pg = svptrue_b32(); + return svld1(pg, p); +} + +static inline sv_float +sv_float_dup (float x) +{ + return svdup_n_f32(x); +} +#endif #else /* dummy definitions to make things compile. */ typedef double v_double; @@ -89,7 +126,6 @@ dummyf (float x) { return x; } - #if WANT_VMATH #if __aarch64__ static v_double @@ -116,101 +152,25 @@ __vn_dummyf (v_float x) { return x; } - -__vpcs static v_float -xy__vn_powf (v_float x) -{ - return __vn_powf (x, x); -} - -__vpcs static v_float -xy_Z_powf (v_float x) +#endif +#if WANT_SVE_MATH +static sv_double +__sv_dummy (sv_double x, sv_bool pg) { - return _ZGVnN4vv_powf (x, x); + return x; } -__vpcs static v_double -xy__vn_pow (v_double x) +static sv_float +__sv_dummyf (sv_float x, sv_bool pg) { - return __vn_pow (x, x); + return x; } -__vpcs static v_double -xy_Z_pow (v_double x) -{ - return _ZGVnN2vv_pow (x, x); -} #endif - -static v_float -xy__v_powf (v_float x) -{ - return __v_powf (x, x); -} - -static v_double -xy__v_pow (v_double x) -{ - return __v_pow (x, x); -} #endif - -static float -xy__s_powf (float x) -{ - return __s_powf (x, x); -} - -static double -xy__s_pow (double x) -{ - return __s_pow (x, x); -} #endif -static double -xypow (double x) -{ - return pow (x, x); -} - -static float -xypowf (float x) -{ - return powf (x, x); -} - -static double -xpow (double x) -{ - return pow (x, 23.4); -} - -static float -xpowf (float x) -{ - return powf (x, 23.4f); -} - -static double -ypow (double x) -{ - return pow (2.34, x); -} - -static float -ypowf (float x) -{ - return powf (2.34f, x); -} - -static float -sincosf_wrap (float x) -{ - float s, c; - sincosf (x, &s, &c); - return s + c; -} +#include "test/mathbench_wrappers.h" static const struct fun { @@ -229,6 +189,10 @@ static const struct fun __vpcs v_double (*vnd) (v_double); __vpcs v_float (*vnf) (v_float); #endif +#if WANT_SVE_MATH + sv_double (*svd) (sv_double, sv_bool); + sv_float (*svf) (sv_float, sv_bool); +#endif } fun; } funtab[] = { #define D(func, lo, hi) {#func, 'd', 0, lo, hi, {.d = func}}, @@ -237,106 +201,25 @@ static const struct fun #define VF(func, lo, hi) {#func, 'f', 'v', lo, hi, {.vf = func}}, #define VND(func, lo, hi) {#func, 'd', 'n', lo, hi, {.vnd = func}}, #define VNF(func, lo, hi) {#func, 'f', 'n', lo, hi, {.vnf = func}}, +#define SVD(func, lo, hi) {#func, 'd', 's', lo, hi, {.svd = func}}, +#define SVF(func, lo, hi) {#func, 'f', 's', lo, hi, {.svf = func}}, D (dummy, 1.0, 2.0) -D (exp, -9.9, 9.9) -D (exp, 0.5, 1.0) -D (exp2, -9.9, 9.9) -D (log, 0.01, 11.1) -D (log, 0.999, 1.001) -D (log2, 0.01, 11.1) -D (log2, 0.999, 1.001) -{"pow", 'd', 0, 0.01, 11.1, {.d = xypow}}, -D (xpow, 0.01, 11.1) -D (ypow, -9.9, 9.9) -D (erf, -6.0, 6.0) - F (dummyf, 1.0, 2.0) -F (expf, -9.9, 9.9) -F (exp2f, -9.9, 9.9) -F (logf, 0.01, 11.1) -F (log2f, 0.01, 11.1) -{"powf", 'f', 0, 0.01, 11.1, {.f = xypowf}}, -F (xpowf, 0.01, 11.1) -F (ypowf, -9.9, 9.9) -{"sincosf", 'f', 0, 0.1, 0.7, {.f = sincosf_wrap}}, -{"sincosf", 'f', 0, 0.8, 3.1, {.f = sincosf_wrap}}, -{"sincosf", 'f', 0, -3.1, 3.1, {.f = sincosf_wrap}}, -{"sincosf", 'f', 0, 3.3, 33.3, {.f = sincosf_wrap}}, -{"sincosf", 'f', 0, 100, 1000, {.f = sincosf_wrap}}, -{"sincosf", 'f', 0, 1e6, 1e32, {.f = sincosf_wrap}}, -F (sinf, 0.1, 0.7) -F (sinf, 0.8, 3.1) -F (sinf, -3.1, 3.1) -F (sinf, 3.3, 33.3) -F (sinf, 100, 1000) -F (sinf, 1e6, 1e32) -F (cosf, 0.1, 0.7) -F (cosf, 0.8, 3.1) -F (cosf, -3.1, 3.1) -F (cosf, 3.3, 33.3) -F (cosf, 100, 1000) -F (cosf, 1e6, 1e32) -F (erff, -4.0, 4.0) #if WANT_VMATH -D (__s_sin, -3.1, 3.1) -D (__s_cos, -3.1, 3.1) -D (__s_exp, -9.9, 9.9) -D (__s_log, 0.01, 11.1) -{"__s_pow", 'd', 0, 0.01, 11.1, {.d = xy__s_pow}}, -F (__s_expf, -9.9, 9.9) -F (__s_expf_1u, -9.9, 9.9) -F (__s_exp2f, -9.9, 9.9) -F (__s_exp2f_1u, -9.9, 9.9) -F (__s_logf, 0.01, 11.1) -{"__s_powf", 'f', 0, 0.01, 11.1, {.f = xy__s_powf}}, -F (__s_sinf, -3.1, 3.1) -F (__s_cosf, -3.1, 3.1) #if __aarch64__ VD (__v_dummy, 1.0, 2.0) -VD (__v_sin, -3.1, 3.1) -VD (__v_cos, -3.1, 3.1) -VD (__v_exp, -9.9, 9.9) -VD (__v_log, 0.01, 11.1) -{"__v_pow", 'd', 'v', 0.01, 11.1, {.vd = xy__v_pow}}, VF (__v_dummyf, 1.0, 2.0) -VF (__v_expf, -9.9, 9.9) -VF (__v_expf_1u, -9.9, 9.9) -VF (__v_exp2f, -9.9, 9.9) -VF (__v_exp2f_1u, -9.9, 9.9) -VF (__v_logf, 0.01, 11.1) -{"__v_powf", 'f', 'v', 0.01, 11.1, {.vf = xy__v_powf}}, -VF (__v_sinf, -3.1, 3.1) -VF (__v_cosf, -3.1, 3.1) #ifdef __vpcs VND (__vn_dummy, 1.0, 2.0) -VND (__vn_exp, -9.9, 9.9) -VND (_ZGVnN2v_exp, -9.9, 9.9) -VND (__vn_log, 0.01, 11.1) -VND (_ZGVnN2v_log, 0.01, 11.1) -{"__vn_pow", 'd', 'n', 0.01, 11.1, {.vnd = xy__vn_pow}}, -{"_ZGVnN2vv_pow", 'd', 'n', 0.01, 11.1, {.vnd = xy_Z_pow}}, -VND (__vn_sin, -3.1, 3.1) -VND (_ZGVnN2v_sin, -3.1, 3.1) -VND (__vn_cos, -3.1, 3.1) -VND (_ZGVnN2v_cos, -3.1, 3.1) VNF (__vn_dummyf, 1.0, 2.0) -VNF (__vn_expf, -9.9, 9.9) -VNF (_ZGVnN4v_expf, -9.9, 9.9) -VNF (__vn_expf_1u, -9.9, 9.9) -VNF (__vn_exp2f, -9.9, 9.9) -VNF (_ZGVnN4v_exp2f, -9.9, 9.9) -VNF (__vn_exp2f_1u, -9.9, 9.9) -VNF (__vn_logf, 0.01, 11.1) -VNF (_ZGVnN4v_logf, 0.01, 11.1) -{"__vn_powf", 'f', 'n', 0.01, 11.1, {.vnf = xy__vn_powf}}, -{"_ZGVnN4vv_powf", 'f', 'n', 0.01, 11.1, {.vnf = xy_Z_powf}}, -VNF (__vn_sinf, -3.1, 3.1) -VNF (_ZGVnN4v_sinf, -3.1, 3.1) -VNF (__vn_cosf, -3.1, 3.1) -VNF (_ZGVnN4v_cosf, -3.1, 3.1) +#endif +#if WANT_SVE_MATH +SVD (__sv_dummy, 1.0, 2.0) +SVF (__sv_dummyf, 1.0, 2.0) #endif #endif #endif +#include "test/mathbench_funcs.h" {0}, #undef F #undef D @@ -344,6 +227,8 @@ VNF (_ZGVnN4v_cosf, -3.1, 3.1) #undef VD #undef VNF #undef VND +#undef SVF +#undef SVD }; static void @@ -508,6 +393,40 @@ runf_vn_latency (__vpcs v_float f (v_float)) } #endif +#if WANT_SVE_MATH +static void +run_sv_thruput (sv_double f (sv_double, sv_bool)) +{ + for (int i = 0; i < N; i += sv_double_len ()) + f (sv_double_load (A+i), svptrue_b64 ()); +} + +static void +runf_sv_thruput (sv_float f (sv_float, sv_bool)) +{ + for (int i = 0; i < N; i += sv_float_len ()) + f (sv_float_load (Af+i), svptrue_b32 ()); +} + +static void +run_sv_latency (sv_double f (sv_double, sv_bool)) +{ + sv_double z = sv_double_dup (zero); + sv_double prev = z; + for (int i = 0; i < N; i += sv_double_len ()) + prev = f (svmad_f64_x (svptrue_b64 (), prev, z, sv_double_load (A+i)), svptrue_b64 ()); +} + +static void +runf_sv_latency (sv_float f (sv_float, sv_bool)) +{ + sv_float z = sv_float_dup (zero); + sv_float prev = z; + for (int i = 0; i < N; i += sv_float_len ()) + prev = f (svmad_f32_x (svptrue_b32 (), prev, z, sv_float_load (Af+i)), svptrue_b32 ()); +} +#endif + static uint64_t tic (void) { @@ -570,6 +489,16 @@ bench1 (const struct fun *f, int type, double lo, double hi) else if (f->prec == 'f' && type == 'l' && f->vec == 'n') TIMEIT (runf_vn_latency, f->fun.vnf); #endif +#if WANT_SVE_MATH + else if (f->prec == 'd' && type == 't' && f->vec == 's') + TIMEIT (run_sv_thruput, f->fun.svd); + else if (f->prec == 'd' && type == 'l' && f->vec == 's') + TIMEIT (run_sv_latency, f->fun.svd); + else if (f->prec == 'f' && type == 't' && f->vec == 's') + TIMEIT (runf_sv_thruput, f->fun.svf); + else if (f->prec == 'f' && type == 'l' && f->vec == 's') + TIMEIT (runf_sv_latency, f->fun.svf); +#endif if (type == 't') { diff --git a/math/test/mathbench_funcs.h b/math/test/mathbench_funcs.h new file mode 100644 index 0000000..ad6dd2a --- /dev/null +++ b/math/test/mathbench_funcs.h @@ -0,0 +1,100 @@ +/* + * Function entries for mathbench. + * + * Copyright (c) 2022, Arm Limited. + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception + */ +D (exp, -9.9, 9.9) +D (exp, 0.5, 1.0) +D (exp2, -9.9, 9.9) +D (log, 0.01, 11.1) +D (log, 0.999, 1.001) +D (log2, 0.01, 11.1) +D (log2, 0.999, 1.001) +{"pow", 'd', 0, 0.01, 11.1, {.d = xypow}}, +D (xpow, 0.01, 11.1) +D (ypow, -9.9, 9.9) +D (erf, -6.0, 6.0) + +F (expf, -9.9, 9.9) +F (exp2f, -9.9, 9.9) +F (logf, 0.01, 11.1) +F (log2f, 0.01, 11.1) +{"powf", 'f', 0, 0.01, 11.1, {.f = xypowf}}, +F (xpowf, 0.01, 11.1) +F (ypowf, -9.9, 9.9) +{"sincosf", 'f', 0, 0.1, 0.7, {.f = sincosf_wrap}}, +{"sincosf", 'f', 0, 0.8, 3.1, {.f = sincosf_wrap}}, +{"sincosf", 'f', 0, -3.1, 3.1, {.f = sincosf_wrap}}, +{"sincosf", 'f', 0, 3.3, 33.3, {.f = sincosf_wrap}}, +{"sincosf", 'f', 0, 100, 1000, {.f = sincosf_wrap}}, +{"sincosf", 'f', 0, 1e6, 1e32, {.f = sincosf_wrap}}, +F (sinf, 0.1, 0.7) +F (sinf, 0.8, 3.1) +F (sinf, -3.1, 3.1) +F (sinf, 3.3, 33.3) +F (sinf, 100, 1000) +F (sinf, 1e6, 1e32) +F (cosf, 0.1, 0.7) +F (cosf, 0.8, 3.1) +F (cosf, -3.1, 3.1) +F (cosf, 3.3, 33.3) +F (cosf, 100, 1000) +F (cosf, 1e6, 1e32) +F (erff, -4.0, 4.0) +#if WANT_VMATH +D (__s_sin, -3.1, 3.1) +D (__s_cos, -3.1, 3.1) +D (__s_exp, -9.9, 9.9) +D (__s_log, 0.01, 11.1) +{"__s_pow", 'd', 0, 0.01, 11.1, {.d = xy__s_pow}}, +F (__s_expf, -9.9, 9.9) +F (__s_expf_1u, -9.9, 9.9) +F (__s_exp2f, -9.9, 9.9) +F (__s_exp2f_1u, -9.9, 9.9) +F (__s_logf, 0.01, 11.1) +{"__s_powf", 'f', 0, 0.01, 11.1, {.f = xy__s_powf}}, +F (__s_sinf, -3.1, 3.1) +F (__s_cosf, -3.1, 3.1) +#if __aarch64__ +VD (__v_sin, -3.1, 3.1) +VD (__v_cos, -3.1, 3.1) +VD (__v_exp, -9.9, 9.9) +VD (__v_log, 0.01, 11.1) +{"__v_pow", 'd', 'v', 0.01, 11.1, {.vd = xy__v_pow}}, +VF (__v_expf, -9.9, 9.9) +VF (__v_expf_1u, -9.9, 9.9) +VF (__v_exp2f, -9.9, 9.9) +VF (__v_exp2f_1u, -9.9, 9.9) +VF (__v_logf, 0.01, 11.1) +{"__v_powf", 'f', 'v', 0.01, 11.1, {.vf = xy__v_powf}}, +VF (__v_sinf, -3.1, 3.1) +VF (__v_cosf, -3.1, 3.1) +#ifdef __vpcs +VND (__vn_exp, -9.9, 9.9) +VND (_ZGVnN2v_exp, -9.9, 9.9) +VND (__vn_log, 0.01, 11.1) +VND (_ZGVnN2v_log, 0.01, 11.1) +{"__vn_pow", 'd', 'n', 0.01, 11.1, {.vnd = xy__vn_pow}}, +{"_ZGVnN2vv_pow", 'd', 'n', 0.01, 11.1, {.vnd = xy_Z_pow}}, +VND (__vn_sin, -3.1, 3.1) +VND (_ZGVnN2v_sin, -3.1, 3.1) +VND (__vn_cos, -3.1, 3.1) +VND (_ZGVnN2v_cos, -3.1, 3.1) +VNF (__vn_expf, -9.9, 9.9) +VNF (_ZGVnN4v_expf, -9.9, 9.9) +VNF (__vn_expf_1u, -9.9, 9.9) +VNF (__vn_exp2f, -9.9, 9.9) +VNF (_ZGVnN4v_exp2f, -9.9, 9.9) +VNF (__vn_exp2f_1u, -9.9, 9.9) +VNF (__vn_logf, 0.01, 11.1) +VNF (_ZGVnN4v_logf, 0.01, 11.1) +{"__vn_powf", 'f', 'n', 0.01, 11.1, {.vnf = xy__vn_powf}}, +{"_ZGVnN4vv_powf", 'f', 'n', 0.01, 11.1, {.vnf = xy_Z_powf}}, +VNF (__vn_sinf, -3.1, 3.1) +VNF (_ZGVnN4v_sinf, -3.1, 3.1) +VNF (__vn_cosf, -3.1, 3.1) +VNF (_ZGVnN4v_cosf, -3.1, 3.1) +#endif +#endif +#endif diff --git a/math/test/mathbench_wrappers.h b/math/test/mathbench_wrappers.h new file mode 100644 index 0000000..8311f0f --- /dev/null +++ b/math/test/mathbench_wrappers.h @@ -0,0 +1,104 @@ +/* + * Function wrappers for mathbench. + * + * Copyright (c) 2022, Arm Limited. + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception + */ +#if WANT_VMATH +#if __aarch64__ + +#ifdef __vpcs +__vpcs static v_float +xy__vn_powf (v_float x) +{ + return __vn_powf (x, x); +} + +__vpcs static v_float +xy_Z_powf (v_float x) +{ + return _ZGVnN4vv_powf (x, x); +} + +__vpcs static v_double +xy__vn_pow (v_double x) +{ + return __vn_pow (x, x); +} + +__vpcs static v_double +xy_Z_pow (v_double x) +{ + return _ZGVnN2vv_pow (x, x); +} +#endif // __vpcs + +static v_float +xy__v_powf (v_float x) +{ + return __v_powf (x, x); +} + +static v_double +xy__v_pow (v_double x) +{ + return __v_pow (x, x); +} +#endif // __aarch64__ + +static float +xy__s_powf (float x) +{ + return __s_powf (x, x); +} + +static double +xy__s_pow (double x) +{ + return __s_pow (x, x); +} +#endif // WANT_VMATH + +static double +xypow (double x) +{ + return pow (x, x); +} + +static float +xypowf (float x) +{ + return powf (x, x); +} + +static double +xpow (double x) +{ + return pow (x, 23.4); +} + +static float +xpowf (float x) +{ + return powf (x, 23.4f); +} + +static double +ypow (double x) +{ + return pow (2.34, x); +} + +static float +ypowf (float x) +{ + return powf (2.34f, x); +} + +static float +sincosf_wrap (float x) +{ + float s, c; + sincosf (x, &s, &c); + return s + c; +} diff --git a/math/test/mathtest.c b/math/test/mathtest.c index 3108967..3168da4 100644 --- a/math/test/mathtest.c +++ b/math/test/mathtest.c @@ -1,8 +1,8 @@ /* * mathtest.c - test rig for mathlib * - * Copyright (c) 1998-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * Copyright (c) 1998-2022, Arm Limited. + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include <assert.h> @@ -196,9 +196,11 @@ int is_complex_rettype(int rettype) { #define TFUNCARM(arg,ret,name,tolerance) { t_func, arg, ret, (void*)& ARM_PREFIX(name), m_none, tolerance, #name } #define MFUNC(arg,ret,name,tolerance) { t_macro, arg, ret, NULL, m_##name, tolerance, #name } +#ifndef PL /* sincosf wrappers for easier testing. */ static float sincosf_sinf(float x) { float s,c; sincosf(x, &s, &c); return s; } static float sincosf_cosf(float x) { float s,c; sincosf(x, &s, &c); return c; } +#endif test_func tfuncs[] = { /* trigonometric */ @@ -218,9 +220,10 @@ test_func tfuncs[] = { TFUNCARM(at_s,rt_s, tanf, 4*ULPUNIT), TFUNCARM(at_s,rt_s, sinf, 3*ULPUNIT/4), TFUNCARM(at_s,rt_s, cosf, 3*ULPUNIT/4), +#ifndef PL TFUNCARM(at_s,rt_s, sincosf_sinf, 3*ULPUNIT/4), TFUNCARM(at_s,rt_s, sincosf_cosf, 3*ULPUNIT/4), - +#endif /* hyperbolic */ TFUNC(at_d, rt_d, atanh, 4*ULPUNIT), TFUNC(at_d, rt_d, asinh, 4*ULPUNIT), diff --git a/math/test/rtest/dotest.c b/math/test/rtest/dotest.c index 6be79e1..5b3e9b4 100644 --- a/math/test/rtest/dotest.c +++ b/math/test/rtest/dotest.c @@ -2,7 +2,7 @@ * dotest.c - actually generate mathlib test cases * * Copyright (c) 1999-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include <stdio.h> diff --git a/math/test/rtest/intern.h b/math/test/rtest/intern.h index 12a9c74..3ebd7dd 100644 --- a/math/test/rtest/intern.h +++ b/math/test/rtest/intern.h @@ -2,7 +2,7 @@ * intern.h * * Copyright (c) 1999-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #ifndef mathtest_intern_h diff --git a/math/test/rtest/main.c b/math/test/rtest/main.c index 0d8ead8..3d533c9 100644 --- a/math/test/rtest/main.c +++ b/math/test/rtest/main.c @@ -2,7 +2,7 @@ * main.c * * Copyright (c) 1999-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include <assert.h> diff --git a/math/test/rtest/random.c b/math/test/rtest/random.c index 5612396..1de3258 100644 --- a/math/test/rtest/random.c +++ b/math/test/rtest/random.c @@ -2,7 +2,7 @@ * random.c - random number generator for producing mathlib test cases * * Copyright (c) 1998-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include "types.h" diff --git a/math/test/rtest/random.h b/math/test/rtest/random.h index b4b22df..0b477d7 100644 --- a/math/test/rtest/random.h +++ b/math/test/rtest/random.h @@ -2,7 +2,7 @@ * random.h - header for random.c * * Copyright (c) 2009-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include "types.h" diff --git a/math/test/rtest/semi.c b/math/test/rtest/semi.c index c9f0daf..70a7844 100644 --- a/math/test/rtest/semi.c +++ b/math/test/rtest/semi.c @@ -2,7 +2,7 @@ * semi.c: test implementations of mathlib seminumerical functions * * Copyright (c) 1999-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include <stdio.h> diff --git a/math/test/rtest/semi.h b/math/test/rtest/semi.h index 17dc415..7a1444e 100644 --- a/math/test/rtest/semi.h +++ b/math/test/rtest/semi.h @@ -2,7 +2,7 @@ * semi.h: header for semi.c * * Copyright (c) 1999-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #ifndef test_semi_h diff --git a/math/test/rtest/types.h b/math/test/rtest/types.h index 53cd557..e15b4e0 100644 --- a/math/test/rtest/types.h +++ b/math/test/rtest/types.h @@ -2,7 +2,7 @@ * types.h * * Copyright (c) 2005-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #ifndef mathtest_types_h diff --git a/math/test/rtest/wrappers.c b/math/test/rtest/wrappers.c index de45ac5..4410171 100644 --- a/math/test/rtest/wrappers.c +++ b/math/test/rtest/wrappers.c @@ -2,7 +2,7 @@ * wrappers.c - wrappers to modify output of MPFR/MPC test functions * * Copyright (c) 2014-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include <assert.h> diff --git a/math/test/rtest/wrappers.h b/math/test/rtest/wrappers.h index 7b09c85..0a8a587 100644 --- a/math/test/rtest/wrappers.h +++ b/math/test/rtest/wrappers.h @@ -2,7 +2,7 @@ * wrappers.h - wrappers to modify output of MPFR/MPC test functions * * Copyright (c) 2014-2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ typedef struct { diff --git a/math/test/runulp.sh b/math/test/runulp.sh index 0190d9a..b4000f6 100755 --- a/math/test/runulp.sh +++ b/math/test/runulp.sh @@ -2,8 +2,8 @@ # ULP error check script. # -# Copyright (c) 2019-2020, Arm Limited. -# SPDX-License-Identifier: MIT +# Copyright (c) 2019-2022, Arm Limited. +# SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception #set -x set -eu @@ -145,7 +145,7 @@ done # vector functions Ldir=0.5 r='n' -flags="${ULPFLAGS:--q} -f" +flags="${ULPFLAGS:--q}" runs= check __s_exp 1 && runs=1 runv= @@ -229,7 +229,7 @@ L_sinf=1.4 L_cosf=1.4 L_powf=2.1 -while read G F R +while read G F R D do [ "$R" = 1 ] || continue case "$G" in \#*) continue ;; esac @@ -239,7 +239,16 @@ do do [ -n "$X" ] || continue case "$X" in \#*) continue ;; esac - t $F $X + disable_fenv="" + if [ -z "$WANT_SIMD_EXCEPT" ] || [ $WANT_SIMD_EXCEPT -eq 0 ]; then + # If library was built with SIMD exceptions + # disabled, disable fenv checking in ulp + # tool. Otherwise, fenv checking may still be + # disabled by adding -f to the end of the run + # line. + disable_fenv="-f" + fi + t $D $disable_fenv $F $X done << EOF $range EOF @@ -255,10 +264,10 @@ log __v_log $runv log __vn_log $runvn log _ZGVnN2v_log $runvn -pow __s_pow $runs -pow __v_pow $runv -pow __vn_pow $runvn -pow _ZGVnN2vv_pow $runvn +pow __s_pow $runs -f +pow __v_pow $runv -f +pow __vn_pow $runvn -f +pow _ZGVnN2vv_pow $runvn -f sin __s_sin $runs sin __v_sin $runv @@ -275,18 +284,18 @@ expf __v_expf $runv expf __vn_expf $runvn expf _ZGVnN4v_expf $runvn -expf_1u __s_expf_1u $runs -expf_1u __v_expf_1u $runv -expf_1u __vn_expf_1u $runvn +expf_1u __s_expf_1u $runs -f +expf_1u __v_expf_1u $runv -f +expf_1u __vn_expf_1u $runvn -f exp2f __s_exp2f $runs exp2f __v_exp2f $runv exp2f __vn_exp2f $runvn exp2f _ZGVnN4v_exp2f $runvn -exp2f_1u __s_exp2f_1u $runs -exp2f_1u __v_exp2f_1u $runv -exp2f_1u __vn_exp2f_1u $runvn +exp2f_1u __s_exp2f_1u $runs -f +exp2f_1u __v_exp2f_1u $runv -f +exp2f_1u __vn_exp2f_1u $runvn -f logf __s_logf $runs logf __v_logf $runv @@ -303,10 +312,10 @@ cosf __v_cosf $runv cosf __vn_cosf $runvn cosf _ZGVnN4v_cosf $runvn -powf __s_powf $runs -powf __v_powf $runv -powf __vn_powf $runvn -powf _ZGVnN4vv_powf $runvn +powf __s_powf $runs -f +powf __v_powf $runv -f +powf __vn_powf $runvn -f +powf _ZGVnN4vv_powf $runvn -f EOF [ 0 -eq $FAIL ] || { diff --git a/math/test/testcases/directed/cosf.tst b/math/test/testcases/directed/cosf.tst index 7916044..7ea0d45 100644 --- a/math/test/testcases/directed/cosf.tst +++ b/math/test/testcases/directed/cosf.tst @@ -1,7 +1,7 @@ ; cosf.tst - Directed test cases for SP cosine ; ; Copyright (c) 2007-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=cosf op1=7fc00001 result=7fc00001 errno=0 func=cosf op1=ffc00001 result=7fc00001 errno=0 diff --git a/math/test/testcases/directed/erf.tst b/math/test/testcases/directed/erf.tst index 7fa4d18..12384ce 100644 --- a/math/test/testcases/directed/erf.tst +++ b/math/test/testcases/directed/erf.tst @@ -1,7 +1,7 @@ ; erf.tst - Directed test cases for erf ; ; Copyright (c) 2007-2020, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=erf op1=7ff80000.00000001 result=7ff80000.00000001 errno=0 func=erf op1=fff80000.00000001 result=7ff80000.00000001 errno=0 diff --git a/math/test/testcases/directed/erff.tst b/math/test/testcases/directed/erff.tst index d05b7b1..28f8fa3 100644 --- a/math/test/testcases/directed/erff.tst +++ b/math/test/testcases/directed/erff.tst @@ -1,7 +1,7 @@ ; erff.tst ; ; Copyright (c) 2007-2020, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=erff op1=7fc00001 result=7fc00001 errno=0 func=erff op1=ffc00001 result=7fc00001 errno=0 diff --git a/math/test/testcases/directed/exp.tst b/math/test/testcases/directed/exp.tst index 85d556c..0bb2ef4 100644 --- a/math/test/testcases/directed/exp.tst +++ b/math/test/testcases/directed/exp.tst @@ -1,7 +1,7 @@ ; Directed test cases for exp ; ; Copyright (c) 2018-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=exp op1=7ff80000.00000001 result=7ff80000.00000001 errno=0 func=exp op1=fff80000.00000001 result=7ff80000.00000001 errno=0 diff --git a/math/test/testcases/directed/exp2.tst b/math/test/testcases/directed/exp2.tst index fa56c9f..7069f90 100644 --- a/math/test/testcases/directed/exp2.tst +++ b/math/test/testcases/directed/exp2.tst @@ -1,7 +1,7 @@ ; Directed test cases for exp2 ; ; Copyright (c) 2018-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=exp2 op1=7ff80000.00000001 result=7ff80000.00000001 errno=0 func=exp2 op1=fff80000.00000001 result=7ff80000.00000001 errno=0 diff --git a/math/test/testcases/directed/exp2f.tst b/math/test/testcases/directed/exp2f.tst index 38cfc3f..6ca2eea 100644 --- a/math/test/testcases/directed/exp2f.tst +++ b/math/test/testcases/directed/exp2f.tst @@ -1,7 +1,7 @@ ; exp2f.tst - Directed test cases for exp2f ; ; Copyright (c) 2017-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=exp2f op1=7fc00001 result=7fc00001 errno=0 func=exp2f op1=ffc00001 result=7fc00001 errno=0 diff --git a/math/test/testcases/directed/expf.tst b/math/test/testcases/directed/expf.tst index ff0f671..89ae8fe 100644 --- a/math/test/testcases/directed/expf.tst +++ b/math/test/testcases/directed/expf.tst @@ -1,7 +1,7 @@ ; expf.tst - Directed test cases for expf ; ; Copyright (c) 2007-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=expf op1=7fc00001 result=7fc00001 errno=0 func=expf op1=ffc00001 result=7fc00001 errno=0 diff --git a/math/test/testcases/directed/log.tst b/math/test/testcases/directed/log.tst index a0aa398..686ea83 100644 --- a/math/test/testcases/directed/log.tst +++ b/math/test/testcases/directed/log.tst @@ -1,7 +1,7 @@ ; Directed test cases for log ; ; Copyright (c) 2018-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=log op1=7ff80000.00000001 result=7ff80000.00000001 errno=0 func=log op1=fff80000.00000001 result=7ff80000.00000001 errno=0 diff --git a/math/test/testcases/directed/log2.tst b/math/test/testcases/directed/log2.tst index ff1286c..361bdde 100644 --- a/math/test/testcases/directed/log2.tst +++ b/math/test/testcases/directed/log2.tst @@ -1,7 +1,7 @@ ; Directed test cases for log2 ; ; Copyright (c) 2018-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=log2 op1=7ff80000.00000001 result=7ff80000.00000001 errno=0 func=log2 op1=fff80000.00000001 result=7ff80000.00000001 errno=0 diff --git a/math/test/testcases/directed/log2f.tst b/math/test/testcases/directed/log2f.tst index 5832c4f..5fce051 100644 --- a/math/test/testcases/directed/log2f.tst +++ b/math/test/testcases/directed/log2f.tst @@ -1,7 +1,7 @@ ; log2f.tst - Directed test cases for log2f ; ; Copyright (c) 2017-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=log2f op1=7fc00001 result=7fc00001 errno=0 func=log2f op1=ffc00001 result=7fc00001 errno=0 diff --git a/math/test/testcases/directed/logf.tst b/math/test/testcases/directed/logf.tst index 6e68a36..a6d1b9d 100644 --- a/math/test/testcases/directed/logf.tst +++ b/math/test/testcases/directed/logf.tst @@ -1,7 +1,7 @@ ; logf.tst - Directed test cases for logf ; ; Copyright (c) 2007-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=logf op1=7fc00001 result=7fc00001 errno=0 func=logf op1=ffc00001 result=7fc00001 errno=0 diff --git a/math/test/testcases/directed/pow.tst b/math/test/testcases/directed/pow.tst index 1966581..879d128 100644 --- a/math/test/testcases/directed/pow.tst +++ b/math/test/testcases/directed/pow.tst @@ -1,7 +1,7 @@ ; Directed test cases for pow ; ; Copyright (c) 2018-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=pow op1=00000000.00000000 op2=00000000.00000000 result=3ff00000.00000000 errno=0 func=pow op1=00000000.00000000 op2=00000000.00000001 result=00000000.00000000 errno=0 diff --git a/math/test/testcases/directed/powf.tst b/math/test/testcases/directed/powf.tst index 3fa8b11..46d5224 100644 --- a/math/test/testcases/directed/powf.tst +++ b/math/test/testcases/directed/powf.tst @@ -1,7 +1,7 @@ ; powf.tst - Directed test cases for powf ; ; Copyright (c) 2007-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=powf op1=7f800001 op2=7f800001 result=7fc00001 errno=0 status=i func=powf op1=7f800001 op2=ff800001 result=7fc00001 errno=0 status=i diff --git a/math/test/testcases/directed/sincosf.tst b/math/test/testcases/directed/sincosf.tst index 4b33d22..cddb346 100644 --- a/math/test/testcases/directed/sincosf.tst +++ b/math/test/testcases/directed/sincosf.tst @@ -1,7 +1,7 @@ ; Directed test cases for SP sincos ; ; Copyright (c) 2007-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=sincosf_sinf op1=7fc00001 result=7fc00001 errno=0 diff --git a/math/test/testcases/directed/sinf.tst b/math/test/testcases/directed/sinf.tst index ded80b1..041b13d 100644 --- a/math/test/testcases/directed/sinf.tst +++ b/math/test/testcases/directed/sinf.tst @@ -1,7 +1,7 @@ ; sinf.tst - Directed test cases for SP sine ; ; Copyright (c) 2007-2019, Arm Limited. -; SPDX-License-Identifier: MIT +; SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception func=sinf op1=7fc00001 result=7fc00001 errno=0 diff --git a/math/test/testcases/random/double.tst b/math/test/testcases/random/double.tst index c24ff80..8e885d6 100644 --- a/math/test/testcases/random/double.tst +++ b/math/test/testcases/random/double.tst @@ -1,7 +1,7 @@ !! double.tst - Random test case specification for DP functions !! !! Copyright (c) 1999-2019, Arm Limited. -!! SPDX-License-Identifier: MIT +!! SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception test exp 10000 test exp2 10000 diff --git a/math/test/testcases/random/float.tst b/math/test/testcases/random/float.tst index d02a227..ea4a5a0 100644 --- a/math/test/testcases/random/float.tst +++ b/math/test/testcases/random/float.tst @@ -1,7 +1,7 @@ !! single.tst - Random test case specification for SP functions !! !! Copyright (c) 1999-2019, Arm Limited. -!! SPDX-License-Identifier: MIT +!! SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception test sinf 10000 test cosf 10000 diff --git a/math/test/ulp.c b/math/test/ulp.c index 51479b8..bb8c3ad 100644 --- a/math/test/ulp.c +++ b/math/test/ulp.c @@ -1,8 +1,8 @@ /* * ULP error checking tool for math functions. * - * Copyright (c) 2019-2020, Arm Limited. - * SPDX-License-Identifier: MIT + * Copyright (c) 2019-2022, Arm Limited. + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include <ctype.h> @@ -214,16 +214,6 @@ struct conf double errlim; }; -/* Wrappers for sincos. */ -static float sincosf_sinf(float x) {(void)cosf(x); return sinf(x);} -static float sincosf_cosf(float x) {(void)sinf(x); return cosf(x);} -static double sincos_sin(double x) {(void)cos(x); return sin(x);} -static double sincos_cos(double x) {(void)sin(x); return cos(x);} -#if USE_MPFR -static int sincos_mpfr_sin(mpfr_t y, const mpfr_t x, mpfr_rnd_t r) { mpfr_cos(y,x,r); return mpfr_sin(y,x,r); } -static int sincos_mpfr_cos(mpfr_t y, const mpfr_t x, mpfr_rnd_t r) { mpfr_sin(y,x,r); return mpfr_cos(y,x,r); } -#endif - /* A bit of a hack: call vector functions twice with the same input in lane 0 but a different value in other lanes: once with an in-range value and then with a special case value. */ @@ -233,50 +223,79 @@ static int secondcall; #if __aarch64__ && WANT_VMATH typedef __f32x4_t v_float; typedef __f64x2_t v_double; -static const float fv[2] = {1.0f, -INFINITY}; -static const double dv[2] = {1.0, -INFINITY}; +/* First element of fv and dv may be changed by -c argument. */ +static float fv[2] = {1.0f, -INFINITY}; +static double dv[2] = {1.0, -INFINITY}; static inline v_float argf(float x) { return (v_float){x,x,x,fv[secondcall]}; } static inline v_double argd(double x) { return (v_double){x,dv[secondcall]}; } +#if WANT_SVE_MATH +#include <arm_sve.h> +typedef __SVFloat32_t sv_float; +typedef __SVFloat64_t sv_double; + +static inline sv_float svargf(float x) { + int n = svcntw(); + float base[n]; + for (int i=0; i<n; i++) + base[i] = (float)x; + base[n-1] = (float) fv[secondcall]; + return svld1(svptrue_b32(), base); +} +static inline sv_double svargd(double x) { + int n = svcntd(); + double base[n]; + for (int i=0; i<n; i++) + base[i] = x; + base[n-1] = dv[secondcall]; + return svld1(svptrue_b64(), base); +} +static inline float svretf(sv_float vec) { + int n = svcntw(); + float res[n]; + svst1(svptrue_b32(), res, vec); + return res[0]; +} +static inline double svretd(sv_double vec) { + int n = svcntd(); + double res[n]; + svst1(svptrue_b64(), res, vec); + return res[0]; +} +#endif +#endif + +#if WANT_SVE_MATH +long double +dummyl (long double x) +{ + return x; +} + +double +dummy (double x) +{ + return x; +} + +static sv_double +__sv_dummy (sv_double x) +{ + return x; +} -static float v_sinf(float x) { return __v_sinf(argf(x))[0]; } -static float v_cosf(float x) { return __v_cosf(argf(x))[0]; } -static float v_expf_1u(float x) { return __v_expf_1u(argf(x))[0]; } -static float v_expf(float x) { return __v_expf(argf(x))[0]; } -static float v_exp2f_1u(float x) { return __v_exp2f_1u(argf(x))[0]; } -static float v_exp2f(float x) { return __v_exp2f(argf(x))[0]; } -static float v_logf(float x) { return __v_logf(argf(x))[0]; } -static float v_powf(float x, float y) { return __v_powf(argf(x),argf(y))[0]; } -static double v_sin(double x) { return __v_sin(argd(x))[0]; } -static double v_cos(double x) { return __v_cos(argd(x))[0]; } -static double v_exp(double x) { return __v_exp(argd(x))[0]; } -static double v_log(double x) { return __v_log(argd(x))[0]; } -static double v_pow(double x, double y) { return __v_pow(argd(x),argd(y))[0]; } -#ifdef __vpcs -static float vn_sinf(float x) { return __vn_sinf(argf(x))[0]; } -static float vn_cosf(float x) { return __vn_cosf(argf(x))[0]; } -static float vn_expf_1u(float x) { return __vn_expf_1u(argf(x))[0]; } -static float vn_expf(float x) { return __vn_expf(argf(x))[0]; } -static float vn_exp2f_1u(float x) { return __vn_exp2f_1u(argf(x))[0]; } -static float vn_exp2f(float x) { return __vn_exp2f(argf(x))[0]; } -static float vn_logf(float x) { return __vn_logf(argf(x))[0]; } -static float vn_powf(float x, float y) { return __vn_powf(argf(x),argf(y))[0]; } -static double vn_sin(double x) { return __vn_sin(argd(x))[0]; } -static double vn_cos(double x) { return __vn_cos(argd(x))[0]; } -static double vn_exp(double x) { return __vn_exp(argd(x))[0]; } -static double vn_log(double x) { return __vn_log(argd(x))[0]; } -static double vn_pow(double x, double y) { return __vn_pow(argd(x),argd(y))[0]; } -static float Z_sinf(float x) { return _ZGVnN4v_sinf(argf(x))[0]; } -static float Z_cosf(float x) { return _ZGVnN4v_cosf(argf(x))[0]; } -static float Z_expf(float x) { return _ZGVnN4v_expf(argf(x))[0]; } -static float Z_exp2f(float x) { return _ZGVnN4v_exp2f(argf(x))[0]; } -static float Z_logf(float x) { return _ZGVnN4v_logf(argf(x))[0]; } -static float Z_powf(float x, float y) { return _ZGVnN4vv_powf(argf(x),argf(y))[0]; } -static double Z_sin(double x) { return _ZGVnN2v_sin(argd(x))[0]; } -static double Z_cos(double x) { return _ZGVnN2v_cos(argd(x))[0]; } -static double Z_exp(double x) { return _ZGVnN2v_exp(argd(x))[0]; } -static double Z_log(double x) { return _ZGVnN2v_log(argd(x))[0]; } -static double Z_pow(double x, double y) { return _ZGVnN2vv_pow(argd(x),argd(y))[0]; } +static sv_float +__sv_dummyf (sv_float x) +{ + return x; +} #endif + +#include "test/ulp_wrappers.h" + +/* Wrappers for SVE functions. */ +#if WANT_SVE_MATH +static double sv_dummy (double x) { return svretd (__sv_dummy (svargd (x))); } +static float sv_dummyf (float x) { return svretf (__sv_dummyf (svargf (x))); } #endif struct fun @@ -322,83 +341,53 @@ static const struct fun fun[] = { #define F2(x) F (x##f, x##f, x, mpfr_##x, 2, 1, f2, 0) #define D1(x) F (x, x, x##l, mpfr_##x, 1, 0, d1, 0) #define D2(x) F (x, x, x##l, mpfr_##x, 2, 0, d2, 0) - F1 (sin) - F1 (cos) - F (sincosf_sinf, sincosf_sinf, sincos_sin, sincos_mpfr_sin, 1, 1, f1, 0) - F (sincosf_cosf, sincosf_cosf, sincos_cos, sincos_mpfr_cos, 1, 1, f1, 0) - F1 (exp) - F1 (exp2) - F1 (log) - F1 (log2) - F2 (pow) - F1 (erf) - D1 (exp) - D1 (exp2) - D1 (log) - D1 (log2) - D2 (pow) - D1 (erf) -#if WANT_VMATH - F (__s_sinf, __s_sinf, sin, mpfr_sin, 1, 1, f1, 0) - F (__s_cosf, __s_cosf, cos, mpfr_cos, 1, 1, f1, 0) - F (__s_expf_1u, __s_expf_1u, exp, mpfr_exp, 1, 1, f1, 0) - F (__s_expf, __s_expf, exp, mpfr_exp, 1, 1, f1, 0) - F (__s_exp2f_1u, __s_exp2f_1u, exp2, mpfr_exp2, 1, 1, f1, 0) - F (__s_exp2f, __s_exp2f, exp2, mpfr_exp2, 1, 1, f1, 0) - F (__s_powf, __s_powf, pow, mpfr_pow, 2, 1, f2, 0) - F (__s_logf, __s_logf, log, mpfr_log, 1, 1, f1, 0) - F (__s_sin, __s_sin, sinl, mpfr_sin, 1, 0, d1, 0) - F (__s_cos, __s_cos, cosl, mpfr_cos, 1, 0, d1, 0) - F (__s_exp, __s_exp, expl, mpfr_exp, 1, 0, d1, 0) - F (__s_log, __s_log, logl, mpfr_log, 1, 0, d1, 0) - F (__s_pow, __s_pow, powl, mpfr_pow, 2, 0, d2, 0) -#if __aarch64__ - F (__v_sinf, v_sinf, sin, mpfr_sin, 1, 1, f1, 1) - F (__v_cosf, v_cosf, cos, mpfr_cos, 1, 1, f1, 1) - F (__v_expf_1u, v_expf_1u, exp, mpfr_exp, 1, 1, f1, 1) - F (__v_expf, v_expf, exp, mpfr_exp, 1, 1, f1, 1) - F (__v_exp2f_1u, v_exp2f_1u, exp2, mpfr_exp2, 1, 1, f1, 1) - F (__v_exp2f, v_exp2f, exp2, mpfr_exp2, 1, 1, f1, 1) - F (__v_logf, v_logf, log, mpfr_log, 1, 1, f1, 1) - F (__v_powf, v_powf, pow, mpfr_pow, 2, 1, f2, 1) - F (__v_sin, v_sin, sinl, mpfr_sin, 1, 0, d1, 1) - F (__v_cos, v_cos, cosl, mpfr_cos, 1, 0, d1, 1) - F (__v_exp, v_exp, expl, mpfr_exp, 1, 0, d1, 1) - F (__v_log, v_log, logl, mpfr_log, 1, 0, d1, 1) - F (__v_pow, v_pow, powl, mpfr_pow, 2, 0, d2, 1) -#ifdef __vpcs - F (__vn_sinf, vn_sinf, sin, mpfr_sin, 1, 1, f1, 1) - F (__vn_cosf, vn_cosf, cos, mpfr_cos, 1, 1, f1, 1) - F (__vn_expf_1u, vn_expf_1u, exp, mpfr_exp, 1, 1, f1, 1) - F (__vn_expf, vn_expf, exp, mpfr_exp, 1, 1, f1, 1) - F (__vn_exp2f_1u, vn_exp2f_1u, exp2, mpfr_exp2, 1, 1, f1, 1) - F (__vn_exp2f, vn_exp2f, exp2, mpfr_exp2, 1, 1, f1, 1) - F (__vn_logf, vn_logf, log, mpfr_log, 1, 1, f1, 1) - F (__vn_powf, vn_powf, pow, mpfr_pow, 2, 1, f2, 1) - F (__vn_sin, vn_sin, sinl, mpfr_sin, 1, 0, d1, 1) - F (__vn_cos, vn_cos, cosl, mpfr_cos, 1, 0, d1, 1) - F (__vn_exp, vn_exp, expl, mpfr_exp, 1, 0, d1, 1) - F (__vn_log, vn_log, logl, mpfr_log, 1, 0, d1, 1) - F (__vn_pow, vn_pow, powl, mpfr_pow, 2, 0, d2, 1) - F (_ZGVnN4v_sinf, Z_sinf, sin, mpfr_sin, 1, 1, f1, 1) - F (_ZGVnN4v_cosf, Z_cosf, cos, mpfr_cos, 1, 1, f1, 1) - F (_ZGVnN4v_expf, Z_expf, exp, mpfr_exp, 1, 1, f1, 1) - F (_ZGVnN4v_exp2f, Z_exp2f, exp2, mpfr_exp2, 1, 1, f1, 1) - F (_ZGVnN4v_logf, Z_logf, log, mpfr_log, 1, 1, f1, 1) - F (_ZGVnN4vv_powf, Z_powf, pow, mpfr_pow, 2, 1, f2, 1) - F (_ZGVnN2v_sin, Z_sin, sinl, mpfr_sin, 1, 0, d1, 1) - F (_ZGVnN2v_cos, Z_cos, cosl, mpfr_cos, 1, 0, d1, 1) - F (_ZGVnN2v_exp, Z_exp, expl, mpfr_exp, 1, 0, d1, 1) - F (_ZGVnN2v_log, Z_log, logl, mpfr_log, 1, 0, d1, 1) - F (_ZGVnN2vv_pow, Z_pow, powl, mpfr_pow, 2, 0, d2, 1) -#endif -#endif +/* Neon routines. */ +#define VF1(x) F (__v_##x##f, v_##x##f, x, mpfr_##x, 1, 1, f1, 0) +#define VF2(x) F (__v_##x##f, v_##x##f, x, mpfr_##x, 2, 1, f2, 0) +#define VD1(x) F (__v_##x, v_##x, x##l, mpfr_##x, 1, 0, d1, 0) +#define VD2(x) F (__v_##x, v_##x, x##l, mpfr_##x, 2, 0, d2, 0) +#define VNF1(x) F (__vn_##x##f, vn_##x##f, x, mpfr_##x, 1, 1, f1, 0) +#define VNF2(x) F (__vn_##x##f, vn_##x##f, x, mpfr_##x, 2, 1, f2, 0) +#define VND1(x) F (__vn_##x, vn_##x, x##l, mpfr_##x, 1, 0, d1, 0) +#define VND2(x) F (__vn_##x, vn_##x, x##l, mpfr_##x, 2, 0, d2, 0) +#define ZVF1(x) F (_ZGVnN4v_##x##f, Z_##x##f, x, mpfr_##x, 1, 1, f1, 0) +#define ZVF2(x) F (_ZGVnN4vv_##x##f, Z_##x##f, x, mpfr_##x, 2, 1, f2, 0) +#define ZVD1(x) F (_ZGVnN2v_##x, Z_##x, x##l, mpfr_##x, 1, 0, d1, 0) +#define ZVD2(x) F (_ZGVnN2vv_##x, Z_##x, x##l, mpfr_##x, 2, 0, d2, 0) +#define ZVNF1(x) VNF1 (x) ZVF1 (x) +#define ZVNF2(x) VNF2 (x) ZVF2 (x) +#define ZVND1(x) VND1 (x) ZVD1 (x) +#define ZVND2(x) VND2 (x) ZVD2 (x) +#define SF1(x) F (__s_##x##f, __s_##x##f, x, mpfr_##x, 1, 1, f1, 0) +#define SF2(x) F (__s_##x##f, __s_##x##f, x, mpfr_##x, 2, 1, f2, 0) +#define SD1(x) F (__s_##x, __s_##x, x##l, mpfr_##x, 1, 0, d1, 0) +#define SD2(x) F (__s_##x, __s_##x, x##l, mpfr_##x, 2, 0, d2, 0) +/* SVE routines. */ +#define SVF1(x) F (__sv_##x##f, sv_##x##f, x, mpfr_##x, 1, 1, f1, 0) +#define SVF2(x) F (__sv_##x##f, sv_##x##f, x, mpfr_##x, 2, 1, f2, 0) +#define SVD1(x) F (__sv_##x, sv_##x, x##l, mpfr_##x, 1, 0, d1, 0) +#define SVD2(x) F (__sv_##x, sv_##x, x##l, mpfr_##x, 2, 0, d2, 0) +#define ZSVF1(x) F (_ZGVsMxv_##x##f, Z_sv_##x##f, x, mpfr_##x, 1, 1, f1, 0) +#define ZSVF2(x) F (_ZGVsMxvv_##x##f, Z_sv_##x##f, x, mpfr_##x, 2, 1, f2, 0) +#define ZSVD1(x) F (_ZGVsMxv_##x, Z_sv_##x, x##l, mpfr_##x, 1, 0, d1, 0) +#define ZSVD2(x) F (_ZGVsMxvv_##x, Z_sv_##x, x##l, mpfr_##x, 2, 0, d2, 0) + +#include "test/ulp_funcs.h" + +#if WANT_SVE_MATH + SVD1 (dummy) + SVF1 (dummy) #endif + #undef F #undef F1 #undef F2 #undef D1 #undef D2 +#undef SVF1 +#undef SVF2 +#undef SVD1 +#undef SVD2 {0}}; /* Boilerplate for generic calls. */ @@ -645,6 +634,11 @@ usage (void) puts ("-q: quiet."); puts ("-m: use mpfr even if faster method is available."); puts ("-f: disable fenv testing (rounding modes and exceptions)."); +#if __aarch64__ && WANT_VMATH + puts ("-c: neutral 'control value' to test behaviour when one lane can affect another. \n" + " This should be different from tested input in other lanes, and non-special \n" + " (i.e. should not trigger fenv exceptions). Default is 1."); +#endif puts ("Supported func:"); for (const struct fun *f = fun; f->name; f++) printf ("\t%s\n", f->name); @@ -812,6 +806,14 @@ main (int argc, char *argv[]) conf.rc = argv[0][0]; } break; +#if __aarch64__ && WANT_VMATH + case 'c': + argc--; + argv++; + fv[0] = strtof(argv[0], 0); + dv[0] = strtod(argv[0], 0); + break; +#endif default: usage (); } diff --git a/math/test/ulp.h b/math/test/ulp.h index a0c3016..327b4bd 100644 --- a/math/test/ulp.h +++ b/math/test/ulp.h @@ -2,7 +2,7 @@ * Generic functions for ULP error estimation. * * Copyright (c) 2019, Arm Limited. - * SPDX-License-Identifier: MIT + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ /* For each different math function type, diff --git a/math/test/ulp_funcs.h b/math/test/ulp_funcs.h new file mode 100644 index 0000000..f5cea4d --- /dev/null +++ b/math/test/ulp_funcs.h @@ -0,0 +1,78 @@ +/* + * Function entries for ulp. + * + * Copyright (c) 2022, Arm Limited. + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception + */ + F1 (sin) + F1 (cos) + F (sincosf_sinf, sincosf_sinf, sincos_sin, sincos_mpfr_sin, 1, 1, f1, 0) + F (sincosf_cosf, sincosf_cosf, sincos_cos, sincos_mpfr_cos, 1, 1, f1, 0) + F1 (exp) + F1 (exp2) + F1 (log) + F1 (log2) + F2 (pow) + F1 (erf) + D1 (exp) + D1 (exp2) + D1 (log) + D1 (log2) + D2 (pow) + D1 (erf) +#if WANT_VMATH + F (__s_sinf, __s_sinf, sin, mpfr_sin, 1, 1, f1, 0) + F (__s_cosf, __s_cosf, cos, mpfr_cos, 1, 1, f1, 0) + F (__s_expf_1u, __s_expf_1u, exp, mpfr_exp, 1, 1, f1, 0) + F (__s_expf, __s_expf, exp, mpfr_exp, 1, 1, f1, 0) + F (__s_exp2f_1u, __s_exp2f_1u, exp2, mpfr_exp2, 1, 1, f1, 0) + F (__s_exp2f, __s_exp2f, exp2, mpfr_exp2, 1, 1, f1, 0) + F (__s_powf, __s_powf, pow, mpfr_pow, 2, 1, f2, 0) + F (__s_logf, __s_logf, log, mpfr_log, 1, 1, f1, 0) + F (__s_sin, __s_sin, sinl, mpfr_sin, 1, 0, d1, 0) + F (__s_cos, __s_cos, cosl, mpfr_cos, 1, 0, d1, 0) + F (__s_exp, __s_exp, expl, mpfr_exp, 1, 0, d1, 0) + F (__s_log, __s_log, logl, mpfr_log, 1, 0, d1, 0) + F (__s_pow, __s_pow, powl, mpfr_pow, 2, 0, d2, 0) +#if __aarch64__ + F (__v_sinf, v_sinf, sin, mpfr_sin, 1, 1, f1, 1) + F (__v_cosf, v_cosf, cos, mpfr_cos, 1, 1, f1, 1) + F (__v_expf_1u, v_expf_1u, exp, mpfr_exp, 1, 1, f1, 1) + F (__v_expf, v_expf, exp, mpfr_exp, 1, 1, f1, 1) + F (__v_exp2f_1u, v_exp2f_1u, exp2, mpfr_exp2, 1, 1, f1, 1) + F (__v_exp2f, v_exp2f, exp2, mpfr_exp2, 1, 1, f1, 1) + F (__v_logf, v_logf, log, mpfr_log, 1, 1, f1, 1) + F (__v_powf, v_powf, pow, mpfr_pow, 2, 1, f2, 1) + F (__v_sin, v_sin, sinl, mpfr_sin, 1, 0, d1, 1) + F (__v_cos, v_cos, cosl, mpfr_cos, 1, 0, d1, 1) + F (__v_exp, v_exp, expl, mpfr_exp, 1, 0, d1, 1) + F (__v_log, v_log, logl, mpfr_log, 1, 0, d1, 1) + F (__v_pow, v_pow, powl, mpfr_pow, 2, 0, d2, 1) +#ifdef __vpcs + F (__vn_sinf, vn_sinf, sin, mpfr_sin, 1, 1, f1, 1) + F (__vn_cosf, vn_cosf, cos, mpfr_cos, 1, 1, f1, 1) + F (__vn_expf_1u, vn_expf_1u, exp, mpfr_exp, 1, 1, f1, 1) + F (__vn_expf, vn_expf, exp, mpfr_exp, 1, 1, f1, 1) + F (__vn_exp2f_1u, vn_exp2f_1u, exp2, mpfr_exp2, 1, 1, f1, 1) + F (__vn_exp2f, vn_exp2f, exp2, mpfr_exp2, 1, 1, f1, 1) + F (__vn_logf, vn_logf, log, mpfr_log, 1, 1, f1, 1) + F (__vn_powf, vn_powf, pow, mpfr_pow, 2, 1, f2, 1) + F (__vn_sin, vn_sin, sinl, mpfr_sin, 1, 0, d1, 1) + F (__vn_cos, vn_cos, cosl, mpfr_cos, 1, 0, d1, 1) + F (__vn_exp, vn_exp, expl, mpfr_exp, 1, 0, d1, 1) + F (__vn_log, vn_log, logl, mpfr_log, 1, 0, d1, 1) + F (__vn_pow, vn_pow, powl, mpfr_pow, 2, 0, d2, 1) + F (_ZGVnN4v_sinf, Z_sinf, sin, mpfr_sin, 1, 1, f1, 1) + F (_ZGVnN4v_cosf, Z_cosf, cos, mpfr_cos, 1, 1, f1, 1) + F (_ZGVnN4v_expf, Z_expf, exp, mpfr_exp, 1, 1, f1, 1) + F (_ZGVnN4v_exp2f, Z_exp2f, exp2, mpfr_exp2, 1, 1, f1, 1) + F (_ZGVnN4v_logf, Z_logf, log, mpfr_log, 1, 1, f1, 1) + F (_ZGVnN4vv_powf, Z_powf, pow, mpfr_pow, 2, 1, f2, 1) + F (_ZGVnN2v_sin, Z_sin, sinl, mpfr_sin, 1, 0, d1, 1) + F (_ZGVnN2v_cos, Z_cos, cosl, mpfr_cos, 1, 0, d1, 1) + F (_ZGVnN2v_exp, Z_exp, expl, mpfr_exp, 1, 0, d1, 1) + F (_ZGVnN2v_log, Z_log, logl, mpfr_log, 1, 0, d1, 1) + F (_ZGVnN2vv_pow, Z_pow, powl, mpfr_pow, 2, 0, d2, 1) +#endif +#endif +#endif diff --git a/math/test/ulp_wrappers.h b/math/test/ulp_wrappers.h new file mode 100644 index 0000000..fd9e00c --- /dev/null +++ b/math/test/ulp_wrappers.h @@ -0,0 +1,59 @@ +/* + * Function wrappers for ulp. + * + * Copyright (c) 2022, Arm Limited. + * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception + */ + +/* Wrappers for sincos. */ +static float sincosf_sinf(float x) {(void)cosf(x); return sinf(x);} +static float sincosf_cosf(float x) {(void)sinf(x); return cosf(x);} +static double sincos_sin(double x) {(void)cos(x); return sin(x);} +static double sincos_cos(double x) {(void)sin(x); return cos(x);} +#if USE_MPFR +static int sincos_mpfr_sin(mpfr_t y, const mpfr_t x, mpfr_rnd_t r) { mpfr_cos(y,x,r); return mpfr_sin(y,x,r); } +static int sincos_mpfr_cos(mpfr_t y, const mpfr_t x, mpfr_rnd_t r) { mpfr_sin(y,x,r); return mpfr_cos(y,x,r); } +#endif + +/* Wrappers for vector functions. */ +#if __aarch64__ && WANT_VMATH +static float v_sinf(float x) { return __v_sinf(argf(x))[0]; } +static float v_cosf(float x) { return __v_cosf(argf(x))[0]; } +static float v_expf_1u(float x) { return __v_expf_1u(argf(x))[0]; } +static float v_expf(float x) { return __v_expf(argf(x))[0]; } +static float v_exp2f_1u(float x) { return __v_exp2f_1u(argf(x))[0]; } +static float v_exp2f(float x) { return __v_exp2f(argf(x))[0]; } +static float v_logf(float x) { return __v_logf(argf(x))[0]; } +static float v_powf(float x, float y) { return __v_powf(argf(x),argf(y))[0]; } +static double v_sin(double x) { return __v_sin(argd(x))[0]; } +static double v_cos(double x) { return __v_cos(argd(x))[0]; } +static double v_exp(double x) { return __v_exp(argd(x))[0]; } +static double v_log(double x) { return __v_log(argd(x))[0]; } +static double v_pow(double x, double y) { return __v_pow(argd(x),argd(y))[0]; } +#ifdef __vpcs +static float vn_sinf(float x) { return __vn_sinf(argf(x))[0]; } +static float vn_cosf(float x) { return __vn_cosf(argf(x))[0]; } +static float vn_expf_1u(float x) { return __vn_expf_1u(argf(x))[0]; } +static float vn_expf(float x) { return __vn_expf(argf(x))[0]; } +static float vn_exp2f_1u(float x) { return __vn_exp2f_1u(argf(x))[0]; } +static float vn_exp2f(float x) { return __vn_exp2f(argf(x))[0]; } +static float vn_logf(float x) { return __vn_logf(argf(x))[0]; } +static float vn_powf(float x, float y) { return __vn_powf(argf(x),argf(y))[0]; } +static double vn_sin(double x) { return __vn_sin(argd(x))[0]; } +static double vn_cos(double x) { return __vn_cos(argd(x))[0]; } +static double vn_exp(double x) { return __vn_exp(argd(x))[0]; } +static double vn_log(double x) { return __vn_log(argd(x))[0]; } +static double vn_pow(double x, double y) { return __vn_pow(argd(x),argd(y))[0]; } +static float Z_sinf(float x) { return _ZGVnN4v_sinf(argf(x))[0]; } +static float Z_cosf(float x) { return _ZGVnN4v_cosf(argf(x))[0]; } +static float Z_expf(float x) { return _ZGVnN4v_expf(argf(x))[0]; } +static float Z_exp2f(float x) { return _ZGVnN4v_exp2f(argf(x))[0]; } +static float Z_logf(float x) { return _ZGVnN4v_logf(argf(x))[0]; } +static float Z_powf(float x, float y) { return _ZGVnN4vv_powf(argf(x),argf(y))[0]; } +static double Z_sin(double x) { return _ZGVnN2v_sin(argd(x))[0]; } +static double Z_cos(double x) { return _ZGVnN2v_cos(argd(x))[0]; } +static double Z_exp(double x) { return _ZGVnN2v_exp(argd(x))[0]; } +static double Z_log(double x) { return _ZGVnN2v_log(argd(x))[0]; } +static double Z_pow(double x, double y) { return _ZGVnN2vv_pow(argd(x),argd(y))[0]; } +#endif +#endif |