diff options
| author | Alex Richardson <arichardson@FreeBSD.org> | 2021-02-22 11:59:12 +0000 |
|---|---|---|
| committer | Alex Richardson <arichardson@FreeBSD.org> | 2021-02-22 11:59:12 +0000 |
| commit | f9f37c002ab5a580accfe26b731eef45e798b435 (patch) | |
| tree | 6c5f3a7746c1d8a0d7a04012d47b6428c7b3057e /math/math_errf.c | |
Import Arm Optimized Routines v21.02vendor/arm-optimized-routines/v21.02
We already have copies of some of these files in the repository without a
vendor import and we should really be using contrib/ instead.
We should also be able to use some of the math functions to allow the
tests to pass on AArch64 (and other architectures) instead of just x86.
We should also be able to reuse some of the tests for the kyua testsuite.
Imported using
```
curl -L https://github.com/ARM-software/optimized-routines/tarball/e823e3abf5f89ecba58a10fc0fd82c13d9984b6b | tar --strip-components=1 -xvzf -
git add .
```
Diffstat (limited to 'math/math_errf.c')
| -rw-r--r-- | math/math_errf.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/math/math_errf.c b/math/math_errf.c new file mode 100644 index 000000000000..d5350b819ab1 --- /dev/null +++ b/math/math_errf.c @@ -0,0 +1,80 @@ +/* + * Single-precision math error handling. + * + * Copyright (c) 2017-2020, Arm Limited. + * SPDX-License-Identifier: MIT + */ + +#include "math_config.h" + +#if WANT_ERRNO +#include <errno.h> +/* NOINLINE reduces code size and avoids making math functions non-leaf + when the error handling is inlined. */ +NOINLINE static float +with_errnof (float y, int e) +{ + errno = e; + return y; +} +#else +#define with_errnof(x, e) (x) +#endif + +/* NOINLINE reduces code size. */ +NOINLINE static float +xflowf (uint32_t sign, float y) +{ + y = eval_as_float (opt_barrier_float (sign ? -y : y) * y); + return with_errnof (y, ERANGE); +} + +HIDDEN float +__math_uflowf (uint32_t sign) +{ + return xflowf (sign, 0x1p-95f); +} + +#if WANT_ERRNO_UFLOW +/* Underflows to zero in some non-nearest rounding mode, setting errno + is valid even if the result is non-zero, but in the subnormal range. */ +HIDDEN float +__math_may_uflowf (uint32_t sign) +{ + return xflowf (sign, 0x1.4p-75f); +} +#endif + +HIDDEN float +__math_oflowf (uint32_t sign) +{ + return xflowf (sign, 0x1p97f); +} + +HIDDEN float +__math_divzerof (uint32_t sign) +{ + float y = opt_barrier_float (sign ? -1.0f : 1.0f) / 0.0f; + return with_errnof (y, ERANGE); +} + +HIDDEN float +__math_invalidf (float x) +{ + float y = (x - x) / (x - x); + return isnan (x) ? y : with_errnof (y, EDOM); +} + +/* Check result and set errno if necessary. */ + +HIDDEN float +__math_check_uflowf (float y) +{ + return y == 0.0f ? with_errnof (y, ERANGE) : y; +} + +HIDDEN float +__math_check_oflowf (float y) +{ + return isinf (y) ? with_errnof (y, ERANGE) : y; +} |
