diff options
-rw-r--r-- | extra/Configs/Config.in.arch | 1 | ||||
-rw-r--r-- | libc/sysdeps/linux/m68k/bits/fenv.h | 98 | ||||
-rw-r--r-- | libc/sysdeps/linux/m68k/fpu_control.h | 77 | ||||
-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 |
21 files changed, 809 insertions, 55 deletions
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch index 960b67d4d..1ea42e6d1 100644 --- a/extra/Configs/Config.in.arch +++ b/extra/Configs/Config.in.arch @@ -166,6 +166,7 @@ config UCLIBC_HAS_FENV depends on TARGET_i386 || \ TARGET_aarch64 || \ TARGET_arm || \ + TARGET_m68k || \ TARGET_metag || \ TARGET_mips || \ TARGET_nds32 || \ diff --git a/libc/sysdeps/linux/m68k/bits/fenv.h b/libc/sysdeps/linux/m68k/bits/fenv.h index b07f0ab51..37c5fe829 100644 --- a/libc/sysdeps/linux/m68k/bits/fenv.h +++ b/libc/sysdeps/linux/m68k/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* 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 @@ -12,31 +11,38 @@ 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 - <http://www.gnu.org/licenses/>. */ + 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 +#if defined __HAVE_68881__ || defined __HAVE_FPU__ || defined __mcffpu__ + /* Define bits representing the exception. We use the bit positions of the appropriate bits in the FPSR Accrued Exception Byte. */ enum { - FE_INEXACT = 1 << 3, -#define FE_INEXACT FE_INEXACT - FE_DIVBYZERO = 1 << 4, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_UNDERFLOW = 1 << 5, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_OVERFLOW = 1 << 6, -#define FE_OVERFLOW FE_OVERFLOW - FE_INVALID = 1 << 7 -#define FE_INVALID FE_INVALID + FE_INEXACT = +# define FE_INEXACT (1 << 3) + FE_INEXACT, + FE_DIVBYZERO = +# define FE_DIVBYZERO (1 << 4) + FE_DIVBYZERO, + FE_UNDERFLOW = +# define FE_UNDERFLOW (1 << 5) + FE_UNDERFLOW, + FE_OVERFLOW = +# define FE_OVERFLOW (1 << 6) + FE_OVERFLOW, + FE_INVALID = +# define FE_INVALID (1 << 7) + FE_INVALID }; -#define FE_ALL_EXCEPT \ +# define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) /* The m68k FPU supports all of the four defined rounding modes. We use @@ -44,21 +50,45 @@ enum appropriate macros. */ enum { - FE_TONEAREST = 0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 1 << 4, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_DOWNWARD = 2 << 4, -#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 3 << 4 -#define FE_UPWARD FE_UPWARD + FE_TONEAREST = +# define FE_TONEAREST 0 + FE_TONEAREST, + FE_TOWARDZERO = +# define FE_TOWARDZERO (1 << 4) + FE_TOWARDZERO, + FE_DOWNWARD = +# define FE_DOWNWARD (2 << 4) + FE_DOWNWARD, + FE_UPWARD = +# define FE_UPWARD (3 << 4) + FE_UPWARD }; +#else + +/* In the soft-float case, only rounding to nearest is supported, with + no exceptions. */ + +# define FE_ALL_EXCEPT 0 + +enum + { + __FE_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0 + FE_TONEAREST + }; + +#endif + /* Type representing exception flags. */ typedef unsigned int fexcept_t; +#if defined __HAVE_68881__ || defined __HAVE_FPU__ || defined __mcffpu__ + /* Type representing floating-point environment. This structure corresponds to the layout of the block written by `fmovem'. */ typedef struct @@ -69,10 +99,30 @@ typedef struct } fenv_t; +#else + +/* Keep ABI compatibility with the type used in the generic + bits/fenv.h, formerly used for no-FPU ColdFire. */ +typedef struct + { + fexcept_t __excepts; + } +fenv_t; + +#endif + /* If the default argument is used we use this value. */ #define FE_DFL_ENV ((const fenv_t *) -1) -#ifdef __USE_GNU +#if defined __USE_GNU && (defined __HAVE_68881__ \ + || defined __HAVE_FPU__ \ + || defined __mcffpu__) /* Floating-point environment where none of the exceptions are masked. */ # define FE_NOMASK_ENV ((const fenv_t *) -2) #endif + +/* 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/m68k/fpu_control.h b/libc/sysdeps/linux/m68k/fpu_control.h index 35ad95e6d..c3a9c6326 100644 --- a/libc/sysdeps/linux/m68k/fpu_control.h +++ b/libc/sysdeps/linux/m68k/fpu_control.h @@ -1,6 +1,5 @@ /* 68k FPU control word definitions. - Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. - This file is part of the GNU C Library. + Copyright (C) 1996-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 @@ -13,8 +12,8 @@ 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 - <http://www.gnu.org/licenses/>. */ + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FPU_CONTROL_H #define _FPU_CONTROL_H @@ -29,9 +28,9 @@ * 12 -> enable trap for OVFL exception * 11 -> enable trap for UNFL exception * 10 -> enable trap for DZ exception - * 9 -> enable trap for INEX2 exception - * 8 -> enable trap for INEX1 exception - * 7-6 -> Precision Control + * 9 -> enable trap for INEX2 exception (INEX on Coldfire) + * 8 -> enable trap for INEX1 exception (IDE on Coldfire) + * 7-6 -> Precision Control (only bit 6 is used on Coldfire) * 5-4 -> Rounding Control * 3-0 -> zero (read as 0, write as 0) * @@ -53,50 +52,66 @@ #include <features.h> +#if defined (__mcoldfire__) && !defined (__mcffpu__) + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +# define _FPU_GETCW(cw) ((cw) = 0) +# define _FPU_SETCW(cw) ((void) (cw)) + +#else + /* masking of interrupts */ -#define _FPU_MASK_BSUN 0x8000 -#define _FPU_MASK_SNAN 0x4000 -#define _FPU_MASK_OPERR 0x2000 -#define _FPU_MASK_OVFL 0x1000 -#define _FPU_MASK_UNFL 0x0800 -#define _FPU_MASK_DZ 0x0400 -#define _FPU_MASK_INEX1 0x0200 -#define _FPU_MASK_INEX2 0x0100 +# define _FPU_MASK_BSUN 0x8000 +# define _FPU_MASK_SNAN 0x4000 +# define _FPU_MASK_OPERR 0x2000 +# define _FPU_MASK_OVFL 0x1000 +# define _FPU_MASK_UNFL 0x0800 +# define _FPU_MASK_DZ 0x0400 +# define _FPU_MASK_INEX1 0x0200 +# define _FPU_MASK_INEX2 0x0100 /* precision control */ -#define _FPU_EXTENDED 0x00 /* RECOMMENDED */ -#define _FPU_DOUBLE 0x80 -#define _FPU_SINGLE 0x40 /* DO NOT USE */ +# ifdef __mcoldfire__ +# define _FPU_DOUBLE 0x00 +# else +# define _FPU_EXTENDED 0x00 /* RECOMMENDED */ +# define _FPU_DOUBLE 0x80 +# endif +# define _FPU_SINGLE 0x40 /* DO NOT USE */ /* rounding control */ -#define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */ -#define _FPU_RC_ZERO 0x10 -#define _FPU_RC_DOWN 0x20 -#define _FPU_RC_UP 0x30 +# define _FPU_RC_NEAREST 0x00 /* RECOMMENDED */ +# define _FPU_RC_ZERO 0x10 +# define _FPU_RC_DOWN 0x20 +# define _FPU_RC_UP 0x30 -#define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */ +# ifdef __mcoldfire__ +# define _FPU_RESERVED 0xFFFF800F +# else +# define _FPU_RESERVED 0xFFFF000F /* Reserved bits in fpucr */ +# endif /* Now two recommended fpucr */ /* The fdlibm code requires no interrupts for exceptions. Don't change the rounding mode, it would break long double I/O! */ -#define _FPU_DEFAULT 0x00000000 +# define _FPU_DEFAULT 0x00000000 /* IEEE: same as above, but exceptions. We must make it non-zero so that __setfpucw works. This bit will be ignored. */ -#define _FPU_IEEE 0x00000001 +# define _FPU_IEEE 0x00000001 + +/* Macros for accessing the hardware control word. */ +# define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("fmove%.l %0, %!" : : "dm" (cw)) +#endif /* Type of the control word. */ typedef unsigned int fpu_control_t __attribute__ ((__mode__ (__SI__))); -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) __asm__ ("fmove%.l %!, %0" : "=dm" (cw)) -#define _FPU_SETCW(cw) __asm__ __volatile__ ("fmove%.l %0, %!" : : "dm" (cw)) - -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif #endif /* _M68K_FPU_CONTROL_H */ 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 instru |