summaryrefslogtreecommitdiffstats
path: root/newlib/libm/common/s_llround.c
diff options
context:
space:
mode:
authorDave Korn <dave.korn.cygwin@gmail.com>2010-07-20 01:33:05 +0000
committerDave Korn <dave.korn.cygwin@gmail.com>2010-07-20 01:33:05 +0000
commite561d3e77e05c211698712d9cbc0b5d1bba8720c (patch)
tree852aebe3d68e9d3917b0a0cd7672016292d4d889 /newlib/libm/common/s_llround.c
parent2af268382aeb3fff60dfe52ef8d001f9a6bd0288 (diff)
downloadcygnal-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.c22
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