This is the mail archive of the libc-alpha@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]

Re: soft-fp: support after-rounding tininess detection


On 02/02/2014 04:25 PM, Joseph S. Myers wrote:
@@ -191,8 +191,22 @@
>  #define _FP_PACK_SEMIRAW(fs, wc, X)				\
>    do								\
>      {								\
> +      int _FP_PACK_SEMIRAW_is_tiny				\
> +	= X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X);		\
> +      if (_FP_TININESS_AFTER_ROUNDING				\
> +	  && _FP_PACK_SEMIRAW_is_tiny)				\
> +	{							\
> +	  FP_DECL_##fs (_FP_PACK_SEMIRAW_T);			\
> +	  _FP_FRAC_COPY_##wc (_FP_PACK_SEMIRAW_T, X);		\
> +	  _FP_PACK_SEMIRAW_T##_s = X##_s;			\
> +	  _FP_PACK_SEMIRAW_T##_e = X##_e;			\
> +	  _FP_FRAC_SLL_##wc (_FP_PACK_SEMIRAW_T, 1);		\
> +	  _FP_ROUND (wc, _FP_PACK_SEMIRAW_T);			\
> +	  if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_SEMIRAW_T))	\
> +	    _FP_PACK_SEMIRAW_is_tiny = 0;			\
> +	}							\
>        _FP_ROUND (wc, X);					\
> -      if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X))		\
> +      if (_FP_PACK_SEMIRAW_is_tiny)				\

Am I missing something, why the SLL is needed for this case?
And if it isn't, then the temporary ought not be needed.

I was thinking

  _FP_ROUND (wc, X);
  _FP_W_TYPE _FPS_over = _FP_FRAC_HIGH_##fs (X) & (_FP_OVERFLOW_##fs >> 1);
  if (X##_e == 0 && !_FP_FRAC_ZEROP_##wc (X)
      && (!_FP_TININESS_AFTER_ROUNDING || _FPS_over)
      && (FP_CUR_EXCEPTIONS & FP_EX_INEXACT)
          || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)))
    FP_SET_EXCEPTION (FP_EX_UNDERFLOW);
  if (_FPS_over)
    ...

> @@ -279,6 +293,17 @@
>  	  else								\
>  	    {								\
>  	      /* we've got a denormalized number */			\
> +	      int _FP_PACK_CANONICAL_is_tiny = 1;			\
> +	      if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0)		\
> +		{							\
> +		  FP_DECL_##fs (_FP_PACK_CANONICAL_T);			\
> +		  _FP_FRAC_COPY_##wc (_FP_PACK_CANONICAL_T, X);		\
> +		  _FP_PACK_CANONICAL_T##_s = X##_s;			\
> +		  _FP_PACK_CANONICAL_T##_e = X##_e;			\
> +		  _FP_ROUND (wc, _FP_PACK_CANONICAL_T);			\
> +		  if (_FP_FRAC_OVERP_##wc (fs, _FP_PACK_CANONICAL_T))	\
> +		    _FP_PACK_CANONICAL_is_tiny = 0;			\
> +		}							\
>  	      X##_e = -X##_e + 1;					\
>  	      if (X##_e <= _FP_WFRACBITS_##fs)				\
>  		{							\
> @@ -296,8 +321,10 @@
>  		      X##_e = 0;					\
>  		      _FP_FRAC_SRL_##wc (X, _FP_WORKBITS);		\
>  		    }							\
> -		  if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)		\
> -		      || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))	\
> +		  if (_FP_PACK_CANONICAL_is_tiny			\
> +		      && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT)		\
> +			  || (FP_TRAPPING_EXCEPTIONS			\
> +			      & FP_EX_UNDERFLOW)))			\
>  		    FP_SET_EXCEPTION (FP_EX_UNDERFLOW);			\

And here, does it work to do

    if (X##_e <= _FP_WFRACBITS_##fs)
      {
+       bool _FPC_is_tiny = 1;
        _FP_FRAC_SRS_##wc (X, X##_e, _FP_WFRACBITS_##fs);
        _FP_ROUND (wc, X);
         if (_FP_FRAC_HIGH_##fs (X)
             & (_FP_OVERFLOW_##fs >> 1))
           {
+            if (_FP_TININESS_AFTER_ROUNDING)
+              _FPRC_is_tiny = 0;
             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);
           }
+        if (_FPC_is_tiny
             && (FP_CUR_EXCEPTIONS & FP_EX_INEXACT)
                 || (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))
           FP_SET_EXCEPTION (FP_EX_UNDERFLOW);
       }


r~


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