summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2008-01-19 15:23:14 +0000
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>2008-01-19 15:23:14 +0000
commitbce5bba7a01fb090f67fec5f79218c505c841af3 (patch)
treee7d7dfc12cae1f1474800071fbc4633fa509ef6e
parentd22976dd5e16e8719abd5c542e17427eeece7ff6 (diff)
- add C99 floating point environment, rounding and exception handling functions
for i386. UCLIBC_HAS_FENV
-rw-r--r--Makefile.in5
-rw-r--r--extra/Configs/Config.in.arch9
-rw-r--r--libm/i386/Makefile.arch24
-rw-r--r--libm/i386/fclrexcpt.c61
-rw-r--r--libm/i386/fedisblxcpt.c55
-rw-r--r--libm/i386/feenablxcpt.c55
-rw-r--r--libm/i386/fegetenv.c34
-rw-r--r--libm/i386/fegetexcept.c32
-rw-r--r--libm/i386/fegetround.c31
-rw-r--r--libm/i386/feholdexcpt.c59
-rw-r--r--libm/i386/fesetenv.c80
-rw-r--r--libm/i386/fesetround.c52
-rw-r--r--libm/i386/feupdateenv.c56
-rw-r--r--libm/i386/fgetexcptflg.c35
-rw-r--r--libm/i386/fraiseexcpt.c118
-rw-r--r--libm/i386/fsetexcptflg.c62
-rw-r--r--libm/i386/ftestexcept.c40
17 files changed, 808 insertions, 0 deletions
diff --git a/Makefile.in b/Makefile.in
index a0969c1fc..c35db752f 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -140,6 +140,11 @@ ifneq ($(UCLIBC_HAS_FLOATS),y)
$(RM) $(PREFIX)$(DEVEL_PREFIX)include/tgmath.h
$(RM) $(PREFIX)$(DEVEL_PREFIX)include/bits/uClibc_fpmax.h
endif
+ifneq ($(UCLIBC_HAS_FENV),y)
+ $(RM) $(PREFIX)$(DEVEL_PREFIX)include/fenv.h \
+ $(PREFIX)$(DEVEL_PREFIX)include/bits/fenv.h \
+ $(PREFIX)$(DEVEL_PREFIX)include/bits/fenvinline.h
+endif
ifneq ($(UCLIBC_HAS_WCHAR),y)
# Remove wide char headers since wide char support is disabled.
$(RM) $(PREFIX)$(DEVEL_PREFIX)include/wctype.h
diff --git a/extra/Configs/Config.in.arch b/extra/Configs/Config.in.arch
index ad853ee7c..248675e07 100644
--- a/extra/Configs/Config.in.arch
+++ b/extra/Configs/Config.in.arch
@@ -159,6 +159,15 @@ config DO_C99_MATH
If your applications require the newer C99 math library functions,
then answer Y.
+config UCLIBC_HAS_FENV
+ bool "Enable C99 Floating-point environment"
+ depends on UCLIBC_HAS_FLOATS
+ default n
+ help
+ If you want the uClibc math library to contain the C99 floating
+ point environment, rounding and exception handling functions then
+ say Y here.
+
config KERNEL_HEADERS
string "Linux kernel header location"
default "/usr/include"
diff --git a/libm/i386/Makefile.arch b/libm/i386/Makefile.arch
new file mode 100644
index 000000000..e1be961f2
--- /dev/null
+++ b/libm/i386/Makefile.arch
@@ -0,0 +1,24 @@
+# Makefile for uClibc
+#
+# Copyright (C) 2000-2008 Erik Andersen <andersen@uclibc.org>
+#
+# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
+#
+# The routines included in this math library are derived from
+# glibc's libm.
+#
+
+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/i386/fclrexcpt.c b/libm/i386/fclrexcpt.c
new file mode 100644
index 000000000..a34060ce8
--- /dev/null
+++ b/libm/i386/fclrexcpt.c
@@ -0,0 +1,61 @@
+/* Clear given exceptions in current floating-point environment.
+ Copyright (C) 1997,99,2000, 2001, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+
+int
+feclearexcept (int excepts)
+{
+ fenv_t temp;
+
+ /* Mask out unsupported bits/exceptions. */
+ excepts &= FE_ALL_EXCEPT;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Clear the relevant bits. */
+ temp.__status_word &= excepts ^ FE_ALL_EXCEPT;
+
+ /* Put the new data in effect. */
+ __asm__ ("fldenv %0" : : "m" (*&temp));
+
+#if 0
+ /* If the CPU supports SSE, we clear the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current MXCSR. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ /* Clear the relevant bits. */
+ xnew_exc &= ~excepts;
+
+ /* Put the new data in effect. */
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+#endif
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/i386/fedisblxcpt.c b/libm/i386/fedisblxcpt.c
new file mode 100644
index 000000000..75dc17897
--- /dev/null
+++ b/libm/i386/fedisblxcpt.c
@@ -0,0 +1,55 @@
+/* Disable floating-point exceptions.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+
+int
+fedisableexcept (int excepts)
+{
+ unsigned short int new_exc, old_exc;
+
+ /* Get the current control word. */
+ __asm__ ("fstcw %0" : "=m" (*&new_exc));
+
+ old_exc = (~new_exc) & FE_ALL_EXCEPT;
+
+ excepts &= FE_ALL_EXCEPT;
+
+ new_exc |= excepts;
+ __asm__ ("fldcw %0" : : "m" (*&new_exc));
+
+#if 0
+ /* If the CPU supports SSE we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current control word. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ xnew_exc |= excepts << 7;
+
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+#endif
+
+ return old_exc;
+}
diff --git a/libm/i386/feenablxcpt.c b/libm/i386/feenablxcpt.c
new file mode 100644
index 000000000..174f9f1ad
--- /dev/null
+++ b/libm/i386/feenablxcpt.c
@@ -0,0 +1,55 @@
+/* Enable floating-point exceptions.
+ Copyright (C) 1999, 2000, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+
+int
+feenableexcept (int excepts)
+{
+ unsigned short int new_exc;
+ unsigned short int old_exc;
+
+ /* Get the current control word. */
+ __asm__ ("fstcw %0" : "=m" (*&new_exc));
+
+ excepts &= FE_ALL_EXCEPT;
+ old_exc = (~new_exc) & FE_ALL_EXCEPT;
+
+ new_exc &= ~excepts;
+ __asm__ ("fldcw %0" : : "m" (*&new_exc));
+
+#if 0
+ /* If the CPU supports SSE we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current control word. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ xnew_exc &= ~(excepts << 7);
+
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+#endif
+
+ return old_exc;
+}
diff --git a/libm/i386/fegetenv.c b/libm/i386/fegetenv.c
new file mode 100644
index 000000000..abbf179e0
--- /dev/null
+++ b/libm/i386/fegetenv.c
@@ -0,0 +1,34 @@
+/* Store current floating-point environment.
+ Copyright (C) 1997,1999,2000,2001,2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetenv (fenv_t *envp)
+{
+ __asm__ ("fnstenv %0" : "=m" (*envp));
+ /* And load it right back since the processor changes the mask.
+ Intel thought this opcode to be used in interrupt handlers which
+ would block all exceptions. */
+ __asm__ ("fldenv %0" : : "m" (*envp));
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/i386/fegetexcept.c b/libm/i386/fegetexcept.c
new file mode 100644
index 000000000..71bac788b
--- /dev/null
+++ b/libm/i386/fegetexcept.c
@@ -0,0 +1,32 @@
+/* Get enabled floating-point exceptions.
+ Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Andreas Jaeger <aj@suse.de>, 1999.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetexcept (void)
+{
+ unsigned short int exc;
+
+ /* Get the current control word. */
+ __asm__ ("fstcw %0" : "=m" (*&exc));
+
+ return (~exc) & FE_ALL_EXCEPT;
+}
diff --git a/libm/i386/fegetround.c b/libm/i386/fegetround.c
new file mode 100644
index 000000000..8ae0c3aff
--- /dev/null
+++ b/libm/i386/fegetround.c
@@ -0,0 +1,31 @@
+/* Return current rounding direction.
+ Copyright (C) 1997 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetround (void)
+{
+ int cw;
+
+ __asm__ ("fnstcw %0" : "=m" (*&cw));
+
+ return cw & 0xc00;
+}
diff --git a/libm/i386/feholdexcpt.c b/libm/i386/feholdexcpt.c
new file mode 100644
index 000000000..d283e9e44
--- /dev/null
+++ b/libm/i386/feholdexcpt.c
@@ -0,0 +1,59 @@
+/* Store current floating-point environment and clear exceptions.
+ Copyright (C) 1997, 1999, 2003, 2004, 2005, 2007
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+
+int
+feholdexcept (fenv_t *envp)
+{
+ fenv_t temp;
+
+ /* Store the environment. */
+ __asm__ ("fnstenv %0" : "=m" (temp));
+ *envp = temp;
+
+ /* Now set all exceptions to non-stop. */
+ temp.__control_word |= 0x3f;
+
+ /* And clear all exceptions. */
+ temp.__status_word &= ~0x3f;
+
+ __asm__ ("fldenv %0" : : "m" (temp));
+
+#if 0
+ /* If the CPU supports SSE we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xwork;
+
+ /* Get the current control word. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xwork));
+
+ /* Set all exceptions to non-stop and clear them. */
+ xwork = (xwork | 0x1f80) & ~0x3f;
+
+ __asm__ ("ldmxcsr %0" : : "m" (*&xwork));
+ }
+#endif
+
+ return 0;
+}
diff --git a/libm/i386/fesetenv.c b/libm/i386/fesetenv.c
new file mode 100644
index 000000000..fdb4fcc92
--- /dev/null
+++ b/libm/i386/fesetenv.c
@@ -0,0 +1,80 @@
+/* Install given floating-point environment.
+ Copyright (C) 1997,98,99,2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <assert.h>
+
+libm_hidden_proto(fesetenv)
+
+int
+fesetenv (const fenv_t *envp)
+{
+ fenv_t temp;
+
+ /* The memory block used by fstenv/fldenv has a size of 28 bytes. */
+ assert (sizeof (fenv_t) == 28);
+
+ /* 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. */
+ __asm__ ("fnstenv %0" : "=m" (*&temp));
+
+ if (envp == FE_DFL_ENV)
+ {
+ temp.__control_word |= FE_ALL_EXCEPT;
+ temp.__control_word &= ~FE_TOWARDZERO;
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__eip = 0;
+ temp.__cs_selector = 0;
+ temp.__opcode = 0;
+ temp.__data_offset = 0;
+ temp.__data_selector = 0;
+ }
+ else if (envp == FE_NOMASK_ENV)
+ {
+ temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO);
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__eip = 0;
+ temp.__cs_selector = 0;
+ temp.__opcode = 0;
+ temp.__data_offset = 0;
+ temp.__data_selector = 0;
+ }
+ else
+ {
+ temp.__control_word &= ~(FE_ALL_EXCEPT | FE_TOWARDZERO);
+ temp.__control_word |= (envp->__control_word
+ & (FE_ALL_EXCEPT | FE_TOWARDZERO));
+ temp.__status_word &= ~FE_ALL_EXCEPT;
+ temp.__status_word |= envp->__status_word & FE_ALL_EXCEPT;
+ temp.__eip = envp->__eip;
+ temp.__cs_selector = envp->__cs_selector;
+ temp.__opcode = envp->__opcode;
+ temp.__data_offset = envp->__data_offset;
+ temp.__data_selector = envp->__data_selector;
+ }
+
+ __asm__ ("fldenv %0" : : "m" (temp));
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def(fesetenv)
diff --git a/libm/i386/fesetround.c b/libm/i386/fesetround.c
new file mode 100644
index 000000000..e1ba16975
--- /dev/null
+++ b/libm/i386/fesetround.c
@@ -0,0 +1,52 @@
+/* Set current rounding direction.
+ Copyright (C) 1997, 2003, 2004, 2005 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+
+int
+fesetround (int round)
+{
+ unsigned short int cw;
+
+ if ((round & ~0xc00) != 0)
+ /* ROUND is no valid rounding mode. */
+ return 1;
+
+ __asm__ ("fnstcw %0" : "=m" (*&cw));
+ cw &= ~0xc00;
+ cw |= round;
+ __asm__ ("fldcw %0" : : "m" (*&cw));
+
+#if 0
+ /* If the CPU supports SSE we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xcw;
+
+ __asm__ ("stmxcsr %0" : "=m" (*&xcw));
+ xcw &= ~0x6000;
+ xcw |= round << 3;
+ __asm__ ("ldmxcsr %0" : : "m" (*&xcw));
+ }
+#endif
+
+ return 0;
+}
diff --git a/libm/i386/feupdateenv.c b/libm/i386/feupdateenv.c
new file mode 100644
index 000000000..91b535dc6
--- /dev/null
+++ b/libm/i386/feupdateenv.c
@@ -0,0 +1,56 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+
+libm_hidden_proto(fesetenv)
+libm_hidden_proto(feraiseexcept)
+
+int
+feupdateenv (const fenv_t *envp)
+{
+ fexcept_t temp;
+ /* unsigned int xtemp = 0; */
+
+ /* Save current exceptions. */
+ __asm__ ("fnstsw %0" : "=m" (*&temp));
+
+#if 0
+ /* If the CPU supports SSE we test the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ __asm__ ("stmxcsr %0" : "=m" (*&xtemp));
+
+ temp = (temp | xtemp) & FE_ALL_EXCEPT;
+#else
+ temp &= FE_ALL_EXCEPT;
+#endif
+
+ /* Install new environment. */
+ fesetenv (envp);
+
+ /* Raise the saved exception. Incidently 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) temp);
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/i386/fgetexcptflg.c b/libm/i386/fgetexcptflg.c
new file mode 100644
index 000000000..f99122610
--- /dev/null
+++ b/libm/i386/fgetexcptflg.c
@@ -0,0 +1,35 @@
+/* Store current representation for exceptions.
+ Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+fegetexceptflag (fexcept_t *flagp, int excepts)
+{
+ fexcept_t temp;
+
+ /* Get the current exceptions. */
+ __asm__ ("fnstsw %0" : "=m" (*&temp));
+
+ *flagp = temp & excepts & FE_ALL_EXCEPT;
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/i386/fraiseexcpt.c b/libm/i386/fraiseexcpt.c
new file mode 100644
index 000000000..fcb3d0e84
--- /dev/null
+++ b/libm/i386/fraiseexcpt.c
@@ -0,0 +1,118 @@
+/* Raise given exceptions.
+ Copyright (C) 1997,99,2000,01,02 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <math.h>
+
+libm_hidden_proto(feraiseexcept)
+
+int
+feraiseexcept (int excepts)
+{
+ /* Raise exceptions represented by EXPECTS. But we must raise only
+ one signal at a time. It is important that if the overflow/underflow
+ exception and the inexact exception are given at the same time,
+ the overflow/underflow exception follows the inexact exception. */
+
+ /* First: invalid exception. */
+ if ((FE_INVALID & excepts) != 0)
+ {
+ /* One example of a invalid operation is 0.0 / 0.0. */
+ double d;
+ __asm__ __volatile__ ("fldz; fdiv %%st, %%st(0); fwait" : "=t" (d));
+ (void) &d;
+ }
+
+ /* Next: division by zero. */
+ if ((FE_DIVBYZERO & excepts) != 0)
+ {
+ double d;
+ __asm__ __volatile__ ("fldz; fld1; fdivp %%st, %%st(1); fwait"
+ : "=t" (d));
+ (void) &d;
+ }
+
+ /* Next: overflow. */
+ if ((FE_OVERFLOW & excepts) != 0)
+ {
+ /* There is no way to raise only the overflow flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_OVERFLOW;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Next: underflow. */
+ if ((FE_UNDERFLOW & excepts) != 0)
+ {
+ /* There is no way to raise only the underflow flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_UNDERFLOW;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Last: inexact. */
+ if ((FE_INEXACT & excepts) != 0)
+ {
+ /* There is no way to raise only the inexact flag. Do it the
+ hard way. */
+ fenv_t temp;
+
+ /* Bah, we have to clear selected exceptions. Since there is no
+ `fldsw' instruction we have to do it the hard way. */
+ __asm__ __volatile__ ("fnstenv %0" : "=m" (*&temp));
+
+ /* Set the relevant bits. */
+ temp.__status_word |= FE_INEXACT;
+
+ /* Put the new data in effect. */
+ __asm__ __volatile__ ("fldenv %0" : : "m" (*&temp));
+
+ /* And raise the exception. */
+ __asm__ __volatile__ ("fwait");
+ }
+
+ /* Success. */
+ return 0;
+}
+libm_hidden_def(feraiseexcept)
diff --git a/libm/i386/fsetexcptflg.c b/libm/i386/fsetexcptflg.c
new file mode 100644
index 000000000..bdd1dcca0
--- /dev/null
+++ b/libm/i386/fsetexcptflg.c
@@ -0,0 +1,62 @@
+/* Set floating-point environment exception handling.
+ Copyright (C) 1997,99,2000,01, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <math.h>
+#include <unistd.h>
+
+int
+fesetexceptflag (const fexcept_t *flagp, int excepts)
+{
+ fenv_t temp;
+
+ /* Get the current environment. We have to do this since we cannot
+ separately set the status word. */
+ __asm__ ("fnstenv %0" : "=m" (*&temp));
+
+ temp.__status_word &= ~(excepts & FE_ALL_EXCEPT);
+ temp.__status_word |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ /* Store the new status word (along with the rest of the environment.
+ Possibly new exceptions are set but they won't get executed unless
+ the next floating-point instruction. */
+ __asm__ ("fldenv %0" : : "m" (*&temp));
+
+#if 0
+ /* If the CPU supports SSE, we set the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ {
+ unsigned int xnew_exc;
+
+ /* Get the current MXCSR. */
+ __asm__ ("stmxcsr %0" : "=m" (*&xnew_exc));
+
+ /* Set the relevant bits. */
+ xnew_exc &= ~(excepts & FE_ALL_EXCEPT);
+ xnew_exc |= *flagp & excepts & FE_ALL_EXCEPT;
+
+ /* Put the new data in effect. */
+ __asm__ ("ldmxcsr %0" : : "m" (*&xnew_exc));
+ }
+#endif
+
+ /* Success. */
+ return 0;
+}
diff --git a/libm/i386/ftestexcept.c b/libm/i386/ftestexcept.c
new file mode 100644
index 000000000..ad6bf8954
--- /dev/null
+++ b/libm/i386/ftestexcept.c
@@ -0,0 +1,40 @@
+/* Test exception in current environment.
+ Copyright (C) 1997, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ 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, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+#include <unistd.h>
+
+int
+fetestexcept (int excepts)
+{
+ int temp;
+ int xtemp = 0;
+
+ /* Get current exceptions. */
+ __asm__ ("fnstsw %0" : "=a" (temp));
+
+#if 0
+ /* If the CPU supports SSE we test the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ __asm__ ("stmxcsr %0" : "=m" (*&xtemp));
+#endif
+
+ return (temp | xtemp) & excepts & FE_ALL_EXCEPT;
+}