diff options
author | Andrew Turner <andrew@FreeBSD.org> | 2025-01-10 10:34:52 +0000 |
---|---|---|
committer | Andrew Turner <andrew@FreeBSD.org> | 2025-01-10 10:39:34 +0000 |
commit | 9d1de25930735261c16ed874a933b4c1f1d9041e (patch) | |
tree | b0cac1c933cc1ecb885c7e757b89ffbf13f1f012 /math/test/ulp.h | |
parent | edc5c0de794f521eb620d2b6cbaee2434442a8f3 (diff) |
Diffstat (limited to 'math/test/ulp.h')
-rw-r--r-- | math/test/ulp.h | 41 |
1 files changed, 24 insertions, 17 deletions
diff --git a/math/test/ulp.h b/math/test/ulp.h index b0bc59aeef8d..de122257d3b1 100644 --- a/math/test/ulp.h +++ b/math/test/ulp.h @@ -1,13 +1,13 @@ /* * Generic functions for ULP error estimation. * - * Copyright (c) 2019-2023, Arm Limited. + * Copyright (c) 2019-2024, Arm Limited. * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ /* For each different math function type, T(x) should add a different suffix to x. - RT(x) should add a return type specific suffix to x. */ + RT(x) should add a return type specific suffix to x. */ #ifdef NEW_RT #undef NEW_RT @@ -47,8 +47,12 @@ static double RT (ulperr) (RT (float) got, const struct RT (ret) * p, int r, if (RT(asuint) (got) == RT(asuint) (want)) return 0.0; if (isnan (got) && isnan (want)) - /* Ignore sign of NaN. */ + /* Ignore sign of NaN, and signalling-ness for MPFR. */ +# if USE_MPFR + return 0; +# else return RT (issignaling) (got) == RT (issignaling) (want) ? 0 : INFINITY; +# endif if (signbit (got) != signbit (want)) { /* Fall through to ULP calculation if ignoring sign of zero and at @@ -80,7 +84,7 @@ static double RT (ulperr) (RT (float) got, const struct RT (ret) * p, int r, // TODO: incorrect when got vs want cross a powof2 boundary /* error = got > want ? got - want - tail ulp - 0.5 ulp - : got - want - tail ulp + 0.5 ulp; */ + : got - want - tail ulp + 0.5 ulp. */ d = got - want; e = d > 0 ? -p->tail - 0.5 : -p->tail + 0.5; } @@ -108,32 +112,34 @@ static int RT(isok_nofenv) (RT(float) ygot, RT(float) ywant) } #endif -static inline void T(call_fenv) (const struct fun *f, struct T(args) a, int r, - RT(float) * y, int *ex) +static inline void T (call_fenv) (const struct fun *f, struct T (args) a, + int r, RT (float) * y, int *ex, + const struct conf *conf) { if (r != FE_TONEAREST) fesetround (r); feclearexcept (FE_ALL_EXCEPT); - *y = T(call) (f, a); + *y = T (call) (f, a, conf); *ex = fetestexcept (FE_ALL_EXCEPT); if (r != FE_TONEAREST) fesetround (FE_TONEAREST); } -static inline void T(call_nofenv) (const struct fun *f, struct T(args) a, - int r, RT(float) * y, int *ex) +static inline void T (call_nofenv) (const struct fun *f, struct T (args) a, + int r, RT (float) * y, int *ex, + const struct conf *conf) { if (r != FE_TONEAREST) fesetround (r); - *y = T(call) (f, a); + *y = T (call) (f, a, conf); *ex = 0; if (r != FE_TONEAREST) fesetround (FE_TONEAREST); } -static inline int T(call_long_fenv) (const struct fun *f, struct T(args) a, - int r, struct RT(ret) * p, - RT(float) ygot, int exgot) +static inline int T (call_long_fenv) (const struct fun *f, struct T (args) a, + int r, struct RT (ret) * p, + RT (float) ygot, int exgot) { if (r != FE_TONEAREST) fesetround (r); @@ -269,6 +275,7 @@ static int T(cmp) (const struct fun *f, struct gen *gen, int r = conf->r; int use_mpfr = conf->mpfr; int fenv = conf->fenv; + for (;;) { struct RT(ret) want; @@ -279,15 +286,15 @@ static int T(cmp) (const struct fun *f, struct gen *gen, RT(float) ygot2; int fail = 0; if (fenv) - T(call_fenv) (f, a, r, &ygot, &exgot); + T (call_fenv) (f, a, r, &ygot, &exgot, conf); else - T(call_nofenv) (f, a, r, &ygot, &exgot); + T (call_nofenv) (f, a, r, &ygot, &exgot, conf); if (f->twice) { secondcall = 1; if (fenv) - T(call_fenv) (f, a, r, &ygot2, &exgot2); + T (call_fenv) (f, a, r, &ygot2, &exgot2, conf); else - T(call_nofenv) (f, a, r, &ygot2, &exgot2); + T (call_nofenv) (f, a, r, &ygot2, &exgot2, conf); secondcall = 0; if (RT(asuint) (ygot) != RT(asuint) (ygot2)) { |