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 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; +} | 
