about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarcus Shawcroft <marcus.shawcroft@linaro.org>2012-11-13 17:01:05 +0000
committerMarcus Shawcroft <marcus.shawcroft@linaro.org>2012-11-13 17:01:05 +0000
commit47594329a9c03fb945f41c19f06401271f9aa9c5 (patch)
tree446ca8eacfca3054d9243cdff7914fa9c134ac68
parent640ac3f1bf2e575b514645fc03cceeeacf7bd845 (diff)
downloadglibc-47594329a9c03fb945f41c19f06401271f9aa9c5.tar.gz
glibc-47594329a9c03fb945f41c19f06401271f9aa9c5.tar.xz
glibc-47594329a9c03fb945f41c19f06401271f9aa9c5.zip
Fix missing truncation UNDERFLOW.
-rw-r--r--ChangeLog7
-rw-r--r--soft-fp/op-common.h25
-rw-r--r--soft-fp/soft-fp.h34
3 files changed, 36 insertions, 30 deletions
diff --git a/ChangeLog b/ChangeLog
index ba9ecf3072..b3bd03f820 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2012-11-13  Marcus Shawcroft  <marcus.shawcroft@linaro.org>
+
+	* soft-fp/op-common.h (_FP_PACK_SEMIRAW): Move underflow
+	detection to immediately after _FP_ROUND().
+	* soft-fp/soft-fp.h (_FP_ROUND): Don't round if working
+	bits are 0.
+
 2012-11-11  David S. Miller  <davem@davemloft.net>
 
 	* sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c: Include
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index db75af53e6..12fb16e5ef 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -134,6 +134,12 @@ do {									\
 #define _FP_PACK_SEMIRAW(fs, wc, X)				\
 do {								\
   _FP_ROUND(wc, X);						\
+  if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc(X))			\
+	{ \
+	  if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)		\
+	      || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))	\
+	    FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
+	} \
   if (_FP_FRAC_HIGH_##fs(X)					\
       & (_FP_OVERFLOW_##fs >> 1))				\
     {								\
@@ -143,24 +149,15 @@ do {								\
 	_FP_OVERFLOW_SEMIRAW(fs, wc, X);			\
     }								\
   _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);				\
-  if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X))	\
+  if (X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X))	\
     {								\
-      if (X##_e == 0)						\
+      if (!_FP_KEEPNANFRACP)					\
 	{							\
-	  if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)		\
-	      || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))	\
-	    FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
+	  _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);		\
+	  X##_s = _FP_NANSIGN_##fs;				\
 	}							\
       else							\
-	{							\
-	  if (!_FP_KEEPNANFRACP)				\
-	    {							\
-	      _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs);		\
-	      X##_s = _FP_NANSIGN_##fs;				\
-	    }							\
-	  else							\
-	    _FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;	\
-	}							\
+	_FP_FRAC_HIGH_RAW_##fs(X) |= _FP_QNANBIT_##fs;		\
     }								\
 } while (0)
 
diff --git a/soft-fp/soft-fp.h b/soft-fp/soft-fp.h
index 750c7fea2d..49a87706cc 100644
--- a/soft-fp/soft-fp.h
+++ b/soft-fp/soft-fp.h
@@ -158,22 +158,24 @@ do {							\
 #define _FP_ROUND(wc, X)			\
 do {						\
 	if (_FP_FRAC_LOW_##wc(X) & 7)		\
-	  FP_SET_EXCEPTION(FP_EX_INEXACT);	\
-	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_SET_EXCEPTION(FP_EX_INEXACT);	\
+	    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;				\
+	      }					\
+	  }					\
 } while (0)
 
 #define FP_CLS_NORMAL		0