diff options
| -rw-r--r-- | extra/Configs/Config.in.arch | 1 | ||||
| -rw-r--r-- | libc/sysdeps/linux/or1k/bits/fenv.h | 84 | ||||
| -rw-r--r-- | libc/sysdeps/linux/or1k/fpu_control.h | 88 | ||||
| -rw-r--r-- | libm/or1k/Makefile.arch | 16 | ||||
| -rw-r--r-- | libm/or1k/fclrexcpt.c | 42 | ||||
| -rw-r--r-- | libm/or1k/fegetenv.c | 28 | ||||
| -rw-r--r-- | libm/or1k/fegetmode.c | 28 | ||||
| -rw-r--r-- | libm/or1k/fegetround.c | 25 | ||||
| -rw-r--r-- | libm/or1k/feholdexcpt.c | 29 | ||||
| -rw-r--r-- | libm/or1k/fenv_private.h | 196 | ||||
| -rw-r--r-- | libm/or1k/fesetenv.c | 28 | ||||
| -rw-r--r-- | libm/or1k/fesetexcept.c | 34 | ||||
| -rw-r--r-- | libm/or1k/fesetmode.c | 38 | ||||
| -rw-r--r-- | libm/or1k/fesetround.c | 35 | ||||
| -rw-r--r-- | libm/or1k/feupdateenv.c | 29 | ||||
| -rw-r--r-- | libm/or1k/fgetexcptflg.c | 28 | ||||
| -rw-r--r-- | libm/or1k/fraiseexcpt.c | 63 | ||||
| -rw-r--r-- | libm/or1k/fsetexcptflg.c | 42 | ||||
| -rw-r--r-- | libm/or1k/ftestexcept.c | 25 | ||||
| -rw-r--r-- | libm/or1k/get-rounding-mode.h | 36 | 
20 files changed, 895 insertions, 0 deletions
| diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch index 1ea42e6d1..cacac7e5e 100644 --- a/extra/Configs/Config.in.arch +++ b/extra/Configs/Config.in.arch @@ -170,6 +170,7 @@ config UCLIBC_HAS_FENV  		   TARGET_metag || \  		   TARGET_mips || \  		   TARGET_nds32 || \ +		   TARGET_or1k || \  		   (TARGET_powerpc && CONFIG_E500) || \  		   TARGET_riscv32 || \  		   TARGET_riscv64 || \ diff --git a/libc/sysdeps/linux/or1k/bits/fenv.h b/libc/sysdeps/linux/or1k/bits/fenv.h new file mode 100644 index 000000000..4701946ff --- /dev/null +++ b/libc/sysdeps/linux/or1k/bits/fenv.h @@ -0,0 +1,84 @@ +/* Floating point environment, OpenRISC version. +   Copyright (C) 2022-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + +#ifdef __or1k_hard_float__ +/* Define bits representing exceptions in the FPCSR status word.  */ +enum +  { +    FE_OVERFLOW = +#define FE_OVERFLOW	(1 << 3) +      FE_OVERFLOW, +    FE_UNDERFLOW = +#define FE_UNDERFLOW	(1 << 4) +      FE_UNDERFLOW, +    FE_INEXACT = +#define FE_INEXACT	(1 << 8) +      FE_INEXACT, +    FE_INVALID = +#define FE_INVALID	(1 << 9) +      FE_INVALID, +    FE_DIVBYZERO = +#define FE_DIVBYZERO	(1 << 11) +      FE_DIVBYZERO, +  }; + +/* All supported exceptions.  */ +#define FE_ALL_EXCEPT	\ +	(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +/* Define bits representing rounding modes in the FPCSR Rmode field.  */ +#define FE_TONEAREST  (0x0 << 1) +#define FE_TOWARDZERO (0x1 << 1) +#define FE_UPWARD     (0x2 << 1) +#define FE_DOWNWARD   (0x3 << 1) + +#else + +/* In the soft-float case only rounding to nearest is supported, with +   no exceptions.  */ + +enum +  { +    __FE_UNDEFINED = -1, + +    FE_TONEAREST = +# define FE_TONEAREST	0x0 +      FE_TONEAREST +  }; + +# define FE_ALL_EXCEPT 0 + +#endif /* __or1k_hard_float__ */ + +/* Type representing exception flags.  */ +typedef unsigned int fexcept_t; + +/* Type representing floating-point environment.  */ +typedef unsigned int fenv_t; + +/* If the default argument is used we use this value.  */ +#define FE_DFL_ENV	((const fenv_t *) -1l) + +/* Type representing floating-point control modes.  */ +typedef unsigned int femode_t; + +/* Default floating-point control modes.  */ +# define FE_DFL_MODE	((const femode_t *) -1L) diff --git a/libc/sysdeps/linux/or1k/fpu_control.h b/libc/sysdeps/linux/or1k/fpu_control.h new file mode 100644 index 000000000..9abde4f42 --- /dev/null +++ b/libc/sysdeps/linux/or1k/fpu_control.h @@ -0,0 +1,88 @@ +/* FPU control word bits.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +#ifndef __or1k_hard_float__ + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT  0x00000000 +# define _FPU_GETCW(cw) (cw) = 0 +# define _FPU_SETCW(cw) (void) (cw) + +#else /* __or1k_hard_float__ */ + +/* Layout of FPCSR: + +   The bits of the FPCSR are defined as follows, this should help +   explain how the masks below have come to be. + +   +-----------+----------------------------+-----+----+ +   |  32 - 12  | 11 10  9  8  7  6  5  4  3 | 2-1 |  0 | +   +-----------+----------------------------+-----+----+ +   |  Reserved | DZ IN IV IX  Z QN SN UN OV | RM  | EE | +   +-----------+----------------------------+-----+----+ + +   Exception flags: + +     DZ - divide by zero flag. +     IN - infinite flag. +     IV - invalid flag. +     IX - inexact flag. +      Z - zero flag. +     QN - qnan flag. +     SN - snan flag. +     UN - underflow flag. +     OV - overflow flag. + +   Rounding modes: + +   The FPCSR bits 2-1 labeled above as RM specify the rounding mode. + +     00 - round to nearest +     01 - round to zero +     10 - round to positive infinity +     11 - round to negative infinity + +   Enabling exceptions: + +     EE - set to enable FPU exceptions. + + */ + +# define _FPU_RESERVED 0xfffff000 +/* Default: rounding to nearest with exceptions disabled.  */ +# define _FPU_DEFAULT  0 +/* IEEE: Same as above with exceptions enabled.  */ +# define _FPU_IEEE     (_FPU_DEFAULT | 1) + +# define _FPU_FPCSR_RM_MASK (0x3 << 1) + +/* Macros for accessing the hardware control word.  */ +# define _FPU_GETCW(cw) __asm__ volatile ("l.mfspr %0,r0,20" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("l.mtspr r0,%0,20" : : "r" (cw)) + +#endif /* __or1k_hard_float__ */ + +/* Type of the control word.  */ +typedef unsigned int fpu_control_t; + +/* Default control word set at startup.  */ +extern fpu_control_t __fpu_control; + +#endif	/* fpu_control.h */ diff --git a/libm/or1k/Makefile.arch b/libm/or1k/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/or1k/Makefile.arch @@ -0,0 +1,16 @@ +# Makefile for uClibc-ng +# Licensed under the LGPL v2.1 or later, 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/or1k/fclrexcpt.c b/libm/or1k/fclrexcpt.c new file mode 100644 index 000000000..ecb327d72 --- /dev/null +++ b/libm/or1k/fclrexcpt.c @@ -0,0 +1,42 @@ +/* Clear given exceptions in current floating-point environment. +   OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include <fpu_control.h> + +int +feclearexcept (int excepts) +{ +  fpu_control_t cw; +  fpu_control_t cw_new; + +  /* Mask out unsupported bits/exceptions.  */ +  excepts &= FE_ALL_EXCEPT; + +  /* Read the complete control word.  */ +  _FPU_GETCW (cw); + +  cw_new = cw & ~excepts; + +  /* Put the new data in effect.  */ +  if (cw != cw_new) +    _FPU_SETCW (cw_new); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fegetenv.c b/libm/or1k/fegetenv.c new file mode 100644 index 000000000..7769d456f --- /dev/null +++ b/libm/or1k/fegetenv.c @@ -0,0 +1,28 @@ +/* Store current floating-point environment. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetenv (fenv_t *envp) +{ +  _FPU_GETCW (*envp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fegetmode.c b/libm/or1k/fegetmode.c new file mode 100644 index 000000000..40a789329 --- /dev/null +++ b/libm/or1k/fegetmode.c @@ -0,0 +1,28 @@ +/* Store current floating-point control modes.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fegetmode (femode_t *modep) +{ +  _FPU_GETCW (*modep); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fegetround.c b/libm/or1k/fegetround.c new file mode 100644 index 000000000..0965de2f9 --- /dev/null +++ b/libm/or1k/fegetround.c @@ -0,0 +1,25 @@ +/* Return current rounding direction.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "get-rounding-mode.h" + +int +fegetround (void) +{ +  return get_rounding_mode (); +} diff --git a/libm/or1k/feholdexcpt.c b/libm/or1k/feholdexcpt.c new file mode 100644 index 000000000..cff06f3d0 --- /dev/null +++ b/libm/or1k/feholdexcpt.c @@ -0,0 +1,29 @@ +/* Store current floating-point environment and clear exceptions. +   OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +feholdexcept (fenv_t *envp) +{ +  libc_feholdexcept_or1k (envp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fenv_private.h b/libm/or1k/fenv_private.h new file mode 100644 index 000000000..ede7d243a --- /dev/null +++ b/libm/or1k/fenv_private.h @@ -0,0 +1,196 @@ +/* Private floating point rounding and exceptions handling.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#ifndef OR1K_FENV_PRIVATE_H +#define OR1K_FENV_PRIVATE_H 1 + +#include <fenv.h> +#include <fpu_control.h> + +static __always_inline void +libc_feholdexcept_or1k (fenv_t *envp) +{ +  fpu_control_t cw; +  fpu_control_t cw_new; + +  /* Get and store the environment.  */ +  _FPU_GETCW (cw); +  *envp = cw; + +  /* Clear the exception status flags.  */ +  cw_new = cw & ~FE_ALL_EXCEPT; + +  if (cw != cw_new) +    _FPU_SETCW (cw_new); +} + +#define libc_feholdexcept  libc_feholdexcept_or1k +#define libc_feholdexceptf libc_feholdexcept_or1k +#define libc_feholdexceptl libc_feholdexcept_or1k + +static __always_inline void +libc_fesetround_or1k (int round) +{ +  fpu_control_t cw; +  fpu_control_t cw_new; + +  _FPU_GETCW (cw); +  cw_new = cw & ~_FPU_FPCSR_RM_MASK; +  cw_new |= round; +  if (cw != cw_new) +    _FPU_SETCW (cw_new); +} + +#define libc_fesetround  libc_fesetround_or1k +#define libc_fesetroundf libc_fesetround_or1k +#define libc_fesetroundl libc_fesetround_or1k + +static __always_inline void +libc_feholdexcept_setround_or1k (fenv_t *envp, int round) +{ +  fpu_control_t cw; +  fpu_control_t cw_new; + +  /* Get and store the environment.  */ +  _FPU_GETCW (cw); +  *envp = cw; + +  /* Clear the status flags and rounding mode.  */ +  cw_new = cw & ~(FE_ALL_EXCEPT | _FPU_FPCSR_RM_MASK); + +  /* Set rounding mode.  */ +  cw_new |= round; + +  if (cw != cw_new) +    _FPU_SETCW (cw_new); +} + +#define libc_feholdexcept_setround  libc_feholdexcept_setround_or1k +#define libc_feholdexcept_setroundf libc_feholdexcept_setround_or1k +#define libc_feholdexcept_setroundl libc_feholdexcept_setround_or1k + +static __always_inline int +libc_fetestexcept_or1k (int ex) +{ +  fpu_control_t cw; + +  /* Get current control word.  */ +  _FPU_GETCW (cw); + +  /* Check if any of the queried exception flags are set.  */ +  return cw & ex & FE_ALL_EXCEPT; +} + +#define libc_fetestexcept  libc_fetestexcept_or1k +#define libc_fetestexceptf libc_fetestexcept_or1k +#define libc_fetestexceptl libc_fetestexcept_or1k + +static __always_inline void +libc_fesetenv_or1k (const fenv_t *envp) +{ +  if (envp == FE_DFL_ENV) +    _FPU_SETCW (_FPU_DEFAULT); +  else +    _FPU_SETCW (*envp); +} + +#define libc_fesetenv  libc_fesetenv_or1k +#define libc_fesetenvf libc_fesetenv_or1k +#define libc_fesetenvl libc_fesetenv_or1k +#define libc_feresetround_noex  libc_fesetenv_or1k +#define libc_feresetround_noexf libc_fesetenv_or1k +#define libc_feresetround_noexl libc_fesetenv_or1k + +static __always_inline int +libc_feupdateenv_test_or1k (const fenv_t *envp, int ex) +{ +  fpu_control_t cw; +  fpu_control_t cw_new; +  int excepts; + +  /* Get current control word.  */ +  _FPU_GETCW (cw); + +  /* Merge current exception flags with the passed fenv.  */ +  excepts = cw & FE_ALL_EXCEPT; +  cw_new = (envp == FE_DFL_ENV ? _FPU_DEFAULT : *envp) | excepts; + +  if (unlikely (cw != cw_new)) +    _FPU_SETCW (cw_new); + +  /* Raise the exceptions if enabled in the new FP state.  */ +  if (unlikely (excepts)) +    feraiseexcept (excepts); + +  return excepts & ex; +} + +#define libc_feupdateenv_test  libc_feupdateenv_test_or1k +#define libc_feupdateenv_testf libc_feupdateenv_test_or1k +#define libc_feupdateenv_testl libc_feupdateenv_test_or1k + +static __always_inline void +libc_feupdateenv_or1k (const fenv_t *envp) +{ +  libc_feupdateenv_test_or1k (envp, 0); +} + +#define libc_feupdateenv  libc_feupdateenv_or1k +#define libc_feupdateenvf libc_feupdateenv_or1k +#define libc_feupdateenvl libc_feupdateenv_or1k + +static __always_inline void +libc_feholdsetround_or1k (fenv_t *envp, int round) +{ +  fpu_control_t cw; + +  _FPU_GETCW (cw); +  *envp = cw; + +  /* Check whether rounding modes are different.  */ +  round = (cw ^ round) & _FPU_FPCSR_RM_MASK; + +  /* Set new rounding mode if different.  */ +  if (unlikely (round != 0)) +    _FPU_SETCW (cw ^ round); +} + +#define libc_feholdsetround  libc_feholdsetround_or1k +#define libc_feholdsetroundf libc_feholdsetround_or1k +#define libc_feholdsetroundl libc_feholdsetround_or1k + +static __always_inline void +libc_feresetround_or1k (fenv_t *envp) +{ +  fpu_control_t cw; +  int round; + +  _FPU_GETCW (cw); + +  /* Check whether rounding modes are different.  */ +  round = (*envp ^ cw) & _FPU_FPCSR_RM_MASK; + +  /* Restore the rounding mode if it was changed.  */ +  if (unlikely (round != 0)) +    _FPU_SETCW (cw ^ round); +} + +#define libc_feresetround  libc_feresetround_or1k +#define libc_feresetroundf libc_feresetround_or1k +#define libc_feresetroundl libc_feresetround_or1k + +#endif diff --git a/libm/or1k/fesetenv.c b/libm/or1k/fesetenv.c new file mode 100644 index 000000000..a9c8448f4 --- /dev/null +++ b/libm/or1k/fesetenv.c @@ -0,0 +1,28 @@ +/* Install given floating-point environment.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fesetenv (const fenv_t *envp) +{ +  libc_fesetenv_or1k (envp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fesetexcept.c b/libm/or1k/fesetexcept.c new file mode 100644 index 000000000..abc5624c3 --- /dev/null +++ b/libm/or1k/fesetexcept.c @@ -0,0 +1,34 @@ +/* Set given exception flags.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fesetexcept (int excepts) +{ +  fpu_control_t cw; +  fpu_control_t cw_new; + +  _FPU_GETCW (cw); +  cw_new = cw | (excepts & FE_ALL_EXCEPT); +  if (cw != cw_new) +    _FPU_SETCW (cw_new); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fesetmode.c b/libm/or1k/fesetmode.c new file mode 100644 index 000000000..74490621b --- /dev/null +++ b/libm/or1k/fesetmode.c @@ -0,0 +1,38 @@ +/* Install given floating-point control modes.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fesetmode (const femode_t *modep) +{ +  fpu_control_t cw; +  fpu_control_t cw_new; + +  _FPU_GETCW (cw); +  cw_new = cw & ~_FPU_FPCSR_RM_MASK; +  if (modep == FE_DFL_MODE) +    cw_new |= (_FPU_DEFAULT & _FPU_FPCSR_RM_MASK); +  else +    cw_new |= (*modep & _FPU_FPCSR_RM_MASK); +  if (cw != cw_new) +    _FPU_SETCW (cw_new); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fesetround.c b/libm/or1k/fesetround.c new file mode 100644 index 000000000..37c2db4ab --- /dev/null +++ b/libm/or1k/fesetround.c @@ -0,0 +1,35 @@ +/* Set current rounding direction.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fesetround (int round) +{ +  switch (round) +    { +    case FE_TONEAREST: +    case FE_TOWARDZERO: +    case FE_DOWNWARD: +    case FE_UPWARD: +      libc_fesetround_or1k (round); +      return 0; +    default: +      return round; /* A nonzero value.  */ +    } +} diff --git a/libm/or1k/feupdateenv.c b/libm/or1k/feupdateenv.c new file mode 100644 index 000000000..b0f42744f --- /dev/null +++ b/libm/or1k/feupdateenv.c @@ -0,0 +1,29 @@ +/* Install given floating-point environment and raise exceptions. +   OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +feupdateenv (const fenv_t *envp) +{ +  libc_feupdateenv_or1k (envp); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fgetexcptflg.c b/libm/or1k/fgetexcptflg.c new file mode 100644 index 000000000..2a725a4c7 --- /dev/null +++ b/libm/or1k/fgetexcptflg.c @@ -0,0 +1,28 @@ +/* Store current state of exceptions.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ +  *flagp = libc_fetestexcept_or1k (excepts); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fraiseexcpt.c b/libm/or1k/fraiseexcpt.c new file mode 100644 index 000000000..31ceb830d --- /dev/null +++ b/libm/or1k/fraiseexcpt.c @@ -0,0 +1,63 @@ +/* Raise given exceptions.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include <fpu_control.h> +#include <float.h> +#include <math.h> + +int +feraiseexcept (int excepts) +{ +  if (excepts == 0) +    return 0; + +  /* Raise exceptions represented by EXPECTS.  */ + +  if (excepts & FE_INEXACT) +  { +    float d = 1.0, x = 3.0; +    __asm__ volatile ("lf.div.s %0, %0, %1" : "+r" (d) : "r" (x)); +  } + +  if (excepts & FE_UNDERFLOW) +  { +    float d = FLT_MIN; +    __asm__ volatile ("lf.mul.s %0, %0, %0" : "+r" (d)); +  } + +  if (excepts & FE_OVERFLOW) +  { +    float d = FLT_MAX; +    __asm__ volatile ("lf.mul.s %0, %0, %0" : "+r" (d) : "r" (d)); +  } + +  if (excepts & FE_DIVBYZERO) +  { +    float d = 1.0, x = 0.0; +    __asm__ volatile ("lf.div.s %0, %0, %1" : "+r" (d) : "r" (x)); +  } + +  if (excepts & FE_INVALID) +  { +    float d = HUGE_VAL, x = 0.0; +    __asm__ volatile ("lf.mul.s %0, %1, %0" : "+r" (d) : "r" (x)); +  } + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/fsetexcptflg.c b/libm/or1k/fsetexcptflg.c new file mode 100644 index 000000000..01c6e8635 --- /dev/null +++ b/libm/or1k/fsetexcptflg.c @@ -0,0 +1,42 @@ +/* Set floating-point environment exception handling. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include <fpu_control.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ +  fpu_control_t cw; +  fpu_control_t cw_new; + +  /* Get the current exceptions.  */ +  _FPU_GETCW (cw); + +  /* Make sure the flags we want restored are legal.  */ +  excepts &= FE_ALL_EXCEPT; + +  /* Now set selected bits from flagp. Note that we ignore all non-flag +     bits from *flagp, so they don't matter.  */ +  cw_new = (cw & ~excepts) | (*flagp & excepts); + +  if (cw != cw_new) +    _FPU_SETCW (cw_new); + +  /* Success.  */ +  return 0; +} diff --git a/libm/or1k/ftestexcept.c b/libm/or1k/ftestexcept.c new file mode 100644 index 000000000..02ddf12c8 --- /dev/null +++ b/libm/or1k/ftestexcept.c @@ -0,0 +1,25 @@ +/* Test exception in current environment.  OpenRISC version. +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#include <fenv.h> +#include "fenv_private.h" + +int +fetestexcept (int excepts) +{ +  return libc_fetestexcept_or1k (excepts); +} diff --git a/libm/or1k/get-rounding-mode.h b/libm/or1k/get-rounding-mode.h new file mode 100644 index 000000000..f65c4ecc0 --- /dev/null +++ b/libm/or1k/get-rounding-mode.h @@ -0,0 +1,36 @@ +/* Determine floating-point rounding mode within libc.  OpenRISC version. + +   Copyright (C) 2024-2025 Free Software Foundation, Inc. + +   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 +   <https://www.gnu.org/licenses/>.  */ + +#ifndef _OR1K_GET_ROUNDING_MODE_H +#define _OR1K_GET_ROUNDING_MODE_H	1 + +#include <fenv.h> +#include <fpu_control.h> + +/* Return the floating-point rounding mode.  */ + +static inline int +get_rounding_mode (void) +{ +  fpu_control_t cw; + +  _FPU_GETCW (cw); +  return cw & _FPU_FPCSR_RM_MASK; +} + +#endif /* get-rounding-mode.h */ | 
