summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2016-02-18 22:42:06 +0000
committerJoseph Myers <joseph@codesourcery.com>2016-02-18 22:42:06 +0000
commite2c631384a1f9795514d8a7303838070ea81e2ec (patch)
tree6562c9aa94c58890e92fec3f96df737c8ed7c6f0
parentb9a76339be2514c700d801e179ef9b6c910eaedf (diff)
downloadglibc-e2c631384a1f9795514d8a7303838070ea81e2ec.tar.gz
Fix ldbl-128ibm fmodl handling of subnormal results (bug 19595).
The ldbl-128ibm implementation of fmodl has completely bogus logic for subnormal results (in this context, that means results for which the result is in the subnormal range for double, not results with absolute value below LDBL_MIN), based on code used for ldbl-128 that is correct in that case but incorrect in the ldbl-128ibm use. This patch fixes it to convert the mantissa into the correct form expected by ldbl_insert_mantissa, removing the other cases of the code that were incorrect and in one case unreachable for ldbl-128ibm. A correct exponent value is then passed to ldbl_insert_mantissa to reflect the shifted result. Tested for powerpc. [BZ #19595] * sysdeps/ieee754/ldbl-128ibm/e_fmodl.c (__ieee754_fmodl): Use common logic for all cases of shifting subnormal results. Do not insert sign bit in shifted mantissa. Always pass -1023 as biased exponent to ldbl_insert_mantissa in subnormal case.
-rw-r--r--ChangeLog6
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/e_fmodl.c14
2 files changed, 11 insertions, 9 deletions
diff --git a/ChangeLog b/ChangeLog
index f9c3118def..48d800c885 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2016-02-18 Joseph Myers <joseph@codesourcery.com>
+ [BZ #19595]
+ * sysdeps/ieee754/ldbl-128ibm/e_fmodl.c (__ieee754_fmodl): Use
+ common logic for all cases of shifting subnormal results. Do not
+ insert sign bit in shifted mantissa. Always pass -1023 as biased
+ exponent to ldbl_insert_mantissa in subnormal case.
+
[BZ #19594]
* sysdeps/ieee754/ldbl-128ibm/s_roundl.c (__roundl): Use __round
on high and low parts then adjust result and use
diff --git a/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c b/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c
index 205097d38f..d756e3e2a6 100644
--- a/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/e_fmodl.c
@@ -130,15 +130,11 @@ __ieee754_fmodl (long double x, long double y)
x = ldbl_insert_mantissa((sx>>63), iy, hx, lx);
} else { /* subnormal output */
n = -1022 - iy;
- if(n<=48) {
- lx = (lx>>n)|((u_int64_t)hx<<(64-n));
- hx >>= n;
- } else if (n<=63) {
- lx = (hx<<(64-n))|(lx>>n); hx = sx;
- } else {
- lx = hx>>(n-64); hx = sx;
- }
- x = ldbl_insert_mantissa((sx>>63), iy, hx, lx);
+ /* We know 1 <= N <= 52, and that there are no nonzero
+ bits in places below 2^-1074. */
+ lx = (lx >> n) | ((u_int64_t) hx << (64 - n));
+ hx >>= n;
+ x = ldbl_insert_mantissa((sx>>63), -1023, hx, lx);
x *= one; /* create necessary signal */
}
return x; /* exact output */