OSDN Git Service

PR fortran/46402
authorjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 16 Jan 2011 16:40:05 +0000 (16:40 +0000)
committerjakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 16 Jan 2011 16:40:05 +0000 (16:40 +0000)
* quadmath.map (QUADMATH_1.0): Add fmaq.
* configure.ac: Check for fenv.h, feholdexcept, fesetround,
feupdateenv, fesetenv and fetestexcept.
* configure: Regenerated.
* config.h.in: Regenerated.
* quadmath.h (fmaq): New prototype.
* quadmath_weak.h (fmaq): Add.
* Makefile.am (libquadmath_la_SOURCES): Add math/fmaq.c.
* Makefile.in: Regenerated.
* quadmath-imp.h: Include config.h.
* math/expq.c: Include fenv.h.
(USE_FENV_H): Define if libm support for fe* is there.
(expq): Add fesetround etc. support if USE_FENV_H is defined.
* math/fmaq.c: New file.
* libquadmath.texi (fmaq): Add.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@168852 138bc75d-0d04-0410-961f-82ee72b054a4

13 files changed:
libquadmath/ChangeLog
libquadmath/Makefile.am
libquadmath/Makefile.in
libquadmath/config.h.in
libquadmath/configure
libquadmath/configure.ac
libquadmath/libquadmath.texi
libquadmath/math/expq.c
libquadmath/math/fmaq.c [new file with mode: 0644]
libquadmath/quadmath-imp.h
libquadmath/quadmath.h
libquadmath/quadmath.map
libquadmath/quadmath_weak.h

index 5158dba..1cb4aa0 100644 (file)
@@ -1,3 +1,22 @@
+2011-01-16  Jakub Jelinek  <jakub@redhat.com>
+
+       PR fortran/46402
+       * quadmath.map (QUADMATH_1.0): Add fmaq.
+       * configure.ac: Check for fenv.h, feholdexcept, fesetround,
+       feupdateenv, fesetenv and fetestexcept.
+       * configure: Regenerated.
+       * config.h.in: Regenerated.
+       * quadmath.h (fmaq): New prototype.
+       * quadmath_weak.h (fmaq): Add.
+       * Makefile.am (libquadmath_la_SOURCES): Add math/fmaq.c.
+       * Makefile.in: Regenerated.
+       * quadmath-imp.h: Include config.h.
+       * math/expq.c: Include fenv.h.
+       (USE_FENV_H): Define if libm support for fe* is there.
+       (expq): Add fesetround etc. support if USE_FENV_H is defined.
+       * math/fmaq.c: New file.
+       * libquadmath.texi (fmaq): Add.
+
 2011-01-14  Tobias Burnus  <burnus@net-b.de>
 
        PR fortran/47182
index 87ebf20..c4bd0e4 100644 (file)
@@ -61,7 +61,7 @@ libquadmath_la_SOURCES = \
   math/erfq.c math/logq.c math/sqrtq.c math/expm1q.c math/lroundq.c \
   math/tanhq.c math/expq.c math/modfq.c math/tanq.c math/fabsq.c \
   math/nanq.c math/tgammaq.c math/finiteq.c math/nextafterq.c \
-  math/truncq.c math/floorq.c math/powq.c
+  math/truncq.c math/floorq.c math/powq.c math/fmaq.c
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
 # values defined in terms of make variables, as is the case for CC and
index 49e6498..a241b13 100644 (file)
@@ -43,17 +43,16 @@ DIST_COMMON = ChangeLog $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
        $(srcdir)/config.h.in $(srcdir)/../mkinstalldirs \
        $(srcdir)/../depcomp $(libquadmath_TEXINFOS)
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/../config/acx.m4 \
+am__aclocal_m4_deps = $(top_srcdir)/../ltoptions.m4 \
+       $(top_srcdir)/../ltsugar.m4 $(top_srcdir)/../ltversion.m4 \
+       $(top_srcdir)/../lt~obsolete.m4 $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/lead-dot.m4 \
        $(top_srcdir)/../config/lthostflags.m4 \
        $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/no-executables.m4 \
-       $(top_srcdir)/../config/override.m4 \
-       $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
-       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
-       $(top_srcdir)/acinclude.m4 $(top_srcdir)/../libtool.m4 \
-       $(top_srcdir)/configure.ac
+       $(top_srcdir)/../config/override.m4 $(top_srcdir)/acinclude.m4 \
+       $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
        $(ACLOCAL_M4)
 am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
@@ -123,7 +122,7 @@ am__dirstamp = $(am__leading_dot)dirstamp
 @BUILD_LIBQUADMATH_TRUE@       math/nanq.lo math/tgammaq.lo \
 @BUILD_LIBQUADMATH_TRUE@       math/finiteq.lo math/nextafterq.lo \
 @BUILD_LIBQUADMATH_TRUE@       math/truncq.lo math/floorq.lo \
-@BUILD_LIBQUADMATH_TRUE@       math/powq.lo
+@BUILD_LIBQUADMATH_TRUE@       math/powq.lo math/fmaq.lo
 libquadmath_la_OBJECTS = $(am_libquadmath_la_OBJECTS)
 libquadmath_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
        $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -325,7 +324,7 @@ AUTOMAKE_OPTIONS = 1.8 foreign
 @BUILD_LIBQUADMATH_TRUE@  math/erfq.c math/logq.c math/sqrtq.c math/expm1q.c math/lroundq.c \
 @BUILD_LIBQUADMATH_TRUE@  math/tanhq.c math/expq.c math/modfq.c math/tanq.c math/fabsq.c \
 @BUILD_LIBQUADMATH_TRUE@  math/nanq.c math/tgammaq.c math/finiteq.c math/nextafterq.c \
-@BUILD_LIBQUADMATH_TRUE@  math/truncq.c math/floorq.c math/powq.c
+@BUILD_LIBQUADMATH_TRUE@  math/truncq.c math/floorq.c math/powq.c math/fmaq.c
 
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
@@ -570,6 +569,7 @@ math/nextafterq.lo: math/$(am__dirstamp) \
 math/truncq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
 math/floorq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
 math/powq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
+math/fmaq.lo: math/$(am__dirstamp) math/$(DEPDIR)/$(am__dirstamp)
 libquadmath.la: $(libquadmath_la_OBJECTS) $(libquadmath_la_DEPENDENCIES) 
        $(libquadmath_la_LINK) $(am_libquadmath_la_rpath) $(libquadmath_la_OBJECTS) $(libquadmath_la_LIBADD) $(LIBS)
 
@@ -643,6 +643,8 @@ mostlyclean-compile:
        -rm -f math/finiteq.lo
        -rm -f math/floorq.$(OBJEXT)
        -rm -f math/floorq.lo
+       -rm -f math/fmaq.$(OBJEXT)
+       -rm -f math/fmaq.lo
        -rm -f math/fmodq.$(OBJEXT)
        -rm -f math/fmodq.lo
        -rm -f math/frexpq.$(OBJEXT)
@@ -756,6 +758,7 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/fabsq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/finiteq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/floorq.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/fmaq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/fmodq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/frexpq.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@math/$(DEPDIR)/hypotq.Plo@am__quote@
index 648942b..5dd1018 100644 (file)
@@ -6,6 +6,24 @@
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
+/* libm includes feholdexcept */
+#undef HAVE_FEHOLDEXCEPT
+
+/* Define to 1 if you have the <fenv.h> header file. */
+#undef HAVE_FENV_H
+
+/* libm includes fesetenv */
+#undef HAVE_FESETENV
+
+/* libm includes fesetround */
+#undef HAVE_FESETROUND
+
+/* libm includes fetestexcept */
+#undef HAVE_FETESTEXCEPT
+
+/* libm includes feupdateenv */
+#undef HAVE_FEUPDATEENV
+
 /* Define to 1 if you have the <inttypes.h> header file. */
 #undef HAVE_INTTYPES_H
 
index baed921..9844d9a 100755 (executable)
@@ -1757,6 +1757,93 @@ $as_echo "$ac_res" >&6; }
   eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
 
 } # ac_fn_c_check_func
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  ac_header_compiler=yes
+else
+  ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+  ac_header_preproc=yes
+else
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+  yes:no: )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+    ;;
+esac
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+              { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+
+} # ac_fn_c_check_header_mongrel
 cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
@@ -10370,7 +10457,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10373 "configure"
+#line 10460 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10476,7 +10563,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 10479 "configure"
+#line 10566 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11781,6 +11868,19 @@ esac
 
 
 
+for ac_header in fenv.h
+do :
+  ac_fn_c_check_header_mongrel "$LINENO" "fenv.h" "ac_cv_header_fenv_h" "$ac_includes_default"
+if test "x$ac_cv_header_fenv_h" = x""yes; then :
+  cat >>confdefs.h <<_ACEOF
+#define HAVE_FENV_H 1
+_ACEOF
+
+fi
+
+done
+
+
 # If available, sqrtl and cbrtl speed up the calculation -
 # but they are not required
 if test x$gcc_no_link != xyes; then
@@ -11874,6 +11974,231 @@ $as_echo "#define HAVE_CBRTL 1" >>confdefs.h
 
 fi
 
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for feholdexcept in -lm" >&5
+$as_echo_n "checking for feholdexcept in -lm... " >&6; }
+if test "${ac_cv_lib_m_feholdexcept+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char feholdexcept ();
+int
+main ()
+{
+return feholdexcept ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_feholdexcept=yes
+else
+  ac_cv_lib_m_feholdexcept=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_feholdexcept" >&5
+$as_echo "$ac_cv_lib_m_feholdexcept" >&6; }
+if test "x$ac_cv_lib_m_feholdexcept" = x""yes; then :
+
+$as_echo "#define HAVE_FEHOLDEXCEPT 1" >>confdefs.h
+
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fesetround in -lm" >&5
+$as_echo_n "checking for fesetround in -lm... " >&6; }
+if test "${ac_cv_lib_m_fesetround+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fesetround ();
+int
+main ()
+{
+return fesetround ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_fesetround=yes
+else
+  ac_cv_lib_m_fesetround=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fesetround" >&5
+$as_echo "$ac_cv_lib_m_fesetround" >&6; }
+if test "x$ac_cv_lib_m_fesetround" = x""yes; then :
+
+$as_echo "#define HAVE_FESETROUND 1" >>confdefs.h
+
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for feupdateenv in -lm" >&5
+$as_echo_n "checking for feupdateenv in -lm... " >&6; }
+if test "${ac_cv_lib_m_feupdateenv+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char feupdateenv ();
+int
+main ()
+{
+return feupdateenv ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_feupdateenv=yes
+else
+  ac_cv_lib_m_feupdateenv=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_feupdateenv" >&5
+$as_echo "$ac_cv_lib_m_feupdateenv" >&6; }
+if test "x$ac_cv_lib_m_feupdateenv" = x""yes; then :
+
+$as_echo "#define HAVE_FEUPDATEENV 1" >>confdefs.h
+
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fesetenv in -lm" >&5
+$as_echo_n "checking for fesetenv in -lm... " >&6; }
+if test "${ac_cv_lib_m_fesetenv+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fesetenv ();
+int
+main ()
+{
+return fesetenv ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_fesetenv=yes
+else
+  ac_cv_lib_m_fesetenv=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fesetenv" >&5
+$as_echo "$ac_cv_lib_m_fesetenv" >&6; }
+if test "x$ac_cv_lib_m_fesetenv" = x""yes; then :
+
+$as_echo "#define HAVE_FESETENV 1" >>confdefs.h
+
+fi
+
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fetestexcept in -lm" >&5
+$as_echo_n "checking for fetestexcept in -lm... " >&6; }
+if test "${ac_cv_lib_m_fetestexcept+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  as_fn_error "Link tests are not allowed after GCC_NO_EXECUTABLES." "$LINENO" 5
+fi
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fetestexcept ();
+int
+main ()
+{
+return fetestexcept ();
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+  ac_cv_lib_m_fetestexcept=yes
+else
+  ac_cv_lib_m_fetestexcept=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+    conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_m_fetestexcept" >&5
+$as_echo "$ac_cv_lib_m_fetestexcept" >&6; }
+if test "x$ac_cv_lib_m_fetestexcept" = x""yes; then :
+
+$as_echo "#define HAVE_FETESTEXCEPT 1" >>confdefs.h
+
+fi
+
 else
   if test "x$ac_cv_lib_m_sqrtl" = x""yes; then
 
@@ -11885,6 +12210,31 @@ $as_echo "#define HAVE_SQRTL 1" >>confdefs.h
 $as_echo "#define HAVE_CBRTL 1" >>confdefs.h
 
   fi
+  if test "x$ac_cv_lib_m_feholdexcept" = x""yes; then
+
+$as_echo "#define HAVE_FEHOLDEXCEPT 1" >>confdefs.h
+
+  fi
+  if test "x$ac_cv_lib_m_fesetround" = x""yes; then
+
+$as_echo "#define HAVE_FESETROUND 1" >>confdefs.h
+
+  fi
+  if test "x$ac_cv_lib_m_feupdateenv" = x""yes; then
+
+$as_echo "#define HAVE_FEUPDATEENV 1" >>confdefs.h
+
+  fi
+  if test "x$ac_cv_lib_m_fesetenv" = x""yes; then
+
+$as_echo "#define HAVE_FESETENV 1" >>confdefs.h
+
+  fi
+  if test "x$ac_cv_lib_m_fetestexcept" = x""yes; then
+
+$as_echo "#define HAVE_FETESTEXCEPT 1" >>confdefs.h
+
+  fi
 fi
 
 # Check for symbol versioning (copied from libssp).
index cae6abb..0bc2315 100644 (file)
@@ -110,11 +110,18 @@ esac
 AC_SUBST(toolexecdir)
 AC_SUBST(toolexeclibdir)
 
+AC_CHECK_HEADERS(fenv.h)
+
 # If available, sqrtl and cbrtl speed up the calculation -
 # but they are not required
 if test x$gcc_no_link != xyes; then
   AC_CHECK_LIB([m],[sqrtl],[AC_DEFINE([HAVE_SQRTL],[1],[libm includes sqrtl])])
   AC_CHECK_LIB([m],[cbrtl],[AC_DEFINE([HAVE_CBRTL],[1],[libm includes cbrtl])])
+  AC_CHECK_LIB([m],[feholdexcept],[AC_DEFINE([HAVE_FEHOLDEXCEPT],[1],[libm includes feholdexcept])])
+  AC_CHECK_LIB([m],[fesetround],[AC_DEFINE([HAVE_FESETROUND],[1],[libm includes fesetround])])
+  AC_CHECK_LIB([m],[feupdateenv],[AC_DEFINE([HAVE_FEUPDATEENV],[1],[libm includes feupdateenv])])
+  AC_CHECK_LIB([m],[fesetenv],[AC_DEFINE([HAVE_FESETENV],[1],[libm includes fesetenv])])
+  AC_CHECK_LIB([m],[fetestexcept],[AC_DEFINE([HAVE_FETESTEXCEPT],[1],[libm includes fetestexcept])])
 else
   if test "x$ac_cv_lib_m_sqrtl" = x""yes; then
     AC_DEFINE([HAVE_SQRTL],[1],[libm includes sqrtl])  
@@ -122,6 +129,21 @@ else
   if test "x$ac_cv_lib_m_cbrtl" = x""yes; then
     AC_DEFINE([HAVE_CBRTL],[1],[libm includes cbrtl])  
   fi
+  if test "x$ac_cv_lib_m_feholdexcept" = x""yes; then
+    AC_DEFINE([HAVE_FEHOLDEXCEPT],[1],[libm includes feholdexcept])
+  fi
+  if test "x$ac_cv_lib_m_fesetround" = x""yes; then
+    AC_DEFINE([HAVE_FESETROUND],[1],[libm includes fesetround])
+  fi
+  if test "x$ac_cv_lib_m_feupdateenv" = x""yes; then
+    AC_DEFINE([HAVE_FEUPDATEENV],[1],[libm includes feupdateenv])
+  fi
+  if test "x$ac_cv_lib_m_fesetenv" = x""yes; then
+    AC_DEFINE([HAVE_FESETENV],[1],[libm includes fesetenv])
+  fi
+  if test "x$ac_cv_lib_m_fetestexcept" = x""yes; then
+    AC_DEFINE([HAVE_FETESTEXCEPT],[1],[libm includes fetestexcept])
+  fi
 fi
 
 # Check for symbol versioning (copied from libssp).
index 8818a37..aba777b 100644 (file)
@@ -113,6 +113,7 @@ The following mathematical functions are available:
 @item @code{fabsq}: absolute value function
 @item @code{finiteq}: check finiteness of value
 @item @code{floorq}: floor value function
+@item @code{fmaq}: fused multiply and add
 @item @code{fmodq}: remainder value function
 @item @code{frexpq}: extract mantissa and exponent
 @item @code{hypotq}: Eucledian distance function
index a5fbc81..2740b4e 100644 (file)
    02111-1307 USA.  */
 
 #include "quadmath-imp.h"
+#ifdef HAVE_FENV_H
+# include <fenv.h>
+# if defined HAVE_FEHOLDEXCEPT && defined HAVE_FESETROUND \
+     && defined HAVE_FESETENV && defined FE_TONEAREST
+#  define USE_FENV_H
+# endif
+#endif
 
 
 /* __expl_table basically consists of four tables, T_EXPL_ARG{1,2} and
@@ -1093,6 +1100,14 @@ expq (__float128 x)
       int tval1, tval2, unsafe, n_i;
       __float128 x22, n, t, result, xl;
       ieee854_float128 ex2_u, scale_u;
+#ifdef USE_FENV_H
+      fenv_t oldenv;
+
+      feholdexcept (&oldenv);
+# ifdef FE_TONEAREST
+      fesetround (FE_TONEAREST);
+# endif
+#endif
 
       /* Calculate n.  */
       n = x * M_1_LN2 + THREEp111;
@@ -1140,6 +1155,9 @@ expq (__float128 x)
       x22 = x + x*x*(P1+x*(P2+x*(P3+x*(P4+x*(P5+x*P6)))));
 
       /* Return result.  */
+#ifdef USE_FENV_H
+      fesetenv (&oldenv);
+#endif
       result = x22 * ex2_u.value + ex2_u.value;
 
       /* Now we can test whether the result is ultimate or if we are unsure.
@@ -1153,12 +1171,24 @@ expq (__float128 x)
 
          union ieee854_long_double ex3_u;
 
+#ifdef USE_FENV_H
+         #ifdef FE_TONEAREST
+           fesetround (FE_TONEAREST);
+         #endif
+#endif
          ex3_u.d = (result - ex2_u.d) - x22 * ex2_u.d;
          ex2_u.d = result;
          ex3_u.ieee.exponent += LDBL_MANT_DIG + 15 + IEEE854_LONG_DOUBLE_BIAS
                                 - ex2_u.ieee.exponent;
          n_i = abs (ex3_u.d);
          n_i = (n_i + 1) / 2;
+#ifdef USE_FENV_H
+         fesetenv (&oldenv);
+         #ifdef FE_TONEAREST
+         if (fegetround () == FE_TONEAREST)
+           n_i -= 0x4000;
+         #endif
+#endif
          if (!n_i) {
            return __ieee754_expl_proc2 (origx);
          }
diff --git a/libquadmath/math/fmaq.c b/libquadmath/math/fmaq.c
new file mode 100644 (file)
index 0000000..126b0a2
--- /dev/null
@@ -0,0 +1,241 @@
+/* Compute x * y + z as ternary operation.
+   Copyright (C) 2010 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
+
+   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 "quadmath-imp.h"
+#include <math.h>
+#include <float.h>
+#ifdef HAVE_FENV_H
+# include <fenv.h>
+# if defined HAVE_FEHOLDEXCEPT && defined HAVE_FESETROUND \
+     && defined HAVE_FEUPDATEENV && defined HAVE_FETESTEXCEPT \
+     && defined FE_TOWARDZERO && defined FE_INEXACT
+#  define USE_FENV_H
+# endif
+#endif
+
+/* This implementation uses rounding to odd to avoid problems with
+   double rounding.  See a paper by Boldo and Melquiond:
+   http://www.lri.fr/~melquion/doc/08-tc.pdf  */
+
+__float128
+fmaq (__float128 x, __float128 y, __float128 z)
+{
+  ieee854_float128 u, v, w;
+  int adjust = 0;
+  u.value = x;
+  v.value = y;
+  w.value = z;
+  if (__builtin_expect (u.ieee.exponent + v.ieee.exponent
+                       >= 0x7fff + IEEE854_FLOAT128_BIAS
+                          - FLT128_MANT_DIG, 0)
+      || __builtin_expect (u.ieee.exponent >= 0x7fff - FLT128_MANT_DIG, 0)
+      || __builtin_expect (v.ieee.exponent >= 0x7fff - FLT128_MANT_DIG, 0)
+      || __builtin_expect (w.ieee.exponent >= 0x7fff - FLT128_MANT_DIG, 0)
+      || __builtin_expect (u.ieee.exponent + v.ieee.exponent
+                          <= IEEE854_FLOAT128_BIAS + FLT128_MANT_DIG, 0))
+    {
+      /* If z is Inf, but x and y are finite, the result should be
+        z rather than NaN.  */
+      if (w.ieee.exponent == 0x7fff
+         && u.ieee.exponent != 0x7fff
+          && v.ieee.exponent != 0x7fff)
+       return (z + x) + y;
+      /* If x or y or z is Inf/NaN, or if fma will certainly overflow,
+        or if x * y is less than half of FLT128_DENORM_MIN,
+        compute as x * y + z.  */
+      if (u.ieee.exponent == 0x7fff
+         || v.ieee.exponent == 0x7fff
+         || w.ieee.exponent == 0x7fff
+         || u.ieee.exponent + v.ieee.exponent
+            > 0x7fff + IEEE854_FLOAT128_BIAS
+         || u.ieee.exponent + v.ieee.exponent
+            < IEEE854_FLOAT128_BIAS - FLT128_MANT_DIG - 2)
+       return x * y + z;
+      if (u.ieee.exponent + v.ieee.exponent
+         >= 0x7fff + IEEE854_FLOAT128_BIAS - FLT128_MANT_DIG)
+       {
+         /* Compute 1p-113 times smaller result and multiply
+            at the end.  */
+         if (u.ieee.exponent > v.ieee.exponent)
+           u.ieee.exponent -= FLT128_MANT_DIG;
+         else
+           v.ieee.exponent -= FLT128_MANT_DIG;
+         /* If x + y exponent is very large and z exponent is very small,
+            it doesn't matter if we don't adjust it.  */
+         if (w.ieee.exponent > FLT128_MANT_DIG)
+           w.ieee.exponent -= FLT128_MANT_DIG;
+         adjust = 1;
+       }
+      else if (w.ieee.exponent >= 0x7fff - FLT128_MANT_DIG)
+       {
+         /* Similarly.
+            If z exponent is very large and x and y exponents are
+            very small, it doesn't matter if we don't adjust it.  */
+         if (u.ieee.exponent > v.ieee.exponent)
+           {
+             if (u.ieee.exponent > FLT128_MANT_DIG)
+               u.ieee.exponent -= FLT128_MANT_DIG;
+           }
+         else if (v.ieee.exponent > FLT128_MANT_DIG)
+           v.ieee.exponent -= FLT128_MANT_DIG;
+         w.ieee.exponent -= FLT128_MANT_DIG;
+         adjust = 1;
+       }
+      else if (u.ieee.exponent >= 0x7fff - FLT128_MANT_DIG)
+       {
+         u.ieee.exponent -= FLT128_MANT_DIG;
+         if (v.ieee.exponent)
+           v.ieee.exponent += FLT128_MANT_DIG;
+         else
+           v.value *= 0x1p113Q;
+       }
+      else if (v.ieee.exponent >= 0x7fff - FLT128_MANT_DIG)
+       {
+         v.ieee.exponent -= FLT128_MANT_DIG;
+         if (u.ieee.exponent)
+           u.ieee.exponent += FLT128_MANT_DIG;
+         else
+           u.value *= 0x1p113Q;
+       }
+      else /* if (u.ieee.exponent + v.ieee.exponent
+                 <= IEEE854_FLOAT128_BIAS + FLT128_MANT_DIG) */
+       {
+         if (u.ieee.exponent > v.ieee.exponent)
+           u.ieee.exponent += 2 * FLT128_MANT_DIG;
+         else
+           v.ieee.exponent += 2 * FLT128_MANT_DIG;
+         if (w.ieee.exponent <= 4 * FLT128_MANT_DIG + 4)
+           {
+             if (w.ieee.exponent)
+               w.ieee.exponent += 2 * FLT128_MANT_DIG;
+             else
+               w.value *= 0x1p226Q;
+             adjust = -1;
+           }
+         /* Otherwise x * y should just affect inexact
+            and nothing else.  */
+       }
+      x = u.value;
+      y = v.value;
+      z = w.value;
+    }
+  /* Multiplication m1 + m2 = x * y using Dekker's algorithm.  */
+#define C ((1LL << (FLT128_MANT_DIG + 1) / 2) + 1)
+  __float128 x1 = x * C;
+  __float128 y1 = y * C;
+  __float128 m1 = x * y;
+  x1 = (x - x1) + x1;
+  y1 = (y - y1) + y1;
+  __float128 x2 = x - x1;
+  __float128 y2 = y - y1;
+  __float128 m2 = (((x1 * y1 - m1) + x1 * y2) + x2 * y1) + x2 * y2;
+
+  /* Addition a1 + a2 = z + m1 using Knuth's algorithm.  */
+  __float128 a1 = z + m1;
+  __float128 t1 = a1 - z;
+  __float128 t2 = a1 - t1;
+  t1 = m1 - t1;
+  t2 = z - t2;
+  __float128 a2 = t1 + t2;
+
+#ifdef USE_FENV_H
+  fenv_t env;
+  feholdexcept (&env);
+  fesetround (FE_TOWARDZERO);
+#endif
+  /* Perform m2 + a2 addition with round to odd.  */
+  u.value = a2 + m2;
+
+  if (__builtin_expect (adjust == 0, 1))
+    {
+#ifdef USE_FENV_H
+      if ((u.ieee.mant_low & 1) == 0 && u.ieee.exponent != 0x7fff)
+       u.ieee.mant_low |= fetestexcept (FE_INEXACT) != 0;
+      feupdateenv (&env);
+#endif
+      /* Result is a1 + u.value.  */
+      return a1 + u.value;
+    }
+  else if (__builtin_expect (adjust > 0, 1))
+    {
+#ifdef USE_FENV_H
+      if ((u.ieee.mant_low & 1) == 0 && u.ieee.exponent != 0x7fff)
+       u.ieee.mant_low |= fetestexcept (FE_INEXACT) != 0;
+      feupdateenv (&env);
+#endif
+      /* Result is a1 + u.value, scaled up.  */
+      return (a1 + u.value) * 0x1p113Q;
+    }
+  else
+    {
+#ifdef USE_FENV_H
+      if ((u.ieee.mant_low & 1) == 0)
+       u.ieee.mant_low |= fetestexcept (FE_INEXACT) != 0;
+#endif
+      v.value = a1 + u.value;
+      /* Ensure the addition is not scheduled after fetestexcept call.  */
+      asm volatile ("" : : "m" (v));
+#ifdef USE_FENV_H
+      int j = fetestexcept (FE_INEXACT) != 0;
+      feupdateenv (&env);
+#else
+      int j = 0;
+#endif
+      /* Ensure the following computations are performed in default rounding
+        mode instead of just reusing the round to zero computation.  */
+      asm volatile ("" : "=m" (u) : "m" (u));
+      /* If a1 + u.value is exact, the only rounding happens during
+        scaling down.  */
+      if (j == 0)
+       return v.value * 0x1p-226Q;
+      /* If result rounded to zero is not subnormal, no double
+        rounding will occur.  */
+      if (v.ieee.exponent > 226)
+       return (a1 + u.value) * 0x1p-226Q;
+      /* If v.value * 0x1p-226Q with round to zero is a subnormal above
+        or equal to FLT128_MIN / 2, then v.value * 0x1p-226Q shifts mantissa
+        down just by 1 bit, which means v.ieee.mant_low |= j would
+        change the round bit, not sticky or guard bit.
+        v.value * 0x1p-226Q never normalizes by shifting up,
+        so round bit plus sticky bit should be already enough
+        for proper rounding.  */
+      if (v.ieee.exponent == 226)
+       {
+         /* v.ieee.mant_low & 2 is LSB bit of the result before rounding,
+            v.ieee.mant_low & 1 is the round bit and j is our sticky
+            bit.  In round-to-nearest 001 rounds down like 00,
+            011 rounds up, even though 01 rounds down (thus we need
+            to adjust), 101 rounds down like 10 and 111 rounds up
+            like 11.  */
+         if ((v.ieee.mant_low & 3) == 1)
+           {
+             v.value *= 0x1p-226Q;
+             if (v.ieee.negative)
+               return v.value - 0x1p-16494Q /* __FLT128_DENORM_MIN__ */;
+             else
+               return v.value + 0x1p-16494Q /* __FLT128_DENORM_MIN__ */;
+           }
+         else
+           return v.value * 0x1p-226Q;
+       }
+      v.ieee.mant_low |= j;
+      return v.value * 0x1p-226Q;
+    }
+}
index e297529..ac9359b 100644 (file)
@@ -24,6 +24,7 @@ Boston, MA 02110-1301, USA.  */
 #include <stdint.h>
 #include <stdlib.h>
 #include "quadmath.h"
+#include "config.h"
 
 
 // Prototypes for internal functions
index 2268360..5fe9549 100644 (file)
@@ -48,6 +48,7 @@ extern __float128 expm1q (__float128);
 extern __float128 fabsq (__float128);
 extern int finiteq (const __float128);
 extern __float128 floorq (__float128);
+extern __float128 fmaq (__float128, __float128, __float128);
 extern __float128 fmodq (__float128, __float128);
 extern __float128 frexpq (__float128, int *);
 extern __float128 hypotq (__float128, __float128);
index 1d016fb..f70cda1 100644 (file)
@@ -19,6 +19,7 @@ QUADMATH_1.0 {
     fabsq;
     finiteq;
     floorq;
+    fmaq;
     fmodq;
     frexpq;
     hypotq;
index a14014e..05b0438 100644 (file)
@@ -55,6 +55,7 @@ __qmath3 (expm1q)
 __qmath3 (fabsq)
 __qmath3 (finiteq)
 __qmath3 (floorq)
+__qmath3 (fmaq)
 __qmath3 (fmodq)
 __qmath3 (frexpq)
 __qmath3 (hypotq)