[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Commits] r20640 - in /fsf/trunk/libc: ./ include/ ports/ ports/sysdeps/arm/ ports/sysdeps/powerpc/nofpu/ stdlib/ sysdeps/generic/ sys...



Author: eglibc
Date: Thu Sep 13 00:01:55 2012
New Revision: 20640

Log:
Import glibc-mainline for 2012-09-13

Added:
    fsf/trunk/libc/include/rounding-mode.h
    fsf/trunk/libc/ports/sysdeps/arm/get-rounding-mode.h
    fsf/trunk/libc/ports/sysdeps/powerpc/nofpu/get-rounding-mode.h
    fsf/trunk/libc/sysdeps/generic/get-rounding-mode.h
    fsf/trunk/libc/sysdeps/s390/fpu/get-rounding-mode.h
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/NEWS
    fsf/trunk/libc/ports/ChangeLog.arm
    fsf/trunk/libc/ports/ChangeLog.powerpc
    fsf/trunk/libc/stdlib/Makefile
    fsf/trunk/libc/stdlib/strtod_l.c
    fsf/trunk/libc/stdlib/tst-strtod-round.c
    fsf/trunk/libc/sysdeps/i386/fpu/libm-test-ulps

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Thu Sep 13 00:01:55 2012
@@ -1,3 +1,34 @@
+2012-09-12  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	[BZ #14518]
+	* include/rounding-mode.h: New file.
+	* sysdeps/generic/get-rounding-mode.h: Likewise.
+	* sysdeps/s390/fpu/get-rounding-mode.h: Likewise.
+	* stdlib/strtod_l.c: Include <rounding-mode.h>.
+	(MAX_VALUE): New macro.
+	(MIN_VALUE): Likewise.
+	(overflow_value): New function.
+	(underflow_value): Likewise.
+	(round_and_return): Use overflow_value and underflow_value to
+	determine return values in overflow and underflow cases.  Use
+	round_away to determine rounding depending on rounding mode.
+	(____STRTOF_INTERNAL): Use overflow_value and underflow_value to
+	determine return values in overflow and underflow cases.
+	* stdlib/tst-strtod-round.c: Include <fenv.h>.
+	(struct test_results): New structure.
+	(struct test): Use struct test_results to store expected results
+	for all rounding modes.
+	(TEST): Include expected results for all rounding modes.
+	(test_in_one_mode): New function.
+	(do_test): Use test_in_one_mode to compute and check results.
+	Check results for all rounding modes.
+	* stdlib/Makefile ($(objpfx)tst-strtod-round): Depend on
+	$(link-libm).
+
+2012-12-09  Allan McRae  <allan@xxxxxxxxxxxxx>
+
+        * sysdeps/i386/fpu/libm-test-ulps: Update
+
 2012-09-11  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
 
 	* sysdeps/generic/_G_config.h (_G_int16_t): Remove.

Modified: fsf/trunk/libc/NEWS
==============================================================================
--- fsf/trunk/libc/NEWS (original)
+++ fsf/trunk/libc/NEWS Thu Sep 13 00:01:55 2012
@@ -13,7 +13,7 @@
   13542, 13717, 13696, 13939, 13966, 14042, 14090, 14166, 14150, 14151,
   14154, 14157, 14166, 14173, 14195, 14237, 14252, 14283, 14298, 14303,
   14307, 14328, 14331, 14336, 14337, 14347, 14349, 14459, 14476, 14505,
-  14510, 14516, 14519, 14532, 14538, 14544, 14545.
+  14510, 14516, 14518, 14519, 14532, 14538, 14544, 14545.
 
 * Support for STT_GNU_IFUNC symbols added for s390 and s390x.
   Optimized versions of memcpy, memset, and memcmp added for System z10 and

Added: fsf/trunk/libc/include/rounding-mode.h
==============================================================================
--- fsf/trunk/libc/include/rounding-mode.h (added)
+++ fsf/trunk/libc/include/rounding-mode.h Thu Sep 13 00:01:55 2012
@@ -1,0 +1,65 @@
+/* Handle floating-point rounding mode within libc.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ROUNDING_MODE_H
+#define _ROUNDING_MODE_H	1
+
+#include <fenv.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+/* Get the architecture-specific definition of how to determine the
+   rounding mode in libc.  This header must also define the FE_*
+   macros for any standard rounding modes the architecture does not
+   have in <fenv.h>, to arbitrary distinct values.  */
+#include <get-rounding-mode.h>
+
+/* Return true if a number should be rounded away from zero in
+   rounding mode MODE, false otherwise.  NEGATIVE is true if the
+   number is negative, false otherwise.  LAST_DIGIT_ODD is true if the
+   last digit of the truncated value (last bit for binary) is odd,
+   false otherwise.  HALF_BIT is true if the number is at least half
+   way from the truncated value to the next value with the
+   least-significant digit in the same place, false otherwise.
+   MORE_BITS is true if the number is not exactly equal to the
+   truncated value or the half-way value, false otherwise.  */
+
+static inline bool
+round_away (bool negative, bool last_digit_odd, bool half_bit, bool more_bits,
+	    int mode)
+{
+  switch (mode)
+    {
+    case FE_DOWNWARD:
+      return negative && (half_bit || more_bits);
+
+    case FE_TONEAREST:
+      return half_bit && (last_digit_odd || more_bits);
+
+    case FE_TOWARDZERO:
+      return false;
+
+    case FE_UPWARD:
+      return !negative && (half_bit || more_bits);
+
+    default:
+      abort ();
+    }
+}
+
+#endif /* rounding-mode.h */

Modified: fsf/trunk/libc/ports/ChangeLog.arm
==============================================================================
--- fsf/trunk/libc/ports/ChangeLog.arm (original)
+++ fsf/trunk/libc/ports/ChangeLog.arm Thu Sep 13 00:01:55 2012
@@ -1,3 +1,7 @@
+2012-09-12  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/arm/get-rounding-mode.h: New file.
+
 2012-08-27  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
 
 	* sysdeps/unix/sysv/linux/arm/kernel-features.h

Modified: fsf/trunk/libc/ports/ChangeLog.powerpc
==============================================================================
--- fsf/trunk/libc/ports/ChangeLog.powerpc (original)
+++ fsf/trunk/libc/ports/ChangeLog.powerpc Thu Sep 13 00:01:55 2012
@@ -1,3 +1,7 @@
+2012-09-12  Joseph Myers  <joseph@xxxxxxxxxxxxxxxx>
+
+	* sysdeps/powerpc/nofpu/get-rounding-mode.h: New file.
+
 2012-07-25  Florian Weimer  <fweimer@xxxxxxxxxx>
 
 	* sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/nptl/libc.abilist:

Added: fsf/trunk/libc/ports/sysdeps/arm/get-rounding-mode.h
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/arm/get-rounding-mode.h (added)
+++ fsf/trunk/libc/ports/sysdeps/arm/get-rounding-mode.h Thu Sep 13 00:01:55 2012
@@ -1,0 +1,42 @@
+/* Determine floating-point rounding mode within libc.  ARM version.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _ARM_GET_ROUNDING_MODE_H
+#define _ARM_GET_ROUNDING_MODE_H	1
+
+#include <arm-features.h>
+#include <fenv.h>
+#include <fpu_control.h>
+
+/* Return the floating-point rounding mode.  */
+
+static inline int
+get_rounding_mode (void)
+{
+  if (ARM_HAVE_VFP)
+    {
+      fpu_control_t fc;
+
+      _FPU_GETCW (fc);
+      return fc & FE_TOWARDZERO;
+    }
+  else
+    return FE_TONEAREST;
+}
+
+#endif /* get-rounding-mode.h */

Added: fsf/trunk/libc/ports/sysdeps/powerpc/nofpu/get-rounding-mode.h
==============================================================================
--- fsf/trunk/libc/ports/sysdeps/powerpc/nofpu/get-rounding-mode.h (added)
+++ fsf/trunk/libc/ports/sysdeps/powerpc/nofpu/get-rounding-mode.h Thu Sep 13 00:01:55 2012
@@ -1,0 +1,35 @@
+/* Determine floating-point rounding mode within libc.  PowerPC
+   soft-float version.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _POWERPC_NOFPU_GET_ROUNDING_MODE_H
+#define _POWERPC_NOFPU_GET_ROUNDING_MODE_H	1
+
+#include <fenv.h>
+
+#include "soft-supp.h"
+
+/* Return the floating-point rounding mode.  */
+
+static inline int
+get_rounding_mode (void)
+{
+  return __sim_round_mode;
+}
+
+#endif /* get-rounding-mode.h */

Modified: fsf/trunk/libc/stdlib/Makefile
==============================================================================
--- fsf/trunk/libc/stdlib/Makefile (original)
+++ fsf/trunk/libc/stdlib/Makefile Thu Sep 13 00:01:55 2012
@@ -150,3 +150,4 @@
 link-libm = $(common-objpfx)math/libm.a
 endif
 $(objpfx)bug-getcontext: $(link-libm)
+$(objpfx)tst-strtod-round: $(link-libm)

Modified: fsf/trunk/libc/stdlib/strtod_l.c
==============================================================================
--- fsf/trunk/libc/stdlib/strtod_l.c (original)
+++ fsf/trunk/libc/stdlib/strtod_l.c Thu Sep 13 00:01:55 2012
@@ -61,6 +61,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdint.h>
+#include <rounding-mode.h>
 
 /* The gmp headers need some configuration frobs.  */
 #define HAVE_ALLOCA 1
@@ -126,6 +127,8 @@
 #define	MIN_EXP		PASTE(FLT,_MIN_EXP)
 #define MAX_10_EXP	PASTE(FLT,_MAX_10_EXP)
 #define MIN_10_EXP	PASTE(FLT,_MIN_10_EXP)
+#define MAX_VALUE	PASTE(FLT,_MAX)
+#define MIN_VALUE	PASTE(FLT,_MIN)
 
 /* Extra macros required to get FLT expanded before the pasting.  */
 #define PASTE(a,b)	PASTE1(a,b)
@@ -172,6 +175,34 @@
 	memcpy (dst, src, (dst##size = src##size) * sizeof (mp_limb_t))
 
 
+/* Set errno and return an overflowing value with sign specified by
+   NEGATIVE.  */
+static FLOAT
+overflow_value (int negative)
+{
+  __set_errno (ERANGE);
+#if FLT_EVAL_METHOD != 0
+  volatile
+#endif
+  FLOAT result = (negative ? -MAX_VALUE : MAX_VALUE) * MAX_VALUE;
+  return result;
+}
+
+
+/* Set errno and return an underflowing value with sign specified by
+   NEGATIVE.  */
+static FLOAT
+underflow_value (int negative)
+{
+  __set_errno (ERANGE);
+#if FLT_EVAL_METHOD != 0
+  volatile
+#endif
+  FLOAT result = (negative ? -MIN_VALUE : MIN_VALUE) * MIN_VALUE;
+  return result;
+}
+
+
 /* Return a floating point number of the needed type according to the given
    multi-precision number after possible rounding.  */
 static FLOAT
@@ -181,10 +212,7 @@
   if (exponent < MIN_EXP - 1)
     {
       if (exponent < MIN_EXP - 1 - MANT_DIG)
-	{
-	  __set_errno (ERANGE);
-	  return negative ? -0.0 : 0.0;
-	}
+	return underflow_value (negative);
 
       mp_size_t shift = MIN_EXP - 1 - exponent;
 
@@ -237,9 +265,14 @@
   if (exponent > MAX_EXP)
     goto overflow;
 
-  if ((round_limb & (((mp_limb_t) 1) << round_bit)) != 0
-      && (more_bits || (retval[0] & 1) != 0
-	  || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0))
+  int mode = get_rounding_mode ();
+
+  if (round_away (negative,
+		  (retval[0] & 1) != 0,
+		  (round_limb & (((mp_limb_t) 1) << round_bit)) != 0,
+		  (more_bits
+		   || (round_limb & ((((mp_limb_t) 1) << round_bit) - 1)) != 0),
+		  mode))
     {
       mp_limb_t cy = __mpn_add_1 (retval, retval, RETURN_LIMB_SIZE, 1);
 
@@ -263,7 +296,7 @@
 
   if (exponent > MAX_EXP)
   overflow:
-    return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
+    return overflow_value (negative);
 
   return MPN2FLOAT (retval, exponent, negative);
 }
@@ -914,9 +947,9 @@
 		  else
 		    {
 		      /* Overflow or underflow.  */
-		      __set_errno (ERANGE);
-		      result = (exp_negative ? (negative ? -0.0 : 0.0) :
-				negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL);
+		      result = (exp_negative
+				? underflow_value (negative)
+				: overflow_value (negative));
 		    }
 
 		  /* Accept all following digits as part of the exponent.  */
@@ -1112,16 +1145,10 @@
   }
 
   if (__builtin_expect (exponent > MAX_10_EXP + 1 - (intmax_t) int_no, 0))
-    {
-      __set_errno (ERANGE);
-      return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
-    }
+    return overflow_value (negative);
 
   if (__builtin_expect (exponent < MIN_10_EXP - (DIG + 1), 0))
-    {
-      __set_errno (ERANGE);
-      return negative ? -0.0 : 0.0;
-    }
+    return underflow_value (negative);
 
   if (int_no > 0)
     {
@@ -1182,10 +1209,7 @@
       /* Now we know the exponent of the number in base two.
 	 Check it against the maximum possible exponent.  */
       if (__builtin_expect (bits > MAX_EXP, 0))
-	{
-	  __set_errno (ERANGE);
-	  return negative ? -FLOAT_HUGE_VAL : FLOAT_HUGE_VAL;
-	}
+	return overflow_value (negative);
 
       /* We have already the first BITS bits of the result.  Together with
 	 the information whether more non-zero bits follow this is enough

Modified: fsf/trunk/libc/stdlib/tst-strtod-round.c
==============================================================================
--- fsf/trunk/libc/stdlib/tst-strtod-round.c (original)
+++ fsf/trunk/libc/stdlib/tst-strtod-round.c Thu Sep 13 00:01:55 2012
@@ -17,6 +17,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#include <fenv.h>
 #include <float.h>
 #include <math.h>
 #include <stdbool.h>
@@ -24,12 +25,16 @@
 #include <stdlib.h>
 #include <string.h>
 
+struct test_results {
+  float f;
+  double d;
+  long double ld;
+};
+
 struct test {
   const char *s;
-  float f;
-  double d;
   bool ld_ok;
-  long double ld;
+  struct test_results rd, rn, rz, ru;
 };
 
 #if LDBL_MANT_DIG == 53 && LDBL_MAX_EXP == 1024
@@ -38,7 +43,14 @@
 	      ld64md, ld64mn, ld64mz, ld64mu,				      \
 	      ld106exact, ld106d, ld106n, ld106z, ld106u,		      \
 	      ld113d, ld113n, ld113z, ld113u)				      \
-  { s, fn, dn, true, ld53n }
+  {									\
+    s,									\
+    true,								\
+    { fd, dd, ld53d },							\
+    { fn, dn, ld53n },							\
+    { fz, dz, ld53z },							\
+    { fu, du, ld53u }							\
+  }
 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16381
 /* This is for the Intel extended float format.  */
 # define TEST(s, fd, fn, fz, fu, dd, dn, dz, du, ld53d, ld53n, ld53z, ld53u,  \
@@ -46,7 +58,14 @@
 	      ld64md, ld64mn, ld64mz, ld64mu,				      \
 	      ld106exact, ld106d, ld106n, ld106z, ld106u,		      \
 	      ld113d, ld113n, ld113z, ld113u)				      \
-  { s, fn, dn, true, ld64in }
+  {									\
+    s,									\
+    true,								\
+    { fd, dd, ld64id },							\
+    { fn, dn, ld64in },							\
+    { fz, dz, ld64iz },							\
+    { fu, du, ld64iu }							\
+  }
 #elif LDBL_MANT_DIG == 64 && LDBL_MAX_EXP == 16384 && LDBL_MIN_EXP == -16382
 /* This is for the Motorola extended float format.  */
 # define TEST(s, fd, fn, fz, fu, dd, dn, dz, du, ld53d, ld53n, ld53z, ld53u,  \
@@ -54,21 +73,42 @@
 	      ld64md, ld64mn, ld64mz, ld64mu,				      \
 	      ld106exact, ld106d, ld106n, ld106z, ld106u,		      \
 	      ld113d, ld113n, ld113z, ld113u)				      \
-  { s, fn, dn, true, ld64mn }
+  {									\
+    s,									\
+    true,								\
+    { fd, dd, ld64md },							\
+    { fn, dn, ld64mn },							\
+    { fz, dz, ld64mz },							\
+    { fu, du, ld64mu }							\
+  }
 #elif LDBL_MANT_DIG == 106 && LDBL_MAX_EXP == 1024
 # define TEST(s, fd, fn, fz, fu, dd, dn, dz, du, ld53d, ld53n, ld53z, ld53u,  \
 	      ld64id, ld64in, ld64iz, ld64iu,				      \
 	      ld64md, ld64mn, ld64mz, ld64mu,				      \
 	      ld106exact, ld106d, ld106n, ld106z, ld106u,		      \
 	      ld113d, ld113n, ld113z, ld113u)				      \
-  { s, fn, dn, ld106exact, ld106n }
+  {									\
+    s,									\
+    ld106exact,								\
+    { fd, dd, ld106d },							\
+    { fn, dn, ld106n },							\
+    { fz, dz, ld106z },							\
+    { fu, du, ld106u }							\
+  }
 #elif LDBL_MANT_DIG == 113 && LDBL_MAX_EXP == 16384
 # define TEST(s, fd, fn, fz, fu, dd, dn, dz, du, ld53d, ld53n, ld53z, ld53u,  \
 	      ld64id, ld64in, ld64iz, ld64iu,				      \
 	      ld64md, ld64mn, ld64mz, ld64mu,				      \
 	      ld106exact, ld106d, ld106n, ld106z, ld106u,		      \
 	      ld113d, ld113n, ld113z, ld113u)				      \
-  { s, fn, dn, true, ld113n }
+  {									\
+    s,									\
+    true,								\
+    { fd, dd, ld113d },							\
+    { fn, dn, ld113n },							\
+    { fz, dz, ld113z },							\
+    { fu, du, ld113u }							\
+  }
 #else
 # error "unknown long double format"
 #endif
@@ -6819,38 +6859,73 @@
 };
 
 static int
+test_in_one_mode (const char *s, const struct test_results *expected,
+		  bool ld_ok, const char *mode_name)
+{
+  int result = 0;
+  float f = strtof (s, NULL);
+  double d = strtod (s, NULL);
+  long double ld = strtold (s, NULL);
+  if (f != expected->f
+      || copysignf (1.0f, f) != copysignf (1.0f, expected->f))
+    {
+      printf ("strtof (%s) returned %a not %a (%s)\n", s, f,
+	      expected->f, mode_name);
+      result = 1;
+    }
+  if (d != expected->d
+      || copysign (1.0, d) != copysign (1.0, expected->d))
+    {
+      printf ("strtod (%s) returned %a not %a (%s)\n", s, d,
+	      expected->d, mode_name);
+      result = 1;
+    }
+  if (ld != expected->ld
+      || copysignl (1.0L, ld) != copysignl (1.0L, expected->ld))
+    {
+      printf ("strtold (%s) returned %La not %La (%s)\n", s, ld,
+	      expected->ld, mode_name);
+      if (ld_ok)
+	result = 1;
+      else
+	printf ("ignoring this inexact long double result\n");
+    }
+  return result;
+}
+
+static int
 do_test (void)
 {
+  int save_round_mode = fegetround ();
   int result = 0;
   for (size_t i = 0; i < sizeof (tests) / sizeof (tests[0]); i++)
     {
-      float f = strtof (tests[i].s, NULL);
-      double d = strtod (tests[i].s, NULL);
-      long double ld = strtold (tests[i].s, NULL);
-      if (f != tests[i].f
-	  || copysignf (1.0f, f) != copysignf (1.0f, tests[i].f))
+      result |= test_in_one_mode (tests[i].s, &tests[i].rn, tests[i].ld_ok,
+				  "default rounding mode");
+#ifdef FE_DOWNWARD
+      if (!fesetround (FE_DOWNWARD))
 	{
-	  printf ("strtof (%s) returned %a not %a\n", tests[i].s, f,
-		  tests[i].f);
-	  result = 1;
+	  result |= test_in_one_mode (tests[i].s, &tests[i].rd, tests[i].ld_ok,
+				      "FE_DOWNWARD");
+	  fesetround (save_round_mode);
 	}
-      if (d != tests[i].d
-	  || copysign (1.0, d) != copysign (1.0, tests[i].d))
+#endif
+#ifdef FE_TOWARDZERO
+      if (!fesetround (FE_TOWARDZERO))
 	{
-	  printf ("strtod (%s) returned %a not %a\n", tests[i].s, d,
-		  tests[i].d);
-	  result = 1;
+	  result |= test_in_one_mode (tests[i].s, &tests[i].rz, tests[i].ld_ok,
+				      "FE_TOWARDZERO");
+	  fesetround (save_round_mode);
 	}
-      if (ld != tests[i].ld
-	  || copysignl (1.0L, ld) != copysignl (1.0L, tests[i].ld))
+#endif
+#ifdef FE_UPWARD
+      if (!fesetround (FE_UPWARD))
 	{
-	  printf ("strtold (%s) returned %La not %La\n", tests[i].s, ld,
-		  tests[i].ld);
-	  if (tests[i].ld_ok)
-	    result = 1;
-	  else
-	    printf ("ignoring this inexact long double result\n");
+	  result |= test_in_one_mode (tests[i].s, &tests[i].ru, tests[i].ld_ok,
+				      "FE_UPWARD");
+	  fesetround (save_round_mode);
 	}
+#endif
     }
   return result;
 }

Added: fsf/trunk/libc/sysdeps/generic/get-rounding-mode.h
==============================================================================
--- fsf/trunk/libc/sysdeps/generic/get-rounding-mode.h (added)
+++ fsf/trunk/libc/sysdeps/generic/get-rounding-mode.h Thu Sep 13 00:01:55 2012
@@ -1,0 +1,124 @@
+/* Determine floating-point rounding mode within libc.  Generic version.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _GET_ROUNDING_MODE_H
+#define _GET_ROUNDING_MODE_H	1
+
+#include <fpu_control.h>
+
+/* Define values for FE_* modes not defined for this architecture.  */
+#ifdef FE_DOWNWARD
+# define ORIG_FE_DOWNWARD FE_DOWNWARD
+#else
+# define ORIG_FE_DOWNWARD 0
+#endif
+#ifdef FE_TONEAREST
+# define ORIG_FE_TONEAREST FE_TONEAREST
+#else
+# define ORIG_FE_TONEAREST 0
+#endif
+#ifdef FE_TOWARDZERO
+# define ORIG_FE_TOWARDZERO FE_TOWARDZERO
+#else
+# define ORIG_FE_TOWARDZERO 0
+#endif
+#ifdef FE_UPWARD
+# define ORIG_FE_UPWARD FE_UPWARD
+#else
+# define ORIG_FE_UPWARD 0
+#endif
+#define FE_CONSTRUCT_DISTINCT_VALUE(X, Y, Z) \
+  ((((X) & 1) | ((Y) & 2) | ((Z) & 4)) ^ 7)
+#ifndef FE_DOWNWARD
+# define FE_DOWNWARD FE_CONSTRUCT_DISTINCT_VALUE (ORIG_FE_TONEAREST,	\
+						  ORIG_FE_TOWARDZERO,	\
+						  ORIG_FE_UPWARD)
+#endif
+#ifndef FE_TONEAREST
+# define FE_TONEAREST FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD,		\
+						   ORIG_FE_TOWARDZERO,	\
+						   ORIG_FE_UPWARD)
+#endif
+#ifndef FE_TOWARDZERO
+# define FE_TOWARDZERO FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD,	\
+						    FE_TONEAREST,	\
+						    ORIG_FE_UPWARD)
+#endif
+#ifndef FE_UPWARD
+# define FE_UPWARD FE_CONSTRUCT_DISTINCT_VALUE (FE_DOWNWARD,	\
+						FE_TONEAREST,	\
+						FE_TOWARDZERO)
+#endif
+
+/* Return the floating-point rounding mode.  */
+
+static inline int
+get_rounding_mode (void)
+{
+#if (defined _FPU_RC_DOWN			\
+     || defined _FPU_RC_NEAREST			\
+     || defined _FPU_RC_ZERO			\
+     || defined _FPU_RC_UP)
+  fpu_control_t fc;
+  const fpu_control_t mask = (0
+# ifdef _FPU_RC_DOWN
+			      | _FPU_RC_DOWN
+# endif
+# ifdef _FPU_RC_NEAREST
+			      | _FPU_RC_NEAREST
+# endif
+# ifdef _FPU_RC_ZERO
+			      | _FPU_RC_ZERO
+# endif
+# ifdef _FPU_RC_UP
+			      | _FPU_RC_UP
+# endif
+			      );
+
+  _FPU_GETCW (fc);
+  switch (fc & mask)
+    {
+# ifdef _FPU_RC_DOWN
+    case _FPU_RC_DOWN:
+      return FE_DOWNWARD;
+# endif
+
+# ifdef _FPU_RC_NEAREST
+    case _FPU_RC_NEAREST:
+      return FE_TONEAREST;
+# endif
+
+# ifdef _FPU_RC_ZERO
+    case _FPU_RC_ZERO:
+      return FE_TOWARDZERO;
+# endif
+
+# ifdef _FPU_RC_UP
+    case _FPU_RC_UP:
+      return FE_UPWARD;
+# endif
+
+    default:
+      abort ();
+    }
+#else
+  return FE_TONEAREST;
+#endif
+}
+
+#endif /* get-rounding-mode.h */

Modified: fsf/trunk/libc/sysdeps/i386/fpu/libm-test-ulps
==============================================================================
--- fsf/trunk/libc/sysdeps/i386/fpu/libm-test-ulps (original)
+++ fsf/trunk/libc/sysdeps/i386/fpu/libm-test-ulps Thu Sep 13 00:01:55 2012
@@ -2398,6 +2398,10 @@
 Test "sin (-0x1p65) == 0.047183876212354673805106149805700013943218":
 float: 1
 ifloat: 1
+Test "sin (0x1.fffff8p+127) == 4.85786063130487339701113680434728152037092e-02":
+float: 1
+Test "sin (0x1p+127) == 6.23385512955870240370428801097126489001833e-01":
+float: 1
 Test "sin (0x1p65) == -0.047183876212354673805106149805700013943218":
 float: 1
 ifloat: 1
@@ -2556,6 +2560,10 @@
 Test "sincos (-0x1p65, &sin_res, &cos_res) puts 0.047183876212354673805106149805700013943218 in sin_res":
 float: 1
 ifloat: 1
+Test "sincos (0x1.fffff8p+127, &sin_res, &cos_res) puts 4.85786063130487339701113680434728152037092e-02 in sin_res":
+float: 1
+Test "sincos (0x1p+127, &sin_res, &cos_res) puts 6.23385512955870240370428801097126489001833e-01 in sin_res":
+float: 1
 Test "sincos (0x1p+50, &sin_res, &cos_res) puts 8.68095904660550604334592502063501320395739e-01 in cos_res":
 float: 1
 ifloat: 1

Added: fsf/trunk/libc/sysdeps/s390/fpu/get-rounding-mode.h
==============================================================================
--- fsf/trunk/libc/sysdeps/s390/fpu/get-rounding-mode.h (added)
+++ fsf/trunk/libc/sysdeps/s390/fpu/get-rounding-mode.h Thu Sep 13 00:01:55 2012
@@ -1,0 +1,37 @@
+/* Determine floating-point rounding mode within libc.  S/390 version.
+   Copyright (C) 2012 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef _S390_GET_ROUNDING_MODE_H
+#define _S390_GET_ROUNDING_MODE_H	1
+
+#include <fenv.h>
+#include <fenv_libc.h>
+#include <fpu_control.h>
+
+/* Return the floating-point rounding mode.  */
+
+static inline int
+get_rounding_mode (void)
+{
+  fpu_control_t fc;
+
+  _FPU_GETCW (fc);
+  return fc & FPC_RM_MASK;
+}
+
+#endif /* get-rounding-mode.h */

_______________________________________________
Commits mailing list
Commits@xxxxxxxxxx
http://eglibc.org/cgi-bin/mailman/listinfo/commits