diff options
Diffstat (limited to 'libm')
-rw-r--r-- | libm/m68k/Makefile.arch | 16 | ||||
-rw-r--r-- | libm/m68k/fclrexcpt.c | 39 | ||||
-rw-r--r-- | libm/m68k/fedisblxcpt.c | 36 | ||||
-rw-r--r-- | libm/m68k/feenablxcpt.c | 36 | ||||
-rw-r--r-- | libm/m68k/fegetenv.c | 33 | ||||
-rw-r--r-- | libm/m68k/fegetexcept.c | 29 | ||||
-rw-r--r-- | libm/m68k/fegetmode.c | 26 | ||||
-rw-r--r-- | libm/m68k/fegetround.c | 28 | ||||
-rw-r--r-- | libm/m68k/feholdexcpt.c | 42 | ||||
-rw-r--r-- | libm/m68k/fesetenv.c | 63 | ||||
-rw-r--r-- | libm/m68k/fesetexcept.c | 30 | ||||
-rw-r--r-- | libm/m68k/fesetmode.c | 31 | ||||
-rw-r--r-- | libm/m68k/fesetround.c | 35 | ||||
-rw-r--r-- | libm/m68k/feupdateenv.c | 39 | ||||
-rw-r--r-- | libm/m68k/fgetexcptflg.c | 32 | ||||
-rw-r--r-- | libm/m68k/fraiseexcpt.c | 106 | ||||
-rw-r--r-- | libm/m68k/fsetexcptflg.c | 38 | ||||
-rw-r--r-- | libm/m68k/ftestexcept.c | 29 |
18 files changed, 688 insertions, 0 deletions
diff --git a/libm/m68k/Makefile.arch b/libm/m68k/Makefile.arch new file mode 100644 index 000000000..bd38690be --- /dev/null +++ b/libm/m68k/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/m68k/fclrexcpt.c b/libm/m68k/fclrexcpt.c new file mode 100644 index 000000000..904ba5a19 --- /dev/null +++ b/libm/m68k/fclrexcpt.c @@ -0,0 +1,39 @@ +/* Clear given exceptions in current floating-point environment. + Copyright (C) 1997-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> + +int +feclearexcept (int excepts) +{ + fexcept_t fpsr; + + /* Mask out unsupported bits/exceptions. */ + excepts &= FE_ALL_EXCEPT; + + /* Fetch the fpu status register. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + /* Clear the relevant bits. */ + fpsr &= ~excepts; + + /* Put the new data in effect. */ + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fedisblxcpt.c b/libm/m68k/fedisblxcpt.c new file mode 100644 index 000000000..c2c593e38 --- /dev/null +++ b/libm/m68k/fedisblxcpt.c @@ -0,0 +1,36 @@ +/* Disable floating-point exceptions. + Copyright (C) 2000-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> + +int +fedisableexcept (int excepts) +{ + unsigned int old_exc, new_exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (new_exc)); + + old_exc = (new_exc >> 6) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + new_exc &= ~(excepts << 6); + __asm__ ("fmove%.l %0,%!" : : "dm" (new_exc)); + + return old_exc; +} diff --git a/libm/m68k/feenablxcpt.c b/libm/m68k/feenablxcpt.c new file mode 100644 index 000000000..9c01dc28b --- /dev/null +++ b/libm/m68k/feenablxcpt.c @@ -0,0 +1,36 @@ +/* Enable floating-point exceptions. + Copyright (C) 2000-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> + +int +feenableexcept (int excepts) +{ + unsigned int new_exc, old_exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (new_exc)); + + old_exc = (new_exc >> 6) & FE_ALL_EXCEPT; + + excepts &= FE_ALL_EXCEPT; + + new_exc |= excepts << 6; + __asm__ ("fmove%.l %0,%!" : : "dm" (new_exc)); + + return old_exc; +} diff --git a/libm/m68k/fegetenv.c b/libm/m68k/fegetenv.c new file mode 100644 index 000000000..2cd0a7c88 --- /dev/null +++ b/libm/m68k/fegetenv.c @@ -0,0 +1,33 @@ +/* Store current floating-point environment. + Copyright (C) 1997-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> + +int +fegetenv (fenv_t *envp) +{ +#ifdef __mcoldfire__ + __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (envp->__control_register)); + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (envp->__status_register)); + __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (envp->__instruction_address)); +#else + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*envp)); +#endif + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fegetexcept.c b/libm/m68k/fegetexcept.c new file mode 100644 index 000000000..1be3f8bf5 --- /dev/null +++ b/libm/m68k/fegetexcept.c @@ -0,0 +1,29 @@ +/* Get enabled floating-point exceptions. + Copyright (C) 2000-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> + +int +fegetexcept (void) +{ + unsigned int exc; + + /* Get the current control register contents. */ + __asm__ ("fmove%.l %!,%0" : "=dm" (exc)); + + return (exc >> 6) & FE_ALL_EXCEPT; +} diff --git a/libm/m68k/fegetmode.c b/libm/m68k/fegetmode.c new file mode 100644 index 000000000..19f49922a --- /dev/null +++ b/libm/m68k/fegetmode.c @@ -0,0 +1,26 @@ +/* Store current floating-point control modes. M68K version. + Copyright (C) 2016-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); + return 0; +} diff --git a/libm/m68k/fegetround.c b/libm/m68k/fegetround.c new file mode 100644 index 000000000..02f6c4c41 --- /dev/null +++ b/libm/m68k/fegetround.c @@ -0,0 +1,28 @@ +/* Return current rounding direction. + Copyright (C) 1997-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> + +int +fegetround (void) +{ + int fpcr; + + __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr)); + + return fpcr & FE_UPWARD; +} diff --git a/libm/m68k/feholdexcpt.c b/libm/m68k/feholdexcpt.c new file mode 100644 index 000000000..c0891969a --- /dev/null +++ b/libm/m68k/feholdexcpt.c @@ -0,0 +1,42 @@ +/* Store current floating-point environment and clear exceptions. + Copyright (C) 1997-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> + +int +feholdexcept (fenv_t *envp) +{ + fexcept_t fpcr, fpsr; + + /* Store the environment. */ +#ifdef __mcoldfire__ + __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (envp->__control_register)); + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (envp->__status_register)); + __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (envp->__instruction_address)); +#else + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*envp)); +#endif + + /* Now clear all exceptions. */ + fpsr = envp->__status_register & ~FE_ALL_EXCEPT; + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + /* And set all exceptions to non-stop. */ + fpcr = envp->__control_register & ~(FE_ALL_EXCEPT << 6); + __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr)); + + return 0; +} diff --git a/libm/m68k/fesetenv.c b/libm/m68k/fesetenv.c new file mode 100644 index 000000000..873eb9abe --- /dev/null +++ b/libm/m68k/fesetenv.c @@ -0,0 +1,63 @@ +/* Install given floating-point environment. + Copyright (C) 1997-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> + +int +fesetenv (const fenv_t *envp) +{ + fenv_t temp; + + /* Install the environment specified by ENVP. But there are a few + values which we do not want to come from the saved environment. + Therefore, we get the current environment and replace the values + we want to use from the environment specified by the parameter. */ +#ifdef __mcoldfire__ + __asm__ ("fmove%.l %/fpcr,%0" : "=dm" (temp.__control_register)); + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (temp.__status_register)); + __asm__ ("fmove%.l %/fpiar,%0" : "=dm" (temp.__instruction_address)); +#else + __asm__ ("fmovem%.l %/fpcr/%/fpsr/%/fpiar,%0" : "=m" (*&temp)); +#endif + + temp.__status_register &= ~FE_ALL_EXCEPT; + temp.__control_register &= ~((FE_ALL_EXCEPT << 6) | FE_UPWARD); + if (envp == FE_DFL_ENV) + ; + else if (envp == FE_NOMASK_ENV) + temp.__control_register |= FE_ALL_EXCEPT << 6; + else + { + temp.__control_register |= (envp->__control_register + & ((FE_ALL_EXCEPT << 6) | FE_UPWARD)); + temp.__status_register |= envp->__status_register & FE_ALL_EXCEPT; + } + +#ifdef __mcoldfire__ + __asm__ __volatile__ ("fmove%.l %0,%/fpiar" + :: "dm" (temp.__instruction_address)); + __asm__ __volatile__ ("fmove%.l %0,%/fpcr" + :: "dm" (temp.__control_register)); + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" + :: "dm" (temp.__status_register)); +#else + __asm__ __volatile__ ("fmovem%.l %0,%/fpcr/%/fpsr/%/fpiar" : : "m" (*&temp)); +#endif + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fesetexcept.c b/libm/m68k/fesetexcept.c new file mode 100644 index 000000000..6ae4a55ea --- /dev/null +++ b/libm/m68k/fesetexcept.c @@ -0,0 +1,30 @@ +/* Set given exception flags. M68K version. + Copyright (C) 2016-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> + +int +fesetexcept (int excepts) +{ + fexcept_t fpsr; + + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + fpsr |= excepts & FE_ALL_EXCEPT; + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + + return 0; +} diff --git a/libm/m68k/fesetmode.c b/libm/m68k/fesetmode.c new file mode 100644 index 000000000..a7e93d616 --- /dev/null +++ b/libm/m68k/fesetmode.c @@ -0,0 +1,31 @@ +/* Install given floating-point control modes. M68K version. + Copyright (C) 2016-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) +{ + femode_t mode; + if (modep == FE_DFL_MODE) + mode = _FPU_DEFAULT; + else + mode = *modep; + _FPU_SETCW (mode); + return 0; +} diff --git a/libm/m68k/fesetround.c b/libm/m68k/fesetround.c new file mode 100644 index 000000000..a8abc4e6e --- /dev/null +++ b/libm/m68k/fesetround.c @@ -0,0 +1,35 @@ +/* Set current rounding direction. + Copyright (C) 1997-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> + +int +fesetround (int round) +{ + fexcept_t fpcr; + + if (round & ~FE_UPWARD) + /* ROUND is no valid rounding mode. */ + return 1; + + __asm__ ("fmove%.l %!,%0" : "=dm" (fpcr)); + fpcr &= ~FE_UPWARD; + fpcr |= round; + __asm__ __volatile__ ("fmove%.l %0,%!" : : "dm" (fpcr)); + + return 0; +} diff --git a/libm/m68k/feupdateenv.c b/libm/m68k/feupdateenv.c new file mode 100644 index 000000000..29dcc712e --- /dev/null +++ b/libm/m68k/feupdateenv.c @@ -0,0 +1,39 @@ +/* Install given floating-point environment and raise exceptions. + Copyright (C) 1997-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> + +int +feupdateenv (const fenv_t *envp) +{ + fexcept_t fpsr; + + /* Save current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + fpsr &= FE_ALL_EXCEPT; + + /* Install new environment. */ + fesetenv (envp); + + /* Raise the saved exception. Incidentally for us the implementation + defined format of the values in objects of type fexcept_t is the + same as the ones specified using the FE_* constants. */ + feraiseexcept ((int) fpsr); + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fgetexcptflg.c b/libm/m68k/fgetexcptflg.c new file mode 100644 index 000000000..7a564555b --- /dev/null +++ b/libm/m68k/fgetexcptflg.c @@ -0,0 +1,32 @@ +/* Store current representation for exceptions. + Copyright (C) 1997-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> + +int +fegetexceptflag (fexcept_t *flagp, int excepts) +{ + fexcept_t fpsr; + + /* Get the current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + *flagp = fpsr & excepts & FE_ALL_EXCEPT; + + /* Success. */ + return 0; +} diff --git a/libm/m68k/fraiseexcpt.c b/libm/m68k/fraiseexcpt.c new file mode 100644 index 000000000..4599c08f7 --- /dev/null +++ b/libm/m68k/fraiseexcpt.c @@ -0,0 +1,106 @@ +/* Raise given exceptions. + Copyright (C) 1997-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 <float.h> +#include <math.h> + +int +feraiseexcept (int excepts) +{ +#if defined(__mcffpu__) + + /* The Coldfire FPU allows an exception to be raised by asserting + the associated EXC bit and then executing an arbitrary arithmetic + instruction. fmove.l is classified as an arithmetic instruction + and suffices for this purpose. + + We therefore raise an exception by setting both the EXC and AEXC + bit associated with the exception (the former being 6 bits to the + left of the latter) and then loading the longword at (%sp) into an + FP register. */ + + inline void + raise_one_exception (int mask) + { + if (excepts & mask) + { + int fpsr; + double unused; + + __asm__ volatile ("fmove%.l %/fpsr,%0" : "=d" (fpsr)); + fpsr |= (mask << 6) | mask; + __asm__ volatile ("fmove%.l %0,%/fpsr" :: "d" (fpsr)); + __asm__ volatile ("fmove%.l (%%sp),%0" : "=f" (unused)); + } + } + + raise_one_exception (FE_INVALID); + raise_one_exception (FE_DIVBYZERO); + raise_one_exception (FE_OVERFLOW); + raise_one_exception (FE_UNDERFLOW); + raise_one_exception (FE_INEXACT); + +#else + /* Raise exceptions represented by EXCEPTS. But we must raise only one + signal at a time. It is important that if the overflow/underflow + exception and the divide by zero exception are given at the same + time, the overflow/underflow exception follows the divide by zero + exception. */ + + /* First: invalid exception. */ + if (excepts & FE_INVALID) + { + /* One example of an invalid operation is 0 * Infinity. */ + double d = HUGE_VAL; + __asm__ __volatile__ ("fmul%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: division by zero. */ + if (excepts & FE_DIVBYZERO) + { + double d = 1.0; + __asm__ __volatile__ ("fdiv%.s %#0r0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: overflow. */ + if (excepts & FE_OVERFLOW) + { + long double d = LDBL_MAX; + + __asm__ __volatile__ ("fmul%.x %0,%0; fnop" : "=f" (d) : "0" (d)); + } + + /* Next: underflow. */ + if (excepts & FE_UNDERFLOW) + { + long double d = -LDBL_MAX; + + __asm__ __volatile__ ("fetox%.x %0; fnop" : "=f" (d) : "0" (d)); + } + + /* Last: inexact. */ + if (excepts & FE_INEXACT) + { + long double d = 1.0; + __asm__ __volatile__ ("fdiv%.s %#0r3,%0; fnop" : "=f" (d) : "0" (d)); + } + +#endif + /* Success. */ + return 0; +} diff --git a/libm/m68k/fsetexcptflg.c b/libm/m68k/fsetexcptflg.c new file mode 100644 index 000000000..18fc1811f --- /dev/null +++ b/libm/m68k/fsetexcptflg.c @@ -0,0 +1,38 @@ +/* Set floating-point environment exception handling. + Copyright (C) 1997-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 <math.h> + +int +fesetexceptflag (const fexcept_t *flagp, int excepts) +{ + fexcept_t fpsr; + + /* Get the current status register. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + /* Install the new exception bits in the Accrued Exception Byte. */ + fpsr &= ~(excepts & FE_ALL_EXCEPT); + fpsr |= *flagp & excepts & FE_ALL_EXCEPT; + + /* Store the new status register. */ + __asm__ __volatile__ ("fmove%.l %0,%/fpsr" : : "dm" (fpsr)); + + /* Success. */ + return 0; +} diff --git a/libm/m68k/ftestexcept.c b/libm/m68k/ftestexcept.c new file mode 100644 index 000000000..1ece1a48d --- /dev/null +++ b/libm/m68k/ftestexcept.c @@ -0,0 +1,29 @@ +/* Test exception in current environment. + Copyright (C) 1997-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> + +int +fetestexcept (int excepts) +{ + fexcept_t fpsr; + + /* Get current exceptions. */ + __asm__ ("fmove%.l %/fpsr,%0" : "=dm" (fpsr)); + + return fpsr & excepts & FE_ALL_EXCEPT; +} |