This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch master updated. glibc-2.20-149-g2004e7f


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  2004e7fb76bd6806253436d63ab3bda7e24c9cc1 (commit)
      from  97827bfc5f5e039f29766369035cf73f0df27888 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sourceware.org/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=2004e7fb76bd6806253436d63ab3bda7e24c9cc1

commit 2004e7fb76bd6806253436d63ab3bda7e24c9cc1
Author: Joseph Myers <joseph@codesourcery.com>
Date:   Tue Nov 4 16:34:49 2014 +0000

    soft-fp: Add _FP_TO_INT_ROUND.
    
    Continuing the series of patches adding soft-fp features from the
    kernel version of soft-fp to glibc so that glibc's version is able to
    replace the old fork of soft-fp in the kernel, this patch adds the
    last major such feature: _FP_TO_INT_ROUND, converting a floating-point
    number to an integer with rounding according to the current rounding
    direction (as opposed to truncating towards zero, which _FP_TO_INT
    does).
    
    The general structure of the implementation follows that of
    _FP_TO_INT, but of course is more complicated.  As with glibc's
    _FP_TO_INT it works with raw input (the kernel versions of these
    macros predate the conversion of _FP_TO_INT and many other macros to
    raw or semi-raw input).  I have not tried to work out what bugs there
    might be in the kernel version that this might fix; it's a
    from-scratch implementation based on _FP_TO_INT.
    
    Tested for powerpc (soft-float) that there is no change to the
    installed shared libraries; also tested with the libm tests with lrint
    / lrintf / llrint / llrintf made to use _FP_TO_INT_ROUND, to provide
    some test of the functionality.  As we don't have benchmarks for those
    functions, I haven't actually included the soft-fp versions of them,
    although I expect them to be faster than the existing code (given that
    the existing code involves adding and subtracting numbers such as
    0x1p52 to achieve the desired rounding, which is not particularly
    efficient when the underlying floating point is software floating
    point).
    
    2014-11-04  Joseph Myers  <joseph@codesourcery.com>
    
    	* soft-fp/op-common.h (_FP_TO_INT_ROUND): New macro.
    	* soft-fp/double.h [_FP_W_TYPE_SIZE < 64] (FP_TO_INT_ROUND_D): New
    	macro.
    	[_FP_W_TYPE_SIZE >= 64] (FP_TO_INT_ROUND_D): Likewise.
    	* soft-fp/extended.h [_FP_W_TYPE_SIZE < 64] (FP_TO_INT_ROUND_E):
    	New macro.
    	[_FP_W_TYPE_SIZE >= 64] (FP_TO_INT_ROUND_E): Likewise.
    	* soft-fp/quad.h [_FP_W_TYPE_SIZE < 64] (FP_TO_INT_ROUND_Q): New
    	macro.
    	[_FP_W_TYPE_SIZE >= 64] (FP_TO_INT_ROUND_Q): Likewise.
    	* soft-fp/single.h (FP_TO_INT_ROUND_S): New macro.

diff --git a/ChangeLog b/ChangeLog
index a6e6e65..380aa86 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2014-11-04  Joseph Myers  <joseph@codesourcery.com>
+
+	* soft-fp/op-common.h (_FP_TO_INT_ROUND): New macro.
+	* soft-fp/double.h [_FP_W_TYPE_SIZE < 64] (FP_TO_INT_ROUND_D): New
+	macro.
+	[_FP_W_TYPE_SIZE >= 64] (FP_TO_INT_ROUND_D): Likewise.
+	* soft-fp/extended.h [_FP_W_TYPE_SIZE < 64] (FP_TO_INT_ROUND_E):
+	New macro.
+	[_FP_W_TYPE_SIZE >= 64] (FP_TO_INT_ROUND_E): Likewise.
+	* soft-fp/quad.h [_FP_W_TYPE_SIZE < 64] (FP_TO_INT_ROUND_Q): New
+	macro.
+	[_FP_W_TYPE_SIZE >= 64] (FP_TO_INT_ROUND_Q): Likewise.
+	* soft-fp/single.h (FP_TO_INT_ROUND_S): New macro.
+
 2014-11-04  Andreas Schwab  <schwab@suse.de>
 
 	* posix/regex_internal.h: Don't include <locale/elem-hash.h>.
diff --git a/soft-fp/double.h b/soft-fp/double.h
index 36a11a5..96d2432 100644
--- a/soft-fp/double.h
+++ b/soft-fp/double.h
@@ -182,6 +182,8 @@ union _FP_UNION_D
 # define FP_CMP_UNORD_D(r, X, Y, ex)	_FP_CMP_UNORD (D, 2, (r), X, Y, (ex))
 
 # define FP_TO_INT_D(r, X, rsz, rsg)	_FP_TO_INT (D, 2, (r), X, (rsz), (rsg))
+# define FP_TO_INT_ROUND_D(r, X, rsz, rsg)	\
+  _FP_TO_INT_ROUND (D, 2, (r), X, (rsz), (rsg))
 # define FP_FROM_INT_D(X, r, rs, rt)	_FP_FROM_INT (D, 2, X, (r), (rs), rt)
 
 # define _FP_FRAC_HIGH_D(X)	_FP_FRAC_HIGH_2 (X)
@@ -304,6 +306,8 @@ union _FP_UNION_D
 # define FP_CMP_UNORD_D(r, X, Y, ex)	_FP_CMP_UNORD (D, 1, (r), X, Y, (ex))
 
 # define FP_TO_INT_D(r, X, rsz, rsg)	_FP_TO_INT (D, 1, (r), X, (rsz), (rsg))
+# define FP_TO_INT_ROUND_D(r, X, rsz, rsg)	\
+  _FP_TO_INT_ROUND (D, 1, (r), X, (rsz), (rsg))
 # define FP_FROM_INT_D(X, r, rs, rt)	_FP_FROM_INT (D, 1, X, (r), (rs), rt)
 
 # define _FP_FRAC_HIGH_D(X)	_FP_FRAC_HIGH_1 (X)
diff --git a/soft-fp/extended.h b/soft-fp/extended.h
index d16fa66..117abfc 100644
--- a/soft-fp/extended.h
+++ b/soft-fp/extended.h
@@ -292,6 +292,8 @@ union _FP_UNION_E
 # define FP_CMP_UNORD_E(r, X, Y, ex)	_FP_CMP_UNORD (E, 4, (r), X, Y, (ex))
 
 # define FP_TO_INT_E(r, X, rsz, rsg)	_FP_TO_INT (E, 4, (r), X, (rsz), (rsg))
+# define FP_TO_INT_ROUND_E(r, X, rsz, rsg)	\
+  _FP_TO_INT_ROUND (E, 4, (r), X, (rsz), (rsg))
 # define FP_FROM_INT_E(X, r, rs, rt)	_FP_FROM_INT (E, 4, X, (r), (rs), rt)
 
 # define _FP_FRAC_HIGH_E(X)	(X##_f[2])
@@ -494,6 +496,8 @@ union _FP_UNION_E
 # define FP_CMP_UNORD_E(r, X, Y, ex)	_FP_CMP_UNORD (E, 2, (r), X, Y, (ex))
 
 # define FP_TO_INT_E(r, X, rsz, rsg)	_FP_TO_INT (E, 2, (r), X, (rsz), (rsg))
+# define FP_TO_INT_ROUND_E(r, X, rsz, rsg)	\
+  _FP_TO_INT_ROUND (E, 2, (r), X, (rsz), (rsg))
 # define FP_FROM_INT_E(X, r, rs, rt)	_FP_FROM_INT (E, 2, X, (r), (rs), rt)
 
 # define _FP_FRAC_HIGH_E(X)	(X##_f1)
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index 73fbe7a..67a7818 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -1525,6 +1525,218 @@
     }									\
   while (0)
 
+/* Convert from floating point to integer, rounding according to the
+   current rounding direction.  Input is raw.  RSIGNED is as for
+   _FP_TO_INT.  */
+#define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)			\
+  do									\
+    {									\
+      if (X##_e < _FP_EXPBIAS_##fs)					\
+	{								\
+	  int _FP_TO_INT_ROUND_rounds_away = 0;				\
+	  if (X##_e == 0)						\
+	    {								\
+	      if (_FP_FRAC_ZEROP_##wc (X))				\
+		{							\
+		  (r) = 0;						\
+		  goto _FP_TO_INT_ROUND_done;				\
+		}							\
+	      else							\
+		{							\
+		  FP_SET_EXCEPTION (FP_EX_DENORM);			\
+		  if (FP_DENORM_ZERO)					\
+		    {							\
+		      (r) = 0;						\
+		      goto _FP_TO_INT_ROUND_done;			\
+		    }							\
+		}							\
+	    }								\
+	  /* The result is 0, 1 or -1 depending on the rounding mode;	\
+	     -1 may cause overflow in the unsigned case.  */		\
+	  switch (FP_ROUNDMODE)						\
+	    {								\
+	    case FP_RND_NEAREST:					\
+	      _FP_TO_INT_ROUND_rounds_away				\
+		= (X##_e == _FP_EXPBIAS_##fs - 1			\
+		   && !_FP_FRAC_ZEROP_##wc (X));			\
+	      break;							\
+	    case FP_RND_ZERO:						\
+	      /* _FP_TO_INT_ROUND_rounds_away is already 0.  */		\
+	      break;							\
+	    case FP_RND_PINF:						\
+	      _FP_TO_INT_ROUND_rounds_away = !X##_s;			\
+	      break;							\
+	    case FP_RND_MINF:						\
+	      _FP_TO_INT_ROUND_rounds_away = X##_s;			\
+	      break;							\
+	    }								\
+	  if ((rsigned) == 0 && _FP_TO_INT_ROUND_rounds_away && X##_s)	\
+	    {								\
+	      /* Result of -1 for an unsigned conversion.  */		\
+	      (r) = 0;							\
+	      FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);	\
+	    }								\
+	  else if ((rsize) == 1 && (rsigned) > 0			\
+		   && _FP_TO_INT_ROUND_rounds_away && !X##_s)		\
+	    {								\
+	      /* Converting to a 1-bit signed bit-field, which cannot	\
+		 represent +1.  */					\
+	      (r) = ((rsigned) == 2 ? -1 : 0);				\
+	      FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);	\
+	    }								\
+	  else								\
+	    {								\
+	      (r) = (_FP_TO_INT_ROUND_rounds_away			\
+		     ? (X##_s ? -1 : 1)					\
+		     : 0);						\
+	      FP_SET_EXCEPTION (FP_EX_INEXACT);				\
+	    }								\
+	}								\
+      else if ((rsigned) == 2						\
+	       && (X##_e						\
+		   >= ((_FP_EXPMAX_##fs					\
+			< _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1) \
+		       ? _FP_EXPMAX_##fs				\
+		       : _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs + (rsize) - 1))) \
+	{								\
+	  /* Overflow resulting in 0.  */				\
+	  (r) = 0;							\
+	  FP_SET_EXCEPTION (FP_EX_INVALID				\
+			    | FP_EX_INVALID_CVI				\
+			    | ((FP_EX_INVALID_SNAN			\
+				&& _FP_ISSIGNAN (fs, wc, X))		\
+			       ? FP_EX_INVALID_SNAN			\
+			       : 0));					\
+	}								\
+      else if ((rsigned) != 2						\
+	       && (X##_e >= (_FP_EXPMAX_##fs < _FP_EXPBIAS_##fs + (rsize) \
+			     ? _FP_EXPMAX_##fs				\
+			     : (_FP_EXPBIAS_##fs + (rsize)		\
+				- ((rsigned) > 0 && !X##_s)))		\
+		   || ((rsigned) == 0 && X##_s)))			\
+	{								\
+	  /* Definite overflow (does not require rounding to tell).  */	\
+	  if ((rsigned) != 0)						\
+	    {								\
+	      (r) = 1;							\
+	      (r) <<= (rsize) - 1;					\
+	      (r) -= 1 - X##_s;						\
+	    }								\
+	  else								\
+	    {								\
+	      (r) = 0;							\
+	      if (!X##_s)						\
+		(r) = ~(r);						\
+	    }								\
+									\
+	  FP_SET_EXCEPTION (FP_EX_INVALID				\
+			    | FP_EX_INVALID_CVI				\
+			    | ((FP_EX_INVALID_SNAN			\
+				&& _FP_ISSIGNAN (fs, wc, X))		\
+			       ? FP_EX_INVALID_SNAN			\
+			       : 0));					\
+	}								\
+      else								\
+	{								\
+	  /* The value is finite, with magnitude at least 1.  If	\
+	     the conversion is unsigned, the value is positive.		\
+	     If RSIGNED is not 2, the value does not definitely		\
+	     overflow by virtue of its exponent, but may still turn	\
+	     out to overflow after rounding; if RSIGNED is 2, the	\
+	     exponent may be such that the value definitely overflows,	\
+	     but at least one mantissa bit will not be shifted out.  */ \
+	  int _FP_TO_INT_ROUND_inexact = 0;				\
+	  _FP_FRAC_HIGH_RAW_##fs (X) |= _FP_IMPLBIT_##fs;		\
+	  if (X##_e >= _FP_EXPBIAS_##fs + _FP_FRACBITS_##fs - 1)	\
+	    {								\
+	      /* The value is an integer, no rounding needed.  */	\
+	      _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize));			\
+	      (r) <<= X##_e - _FP_EXPBIAS_##fs - _FP_FRACBITS_##fs + 1; \
+	    }								\
+	  else								\
+	    {								\
+	      /* May need to shift in order to round (unless there	\
+		 are exactly _FP_WORKBITS fractional bits already).  */	\
+	      int _FP_TO_INT_ROUND_rshift				\
+		= (_FP_FRACBITS_##fs + _FP_EXPBIAS_##fs			\
+		   - 1 - _FP_WORKBITS - X##_e);				\
+	      if (_FP_TO_INT_ROUND_rshift > 0)				\
+		_FP_FRAC_SRS_##wc (X, _FP_TO_INT_ROUND_rshift,		\
+				   _FP_WFRACBITS_##fs);			\
+	      else if (_FP_TO_INT_ROUND_rshift < 0)			\
+		_FP_FRAC_SLL_##wc (X, -_FP_TO_INT_ROUND_rshift);	\
+	      /* Round like _FP_ROUND, but setting			\
+		 _FP_TO_INT_ROUND_inexact instead of directly setting	\
+		 the "inexact" exception, since it may turn out we	\
+		 should set "invalid" instead.  */			\
+	      if (_FP_FRAC_LOW_##wc (X) & 7)				\
+		{							\
+		  _FP_TO_INT_ROUND_inexact = 1;				\
+		  switch (FP_ROUNDMODE)					\
+		    {							\
+		    case FP_RND_NEAREST:				\
+		      _FP_ROUND_NEAREST (wc, X);			\
+		      break;						\
+		    case FP_RND_ZERO:					\
+		      _FP_ROUND_ZERO (wc, X);				\
+		      break;						\
+		    case FP_RND_PINF:					\
+		      _FP_ROUND_PINF (wc, X);				\
+		      break;						\
+		    case FP_RND_MINF:					\
+		      _FP_ROUND_MINF (wc, X);				\
+		      break;						\
+		    }							\
+		}							\
+	      _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);			\
+	      _FP_FRAC_ASSEMBLE_##wc ((r), X, (rsize));			\
+	    }								\
+	  if ((rsigned) != 0 && X##_s)					\
+	    (r) = -(r);							\
+	  /* An exponent of RSIZE - 1 always needs testing for		\
+	     overflow (either directly overflowing, or overflowing	\
+	     when rounding up results in 2^RSIZE).  An exponent of	\
+	     RSIZE - 2 can overflow for positive values when rounding	\
+	     up to 2^(RSIZE-1), but cannot overflow for negative	\
+	     values.  Smaller exponents cannot overflow.  */		\
+	  if (X##_e >= (_FP_EXPBIAS_##fs + (rsize) - 1			\
+			- ((rsigned) > 0 && !X##_s)))			\
+	    {								\
+	      if (X##_e > _FP_EXPBIAS_##fs + (rsize) - 1		\
+		  || (X##_e == _FP_EXPBIAS_##fs + (rsize) - 1		\
+		      && (X##_s						\
+			  ? (r) != (((typeof (r)) 1) << ((rsize) - 1))	\
+			  : ((rsigned) > 0 || (r) == 0)))		\
+		  || ((rsigned) > 0					\
+		      && !X##_s						\
+		      && X##_e == _FP_EXPBIAS_##fs + (rsize) - 2	\
+		      && (r) == (((typeof (r)) 1) << ((rsize) - 1))))	\
+		{							\
+		  if ((rsigned) != 2)					\
+		    {							\
+		      if ((rsigned) != 0)				\
+			{						\
+			  (r) = 1;					\
+			  (r) <<= (rsize) - 1;				\
+			  (r) -= 1 - X##_s;				\
+			}						\
+		      else						\
+			{						\
+			  (r) = 0;					\
+			  (r) = ~(r);					\
+			}						\
+		    }							\
+		  _FP_TO_INT_ROUND_inexact = 0;				\
+		  FP_SET_EXCEPTION (FP_EX_INVALID | FP_EX_INVALID_CVI);	\
+		}							\
+	    }								\
+	  if (_FP_TO_INT_ROUND_inexact)					\
+	    FP_SET_EXCEPTION (FP_EX_INEXACT);				\
+	}								\
+    _FP_TO_INT_ROUND_done: ;						\
+    }									\
+  while (0)
+
 /* Convert integer to fp.  Output is raw.  RTYPE is unsigned even if
    input is signed.  */
 #define _FP_FROM_INT(fs, wc, X, r, rsize, rtype)			\
diff --git a/soft-fp/quad.h b/soft-fp/quad.h
index b8cd310..8b7f0a0 100644
--- a/soft-fp/quad.h
+++ b/soft-fp/quad.h
@@ -187,6 +187,8 @@ union _FP_UNION_Q
 # define FP_CMP_UNORD_Q(r, X, Y, ex)	_FP_CMP_UNORD (Q, 4, (r), X, Y, (ex))
 
 # define FP_TO_INT_Q(r, X, rsz, rsg)	_FP_TO_INT (Q, 4, (r), X, (rsz), (rsg))
+# define FP_TO_INT_ROUND_Q(r, X, rsz, rsg)	\
+  _FP_TO_INT_ROUND (Q, 4, (r), X, (rsz), (rsg))
 # define FP_FROM_INT_Q(X, r, rs, rt)	_FP_FROM_INT (Q, 4, X, (r), (rs), rt)
 
 # define _FP_FRAC_HIGH_Q(X)	_FP_FRAC_HIGH_4 (X)
@@ -311,6 +313,8 @@ union _FP_UNION_Q
 # define FP_CMP_UNORD_Q(r, X, Y, ex)	_FP_CMP_UNORD (Q, 2, (r), X, Y, (ex))
 
 # define FP_TO_INT_Q(r, X, rsz, rsg)	_FP_TO_INT (Q, 2, (r), X, (rsz), (rsg))
+# define FP_TO_INT_ROUND_Q(r, X, rsz, rsg)	\
+  _FP_TO_INT_ROUND (Q, 2, (r), X, (rsz), (rsg))
 # define FP_FROM_INT_Q(X, r, rs, rt)	_FP_FROM_INT (Q, 2, X, (r), (rs), rt)
 
 # define _FP_FRAC_HIGH_Q(X)	_FP_FRAC_HIGH_2 (X)
diff --git a/soft-fp/single.h b/soft-fp/single.h
index 086a558..83c0de6 100644
--- a/soft-fp/single.h
+++ b/soft-fp/single.h
@@ -180,6 +180,8 @@ union _FP_UNION_S
 #define FP_CMP_UNORD_S(r, X, Y, ex)	_FP_CMP_UNORD (S, 1, (r), X, Y, (ex))
 
 #define FP_TO_INT_S(r, X, rsz, rsg)	_FP_TO_INT (S, 1, (r), X, (rsz), (rsg))
+#define FP_TO_INT_ROUND_S(r, X, rsz, rsg)	\
+  _FP_TO_INT_ROUND (S, 1, (r), X, (rsz), (rsg))
 #define FP_FROM_INT_S(X, r, rs, rt)	_FP_FROM_INT (S, 1, X, (r), (rs), rt)
 
 #define _FP_FRAC_HIGH_S(X)	_FP_FRAC_HIGH_1 (X)

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog           |   14 ++++
 soft-fp/double.h    |    4 +
 soft-fp/extended.h  |    4 +
 soft-fp/op-common.h |  212 +++++++++++++++++++++++++++++++++++++++++++++++++++
 soft-fp/quad.h      |    4 +
 soft-fp/single.h    |    2 +
 6 files changed, 240 insertions(+), 0 deletions(-)


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]