diff options
Diffstat (limited to 'libm')
-rw-r--r-- | libm/kvx/Makefile.arch | 22 | ||||
-rw-r--r-- | libm/kvx/feclearexcept.c | 20 | ||||
-rw-r--r-- | libm/kvx/fegetenv.c | 21 | ||||
-rw-r--r-- | libm/kvx/fegetexceptflag.c | 24 | ||||
-rw-r--r-- | libm/kvx/fegetround.c | 16 | ||||
-rw-r--r-- | libm/kvx/feholdexcept.c | 26 | ||||
-rw-r--r-- | libm/kvx/feraiseexcept.c | 24 | ||||
-rw-r--r-- | libm/kvx/fesetenv.c | 23 | ||||
-rw-r--r-- | libm/kvx/fesetexceptflag.c | 24 | ||||
-rw-r--r-- | libm/kvx/fesetround.c | 21 | ||||
-rw-r--r-- | libm/kvx/fetestexcept.c | 21 | ||||
-rw-r--r-- | libm/kvx/feupdateenv.c | 24 | ||||
-rw-r--r-- | libm/s_lrint.c | 20 | ||||
-rw-r--r-- | libm/s_nextafter.c | 9 | ||||
-rw-r--r-- | libm/w_j0f.c | 2 |
15 files changed, 283 insertions, 14 deletions
diff --git a/libm/kvx/Makefile.arch b/libm/kvx/Makefile.arch new file mode 100644 index 000000000..e26adb6f1 --- /dev/null +++ b/libm/kvx/Makefile.arch @@ -0,0 +1,22 @@ +# Makefile for uClibc +# +# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org> +# Copyright (C) 2018 Kalray Inc. +# +# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. + + +ifeq ($(UCLIBC_HAS_FENV),y) +libm_ARCH_SRC:=$(wildcard $(libm_ARCH_DIR)/*.c) +libm_ARCH_OBJ:=$(patsubst $(libm_ARCH_DIR)/%.c,$(libm_ARCH_OUT)/%.o,$(libm_ARCH_SRC)) +endif + +libm_ARCH_OBJS:=$(libm_ARCH_OBJ) + +ifeq ($(DOPIC),y) +libm-a-y+=$(libm_ARCH_OBJS:.o=.os) +else +libm-a-y+=$(libm_ARCH_OBJS) +endif +libm-so-y+=$(libm_ARCH_OBJS:.o=.os) + diff --git a/libm/kvx/feclearexcept.c b/libm/kvx/feclearexcept.c new file mode 100644 index 000000000..d886cf30e --- /dev/null +++ b/libm/kvx/feclearexcept.c @@ -0,0 +1,20 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides feclearexcept for the Coolidge processor. +*/ + +#include <fenv.h> + +int feclearexcept(int excepts) +{ + /* Mask excepts to be sure only supported flag bits are set */ + excepts &= FE_ALL_EXCEPT; + + /* Set $cs with 'excepts' as a clear mask. */ + __builtin_kvx_wfxl(KVX_SFR_CS, excepts); + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/kvx/fegetenv.c b/libm/kvx/fegetenv.c new file mode 100644 index 000000000..0f99541b2 --- /dev/null +++ b/libm/kvx/fegetenv.c @@ -0,0 +1,21 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides fegetenv for the Coolidge processor. +*/ + +#include <fenv.h> + +int fegetenv(fenv_t *envp) +{ + /* Get the current environment ($cs) */ + fenv_t fe; + fe = __builtin_kvx_get(KVX_SFR_CS); + + /* Mask $cs status to keep exception flags and rounding mode only. */ + *envp = (fe & (FE_ALL_EXCEPT | FE_RND_MASK)); + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/kvx/fegetexceptflag.c b/libm/kvx/fegetexceptflag.c new file mode 100644 index 000000000..72738ec09 --- /dev/null +++ b/libm/kvx/fegetexceptflag.c @@ -0,0 +1,24 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides fegetexceptflag for the Coolidge processor. +*/ + +#include <fenv.h> + +int fegetexceptflag(fexcept_t *flagp, int excepts) +{ + /* Mask excepts to be sure only supported flag bits are set */ + excepts &= FE_ALL_EXCEPT; + + /* Get the current exception flags of the $cs register. */ + fexcept_t flags; + flags = __builtin_kvx_get(KVX_SFR_CS); + + /* Return the requested flags in flagp */ + *flagp = flags & excepts; + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/kvx/fegetround.c b/libm/kvx/fegetround.c new file mode 100644 index 000000000..05e872506 --- /dev/null +++ b/libm/kvx/fegetround.c @@ -0,0 +1,16 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides fegetround for the Coolidge processor. +*/ + +#include <fenv.h> + +int fegetround(void) +{ + /* Get all $cs flags (exception flags and rounding mode) */ + fenv_t rm; + rm = __builtin_kvx_get(KVX_SFR_CS); + + /* Return the rounding mode */ + return rm & FE_RND_MASK; +} diff --git a/libm/kvx/feholdexcept.c b/libm/kvx/feholdexcept.c new file mode 100644 index 000000000..e9dfc1862 --- /dev/null +++ b/libm/kvx/feholdexcept.c @@ -0,0 +1,26 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides feholdexcept for the Coolidge processor. +*/ + +#include <fenv.h> + +int feholdexcept(fenv_t *envp) +{ + /* Get the current environment ($cs) */ + fenv_t fe; + fe = __builtin_kvx_get(KVX_SFR_CS); + + /* Mask $cs status to keep exception flags and rounding mode only. */ + *envp = (fe & (FE_ALL_EXCEPT | FE_RND_MASK)); + + /* Set $cs with 'FE_ALL_EXCEPT' as a clear mask. */ + __builtin_kvx_wfxl(KVX_SFR_CS, FE_ALL_EXCEPT); + + /* KVX does not raise FP traps so it is always in a "non-stop" mode */ + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/kvx/feraiseexcept.c b/libm/kvx/feraiseexcept.c new file mode 100644 index 000000000..156bf66cf --- /dev/null +++ b/libm/kvx/feraiseexcept.c @@ -0,0 +1,24 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides feraiseexcept for the Coolidge processor. +*/ + +#include <fenv.h> + +int feraiseexcept(int excepts) +{ + /* Mask excepts to be sure only supported flag bits are set */ + excepts &= FE_ALL_EXCEPT; + + /* Set $cs with 'excepts' as a set mask. */ + __builtin_kvx_wfxl(KVX_SFR_CS, (long long)excepts << 32); + + /* C99 requirements are met. The flags are raised at the same time + so order is preserved. FE_INEXACT is not raised if one of the + exceptions is FE_OVERFLOW or FE_UNDERFLOW. */ + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/kvx/fesetenv.c b/libm/kvx/fesetenv.c new file mode 100644 index 000000000..0a85f1128 --- /dev/null +++ b/libm/kvx/fesetenv.c @@ -0,0 +1,23 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides fesetenv for the Coolidge processor. +*/ + +#include <fenv.h> + +int fesetenv(const fenv_t *envp) +{ + /* Mask *envp to be sure only valid bits are set */ + fenv_t fe = *envp; + fe &= (FE_ALL_EXCEPT|FE_RND_MASK); + + /* Set exception flags and rounding mode bit-fields of $cs, with + 'fe' as a set mask and FE_ALL_EXCEPT|FE_RND_MASK as a clear + mask. */ + __builtin_kvx_wfxl(KVX_SFR_CS, ((long long)fe << 32) | FE_ALL_EXCEPT | FE_RND_MASK); + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/kvx/fesetexceptflag.c b/libm/kvx/fesetexceptflag.c new file mode 100644 index 000000000..49180dc87 --- /dev/null +++ b/libm/kvx/fesetexceptflag.c @@ -0,0 +1,24 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides fesetexceptflag for the Coolidge processor. +*/ + +#include <fenv.h> + +int fesetexceptflag(const fexcept_t *flagp, int excepts) +{ + /* Mask excepts to be sure only supported flag bits are set */ + excepts &= FE_ALL_EXCEPT; + + /* Set the requested flags */ + fexcept_t flags = (*flagp & excepts); + + /* Set $cs with 'flags' as a set mask and FE_ALL_EXCEPT as a clear + mask. */ + __builtin_kvx_wfxl(KVX_SFR_CS, (long long)flags << 32 | FE_ALL_EXCEPT); + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/kvx/fesetround.c b/libm/kvx/fesetround.c new file mode 100644 index 000000000..c1a24458e --- /dev/null +++ b/libm/kvx/fesetround.c @@ -0,0 +1,21 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides fesetround for the Coolidge processor. +*/ + +#include <fenv.h> + +int fesetround(int rounding_mode) +{ + /* Mask round to be sure only valid rounding bits are set */ + rounding_mode &= FE_RND_MASK; + + /* Set rounding mode bit-fields of $cs, with 'rounding_mode' as a + set mask and FE_RND_MASK as a clear mask. */ + __builtin_kvx_wfxl(KVX_SFR_CS, ((long long)rounding_mode << 32) | FE_RND_MASK); + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/kvx/fetestexcept.c b/libm/kvx/fetestexcept.c new file mode 100644 index 000000000..b8ed8f0e6 --- /dev/null +++ b/libm/kvx/fetestexcept.c @@ -0,0 +1,21 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides fesetexcept for the Coolidge processor. +*/ + +#include <fenv.h> + +int fetestexcept(int excepts) +{ + /* Mask excepts to be sure only supported flag bits are set */ + excepts &= FE_ALL_EXCEPT; + + /* Get the current exception flags of the $cs register. */ + fexcept_t flags; + flags = __builtin_kvx_get(KVX_SFR_CS); + + /* Return the floating-point exception macros that are both included + in excepts and correspond to the floating-point exceptions + currently set. */ + return (flags & excepts); +} diff --git a/libm/kvx/feupdateenv.c b/libm/kvx/feupdateenv.c new file mode 100644 index 000000000..f64510308 --- /dev/null +++ b/libm/kvx/feupdateenv.c @@ -0,0 +1,24 @@ +/* + (C) Copyright 2019 Kalray S.A. + This file provides feupdateenv for the Coolidge processor. +*/ + +#include <fenv.h> + +int feupdateenv(const fenv_t *envp) +{ + /* Mask *envp to be sure only valid bits are set */ + fenv_t fe = *envp; + fe &= (FE_ALL_EXCEPT|FE_RND_MASK); + + /* Update exception flags and rounding mode bit-fields of $cs, with + 'fe' as a set mask and FE_RND_MASK as a clear mask. FE_ALL_EXCEPT + is not cleared: restores rounding mode and updates exception + flags. */ + __builtin_kvx_wfxl(KVX_SFR_CS, ((long long)fe << 32) | FE_RND_MASK); + + /* The above insn cannot fail (while the OS allows access to the + floating-point exception flags of the $cs register). Return + success. */ + return 0; +} diff --git a/libm/s_lrint.c b/libm/s_lrint.c index 09800d8de..2a8db9fbe 100644 --- a/libm/s_lrint.c +++ b/libm/s_lrint.c @@ -49,19 +49,13 @@ lrint (double x) if (_j0 < 20) { - if (_j0 < -1) - return 0; - else - { - w = two52[sx] + x; - t = w - two52[sx]; - EXTRACT_WORDS (i0, i1, t); - _j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; - i0 &= 0xfffff; - i0 |= 0x100000; - - result = i0 >> (20 - _j0); - } + w = two52[sx] + x; + t = w - two52[sx]; + EXTRACT_WORDS (i0, i1, t); + _j0 = ((i0 >> 20) & 0x7ff) - 0x3ff; + i0 &= 0xfffff; + i0 |= 0x100000; + result = (_j0 < 0 ? 0 : i0 >> (20 - _j0)); } else if (_j0 < (int32_t) (8 * sizeof (long int)) - 1) { diff --git a/libm/s_nextafter.c b/libm/s_nextafter.c index 73a8ab2be..7eb4ec46e 100644 --- a/libm/s_nextafter.c +++ b/libm/s_nextafter.c @@ -18,6 +18,7 @@ #include "math.h" #include "math_private.h" +#include <float.h> double nextafter(double x, double y) { @@ -68,5 +69,13 @@ double nextafter(double x, double y) return x; } libm_hidden_def(nextafter) +#if LDBL_MANT_DIG == DBL_MANT_DIG strong_alias_untyped(nextafter, nexttoward) libm_hidden_def(nexttoward) +#else +double nexttoward(double x, long double y) +{ + return nextafter(x, y); +} +libm_hidden_def(nexttoward) +#endif diff --git a/libm/w_j0f.c b/libm/w_j0f.c index 89821bc98..496e098cd 100644 --- a/libm/w_j0f.c +++ b/libm/w_j0f.c @@ -63,6 +63,6 @@ y0f (float x) return __kernel_standard_f (x, x, 135); } # endif /* __UCLIBC_HAS_FENV__ */ - return (float) __ieee754_y0f ((double) x); + return (float) __ieee754_y0 ((double) x); } #endif /* __DO_XSI_MATH__ */ |