This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: soft-fp: support after-rounding tininess detection
- From: Richard Henderson <rth at twiddle dot net>
- To: "Joseph S. Myers" <joseph at codesourcery dot com>, libc-alpha at sourceware dot org
- Cc: Richard Henderson <rth at redhat dot com>
- Date: Tue, 11 Feb 2014 13:36:38 -0800
- Subject: Re: soft-fp: support after-rounding tininess detection
- Authentication-results: sourceware.org; auth=none
- References: <Pine dot LNX dot 4 dot 64 dot 1402030023100 dot 7179 at digraph dot polyomino dot org dot uk>
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~