diff options
author | Dave Korn <dave.korn.cygwin@gmail.com> | 2010-07-20 01:33:05 +0000 |
---|---|---|
committer | Dave Korn <dave.korn.cygwin@gmail.com> | 2010-07-20 01:33:05 +0000 |
commit | e561d3e77e05c211698712d9cbc0b5d1bba8720c (patch) | |
tree | 852aebe3d68e9d3917b0a0cd7672016292d4d889 /newlib/libm/common/s_llround.c | |
parent | 2af268382aeb3fff60dfe52ef8d001f9a6bd0288 (diff) | |
download | cygnal-e561d3e77e05c211698712d9cbc0b5d1bba8720c.tar.gz cygnal-e561d3e77e05c211698712d9cbc0b5d1bba8720c.tar.bz2 cygnal-e561d3e77e05c211698712d9cbc0b5d1bba8720c.zip |
* libm/common/fdlibm.h (SAFE_LEFT_SHIFT): New macro definition.
(SAFE_RIGHT_SHIFT): Likewise.
* libm/common/s_llround.c (llround): Annotate shift operations with
possible shift amount ranges, and use SAFE_RIGHT_SHIFT to avoid
undefined behaviour.
* libm/common/s_lround.c (lround): Likewise.
Diffstat (limited to 'newlib/libm/common/s_llround.c')
-rw-r--r-- | newlib/libm/common/s_llround.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/newlib/libm/common/s_llround.c b/newlib/libm/common/s_llround.c index 923f885ca..3dcb5ff92 100644 --- a/newlib/libm/common/s_llround.c +++ b/newlib/libm/common/s_llround.c @@ -31,8 +31,10 @@ llround(double x) msw &= 0x000fffff; msw |= 0x00100000; + /* exponent_less_1023 in [-1024,1023] */ if (exponent_less_1023 < 20) { + /* exponent_less_1023 in [-1024,19] */ if (exponent_less_1023 < 0) { if (exponent_less_1023 < -1) @@ -42,20 +44,34 @@ llround(double x) } else { + /* exponent_less_1023 in [0,19] */ + /* shift amt in [0,19] */ msw += 0x80000 >> exponent_less_1023; + /* shift amt in [20,1] */ result = msw >> (20 - exponent_less_1023); } } else if (exponent_less_1023 < (8 * sizeof (long long int)) - 1) { + /* 64bit longlong: exponent_less_1023 in [20,62] */ if (exponent_less_1023 >= 52) - result = ((long long int) msw << (exponent_less_1023 - 20)) | (lsw << (exponent_less_1023 - 52)); + /* 64bit longlong: exponent_less_1023 in [52,62] */ + /* 64bit longlong: shift amt in [32,42] */ + result = ((long long int) msw << (exponent_less_1023 - 20)) + /* 64bit longlong: shift amt in [0,10] */ + | (lsw << (exponent_less_1023 - 52)); else { - unsigned int tmp = lsw + (0x80000000 >> (exponent_less_1023 - 20)); + /* 64bit longlong: exponent_less_1023 in [20,51] */ + unsigned int tmp = lsw + /* 64bit longlong: shift amt in [0,31] */ + + (0x80000000 >> (exponent_less_1023 - 20)); if (tmp < lsw) ++msw; - result = ((long long int) msw << (exponent_less_1023 - 20)) | (tmp >> (52 - exponent_less_1023)); + /* 64bit longlong: shift amt in [0,31] */ + result = ((long long int) msw << (exponent_less_1023 - 20)) + /* ***64bit longlong: shift amt in [32,1] */ + | SAFE_RIGHT_SHIFT (tmp, (52 - exponent_less_1023)); } } else |