2000-08-28 05:59:48 +00:00
|
|
|
/* Enable floating-point exceptions.
|
2024-01-01 18:12:26 +00:00
|
|
|
Copyright (C) 2000-2024 Free Software Foundation, Inc.
|
2000-08-28 05:59:48 +00:00
|
|
|
This file is part of the GNU C Library.
|
|
|
|
|
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
2001-07-06 04:58:11 +00:00
|
|
|
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.
|
2000-08-28 05:59:48 +00:00
|
|
|
|
|
|
|
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
|
2001-07-06 04:58:11 +00:00
|
|
|
Lesser General Public License for more details.
|
2000-08-28 05:59:48 +00:00
|
|
|
|
2001-07-06 04:58:11 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2012-02-09 23:18:22 +00:00
|
|
|
License along with the GNU C Library; if not, see
|
Prefer https to http for gnu.org and fsf.org URLs
Also, change sources.redhat.com to sourceware.org.
This patch was automatically generated by running the following shell
script, which uses GNU sed, and which avoids modifying files imported
from upstream:
sed -ri '
s,(http|ftp)(://(.*\.)?(gnu|fsf|sourceware)\.org($|[^.]|\.[^a-z])),https\2,g
s,(http|ftp)(://(.*\.)?)sources\.redhat\.com($|[^.]|\.[^a-z]),https\2sourceware.org\4,g
' \
$(find $(git ls-files) -prune -type f \
! -name '*.po' \
! -name 'ChangeLog*' \
! -path COPYING ! -path COPYING.LIB \
! -path manual/fdl-1.3.texi ! -path manual/lgpl-2.1.texi \
! -path manual/texinfo.tex ! -path scripts/config.guess \
! -path scripts/config.sub ! -path scripts/install-sh \
! -path scripts/mkinstalldirs ! -path scripts/move-if-change \
! -path INSTALL ! -path locale/programs/charmap-kw.h \
! -path po/libc.pot ! -path sysdeps/gnu/errlist.c \
! '(' -name configure \
-execdir test -f configure.ac -o -f configure.in ';' ')' \
! '(' -name preconfigure \
-execdir test -f preconfigure.ac ';' ')' \
-print)
and then by running 'make dist-prepare' to regenerate files built
from the altered files, and then executing the following to cleanup:
chmod a+x sysdeps/unix/sysv/linux/riscv/configure
# Omit irrelevant whitespace and comment-only changes,
# perhaps from a slightly-different Autoconf version.
git checkout -f \
sysdeps/csky/configure \
sysdeps/hppa/configure \
sysdeps/riscv/configure \
sysdeps/unix/sysv/linux/csky/configure
# Omit changes that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/powerpc/powerpc64/ppc-mcount.S: trailing lines
git checkout -f \
sysdeps/powerpc/powerpc64/ppc-mcount.S \
sysdeps/unix/sysv/linux/s390/s390-64/syscall.S
# Omit change that caused a pre-commit check to fail like this:
# remote: *** error: sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S: last line does not end in newline
git checkout -f sysdeps/sparc/sparc64/multiarch/memcpy-ultra3.S
2019-09-07 05:40:42 +00:00
|
|
|
<https://www.gnu.org/licenses/>. */
|
2000-08-28 05:59:48 +00:00
|
|
|
|
|
|
|
#include <fenv_libc.h>
|
|
|
|
|
|
|
|
int
|
|
|
|
feenableexcept (int excepts)
|
|
|
|
{
|
2014-04-28 19:38:24 +00:00
|
|
|
fenv_union_t fe, curr;
|
2014-04-29 12:45:05 +00:00
|
|
|
int result, new;
|
2000-08-28 05:59:48 +00:00
|
|
|
|
2014-04-28 19:38:24 +00:00
|
|
|
/* Get current exception mask to return. */
|
2019-09-19 16:58:46 +00:00
|
|
|
fe.fenv = curr.fenv = fegetenv_control ();
|
2014-04-28 19:38:24 +00:00
|
|
|
result = fenv_reg_to_exceptions (fe.l);
|
2000-08-28 05:59:48 +00:00
|
|
|
|
|
|
|
if ((excepts & FE_ALL_INVALID) == FE_ALL_INVALID)
|
|
|
|
excepts = (excepts | FE_INVALID) & ~ FE_ALL_INVALID;
|
|
|
|
|
[powerpc] fe{en,dis}ableexcept, fesetmode: optimize FPSCR accesses
Since fe{en,dis}ableexcept() and fesetmode() read-modify-write just the
"mode" (exception enable and rounding mode) bits of the Floating Point Status
Control Register (FPSCR), the lighter weight 'mffsl' instruction can be used
to read the FPSCR (enables and rounding mode), and 'mtfsf 0b00000011' can be
used to write just those bits back to the FPSCR. The net is better performance.
In addition, fe{en,dis}ableexcept() read the FPSCR again after writing it, or
they determine that it doesn't need to be written because it is not changing.
In either case, the local variable holds the current values of the enable
bits in the FPSCR. This local variable can be used instead of again reading
the FPSCR.
Also, that value of the FPSCR which is read the second time is validated
against the requested enables. Since the write can't fail, this validation
step is unnecessary, and can be removed. Instead, the exceptions to be
enabled (or disabled) are transformed into available bits in the FPSCR,
then validated after being transformed back, to ensure that all requested
bits are actually being set. For example, FE_INVALID_SQRT can be
requested, but cannot actually be set. This bit is not mapped during the
transformations, so a test for that bit being set before and after
transformations will show the bit would not be set, and the function will
return -1 for failure.
Finally, convert the local macros in fesetmode.c to more generally useful
macros in fenv_libc.h.
2019-07-19 00:37:13 +00:00
|
|
|
new = fenv_exceptions_to_reg (excepts);
|
|
|
|
|
|
|
|
if (fenv_reg_to_exceptions (new) != excepts)
|
|
|
|
return -1;
|
|
|
|
|
2014-04-28 19:38:24 +00:00
|
|
|
/* Sets the new exception mask. */
|
[powerpc] fe{en,dis}ableexcept, fesetmode: optimize FPSCR accesses
Since fe{en,dis}ableexcept() and fesetmode() read-modify-write just the
"mode" (exception enable and rounding mode) bits of the Floating Point Status
Control Register (FPSCR), the lighter weight 'mffsl' instruction can be used
to read the FPSCR (enables and rounding mode), and 'mtfsf 0b00000011' can be
used to write just those bits back to the FPSCR. The net is better performance.
In addition, fe{en,dis}ableexcept() read the FPSCR again after writing it, or
they determine that it doesn't need to be written because it is not changing.
In either case, the local variable holds the current values of the enable
bits in the FPSCR. This local variable can be used instead of again reading
the FPSCR.
Also, that value of the FPSCR which is read the second time is validated
against the requested enables. Since the write can't fail, this validation
step is unnecessary, and can be removed. Instead, the exceptions to be
enabled (or disabled) are transformed into available bits in the FPSCR,
then validated after being transformed back, to ensure that all requested
bits are actually being set. For example, FE_INVALID_SQRT can be
requested, but cannot actually be set. This bit is not mapped during the
transformations, so a test for that bit being set before and after
transformations will show the bit would not be set, and the function will
return -1 for failure.
Finally, convert the local macros in fesetmode.c to more generally useful
macros in fenv_libc.h.
2019-07-19 00:37:13 +00:00
|
|
|
fe.l |= new;
|
2014-04-28 19:38:24 +00:00
|
|
|
|
|
|
|
if (fe.l != curr.l)
|
2019-09-19 19:04:45 +00:00
|
|
|
fesetenv_control (fe.fenv);
|
2000-08-28 05:59:48 +00:00
|
|
|
|
2019-09-19 14:13:14 +00:00
|
|
|
__TEST_AND_EXIT_NON_STOP (0ULL, fe.l);
|
2000-08-28 05:59:48 +00:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|