Fix dbl-64 e_sqrt.c for non-default rounding modes (bug 16271).

This commit is contained in:
Joseph Myers 2013-11-28 16:50:38 +00:00
parent 5a4c6d53f5
commit 3c1c46a64a
31 changed files with 110 additions and 5 deletions

View File

@ -1,3 +1,20 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
[BZ #16271]
* sysdeps/ieee754/dbl-64/e_sqrt.c (__ieee754_sqrt): Set
round-to-nearest then adjust result for other rounding modes.
* include/fenv.h (fegetround): Use libm_hidden_proto.
* math/fegetround.c (fegetround): Use libm_hidden_def.
* sysdeps/i386/fpu/fegetround.c (fegetround): Likewise.
* sysdeps/powerpc/fpu/fegetround.c (fegetround): Likewise.
* sysdeps/powerpc/nofpu/fegetround.c (fegetround): Likewise.
* sysdeps/powerpc/powerpc32/e500/nofpu/fegetround.c (fegetround):
Likewise.
* sysdeps/s390/fpu/fegetround.c (fegetround): Likewise.
* sysdeps/sh/sh4/fpu/fegetround.c (fegetround): Likewise.
* sysdeps/sparc/fpu/fegetround.c (fegetround): Likewise.
* sysdeps/x86_64/fpu/fegetround.c (fegetround): Likewise.
2013-11-28 Siddhesh Poyarekar <siddhesh@redhat.com>
[BZ #16077]

2
NEWS
View File

@ -19,7 +19,7 @@ Version 2.19
15897, 15905, 15909, 15917, 15919, 15921, 15923, 15939, 15948, 15963,
15966, 15985, 15988, 15997, 16032, 16034, 16036, 16037, 16041, 16055,
16071, 16072, 16074, 16077, 16078, 16103, 16112, 16143, 16144, 16146,
16150, 16151, 16153, 16167, 16172, 16245.
16150, 16151, 16153, 16167, 16172, 16245, 16271.
* The public headers no longer use __unused nor __block. This change is to
support compiling programs that are derived from BSD sources and use

View File

@ -16,6 +16,7 @@ extern int __feupdateenv (const fenv_t *__envp);
libm_hidden_proto (feraiseexcept)
libm_hidden_proto (fegetenv)
libm_hidden_proto (fegetround)
libm_hidden_proto (fesetenv)
libm_hidden_proto (fesetround)
libm_hidden_proto (feholdexcept)

View File

@ -28,4 +28,5 @@ fegetround (void)
return 0;
#endif
}
libm_hidden_def (fegetround)
stub_warning (fegetround)

View File

@ -1,3 +1,8 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/aarch64/fpu/fegetround.c (fegetround): Use
libm_hidden_def.
2013-11-26 Will Newton <will.newton@linaro.org>
* sysdeps/aarch64/dl-irel.h: Include ldsodefs.h.

View File

@ -1,3 +1,8 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/alpha/fpu/fegetround.c (fegetround): Use
libm_hidden_def.
2013-11-26 Ondřej Bílka <neleai@seznam.cz>
* sysdeps/unix/sysv/linux/alpha/bits/ipc.h: Use __glibc_reserved instead __unused.
* sysdeps/unix/sysv/linux/alpha/bits/msq.h: Likewise.

View File

@ -1,3 +1,7 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/am33/fpu/fegetround.c (fegetround): Use libm_hidden_def.
2013-10-30 Mike Frysinger <vapier@gentoo.org>
* sysdeps/unix/sysv/linux/am33/configure.in: Moved to ...

View File

@ -1,3 +1,7 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/arm/fegetround.c (fegetround): Use libm_hidden_def.
2013-11-26 Ondřej Bílka <neleai@seznam.cz>
* sysdeps/unix/sysv/linux/arm/bits/shm.h: Use __glibc_reserved instead __unused.

View File

@ -1,3 +1,7 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/hppa/fpu/fegetround.c (fegetround): Use libm_hidden_def.
2013-11-26 Ondřej Bílka <neleai@seznam.cz>
* sysdeps/unix/sysv/linux/hppa/bits/ipc.h: Use __glibc_reserved instead __unused.
* sysdeps/unix/sysv/linux/hppa/bits/msq.h: Likewise.

View File

@ -1,3 +1,7 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/ia64/fpu/fegetround.c (fegetround): Use libm_hidden_def.
2013-11-26 Ondřej Bílka <neleai@seznam.cz>
* sysdeps/unix/sysv/linux/ia64/bits/ipc.h: Use __glibc_reserved instead __unused.
* sysdeps/unix/sysv/linux/ia64/bits/msq.h: Likewise.

View File

@ -1,3 +1,7 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/m68k/fpu/fegetround.c (fegetround): Use libm_hidden_def.
2013-11-26 Ondřej Bílka <neleai@seznam.cz>
* sysdeps/unix/sysv/linux/m68k/bits/stat.h: Use __glibc_reserved instead __unused.

View File

@ -1,3 +1,8 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/microblaze/fegetround.c (fegetround): Use
libm_hidden_def.
2013-11-26 Ondřej Bílka <neleai@seznam.cz>
* sysdeps/unix/sysv/linux/microblaze/bits/stat.h: Use __glibc_reserved instead __unused.
* sysdeps/unix/sysv/linux/microblaze/kernel_stat.h: Likewise.

View File

@ -1,3 +1,7 @@
2013-11-28 Joseph Myers <joseph@codesourcery.com>
* sysdeps/mips/fpu/fegetround.c (fegetround): Use libm_hidden_def.
2013-11-27 Aurelien Jarno <aurelien@aurel32.net>
* sysdeps/unix/sysv/linux/mips/bits/resource.h (RLIM64_INFINITY): Fix

View File

@ -26,3 +26,4 @@ fegetround (void)
_FPU_GETCW (fpcr);
return fpcr & FE_TOWARDZERO;
}
libm_hidden_def (fegetround)

View File

@ -28,3 +28,4 @@ fegetround (void)
return (fpcr >> FPCR_ROUND_SHIFT) & 3;
}
libm_hidden_def (fegetround)

View File

@ -32,3 +32,4 @@ fegetround (void)
return (cw & ROUND_MASK);
}
libm_hidden_def (fegetround)

View File

@ -37,3 +37,4 @@ fegetround (void)
/* The current soft-float implementation only handles TONEAREST. */
return FE_TONEAREST;
}
libm_hidden_def (fegetround)

View File

@ -24,3 +24,4 @@ fegetround (void)
{
return get_rounding_mode ();
}
libm_hidden_def (fegetround)

View File

@ -24,3 +24,4 @@ fegetround (void)
{
return get_rounding_mode ();
}
libm_hidden_def (fegetround)

View File

@ -28,3 +28,4 @@ fegetround (void)
return fpcr & FE_UPWARD;
}
libm_hidden_def (fegetround)

View File

@ -22,3 +22,4 @@ fegetround (void)
{
return FE_TONEAREST;
}
libm_hidden_def (fegetround)

View File

@ -30,3 +30,4 @@ fegetround (void)
return cw & _FPU_RC_MASK;
}
libm_hidden_def (fegetround)

View File

@ -28,3 +28,4 @@ fegetround (void)
return cw & 0xc00;
}
libm_hidden_def (fegetround)

View File

@ -66,8 +66,9 @@ __ieee754_sqrt (double x)
/*----------------- 2^-1022 <= | x |< 2^1024 -----------------*/
if (k > 0x000fffff && k < 0x7ff00000)
{
int rm = fegetround ();
fenv_t env;
libc_feholdexcept (&env);
libc_feholdexcept_setround (&env, FE_TONEAREST);
double ret;
y = 1.0 - t * (t * s);
t = t * (rt0 + y * (rt1 + y * (rt2 + y * rt3)));
@ -82,15 +83,44 @@ __ieee754_sqrt (double x)
{
res1 = res + 1.5 * ((y - res) + del);
EMULV (res, res1, z, zz, p, hx, tx, hy, ty); /* (z+zz)=res*res1 */
ret = ((((z - s) + zz) < 0) ? max (res, res1) :
min (res, res1)) * c.x;
res = ((((z - s) + zz) < 0) ? max (res, res1) :
min (res, res1));
ret = res * c.x;
}
math_force_eval (ret);
libc_fesetenv (&env);
if (x / ret != ret)
double dret = x / ret;
if (dret != ret)
{
double force_inexact = 1.0 / 3.0;
math_force_eval (force_inexact);
/* The square root is inexact, ret is the round-to-nearest
value which may need adjusting for other rounding
modes. */
switch (rm)
{
#ifdef FE_UPWARD
case FE_UPWARD:
if (dret > ret)
ret = (res + 0x1p-1022) * c.x;
break;
#endif
#ifdef FE_DOWNWARD
case FE_DOWNWARD:
#endif
#ifdef FE_TOWARDZERO
case FE_TOWARDZERO:
#endif
#if defined FE_DOWNWARD || defined FE_TOWARDZERO
if (dret < ret)
ret = (res - 0x1p-1022) * c.x;
break;
#endif
default:
break;
}
}
/* Otherwise (x / ret == ret), either the square root was exact or
the division was inexact. */

View File

@ -24,3 +24,4 @@ fegetround (void)
{
return __fegetround();
}
libm_hidden_def (fegetround)

View File

@ -26,3 +26,4 @@ fegetround (void)
{
return __sim_round_mode_thread;
}
libm_hidden_def (fegetround)

View File

@ -27,3 +27,4 @@ fegetround (void)
fpescr = fegetenv_register ();
return fpescr & 3;
}
libm_hidden_def (fegetround)

View File

@ -29,3 +29,4 @@ fegetround (void)
return cw & FPC_RM_MASK;
}
libm_hidden_def (fegetround)

View File

@ -30,3 +30,4 @@ fegetround (void)
return cw & 0x1;
}
libm_hidden_def (fegetround)

View File

@ -27,3 +27,4 @@ fegetround (void)
return tmp & __FE_ROUND_MASK;
}
libm_hidden_def (fegetround)

View File

@ -30,3 +30,4 @@ fegetround (void)
return cw & 0xc00;
}
libm_hidden_def (fegetround)