diff options
Diffstat (limited to 'sysdeps/or1k')
-rw-r--r-- | sysdeps/or1k/fpu/fclrexcpt.c | 44 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fegetenv.c | 32 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fegetmode.c | 29 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fegetround.c | 29 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/feholdexcpt.c | 33 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fenv_private.h | 199 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fesetenv.c | 32 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fesetexcept.c | 35 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fesetmode.c | 39 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fesetround.c | 39 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/feupdateenv.c | 33 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fgetexcptflg.c | 29 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fix-fp-int-convert-overflow.h | 38 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fraiseexcpt.c | 67 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/fsetexcptflg.c | 43 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/ftestexcept.c | 27 | ||||
-rw-r--r-- | sysdeps/or1k/fpu/get-rounding-mode.h | 38 | ||||
-rw-r--r-- | sysdeps/or1k/fpu_control.h | 89 | ||||
-rw-r--r-- | sysdeps/or1k/math-tests-snan-payload.h | 26 | ||||
-rw-r--r-- | sysdeps/or1k/math-tests-trap.h | 27 | ||||
-rw-r--r-- | sysdeps/or1k/sfp-machine.h | 17 |
21 files changed, 945 insertions, 0 deletions
diff --git a/sysdeps/or1k/fpu/fclrexcpt.c b/sysdeps/or1k/fpu/fclrexcpt.c new file mode 100644 index 0000000..44224f9 --- /dev/null +++ b/sysdeps/or1k/fpu/fclrexcpt.c @@ -0,0 +1,44 @@ +/* Clear given exceptions in current floating-point environment. + OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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; +} +libm_hidden_def (feclearexcept) diff --git a/sysdeps/or1k/fpu/fegetenv.c b/sysdeps/or1k/fpu/fegetenv.c new file mode 100644 index 0000000..70c75aa --- /dev/null +++ b/sysdeps/or1k/fpu/fegetenv.c @@ -0,0 +1,32 @@ +/* Store current floating-point environment. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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; +} +libm_hidden_def (__fegetenv) +weak_alias (__fegetenv, fegetenv) +libm_hidden_weak (fegetenv) diff --git a/sysdeps/or1k/fpu/fegetmode.c b/sysdeps/or1k/fpu/fegetmode.c new file mode 100644 index 0000000..7fffd2e --- /dev/null +++ b/sysdeps/or1k/fpu/fegetmode.c @@ -0,0 +1,29 @@ +/* Store current floating-point control modes. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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/sysdeps/or1k/fpu/fegetround.c b/sysdeps/or1k/fpu/fegetround.c new file mode 100644 index 0000000..7e993b9 --- /dev/null +++ b/sysdeps/or1k/fpu/fegetround.c @@ -0,0 +1,29 @@ +/* Return current rounding direction. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 (); +} +libm_hidden_def (__fegetround) +weak_alias (__fegetround, fegetround) +libm_hidden_weak (fegetround) diff --git a/sysdeps/or1k/fpu/feholdexcpt.c b/sysdeps/or1k/fpu/feholdexcpt.c new file mode 100644 index 0000000..0036e41 --- /dev/null +++ b/sysdeps/or1k/fpu/feholdexcpt.c @@ -0,0 +1,33 @@ +/* Store current floating-point environment and clear exceptions. + OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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; +} +libm_hidden_def (__feholdexcept) +weak_alias (__feholdexcept, feholdexcept) +libm_hidden_weak (feholdexcept) diff --git a/sysdeps/or1k/fpu/fenv_private.h b/sysdeps/or1k/fpu/fenv_private.h new file mode 100644 index 0000000..4f401e7 --- /dev/null +++ b/sysdeps/or1k/fpu/fenv_private.h @@ -0,0 +1,199 @@ +/* Private floating point rounding and exceptions handling. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 (__glibc_unlikely (cw != cw_new)) + _FPU_SETCW (cw_new); + + /* Raise the exceptions if enabled in the new FP state. */ + if (__glibc_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 (__glibc_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 (__glibc_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 + +#include_next <fenv_private.h> + +#endif diff --git a/sysdeps/or1k/fpu/fesetenv.c b/sysdeps/or1k/fpu/fesetenv.c new file mode 100644 index 0000000..742ca71 --- /dev/null +++ b/sysdeps/or1k/fpu/fesetenv.c @@ -0,0 +1,32 @@ +/* Install given floating-point environment. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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; +} +libm_hidden_def (__fesetenv) +weak_alias (__fesetenv, fesetenv) +libm_hidden_weak (fesetenv) diff --git a/sysdeps/or1k/fpu/fesetexcept.c b/sysdeps/or1k/fpu/fesetexcept.c new file mode 100644 index 0000000..43734ea --- /dev/null +++ b/sysdeps/or1k/fpu/fesetexcept.c @@ -0,0 +1,35 @@ +/* Set given exception flags. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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/sysdeps/or1k/fpu/fesetmode.c b/sysdeps/or1k/fpu/fesetmode.c new file mode 100644 index 0000000..d455692 --- /dev/null +++ b/sysdeps/or1k/fpu/fesetmode.c @@ -0,0 +1,39 @@ +/* Install given floating-point control modes. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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/sysdeps/or1k/fpu/fesetround.c b/sysdeps/or1k/fpu/fesetround.c new file mode 100644 index 0000000..c2ada98 --- /dev/null +++ b/sysdeps/or1k/fpu/fesetround.c @@ -0,0 +1,39 @@ +/* Set current rounding direction. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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. */ + } +} +libm_hidden_def (__fesetround) +weak_alias (__fesetround, fesetround) +libm_hidden_weak (fesetround) diff --git a/sysdeps/or1k/fpu/feupdateenv.c b/sysdeps/or1k/fpu/feupdateenv.c new file mode 100644 index 0000000..3355bf6 --- /dev/null +++ b/sysdeps/or1k/fpu/feupdateenv.c @@ -0,0 +1,33 @@ +/* Install given floating-point environment and raise exceptions. + OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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; +} +libm_hidden_def (__feupdateenv) +weak_alias (__feupdateenv, feupdateenv) +libm_hidden_weak (feupdateenv) diff --git a/sysdeps/or1k/fpu/fgetexcptflg.c b/sysdeps/or1k/fpu/fgetexcptflg.c new file mode 100644 index 0000000..a954f6a --- /dev/null +++ b/sysdeps/or1k/fpu/fgetexcptflg.c @@ -0,0 +1,29 @@ +/* Store current state of exceptions. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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/sysdeps/or1k/fpu/fix-fp-int-convert-overflow.h b/sysdeps/or1k/fpu/fix-fp-int-convert-overflow.h new file mode 100644 index 0000000..7810428 --- /dev/null +++ b/sysdeps/or1k/fpu/fix-fp-int-convert-overflow.h @@ -0,0 +1,38 @@ +/* Fix for conversion of floating point to integer overflow. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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 FIX_FP_INT_CONVERT_OVERFLOW_H +#define FIX_FP_INT_CONVERT_OVERFLOW_H 1 + +/* The generic libgcc2.c conversions from floating point to long long + may not raise the correct exceptions on overflow (and may raise + spurious "inexact" exceptions even in non-overflow cases, see + <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59412>). */ +#define FIX_FLT_LONG_CONVERT_OVERFLOW 0 +#define FIX_FLT_LLONG_CONVERT_OVERFLOW 1 + +#define FIX_DBL_LONG_CONVERT_OVERFLOW 0 +#define FIX_DBL_LLONG_CONVERT_OVERFLOW 1 + +#define FIX_LDBL_LONG_CONVERT_OVERFLOW 0 +#define FIX_LDBL_LLONG_CONVERT_OVERFLOW 0 + +#define FIX_FLT128_LONG_CONVERT_OVERFLOW 0 +#define FIX_FLT128_LLONG_CONVERT_OVERFLOW 0 + +#endif /* fix-fp-int-convert-overflow.h */ diff --git a/sysdeps/or1k/fpu/fraiseexcpt.c b/sysdeps/or1k/fpu/fraiseexcpt.c new file mode 100644 index 0000000..bbacfd5 --- /dev/null +++ b/sysdeps/or1k/fpu/fraiseexcpt.c @@ -0,0 +1,67 @@ +/* Raise given exceptions. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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; +} +libm_hidden_def (__feraiseexcept) +weak_alias (__feraiseexcept, feraiseexcept) +libm_hidden_weak (feraiseexcept) diff --git a/sysdeps/or1k/fpu/fsetexcptflg.c b/sysdeps/or1k/fpu/fsetexcptflg.c new file mode 100644 index 0000000..c327e4c --- /dev/null +++ b/sysdeps/or1k/fpu/fsetexcptflg.c @@ -0,0 +1,43 @@ +/* Set floating-point environment exception handling. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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/sysdeps/or1k/fpu/ftestexcept.c b/sysdeps/or1k/fpu/ftestexcept.c new file mode 100644 index 0000000..59f06af --- /dev/null +++ b/sysdeps/or1k/fpu/ftestexcept.c @@ -0,0 +1,27 @@ +/* Test exception in current environment. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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); +} +libm_hidden_def (fetestexcept) diff --git a/sysdeps/or1k/fpu/get-rounding-mode.h b/sysdeps/or1k/fpu/get-rounding-mode.h new file mode 100644 index 0000000..a66d553 --- /dev/null +++ b/sysdeps/or1k/fpu/get-rounding-mode.h @@ -0,0 +1,38 @@ +/* Determine floating-point rounding mode within libc. OpenRISC version. + + Copyright (C) 2024 Free Software Foundation, Inc. + + This file is part of the GNU C Library. + + 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 */ diff --git a/sysdeps/or1k/fpu_control.h b/sysdeps/or1k/fpu_control.h new file mode 100644 index 0000000..f89364a --- /dev/null +++ b/sysdeps/or1k/fpu_control.h @@ -0,0 +1,89 @@ +/* FPU control word bits. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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/sysdeps/or1k/math-tests-snan-payload.h b/sysdeps/or1k/math-tests-snan-payload.h new file mode 100644 index 0000000..62467a3 --- /dev/null +++ b/sysdeps/or1k/math-tests-snan-payload.h @@ -0,0 +1,26 @@ +/* Configuration for math tests: sNaN payloads. OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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_MATH_TESTS_SNAN_PAYLOAD_H +#define OR1K_MATH_TESTS_SNAN_PAYLOAD_H 1 + +/* OpenRISC floating-point instructions do not preserve NaN + payloads. */ +#define SNAN_TESTS_PRESERVE_PAYLOAD 0 + +#endif /* math-tests-snan-payload.h */ diff --git a/sysdeps/or1k/math-tests-trap.h b/sysdeps/or1k/math-tests-trap.h new file mode 100644 index 0000000..a95b42d --- /dev/null +++ b/sysdeps/or1k/math-tests-trap.h @@ -0,0 +1,27 @@ +/* Configuration for math tests: support for enabling exception traps. + OpenRISC version. + Copyright (C) 2024 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + 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_MATH_TESTS_TRAP_H +#define OR1K_MATH_TESTS_TRAP_H 1 + +#include <fenv.h> + +#define EXCEPTION_ENABLE_SUPPORTED(EXCEPT) ((EXCEPT) == 0) + +#endif /* math-tests-trap.h */ diff --git a/sysdeps/or1k/sfp-machine.h b/sysdeps/or1k/sfp-machine.h index d17fd37..70aa421 100644 --- a/sysdeps/or1k/sfp-machine.h +++ b/sysdeps/or1k/sfp-machine.h @@ -90,4 +90,21 @@ #define FP_ROUNDMODE (_fpcsr & FP_RND_MASK) +#ifdef __or1k_hard_float__ +#define FP_INIT_ROUNDMODE \ +do { \ + __asm__ volatile ("l.mfspr %0,r0,20" : "=r" (_fpcsr)); \ +} while (0) + +#define FP_HANDLE_EXCEPTIONS \ +do { \ + if (__builtin_expect (_fex, 0)) \ + { \ + _fpcsr &= ~FP_EX_ALL; \ + _fpcsr |= _fex; \ + __asm__ volatile ("l.mtspr r0,%0,20" : : "r" (_fpcsr)); \ + } \ +} while (0) +#endif /* __or1k_hard_float__ */ + #define _FP_TININESS_AFTER_ROUNDING 0 |