patch-2.3.30 linux/include/math-emu/op-common.h

Next file: linux/include/math-emu/quad.h
Previous file: linux/include/math-emu/op-2.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.29/linux/include/math-emu/op-common.h linux/include/math-emu/op-common.h
@@ -54,6 +54,11 @@
 	X##_e -= _FP_EXPBIAS_##fs - 1 + _shift;				\
 	X##_c = FP_CLS_NORMAL;						\
 	FP_SET_EXCEPTION(FP_EX_DENORM);					\
+	if (FP_DENORM_ZERO)						\
+	  {								\
+	    FP_SET_EXCEPTION(FP_EX_INEXACT);				\
+	    X##_c = FP_CLS_ZERO;					\
+	  }								\
       }									\
     break;								\
 									\
@@ -618,6 +623,8 @@
  * 1:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
  *     on the sign in such case.
+ * 2:  the number is required to be -(2^(rsize-1))..(2^(rsize-1))-1, if not, NV is
+ *     set plus the result is truncated to fit into destination.
  * -1: the number is required to be -(2^(rsize-1))..(2^rsize)-1, if not, NV is
  *     set plus the result is either -(2^(rsize-1)) or (2^(rsize-1))-1 depending
  *     on the sign in such case.
@@ -638,12 +645,25 @@
 	  {	/* overflow */							\
 	  case FP_CLS_NAN:                                                      \
 	  case FP_CLS_INF:							\
-	    if (rsigned)							\
+	    if (rsigned == 2)							\
+	      {									\
+		if (X##_c != FP_CLS_NORMAL					\
+		    || X##_e >= rsize - 1 + _FP_WFRACBITS_##fs)			\
+		  r = 0;							\
+		else								\
+		  {								\
+		    _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));	\
+		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
+		  }								\
+	      }									\
+	    else if (rsigned)							\
 	      {									\
 		r = 1;								\
 		r <<= rsize - 1;						\
 		r -= 1 - X##_s;							\
-	      } else {								\
+	      }									\
+	    else								\
+	      {									\
 		r = 0;								\
 		if (X##_s)							\
 		  r = ~r;							\
@@ -675,6 +695,67 @@
 	      r = -r;								\
 	  }									\
 	break;									\
+      }										\
+  } while (0)
+
+#define _FP_TO_INT_ROUND(fs, wc, r, X, rsize, rsigned)				\
+  do {										\
+    r = 0;									\
+    switch (X##_c)								\
+      {										\
+      case FP_CLS_NORMAL:							\
+	if (X##_e >= _FP_FRACBITS_##fs - 1)					\
+	  {									\
+	    if (X##_e < rsize - 1 + _FP_WFRACBITS_##fs)				\
+	      {									\
+		if (X##_e >= _FP_WFRACBITS_##fs - 1)				\
+		  {								\
+		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
+		    r <<= X##_e - _FP_WFRACBITS_##fs + 1;			\
+		  }								\
+		else								\
+		  {								\
+		    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS - X##_e			\
+				      + _FP_FRACBITS_##fs - 1);			\
+		    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);			\
+		  }								\
+	      }									\
+	  }									\
+	else									\
+	  {									\
+	    if (X##_e <= -_FP_WORKBITS - 1)					\
+	      _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc);				\
+	    else								\
+	      _FP_FRAC_SRS_##wc(X, _FP_FRACBITS_##fs - 1 - X##_e,		\
+				_FP_WFRACBITS_##fs);				\
+	    _FP_ROUND(wc, X);							\
+	    _FP_FRAC_SRL_##wc(X, _FP_WORKBITS);					\
+	    _FP_FRAC_ASSEMBLE_##wc(r, X, rsize);				\
+	  }									\
+	if (rsigned && X##_s)							\
+	  r = -r;								\
+	if (X##_e >= rsize - (rsigned > 0 || X##_s)				\
+	    || (!rsigned && X##_s))						\
+	  {	/* overflow */							\
+	  case FP_CLS_NAN:                                                      \
+	  case FP_CLS_INF:							\
+	    if (!rsigned)							\
+	      {									\
+		r = 0;								\
+		if (X##_s)							\
+		  r = ~r;							\
+	      }									\
+	    else if (rsigned != 2)						\
+	      {									\
+		r = 1;								\
+		r <<= rsize - 1;						\
+		r -= 1 - X##_s;							\
+	      }									\
+	    FP_SET_EXCEPTION(FP_EX_INVALID);					\
+	  }									\
+	break;									\
+      case FP_CLS_ZERO:								\
+        break;									\
       }										\
   } while (0)
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)