OSDN Git Service

PR fortran/31202
authorfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Aug 2007 21:26:10 +0000 (21:26 +0000)
committerfxcoudert <fxcoudert@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 3 Aug 2007 21:26:10 +0000 (21:26 +0000)
        * f95-lang.c (gfc_init_builtin_functions): Defin builtins for
        lround{f,,l} and llround{f,,l}.
        * trans-intrinsic.c (build_fix_expr): Generate calls to the
        {l,}round{f,,l} functions.

        * intrinsics/c99_functions.c (roundl,lroundf,lround,lroundl,
        llroundf,llround,llroundl): New functions.
        * c99_protos.h (roundl,lroundf,lround,lroundl,llroundf,llround,
        llroundl): New prototypes.
        * configure.ac: Check for lroundf, lround, lroundl, llroundf,
        llround and llroundl.
        * configure: Regenerate.
        * Makefile.in: Regenerate.
        * config.h.in: Regenerate.

        * gfortran.dg/nint_2.f90: New test.

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

12 files changed:
gcc/fortran/ChangeLog
gcc/fortran/f95-lang.c
gcc/fortran/trans-intrinsic.c
gcc/testsuite/ChangeLog
gcc/testsuite/gfortran.dg/nint_2.f90 [new file with mode: 0644]
libgfortran/ChangeLog
libgfortran/Makefile.in
libgfortran/c99_protos.h
libgfortran/config.h.in
libgfortran/configure
libgfortran/configure.ac
libgfortran/intrinsics/c99_functions.c

index c8e4a3c..5d1695b 100644 (file)
@@ -1,3 +1,11 @@
+2007-08-03  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+
+       PR fortran/31202
+       * f95-lang.c (gfc_init_builtin_functions): Defin builtins for 
+       lround{f,,l} and llround{f,,l}.
+       * trans-intrinsic.c (build_fix_expr): Generate calls to the
+       {l,}round{f,,l} functions.
+
 2007-08-01  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR libfortran/32954
index 0cecac0..425f4d3 100644 (file)
@@ -852,7 +852,7 @@ gfc_init_builtin_functions (void)
   tree func_double_doublep_doublep;
   tree func_longdouble_longdoublep_longdoublep;
   tree ftype, ptype;
-  tree tmp;
+  tree tmp, type;
   tree builtin_types[(int) BT_LAST + 1];
 
   build_builtin_fntypes (mfunc_float, float_type_node);
@@ -942,6 +942,31 @@ gfc_init_builtin_functions (void)
   gfc_define_builtin ("__builtin_fmodf", mfunc_float[1], 
                      BUILT_IN_FMODF, "fmodf", true);
 
+  /* lround{f,,l} and llround{f,,l} */
+  type = tree_cons (NULL_TREE, float_type_node, void_list_node);
+  tmp = build_function_type (long_integer_type_node, type); 
+  gfc_define_builtin ("__builtin_lroundf", tmp, BUILT_IN_LROUNDF,
+                     "lroundf", true);
+  tmp = build_function_type (long_long_integer_type_node, type); 
+  gfc_define_builtin ("__builtin_llroundf", tmp, BUILT_IN_LLROUNDF,
+                     "llroundf", true);
+
+  type = tree_cons (NULL_TREE, double_type_node, void_list_node);
+  tmp = build_function_type (long_integer_type_node, type); 
+  gfc_define_builtin ("__builtin_lround", tmp, BUILT_IN_LROUND,
+                     "lround", true);
+  tmp = build_function_type (long_long_integer_type_node, type); 
+  gfc_define_builtin ("__builtin_llround", tmp, BUILT_IN_LLROUND,
+                     "llround", true);
+
+  type = tree_cons (NULL_TREE, long_double_type_node, void_list_node);
+  tmp = build_function_type (long_integer_type_node, type); 
+  gfc_define_builtin ("__builtin_lroundl", tmp, BUILT_IN_LROUNDL,
+                     "lroundl", true);
+  tmp = build_function_type (long_long_integer_type_node, type); 
+  gfc_define_builtin ("__builtin_llroundl", tmp, BUILT_IN_LLROUNDL,
+                     "llroundl", true);
+
   /* These are used to implement the ** operator.  */
   gfc_define_builtin ("__builtin_powl", mfunc_longdouble[1], 
                      BUILT_IN_POWL, "powl", true);
index 39deadb..dc67240 100644 (file)
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
+#include "tm.h"
 #include "tree.h"
 #include "ggc.h"
 #include "toplev.h"
@@ -308,34 +309,57 @@ build_fixbound_expr (stmtblock_t * pblock, tree arg, tree type, int up)
 }
 
 
-/* This is needed because the gcc backend only implements FIX_TRUNC_EXPR
-   NINT(x) = INT(x + ((x > 0) ? 0.5 : -0.5)).  */
+/* Round to nearest integer, away from zero.  */
 
 static tree
-build_round_expr (stmtblock_t * pblock, tree arg, tree type)
+build_round_expr (tree arg, tree restype)
 {
   tree tmp;
-  tree cond;
-  tree neg;
-  tree pos;
   tree argtype;
-  REAL_VALUE_TYPE r;
+  tree fn;
+  bool longlong, convert;
+  int argprec, resprec;
 
   argtype = TREE_TYPE (arg);
-  arg = gfc_evaluate_now (arg, pblock);
+  argprec = TYPE_PRECISION (argtype);
+  resprec = TYPE_PRECISION (restype);
 
-  real_from_string (&r, "0.5");
-  pos = build_real (argtype, r);
-
-  real_from_string (&r, "-0.5");
-  neg = build_real (argtype, r);
+  /* Depending on the type of the result, choose the long int intrinsic
+     (lround family) or long long intrinsic (llround).  We might also
+     need to convert the result afterwards.  */
+  if (resprec <= LONG_TYPE_SIZE)
+    {
+      longlong = false;
+      if (resprec != LONG_TYPE_SIZE)
+       convert = true;
+      else
+       convert = false;
+    }
+  else if (resprec <= LONG_LONG_TYPE_SIZE)
+    {
+      longlong = true;
+      if (resprec != LONG_LONG_TYPE_SIZE)
+       convert = true;
+      else
+       convert = false;
+    }
+  else
+    gcc_unreachable ();
 
-  tmp = gfc_build_const (argtype, integer_zero_node);
-  cond = fold_build2 (GT_EXPR, boolean_type_node, arg, tmp);
+  /* Now, depending on the argument type, we choose between intrinsics.  */
+  if (argprec == TYPE_PRECISION (float_type_node))
+    fn = built_in_decls[longlong ? BUILT_IN_LLROUNDF : BUILT_IN_LROUNDF];
+  else if (argprec == TYPE_PRECISION (double_type_node))
+    fn = built_in_decls[longlong ? BUILT_IN_LLROUND : BUILT_IN_LROUND];
+  else if (argprec == TYPE_PRECISION (long_double_type_node))
+    fn = built_in_decls[longlong ? BUILT_IN_LLROUNDL : BUILT_IN_LROUNDL];
+  else
+    gcc_unreachable ();
 
-  tmp = fold_build3 (COND_EXPR, argtype, cond, pos, neg);
-  tmp = fold_build2 (PLUS_EXPR, argtype, arg, tmp);
-  return fold_build1 (FIX_TRUNC_EXPR, type, tmp);
+  tmp = build_call_expr (fn, 1, arg);
+  if (convert)
+    tmp = fold_convert (restype, tmp);
+  return tmp;
 }
 
 
@@ -358,11 +382,15 @@ build_fix_expr (stmtblock_t * pblock, tree arg, tree type,
       break;
 
     case RND_ROUND:
-      return build_round_expr (pblock, arg, type);
+      return build_round_expr (arg, type);
+      break;
 
-    default:
-      gcc_assert (op == RND_TRUNC);
+    case RND_TRUNC:
       return build1 (FIX_TRUNC_EXPR, type, arg);
+      break;
+
+    default:
+      gcc_unreachable ();
     }
 }
 
index 892eb9c..e548278 100644 (file)
@@ -1,3 +1,8 @@
+2007-08-03  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+
+       PR fortran/31202
+       * gfortran.dg/nint_2.f90: New test.
+
 2007-08-03  Nathan Froyd  <froydnj@codesourcery.com>
 
        * gcc.dg/tree-ssa/loop-1.c: Skip on powerpc targets if -mlongcall.
diff --git a/gcc/testsuite/gfortran.dg/nint_2.f90 b/gcc/testsuite/gfortran.dg/nint_2.f90
new file mode 100644 (file)
index 0000000..b993cb4
--- /dev/null
@@ -0,0 +1,51 @@
+! Test that NINT gives right results even in corner cases
+!
+! PR 31202
+! http://gcc.gnu.org/ml/fortran/2005-04/msg00139.html
+!
+! { dg-do run }
+  real(kind=8) :: a
+  integer(kind=8) :: i1, i2
+  real :: b
+  integer :: j1, j2
+
+  a = nearest(0.5_8,-1.0_8)
+  i2 = nint(nearest(0.5_8,-1.0_8))
+  i1 = nint(a)
+  if (i1 /= 0 .or. i2 /= 0) call abort
+
+  a = 0.5_8
+  i2 = nint(0.5_8)
+  i1 = nint(a)
+  if (i1 /= 1 .or. i2 /= 1) call abort
+
+  a = nearest(0.5_8,1.0_8)
+  i2 = nint(nearest(0.5_8,1.0_8))
+  i1 = nint(a)
+  if (i1 /= 1 .or. i2 /= 1) call abort
+
+  b = nearest(0.5,-1.0)
+  j2 = nint(nearest(0.5,-1.0))
+  j1 = nint(b)
+  if (j1 /= 0 .or. j2 /= 0) call abort
+
+  b = 0.5
+  j2 = nint(0.5)
+  j1 = nint(b)
+  if (j1 /= 1 .or. j2 /= 1) call abort
+
+  b = nearest(0.5,1.0)
+  j2 = nint(nearest(0.5,1.0))
+  j1 = nint(b)
+  if (j1 /= 1 .or. j2 /= 1) call abort
+
+  a = 4503599627370497.0_8
+  i1 = nint(a,kind=8)
+  i2 = nint(4503599627370497.0_8,kind=8)
+  if (i1 /= i2 .or. i1 /= 4503599627370497_8) call abort
+
+  a = -4503599627370497.0_8
+  i1 = nint(a,kind=8)
+  i2 = nint(-4503599627370497.0_8,kind=8)
+  if (i1 /= i2 .or. i1 /= -4503599627370497_8) call abort
+  end
index 7642d96..eb03d0a 100644 (file)
@@ -1,3 +1,16 @@
+2007-08-03  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
+
+       PR fortran/31202
+       * intrinsics/c99_functions.c (roundl,lroundf,lround,lroundl,
+       llroundf,llround,llroundl): New functions.
+       * c99_protos.h (roundl,lroundf,lround,lroundl,llroundf,llround,
+       llroundl): New prototypes.
+       * configure.ac: Check for lroundf, lround, lroundl, llroundf,
+       llround and llroundl.
+       * configure: Regenerate.
+       * Makefile.in: Regenerate.
+       * config.h.in: Regenerate.
+
 2007-07-30  Francois-Xavier Coudert  <fxcoudert@gcc.gnu.org>
 
        * libgfortran.h: Include <stdarg.h>.
index 90715d4..9d78ad2 100644 (file)
@@ -50,8 +50,8 @@ am__aclocal_m4_deps = $(top_srcdir)/../config/depstand.m4 \
        $(top_srcdir)/../config/multi.m4 \
        $(top_srcdir)/../config/stdint.m4 \
        $(top_srcdir)/../ltoptions.m4 $(top_srcdir)/../ltsugar.m4 \
-       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/acinclude.m4 \
-       $(top_srcdir)/../config/acx.m4 \
+       $(top_srcdir)/../ltversion.m4 $(top_srcdir)/../lt~obsolete.m4 \
+       $(top_srcdir)/acinclude.m4 $(top_srcdir)/../config/acx.m4 \
        $(top_srcdir)/../config/no-executables.m4 \
        $(top_srcdir)/../libtool.m4 $(top_srcdir)/configure.ac
 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
@@ -343,9 +343,13 @@ SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 STRIP = @STRIP@
 VERSION = @VERSION@
+ac_ct_AR = @ac_ct_AR@
+ac_ct_AS = @ac_ct_AS@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
 ac_ct_FC = @ac_ct_FC@
+ac_ct_RANLIB = @ac_ct_RANLIB@
+ac_ct_STRIP = @ac_ct_STRIP@
 am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
 am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
 am__include = @am__include@
@@ -362,9 +366,6 @@ build_os = @build_os@
 build_subdir = @build_subdir@
 build_vendor = @build_vendor@
 datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
 enable_shared = @enable_shared@
 enable_static = @enable_static@
 exec_prefix = @exec_prefix@
@@ -375,23 +376,19 @@ host_cpu = @host_cpu@
 host_os = @host_os@
 host_subdir = @host_subdir@
 host_vendor = @host_vendor@
-htmldir = @htmldir@
 includedir = @includedir@
 infodir = @infodir@
 install_sh = @install_sh@
 libdir = @libdir@
 libexecdir = @libexecdir@
-localedir = @localedir@
 localstatedir = @localstatedir@
 lt_ECHO = @lt_ECHO@
 mandir = @mandir@
 mkdir_p = @mkdir_p@
 multi_basedir = @multi_basedir@
 oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
-psdir = @psdir@
 sbindir = @sbindir@
 sharedstatedir = @sharedstatedir@
 sysconfdir = @sysconfdir@
index 369299d..c4738db 100644 (file)
@@ -200,6 +200,43 @@ extern double round(double);
 extern float roundf(float);
 #endif
 
+#if !defined(HAVE_ROUNDL) && defined(HAVE_CEILL)
+#define HAVE_ROUNDL 1
+extern long double roundl(long double);
+#endif
+
+
+
+#if !defined(HAVE_LROUNDF) && defined(HAVE_ROUNDF)
+#define HAVE_LROUNDF 1
+long int lroundf (float);
+#endif
+
+#if !defined(HAVE_LROUND) && defined(HAVE_ROUND)
+#define HAVE_LROUND 1
+long int lround (double);
+#endif
+
+#if !defined(HAVE_LROUNDL) && defined(HAVE_ROUNDL)
+#define HAVE_LROUNDL 1
+long int lroundl (long double);
+#endif
+
+#if !defined(HAVE_LLROUNDF) && defined(HAVE_ROUNDF)
+#define HAVE_LLROUNDF 1
+long long int llroundf (float);
+#endif
+
+#if !defined(HAVE_LLROUND) && defined(HAVE_ROUND)
+#define HAVE_LLROUND 1
+long long int llround (double);
+#endif
+
+#if !defined(HAVE_LLROUNDL) && defined(HAVE_ROUNDL)
+#define HAVE_LLROUNDL 1
+long long int llroundl (long double);
+#endif
+
 /* Wrappers for systems without the various C99 single precision Bessel
    functions.  */
 
index 0779149..4099c39 100644 (file)
 /* Define to 1 if you have the `link' function. */
 #undef HAVE_LINK
 
+/* libm includes llround */
+#undef HAVE_LLROUND
+
+/* libm includes llroundf */
+#undef HAVE_LLROUNDF
+
+/* libm includes llroundl */
+#undef HAVE_LLROUNDL
+
 /* libm includes log */
 #undef HAVE_LOG
 
 /* libm includes logl */
 #undef HAVE_LOGL
 
+/* libm includes lround */
+#undef HAVE_LROUND
+
+/* libm includes lroundf */
+#undef HAVE_LROUNDF
+
+/* libm includes lroundl */
+#undef HAVE_LROUNDL
+
 /* Define to 1 if you have the `lstat' function. */
 #undef HAVE_LSTAT
 
index 7e568a3..b9a0cf5 100755 (executable)
@@ -26314,6 +26314,468 @@ _ACEOF
 
 fi
 
+echo "$as_me:$LINENO: checking for lroundf in -lm" >&5
+echo $ECHO_N "checking for lroundf in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_lroundf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char lroundf ();
+int
+main ()
+{
+lroundf ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_lroundf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_lroundf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_lroundf" >&5
+echo "${ECHO_T}$ac_cv_lib_m_lroundf" >&6
+if test $ac_cv_lib_m_lroundf = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LROUNDF 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for lround in -lm" >&5
+echo $ECHO_N "checking for lround in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_lround+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char lround ();
+int
+main ()
+{
+lround ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_lround=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_lround=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_lround" >&5
+echo "${ECHO_T}$ac_cv_lib_m_lround" >&6
+if test $ac_cv_lib_m_lround = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LROUND 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for lroundl in -lm" >&5
+echo $ECHO_N "checking for lroundl in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_lroundl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char lroundl ();
+int
+main ()
+{
+lroundl ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_lroundl=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_lroundl=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_lroundl" >&5
+echo "${ECHO_T}$ac_cv_lib_m_lroundl" >&6
+if test $ac_cv_lib_m_lroundl = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LROUNDL 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for llroundf in -lm" >&5
+echo $ECHO_N "checking for llroundf in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_llroundf+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char llroundf ();
+int
+main ()
+{
+llroundf ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_llroundf=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_llroundf=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_llroundf" >&5
+echo "${ECHO_T}$ac_cv_lib_m_llroundf" >&6
+if test $ac_cv_lib_m_llroundf = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LLROUNDF 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for llround in -lm" >&5
+echo $ECHO_N "checking for llround in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_llround+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char llround ();
+int
+main ()
+{
+llround ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_llround=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_llround=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_llround" >&5
+echo "${ECHO_T}$ac_cv_lib_m_llround" >&6
+if test $ac_cv_lib_m_llround = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LLROUND 1
+_ACEOF
+
+fi
+
+echo "$as_me:$LINENO: checking for llroundl in -lm" >&5
+echo $ECHO_N "checking for llroundl in -lm... $ECHO_C" >&6
+if test "${ac_cv_lib_m_llroundl+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lm  $LIBS"
+if test x$gcc_no_link = xyes; then
+  { { echo "$as_me:$LINENO: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&5
+echo "$as_me: error: Link tests are not allowed after GCC_NO_EXECUTABLES." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any gcc2 internal prototype to avoid an error.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+   builtin and then its argument prototype would still apply.  */
+char llroundl ();
+int
+main ()
+{
+llroundl ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+  (eval $ac_link) 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+        { ac_try='test -z "$ac_c_werror_flag"
+                        || test ! -s conftest.err'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; } &&
+        { ac_try='test -s conftest$ac_exeext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_cv_lib_m_llroundl=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_lib_m_llroundl=no
+fi
+rm -f conftest.err conftest.$ac_objext \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_lib_m_llroundl" >&5
+echo "${ECHO_T}$ac_cv_lib_m_llroundl" >&6
+if test $ac_cv_lib_m_llroundl = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LLROUNDL 1
+_ACEOF
+
+fi
+
 echo "$as_me:$LINENO: checking for scalbnf in -lm" >&5
 echo $ECHO_N "checking for scalbnf in -lm... $ECHO_C" >&6
 if test "${ac_cv_lib_m_scalbnf+set}" = set; then
index 0c85326..8709e16 100644 (file)
@@ -301,6 +301,12 @@ AC_CHECK_LIB([m],[cpowl],[AC_DEFINE([HAVE_CPOWL],[1],[libm includes cpowl])])
 AC_CHECK_LIB([m],[roundf],[AC_DEFINE([HAVE_ROUNDF],[1],[libm includes roundf])])
 AC_CHECK_LIB([m],[round],[AC_DEFINE([HAVE_ROUND],[1],[libm includes round])])
 AC_CHECK_LIB([m],[roundl],[AC_DEFINE([HAVE_ROUNDL],[1],[libm includes roundl])])
+AC_CHECK_LIB([m],[lroundf],[AC_DEFINE([HAVE_LROUNDF],[1],[libm includes lroundf])])
+AC_CHECK_LIB([m],[lround],[AC_DEFINE([HAVE_LROUND],[1],[libm includes lround])])
+AC_CHECK_LIB([m],[lroundl],[AC_DEFINE([HAVE_LROUNDL],[1],[libm includes lroundl])])
+AC_CHECK_LIB([m],[llroundf],[AC_DEFINE([HAVE_LLROUNDF],[1],[libm includes llroundf])])
+AC_CHECK_LIB([m],[llround],[AC_DEFINE([HAVE_LLROUND],[1],[libm includes llround])])
+AC_CHECK_LIB([m],[llroundl],[AC_DEFINE([HAVE_LLROUNDL],[1],[libm includes llroundl])])
 AC_CHECK_LIB([m],[scalbnf],[AC_DEFINE([HAVE_SCALBNF],[1],[libm includes scalbnf])])
 AC_CHECK_LIB([m],[scalbn],[AC_DEFINE([HAVE_SCALBN],[1],[libm includes scalbn])])
 AC_CHECK_LIB([m],[scalbnl],[AC_DEFINE([HAVE_SCALBNL],[1],[libm includes scalbnl])])
index 8b82ae3..e36c5ba 100644 (file)
@@ -500,6 +500,35 @@ powf(float x, float y)
 
 /* Algorithm by Steven G. Kargl.  */
 
+#if !defined(HAVE_ROUNDL) && defined(HAVE_CEILL)
+#define HAVE_ROUNDL 1
+/* Round to nearest integral value.  If the argument is halfway between two
+   integral values then round away from zero.  */
+
+long double
+roundl(long double x)
+{
+   long double t;
+   if (!isfinite (x))
+     return (x);
+
+   if (x >= 0.0)
+    {
+      t = ceill(x);
+      if (t - x > 0.5)
+       t -= 1.0;
+      return (t);
+    } 
+   else 
+    {
+      t = ceill(-x);
+      if (t + x > 0.5)
+       t -= 1.0;
+      return (-t);
+    }
+}
+#endif
+
 #ifndef HAVE_ROUND
 #define HAVE_ROUND 1
 /* Round to nearest integral value.  If the argument is halfway between two
@@ -558,6 +587,64 @@ roundf(float x)
 }
 #endif
 
+
+/* lround{f,,l} and llround{f,,l} functions.  */
+
+#if !defined(HAVE_LROUNDF) && defined(HAVE_ROUNDF)
+#define HAVE_LROUNDF 1
+long int
+lroundf (float x)
+{
+  return (long int) roundf (x);
+}
+#endif
+
+#if !defined(HAVE_LROUND) && defined(HAVE_ROUND)
+#define HAVE_LROUND 1
+long int
+lround (double x)
+{
+  return (long int) round (x);
+}
+#endif
+
+#if !defined(HAVE_LROUNDL) && defined(HAVE_ROUNDL)
+#define HAVE_LROUNDL 1
+long int
+lroundl (long double x)
+{
+  return (long long int) roundl (x);
+}
+#endif
+
+#if !defined(HAVE_LLROUNDF) && defined(HAVE_ROUNDF)
+#define HAVE_LLROUNDF 1
+long long int
+llroundf (float x)
+{
+  return (long long int) roundf (x);
+}
+#endif
+
+#if !defined(HAVE_LLROUND) && defined(HAVE_ROUND)
+#define HAVE_LLROUND 1
+long long int
+llround (double x)
+{
+  return (long long int) round (x);
+}
+#endif
+
+#if !defined(HAVE_LLROUNDL) && defined(HAVE_ROUNDL)
+#define HAVE_LLROUNDL 1
+long long int
+llroundl (long double x)
+{
+  return (long long int) roundl (x);
+}
+#endif
+
+
 #ifndef HAVE_LOG10L
 #define HAVE_LOG10L 1
 /* log10 function for long double variables. The version provided here