diff options
Diffstat (limited to 'libc/sysdeps/linux')
24 files changed, 1070 insertions, 431 deletions
diff --git a/libc/sysdeps/linux/arc/bits/fenv.h b/libc/sysdeps/linux/arc/bits/fenv.h new file mode 100644 index 000000000..c5c76cb93 --- /dev/null +++ b/libc/sysdeps/linux/arc/bits/fenv.h @@ -0,0 +1,75 @@ +/* Floating point environment. ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FENV_H +# error "Never use <bits/fenv.h> directly; include <fenv.h> instead." +#endif + +enum + { + FE_INVALID = +# define FE_INVALID (0x01) + FE_INVALID, + FE_DIVBYZERO = +# define FE_DIVBYZERO (0x02) + FE_DIVBYZERO, + FE_OVERFLOW = +# define FE_OVERFLOW (0x04) + FE_OVERFLOW, + FE_UNDERFLOW = +# define FE_UNDERFLOW (0x08) + FE_UNDERFLOW, + FE_INEXACT = +# define FE_INEXACT (0x10) + FE_INEXACT + }; + +# define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) + +enum + { + FE_TOWARDZERO = +# define FE_TOWARDZERO (0x0) + FE_TOWARDZERO, + FE_TONEAREST = +# define FE_TONEAREST (0x1) /* default */ + FE_TONEAREST, + FE_UPWARD = +# define FE_UPWARD (0x2) + FE_UPWARD, + FE_DOWNWARD = +# define FE_DOWNWARD (0x3) + FE_DOWNWARD + }; + +typedef unsigned int fexcept_t; + +typedef struct +{ + unsigned int __fpcr; + unsigned int __fpsr; +} fenv_t; + +/* If the default argument is used we use this value. */ +#define FE_DFL_ENV ((const fenv_t *) -1) + +/* 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/arc/fpu_control.h b/libc/sysdeps/linux/arc/fpu_control.h new file mode 100644 index 000000000..e833de3aa --- /dev/null +++ b/libc/sysdeps/linux/arc/fpu_control.h @@ -0,0 +1,104 @@ +/* FPU control word bits. ARC version. + Copyright (C) 2020-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* ARC FPU control register bits. + + [ 0] -> IVE: Enable invalid operation exception. + if 0, soft exception: status register IV flag set. + if 1, hardware exception trap (not supported in Linux yet). + [ 1] -> DZE: Enable division by zero exception. + if 0, soft exception: status register IV flag set. + if 1, hardware exception: (not supported in Linux yet). + [9:8] -> RM: Rounding Mode: + 00 - Rounding toward zero. + 01 - Rounding to nearest (default). + 10 - Rounding (up) toward plus infinity. + 11 - Rounding (down)toward minus infinity. + + ARC FPU status register bits. + + [ 0] -> IV: flag invalid operation. + [ 1] -> DZ: flag division by zero. + [ 2] -> OV: flag Overflow operation. + [ 3] -> UV: flag Underflow operation. + [ 4] -> IX: flag Inexact operation. + [31] -> FWE: Flag Write Enable. + If 1, above flags writable explicitly (clearing), + else IoW and only writable indirectly via bits [12:7]. */ + +#include <features.h> + +#if !defined(__ARC_FPU_SP__) && !defined(__ARC_FPU_DP__) + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +# define _FPU_GETCW(cw) (cw) = 0 +# define _FPU_SETCW(cw) (void) (cw) +# define _FPU_GETS(cw) (cw) = 0 +# define _FPU_SETS(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else + +#define _FPU_RESERVED 0 + +/* The fdlibm code requires strict IEEE double precision arithmetic, + and no interrupts for exceptions, rounding to nearest. + So only RM set to b'01. */ +# define _FPU_DEFAULT 0x00000100 + +/* Actually default needs to have FWE bit as 1 but that is already + ingrained into _FPU_SETS macro below. */ +#define _FPU_FPSR_DEFAULT 0x00000000 + +#define __FPU_RND_SHIFT 8 +#define __FPU_RND_MASK 0x3 + +/* Type of the control word. */ +typedef unsigned int fpu_control_t; + +/* Macros for accessing the hardware control word. */ +# define _FPU_GETCW(cw) __asm__ volatile ("lr %0, [0x300]" : "=r" (cw)) +# define _FPU_SETCW(cw) __asm__ volatile ("sr %0, [0x300]" : : "r" (cw)) + +/* Macros for accessing the hardware status word. + Writing to FPU_STATUS requires a "control" bit FWE to be able to set the + exception flags directly (as opposed to side-effects of FP instructions). + That is done in the macro here to keeps callers agnostic of this detail. + And given FWE is write-only and RAZ, no need to "clear" it in _FPU_GETS + macro. */ +# define _FPU_GETS(cw) \ + __asm__ volatile ("lr %0, [0x301] \r\n" \ + : "=r" (cw)) + +# define _FPU_SETS(cw) \ + do { \ + unsigned int __fwe = 0x80000000 | (cw); \ + __asm__ volatile ("sr %0, [0x301] \r\n" \ + : : "r" (__fwe)); \ + } while (0) + +/* Default control word set at startup. */ +extern fpu_control_t __fpu_control; + +#endif + +#endif /* fpu_control.h */ diff --git a/libc/sysdeps/linux/arm/bits/fenv.h b/libc/sysdeps/linux/arm/bits/fenv.h index 106bf36c2..ab60b9e70 100644 --- a/libc/sysdeps/linux/arm/bits/fenv.h +++ b/libc/sysdeps/linux/arm/bits/fenv.h @@ -1,5 +1,4 @@ -/* Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* Copyright (C) 2004-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,87 +11,77 @@ 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 -#ifdef __MAVERICK__ - /* Define bits representing exceptions in the FPU status word. */ enum { - FE_INVALID = 1, -#define FE_INVALID FE_INVALID - FE_OVERFLOW = 4, -#define FE_OVERFLOW FE_OVERFLOW - FE_UNDERFLOW = 8, -#define FE_UNDERFLOW FE_UNDERFLOW - FE_INEXACT = 16, -#define FE_INEXACT FE_INEXACT + FE_INVALID = +#define FE_INVALID 1 + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO 2 + FE_DIVBYZERO, + FE_OVERFLOW = +#define FE_OVERFLOW 4 + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW 8 + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT 16 + FE_INEXACT, }; /* Amount to shift by to convert an exception to a mask bit. */ -#define FE_EXCEPT_SHIFT 5 +#define FE_EXCEPT_SHIFT 8 /* All supported exceptions. */ -#define FE_ALL_EXCEPT \ - (FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) - -/* IEEE rounding modes. */ -enum - { - FE_TONEAREST = 0, -#define FE_TONEAREST FE_TONEAREST - FE_TOWARDZERO = 0x400, -#define FE_TOWARDZERO FE_TOWARDZERO - FE_DOWNWARD = 0x800, -#define FE_DOWNWARD FE_DOWNWARD - FE_UPWARD = 0xc00, -#define FE_UPWARD FE_UPWARD - }; - -#define FE_ROUND_MASK (FE_UPWARD) - -#else /* !__MAVERICK__ */ +#define FE_ALL_EXCEPT \ + (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) -/* Define bits representing exceptions in the FPU status word. */ +/* VFP supports all of the four defined rounding modes. */ enum { - FE_INVALID = 1, -#define FE_INVALID FE_INVALID - FE_DIVBYZERO = 2, -#define FE_DIVBYZERO FE_DIVBYZERO - FE_OVERFLOW = 4, -#define FE_OVERFLOW FE_OVERFLOW - FE_UNDERFLOW = 8, -#define FE_UNDERFLOW FE_UNDERFLOW - }; - -/* Amount to shift by to convert an exception to a mask bit. */ -#define FE_EXCEPT_SHIFT 16 - -/* All supported exceptions. */ -#define FE_ALL_EXCEPT \ - (FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW) - -/* The ARM FPU basically only supports round-to-nearest. Other rounding - modes exist, but you have to encode them in the actual instruction. */ + FE_TONEAREST = #define FE_TONEAREST 0 - -#endif /* __MAVERICK__ */ + FE_TONEAREST, + FE_UPWARD = +#define FE_UPWARD 0x400000 + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD 0x800000 + FE_DOWNWARD, + FE_TOWARDZERO = +#define FE_TOWARDZERO 0xc00000 + FE_TOWARDZERO + }; /* Type representing exception flags. */ -typedef unsigned long int fexcept_t; +typedef unsigned int fexcept_t; /* Type representing floating-point environment. */ typedef struct { - unsigned long int __cw; + unsigned int __cw; } fenv_t; /* If the default argument is used we use this value. */ -#define FE_DFL_ENV ((fenv_t *) -1l) +#define FE_DFL_ENV ((const fenv_t *) -1l) + +#ifdef __USE_GNU +/* 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/arm/fpu_control.h b/libc/sysdeps/linux/arm/fpu_control.h index 1b9b09df6..05ac6a03c 100644 --- a/libc/sysdeps/linux/arm/fpu_control.h +++ b/libc/sysdeps/linux/arm/fpu_control.h @@ -1,6 +1,5 @@ -/* FPU control word definitions. ARM version. - Copyright (C) 1996, 1997, 1998, 2000 Free Software Foundation, Inc. - This file is part of the GNU C Library. +/* FPU control word definitions. ARM VFP version. + Copyright (C) 2004-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,13 +12,22 @@ 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 -#ifdef __VFP_FP__ +#if !(defined(_LIBC) && !defined(_LIBC_TEST)) && defined(__SOFTFP__) + +#define _FPU_RESERVED 0xffffffff +#define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +#define _FPU_GETCW(cw) (cw) = 0 +#define _FPU_SETCW(cw) (void) (cw) +extern fpu_control_t __fpu_control; + +#else /* masking of interrupts */ #define _FPU_MASK_IM 0x00000100 /* invalid operation */ @@ -28,175 +36,39 @@ #define _FPU_MASK_UM 0x00000800 /* underflow */ #define _FPU_MASK_PM 0x00001000 /* inexact */ +#define _FPU_MASK_NZCV 0xf0000000 /* NZCV flags */ +#define _FPU_MASK_RM 0x00c00000 /* rounding mode */ +#define _FPU_MASK_EXCEPT 0x00001f1f /* all exception flags */ + /* Some bits in the FPSCR are not yet defined. They must be preserved when modifying the contents. */ -#define _FPU_RESERVED 0x0e08e0e0 +#define _FPU_RESERVED 0x00086060 #define _FPU_DEFAULT 0x00000000 -/* Default + exceptions enabled. */ + +/* Default + exceptions enabled. */ #define _FPU_IEEE (_FPU_DEFAULT | 0x00001f00) /* Type of the control word. */ typedef unsigned int fpu_control_t; /* Macros for accessing the hardware control word. */ +#ifdef __SOFTFP__ /* This is fmrx %0, fpscr. */ -#define _FPU_GETCW(cw) \ +# define _FPU_GETCW(cw) \ __asm__ __volatile__ ("mrc p10, 7, %0, cr1, cr0, 0" : "=r" (cw)) /* This is fmxr fpscr, %0. */ -#define _FPU_SETCW(cw) \ +# define _FPU_SETCW(cw) \ __asm__ __volatile__ ("mcr p10, 7, %0, cr1, cr0, 0" : : "r" (cw)) +#else +# define _FPU_GETCW(cw) \ + __asm__ __volatile__ ("vmrs %0, fpscr" : "=r" (cw)) +# define _FPU_SETCW(cw) \ + __asm__ __volatile__ ("vmsr fpscr, %0" : : "r" (cw)) +#endif -#elif defined __MAVERICK__ - -/* DSPSC register: (from EP9312 User's Guide) - * - * bits 31..29 - DAID - * bits 28..26 - HVID - * bits 25..24 - RSVD - * bit 23 - ISAT - * bit 22 - UI - * bit 21 - INT - * bit 20 - AEXC - * bits 19..18 - SAT - * bits 17..16 - FCC - * bit 15 - V - * bit 14 - FWDEN - * bit 13 - Invalid - * bit 12 - Denorm - * bits 11..10 - RM - * bits 9..5 - IXE, UFE, OFE, RSVD, IOE - * bits 4..0 - IX, UF, OF, RSVD, IO - */ - -/* masking of interrupts */ -#define _FPU_MASK_IM (1 << 5) /* invalid operation */ -#define _FPU_MASK_ZM 0 /* divide by zero */ -#define _FPU_MASK_OM (1 << 7) /* overflow */ -#define _FPU_MASK_UM (1 << 8) /* underflow */ -#define _FPU_MASK_PM (1 << 9) /* inexact */ -#define _FPU_MASK_DM 0 /* denormalized operation */ - -#define _FPU_RESERVED 0xfffff000 /* These bits are reserved. */ - -#define _FPU_DEFAULT 0x00b00000 /* Default value. */ -#define _FPU_IEEE 0x00b003a0 /* Default + exceptions enabled. */ - -/* Type of the control word. */ -typedef unsigned int fpu_control_t; - -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) ({ \ - register int __t1, __t2; \ - \ - __asm__ __volatile__ ( \ - "cfmvr64l %1, mvdx0\n\t" \ - "cfmvr64h %2, mvdx0\n\t" \ - "cfmv32sc mvdx0, dspsc\n\t" \ - "cfmvr64l %0, mvdx0\n\t" \ - "cfmv64lr mvdx0, %1\n\t" \ - "cfmv64hr mvdx0, %2" \ - : "=r" (cw), "=r" (__t1), "=r" (__t2) \ - ); \ -}) - -#define _FPU_SETCW(cw) ({ \ - register int __t0, __t1, __t2; \ - \ - __asm__ __volatile__ ( \ - "cfmvr64l %1, mvdx0\n\t" \ - "cfmvr64h %2, mvdx0\n\t" \ - "cfmv64lr mvdx0, %0\n\t" \ - "cfmvsc32 dspsc, mvdx0\n\t" \ - "cfmv64lr mvdx0, %1\n\t" \ - "cfmv64hr mvdx0, %2" \ - : "=r" (__t0), "=r" (__t1), "=r" (__t2) \ - : "0" (cw) \ - ); \ -}) - -#else /* !__MAVERICK__ */ - -/* We have a slight terminology confusion here. On the ARM, the register - * we're interested in is actually the FPU status word - the FPU control - * word is something different (which is implementation-defined and only - * accessible from supervisor mode.) - * - * The FPSR looks like this: - * - * 31-24 23-16 15-8 7-0 - * | system ID | trap enable | system control | exception flags | - * - * We ignore the system ID bits; for interest's sake they are: - * - * 0000 "old" FPE - * 1000 FPPC hardware - * 0001 FPE 400 - * 1001 FPA hardware - * - * The trap enable and exception flags are both structured like this: - * - * 7 - 5 4 3 2 1 0 - * | reserved | INX | UFL | OFL | DVZ | IVO | - * - * where a `1' bit in the enable byte means that the trap can occur, and - * a `1' bit in the flags byte means the exception has occurred. - * - * The exceptions are: - * - * IVO - invalid operation - * DVZ - divide by zero - * OFL - overflow - * UFL - underflow - * INX - inexact (do not use; implementations differ) - * - * The system control byte looks like this: - * - * 7-5 4 3 2 1 0 - * | reserved | AC | EP | SO | NE | ND | - * - * where the bits mean - * - * ND - no denormalised numbers (force them all to zero) - * NE - enable NaN exceptions - * SO - synchronous operation - * EP - use expanded packed-decimal format - * AC - use alternate definition for C flag on compare operations - */ - -/* masking of interrupts */ -#define _FPU_MASK_IM 0x00010000 /* invalid operation */ -#define _FPU_MASK_ZM 0x00020000 /* divide by zero */ -#define _FPU_MASK_OM 0x00040000 /* overflow */ -#define _FPU_MASK_UM 0x00080000 /* underflow */ -#define _FPU_MASK_PM 0x00100000 /* inexact */ -#define _FPU_MASK_DM 0x00000000 /* denormalized operation */ - -/* The system id bytes cannot be changed. - Only the bottom 5 bits in the trap enable byte can be changed. - Only the bottom 5 bits in the system control byte can be changed. - Only the bottom 5 bits in the exception flags are used. - The exception flags are set by the fpu, but can be zeroed by the user. */ -#define _FPU_RESERVED 0xffe0e0e0 /* These bits are reserved. */ - -/* The fdlibm code requires strict IEEE double precision arithmetic, - no interrupts for exceptions, rounding to nearest. Changing the - rounding mode will break long double I/O. Turn on the AC bit, - the compiler generates code that assumes it is on. */ -#define _FPU_DEFAULT 0x00001000 /* Default value. */ -#define _FPU_IEEE 0x001f1000 /* Default + exceptions enabled. */ - -/* Type of the control word. */ -typedef unsigned int fpu_control_t; - -/* Macros for accessing the hardware control word. */ -#define _FPU_GETCW(cw) __asm__ ("rfs %0" : "=r" (cw)) -#define _FPU_SETCW(cw) __asm__ ("wfs %0" : : "r" (cw)) - -#endif /* __MAVERICK__ */ - -#if 0 /* Default control word set at startup. */ extern fpu_control_t __fpu_control; -#endif + +#endif /* __SOFTFP__ */ #endif /* _FPU_CONTROL_H */ diff --git a/libc/sysdeps/linux/common/getentropy.c b/libc/sysdeps/linux/common/getentropy.c new file mode 100644 index 000000000..55bd48a12 --- /dev/null +++ b/libc/sysdeps/linux/common/getentropy.c @@ -0,0 +1,45 @@ +/* + * getentropy() by wrapping getrandom(), for µClibc-ng + * + * © 2025 mirabilos Ⓕ CC0 or MirBSD or GNU LGPLv2 + * + * Note: may be a thread cancellation point, unlike the + * implementations in glibc and musl libc. Should this + * ever become a concern, it will need patching. + */ + +#define _DEFAULT_SOURCE +#include <errno.h> +#include <unistd.h> +#include <sys/random.h> + +#ifdef __NR_getrandom +int +getentropy(void *__buf, size_t __len) +{ + ssize_t n; + + if (__len > 256U) { + errno = EIO; + return (-1); + } + + again: + if ((n = getrandom(__buf, __len, 0)) == -1) + switch (errno) { + case EAGAIN: /* should not happen but better safe than sorry */ + case EINTR: + goto again; + default: + errno = EIO; + /* FALLTHROUGH */ + case EFAULT: + case ENOSYS: + return (-1); + } + if ((size_t)n != __len) + /* also shouldn’t happen (safety net) */ + goto again; + return (0); +} +#endif diff --git a/libc/sysdeps/linux/common/getrandom.c b/libc/sysdeps/linux/common/getrandom.c index bb9841463..1db1663b9 100644 --- a/libc/sysdeps/linux/common/getrandom.c +++ b/libc/sysdeps/linux/common/getrandom.c @@ -8,6 +8,7 @@ #include <sys/syscall.h> #include <sys/random.h> + #ifdef __NR_getrandom -_syscall3(int, getrandom, void *, buf, size_t, buflen, unsigned int, flags) +_syscall3(ssize_t, getrandom, void *, buf, size_t, buflen, unsigned int, flags) #endif diff --git a/libc/sysdeps/linux/common/sys/random.h b/libc/sysdeps/linux/common/sys/random.h index 3d24e439b..c3d9cf575 100644 --- a/libc/sysdeps/linux/common/sys/random.h +++ b/libc/sysdeps/linux/common/sys/random.h @@ -4,11 +4,19 @@ #ifndef _SYS_RANDOM_H #define _SYS_RANDOM_H 1 + #include <features.h> #include <stddef.h> __BEGIN_DECLS +#include <bits/types.h> + +#ifndef __ssize_t_defined +typedef __ssize_t ssize_t; +# define __ssize_t_defined +#endif + #if defined __UCLIBC_LINUX_SPECIFIC__ # if 0 /*def __ASSUME_GETRANDOM_SYSCALL */ # include <linux/random.h> @@ -26,9 +34,15 @@ __BEGIN_DECLS # define GRND_RANDOM 0x0002 # define GRND_INSECURE 0x0004 # endif -/* FIXME: aren't there a couple of __restrict and const missing ? */ -extern int getrandom(void *__buf, size_t count, unsigned int flags) +extern ssize_t getrandom(void *__buf, size_t count, unsigned int flags) __nonnull ((1)) __wur; + +/* OpenBSD-compatible access to random bytes. + May be a cancellation point here, unlike in glibc/musl. */ +# ifndef __getentropy_defined +extern int getentropy(void *__buf, size_t __len) __nonnull ((1)) __wur; +# define __getentropy_defined +# endif #endif __END_DECLS diff --git a/libc/sysdeps/linux/csky/bits/fenv.h b/libc/sysdeps/linux/csky/bits/fenv.h index 3359e1f8e..1428f385a 100644 --- a/libc/sysdeps/linux/csky/bits/fenv.h +++ b/libc/sysdeps/linux/csky/bits/fenv.h @@ -1,65 +1,108 @@ -/* - * Copyright (C) 2017 Hangzhou C-SKY Microsystems co.,ltd. - * - * Licensed under the LGPL v2.1 or later, see the file COPYING.LIB - * in this tarball. - */ +/* Floating point environment. C-SKY version. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ #ifndef _FENV_H # error "Never use <bits/fenv.h> directly; include <fenv.h> instead." #endif -/* Define bits representing the exception. We use the bit positions of - the appropriate bits in the FPSR Accrued Exception Byte. */ +#ifdef __csky_hard_float__ +/* Define bits representing the exception. We use the bit positions + of the appropriate bits in the FPU control word. */ 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_INVALID = +#define FE_INVALID 0x01 + FE_INVALID, + FE_DIVBYZERO = +#define FE_DIVBYZERO 0x02 + FE_DIVBYZERO, + FE_OVERFLOW = +#define FE_OVERFLOW 0x04 + FE_OVERFLOW, + FE_UNDERFLOW = +#define FE_UNDERFLOW 0x08 + FE_UNDERFLOW, + FE_INEXACT = +#define FE_INEXACT 0x10 + FE_INEXACT, + __FE_DENORMAL = 0x20 }; #define FE_ALL_EXCEPT \ (FE_INEXACT | FE_DIVBYZERO | FE_UNDERFLOW | FE_OVERFLOW | FE_INVALID) -/* The csky FPU supports all of the four defined rounding modes. We use - the bit positions in the FPCR Mode Control Byte as the values for the - appropriate macros. */ +/* The C-SKY FPU supports all of the four defined rounding modes. We + use again the bit positions in the FPU control word as the values + for the appropriate macros. */ +enum + { + FE_TONEAREST = +#define FE_TONEAREST (0x0 << 24) + FE_TONEAREST, + FE_TOWARDZERO = +#define FE_TOWARDZERO (0x1 << 24) + FE_TOWARDZERO, + FE_UPWARD = +#define FE_UPWARD (0x2 << 24) + FE_UPWARD, + FE_DOWNWARD = +#define FE_DOWNWARD (0x3 << 24) + FE_DOWNWARD, + __FE_ROUND_MASK = (0x3 << 24) + }; + +#else + +/* In the soft-float case, only rounding to nearest is supported, with + no exceptions. */ + 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_UNDEFINED = -1, + + FE_TONEAREST = +# define FE_TONEAREST 0x0 + FE_TONEAREST }; +# define FE_ALL_EXCEPT 0 + +#endif + /* Type representing exception flags. */ typedef unsigned int fexcept_t; -/* Type representing floating-point environment. This structure - corresponds to the layout of the block written by `fmovem'. */ +/* Type representing floating-point environment. */ typedef struct - { - unsigned int __control_register; - unsigned int __status_register; - unsigned int __instruction_address; - } -fenv_t; +{ + unsigned int __fpcr; + unsigned int __fpsr; +} fenv_t; /* If the default argument is used we use this value. */ -#define FE_DFL_ENV ((__const fenv_t *) -1) +#define FE_DFL_ENV ((const fenv_t *) -1) -#ifdef __USE_GNU +#if defined __USE_GNU && defined __csky_hard_float__ /* Floating-point environment where none of the exceptions are masked. */ -# define FE_NOMASK_ENV ((__const fenv_t *) -2) +# 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/csky/fpu_control.h b/libc/sysdeps/linux/csky/fpu_control.h new file mode 100644 index 000000000..a2d615554 --- /dev/null +++ b/libc/sysdeps/linux/csky/fpu_control.h @@ -0,0 +1,147 @@ +/* FPU control word bits. C-SKY version. + Copyright (C) 2018-2025 Free Software Foundation, Inc. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library. If not, see + <https://www.gnu.org/licenses/>. */ + +#ifndef _FPU_CONTROL_H +#define _FPU_CONTROL_H + +/* C-SKY FPU floating point control register bits. + + 31-28 -> Reserved (read as 0, write with 0). + 27 -> 0: Flush denormalized results to zero. + 1: Flush denormalized results to signed minimal normal number. + 26 -> Reserved (read as 0, write with 0). + 25-24 -> Rounding control. + 23-6 -> Reserved (read as 0, write with 0). + 5 -> Enable exception for input denormalized exception. + 4 -> Enable exception for inexact exception. + 3 -> Enable exception for underflow exception. + 2 -> Enable exception for overflow exception. + 1 -> Enable exception for division by zero exception. + 0 -> Enable exception for invalid operation exception. + + Rounding Control: + 00 - Rounding to nearest (RN). + 01 - Rounding toward zero (RZ). + 10 - Rounding (up) toward plus infinity (RP). + 11 - Rounding (down)toward minus infinity (RM). + + C-SKY FPU floating point exception status register bits. + + 15 -> Accumulate bit for any exception. + 14 -> Reserved (read as 0, write with 0). + 13 -> Cause bit for input denormalized exception. + 12 -> Cause bit for inexact exception. + 11 -> Cause bit for underflow exception. + 10 -> Cause bit for overflow exception. + 9 -> Cause bit for division by zero exception. + 8 -> Cause bit for invalid operation exception. + 7 -> Flag bit for any exception. + 6 -> Reserved (read as 0, write with 0). + 5 -> Flag exception for input denormalized exception. + 4 -> Flag exception for inexact exception. + 3 -> Flag exception for underflow exception. + 2 -> Flag exception for overflow exception. + 1 -> Flag exception for division by zero exception. + 0 -> Flag exception for invalid operation exception. */ + +#include <features.h> + +#ifdef __csky_soft_float__ + +# define _FPU_RESERVED 0xffffffff +# define _FPU_DEFAULT 0x00000000 +typedef unsigned int fpu_control_t; +# define _FPU_GETCW(cw) (cw) = 0 +# define _FPU_SETCW(cw) (void) (cw) +# define _FPU_GETFPSR(cw) (cw) = 0 +# define _FPU_SETFPSR(cw) (void) (cw) +extern fpu_control_t __fpu_control; |