about summary refs log tree commit diff
path: root/soft-fp
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-05-30 13:41:01 -0700
committerDavid S. Miller <davem@davemloft.net>2012-05-30 13:41:01 -0700
commitae251b0b58b6fff00a572fe1497eddec8433a9d3 (patch)
tree84a641823647c7996b6269b18276e722e9cb8022 /soft-fp
parent35c166e492b1c806b1e0c1d26f4e1385a7cfb055 (diff)
downloadglibc-ae251b0b58b6fff00a572fe1497eddec8433a9d3.tar.gz
glibc-ae251b0b58b6fff00a572fe1497eddec8433a9d3.tar.xz
glibc-ae251b0b58b6fff00a572fe1497eddec8433a9d3.zip
Fix underflow generation in soft-fp.
	* soft-fp/soft-fp.h (FP_CUR_EXCEPTIONS): Define.
	(FP_TRAPPING_EXCEPTIONS): Provide default implementation.
	* sysdeps/sparc/sparc32/soft-fp/sfp-machine.h
	(FP_TRAPPING_EXCEPTIONS): Define.
	* sysdeps/sparc/sparc64/soft-fp/sfp-machine.h
	(FP_TRAPPING_EXCEPTIONS): Define.
	* soft-fp/op-common.h (_FP_PACK_SEMIRAW): Signal underflow for
	subnormals only when inexact has been signalled or underflow
	exceptions are enabled.
	(_FP_PACK_CANONICAL): Likewise.
Diffstat (limited to 'soft-fp')
-rw-r--r--soft-fp/op-common.h13
-rw-r--r--soft-fp/soft-fp.h7
2 files changed, 17 insertions, 3 deletions
diff --git a/soft-fp/op-common.h b/soft-fp/op-common.h
index b70026f909..db75af53e6 100644
--- a/soft-fp/op-common.h
+++ b/soft-fp/op-common.h
@@ -1,5 +1,5 @@
 /* Software floating-point emulation. Common operations.
-   Copyright (C) 1997,1998,1999,2006,2007 Free Software Foundation, Inc.
+   Copyright (C) 1997,1998,1999,2006,2007,2012 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Richard Henderson (rth@cygnus.com),
 		  Jakub Jelinek (jj@ultra.linux.cz),
@@ -146,7 +146,11 @@ do {								\
   if (!_FP_EXP_NORMAL(fs, wc, X) && !_FP_FRAC_ZEROP_##wc(X))	\
     {								\
       if (X##_e == 0)						\
-	FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
+	{							\
+	  if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)		\
+	      || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))	\
+	    FP_SET_EXCEPTION(FP_EX_UNDERFLOW);			\
+	}							\
       else							\
 	{							\
 	  if (!_FP_KEEPNANFRACP)				\
@@ -226,13 +230,16 @@ do {								\
 	      {							\
 	        X##_e = 1;					\
 	        _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc);	\
+		FP_SET_EXCEPTION(FP_EX_INEXACT);		\
 	      }							\
 	    else						\
 	      {							\
 		X##_e = 0;					\
 		_FP_FRAC_SRL_##wc(X, _FP_WORKBITS);		\
-		FP_SET_EXCEPTION(FP_EX_UNDERFLOW);		\
 	      }							\
+	    if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)		\
+		|| (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))	\
+	      FP_SET_EXCEPTION(FP_EX_UNDERFLOW);		\
 	  }							\
 	else							\
 	  {							\
diff --git a/soft-fp/soft-fp.h b/soft-fp/soft-fp.h
index 46cb1cfaef..750c7fea2d 100644
--- a/soft-fp/soft-fp.h
+++ b/soft-fp/soft-fp.h
@@ -128,6 +128,13 @@
 #define FP_CLEAR_EXCEPTIONS				\
   _fex = 0
 
+#define FP_CUR_EXCEPTIONS				\
+  (_fex)
+
+#ifndef FP_TRAPPING_EXCEPTIONS
+#define FP_TRAPPING_EXCEPTIONS 0
+#endif
+
 #define _FP_ROUND_NEAREST(wc, X)			\
 do {							\
     if ((_FP_FRAC_LOW_##wc(X) & 15) != _FP_WORK_ROUND)	\