summaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/i386/fpu/feholdexcpt.c20
-rw-r--r--sysdeps/i386/fpu/feupdateenv.c15
-rw-r--r--sysdeps/i386/fpu/math_private.h18
-rw-r--r--sysdeps/i386/fpu/s_nextafterl.c18
-rw-r--r--sysdeps/i386/fpu/s_nexttoward.c25
-rw-r--r--sysdeps/i386/fpu/s_nexttowardf.c25
-rw-r--r--sysdeps/ia64/fpu/feholdexcpt.c18
-rw-r--r--sysdeps/ia64/fpu/fesetround.c6
-rw-r--r--sysdeps/ia64/fpu/feupdateenv.c8
-rw-r--r--sysdeps/ieee754/flt-32/s_nextafterf.c20
-rw-r--r--sysdeps/ieee754/ldbl-128/s_nextafterl.c18
-rw-r--r--sysdeps/ieee754/ldbl-128/s_nexttoward.c23
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c20
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c23
-rw-r--r--sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c26
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nextafterl.c20
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nexttoward.c23
-rw-r--r--sysdeps/ieee754/ldbl-96/s_nexttowardf.c28
-rw-r--r--sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c28
-rw-r--r--sysdeps/unix/sysv/linux/bits/sched.h6
-rw-r--r--sysdeps/unix/sysv/linux/sync_file_range.c6
-rw-r--r--sysdeps/x86_64/fpu/fedisblxcpt.c6
-rw-r--r--sysdeps/x86_64/fpu/feenablxcpt.c6
-rw-r--r--sysdeps/x86_64/fpu/feholdexcpt.c17
-rw-r--r--sysdeps/x86_64/fpu/feupdateenv.c51
-rw-r--r--sysdeps/x86_64/fpu/math_private.h21
26 files changed, 315 insertions, 180 deletions
diff --git a/sysdeps/i386/fpu/feholdexcpt.c b/sysdeps/i386/fpu/feholdexcpt.c
index feaa24b8d9..e9fdfcae87 100644
--- a/sysdeps/i386/fpu/feholdexcpt.c
+++ b/sysdeps/i386/fpu/feholdexcpt.c
@@ -1,5 +1,6 @@
/* Store current floating-point environment and clear exceptions.
- Copyright (C) 1997, 1999, 2003, 2004, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1999, 2003, 2004, 2005, 2007
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -26,14 +27,19 @@
int
feholdexcept (fenv_t *envp)
{
- unsigned short int work;
+ fenv_t temp;
/* Store the environment. */
- __asm__ ("fnstenv %0" : "=m" (*envp));
+ __asm__ ("fnstenv %0" : "=m" (temp));
+ *envp = temp;
/* Now set all exceptions to non-stop. */
- work = envp->__control_word | 0x3f;
- __asm__ ("fldcw %0" : : "m" (*&work));
+ temp.__control_word |= 0x3f;
+
+ /* And clear all exceptions. */
+ temp.__status_word &= ~0x3f;
+
+ __asm__ ("fldenv %0" : : "m" (temp));
/* If the CPU supports SSE we set the MXCSR as well. */
if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
@@ -43,8 +49,8 @@ feholdexcept (fenv_t *envp)
/* Get the current control word. */
__asm__ ("stmxcsr %0" : "=m" (*&xwork));
- /* Set all exceptions to non-stop. */
- xwork |= 0x1f80;
+ /* Set all exceptions to non-stop and clear them. */
+ xwork = (xwork | 0x1f80) & ~0x3f;
__asm__ ("ldmxcsr %0" : : "m" (*&xwork));
}
diff --git a/sysdeps/i386/fpu/feupdateenv.c b/sysdeps/i386/fpu/feupdateenv.c
index a443f500bc..a58963837f 100644
--- a/sysdeps/i386/fpu/feupdateenv.c
+++ b/sysdeps/i386/fpu/feupdateenv.c
@@ -1,5 +1,5 @@
/* Install given floating-point environment and raise exceptions.
- Copyright (C) 1997,99,2000,01 Free Software Foundation, Inc.
+ Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
@@ -20,20 +20,29 @@
#include <fenv.h>
#include <bp-sym.h>
+#include <unistd.h>
+#include <dl-procinfo.h>
+#include <ldsodefs.h>
int
__feupdateenv (const fenv_t *envp)
{
fexcept_t temp;
+ unsigned int xtemp = 0;
/* Save current exceptions. */
__asm__ ("fnstsw %0" : "=m" (*&temp));
- temp &= FE_ALL_EXCEPT;
+
+ /* If the CPU supports SSE we test the MXCSR as well. */
+ if ((GLRO(dl_hwcap) & HWCAP_I386_XMM) != 0)
+ __asm__ ("stmxcsr %0" : "=m" (*&xtemp));
+
+ temp = (temp | xtemp) & FE_ALL_EXCEPT;
/* Install new environment. */
fesetenv (envp);
- /* Raise the safed exception. Incidently for us the implementation
+ /* Raise the saved exception. Incidently for us the implementation
defined format of the values in objects of type fexcept_t is the
same as the ones specified using the FE_* constants. */
feraiseexcept ((int) temp);
diff --git a/sysdeps/i386/fpu/math_private.h b/sysdeps/i386/fpu/math_private.h
new file mode 100644
index 0000000000..a426788ef1
--- /dev/null
+++ b/sysdeps/i386/fpu/math_private.h
@@ -0,0 +1,18 @@
+#ifndef _MATH_PRIVATE_H
+
+#define math_opt_barrier(x) \
+({ __typeof(x) __x; \
+ __asm ("" : "=t" (__x) : "0" (x)); \
+ __x; })
+#define math_force_eval(x) \
+do \
+ { \
+ if (sizeof (x) <= sizeof (double)) \
+ __asm __volatile ("" : : "m" (x)); \
+ else \
+ __asm __volatile ("" : : "f" (x)); \
+ } \
+while (0)
+
+#include <math/math_private.h>
+#endif
diff --git a/sysdeps/i386/fpu/s_nextafterl.c b/sysdeps/i386/fpu/s_nextafterl.c
index 5b617cb4e7..aef0a144e5 100644
--- a/sysdeps/i386/fpu/s_nextafterl.c
+++ b/sysdeps/i386/fpu/s_nextafterl.c
@@ -27,7 +27,7 @@ static char rcsid[] = "$NetBSD: $";
*/
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
#ifdef __STDC__
long double __nextafterl(long double x, long double y)
@@ -52,9 +52,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if(x==y) return y; /* x=y, return y */
if((ix|hx|lx)==0) { /* x == 0 */
+ long double u;
SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(esx>=0) { /* x > 0 */
if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
@@ -109,12 +112,9 @@ static char rcsid[] = "$NetBSD: $";
}
esy = esx&0x7fff;
if(esy==0x7fff) return x+x; /* overflow */
- if(esy==0) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
- SET_LDOUBLE_WORDS(y,esx,hx,lx);
- return y;
- }
+ if(esy==0) {
+ long double u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
SET_LDOUBLE_WORDS(x,esx,hx,lx);
return x;
diff --git a/sysdeps/i386/fpu/s_nexttoward.c b/sysdeps/i386/fpu/s_nexttoward.c
index 2bd768e448..9bd86a3724 100644
--- a/sysdeps/i386/fpu/s_nexttoward.c
+++ b/sysdeps/i386/fpu/s_nexttoward.c
@@ -27,7 +27,8 @@ static char rcsid[] = "$NetBSD: $";
*/
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
+#include <float.h>
#ifdef __STDC__
double __nexttoward(double x, long double y)
@@ -52,10 +53,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if((ix|lx)==0) { /* x == 0 */
- double x2;
+ double u;
INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
- x2 = x*x;
- if(x2==x) return x2; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
@@ -85,16 +88,14 @@ static char rcsid[] = "$NetBSD: $";
hy = hx&0x7ff00000;
if(hy>=0x7ff00000) {
x = x+x; /* overflow */
- /* Force conversion to double. */
- asm ("" : "=m"(x) : "m"(x));
+ if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
+ /* Force conversion to double. */
+ asm ("" : "+m"(x));
return x;
}
- if(hy<0x00100000) { /* underflow */
- double x2 = x*x;
- if(x2!=x) { /* raise underflow flag */
- INSERT_WORDS(x2,hx,lx);
- return x2;
- }
+ if(hy<0x00100000) {
+ double u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
INSERT_WORDS(x,hx,lx);
return x;
diff --git a/sysdeps/i386/fpu/s_nexttowardf.c b/sysdeps/i386/fpu/s_nexttowardf.c
index 3fbe53c338..25f70e4f4d 100644
--- a/sysdeps/i386/fpu/s_nexttowardf.c
+++ b/sysdeps/i386/fpu/s_nexttowardf.c
@@ -19,7 +19,8 @@ static char rcsid[] = "$NetBSD: $";
#endif
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
+#include <float.h>
#ifdef __STDC__
float __nexttowardf(float x, long double y)
@@ -44,10 +45,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if(ix==0) { /* x == 0 */
- float x2;
+ float u;
SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
- x2 = x*x;
- if(x2==x) return x2; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
@@ -69,16 +72,14 @@ static char rcsid[] = "$NetBSD: $";
hy = hx&0x7f800000;
if(hy>=0x7f800000) {
x = x+x; /* overflow */
- /* Force conversion to float. */
- asm ("" : "=m"(x) : "m"(x));
+ if (FLT_EVAL_METHOD != 0)
+ /* Force conversion to float. */
+ asm ("" : "+m"(x));
return x;
}
- if(hy<0x00800000) { /* underflow */
- float x2 = x*x;
- if(x2!=x) { /* raise underflow flag */
- SET_FLOAT_WORD(x2,hx);
- return x2;
- }
+ if(hy<0x00800000) {
+ float u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
SET_FLOAT_WORD(x,hx);
return x;
diff --git a/sysdeps/ia64/fpu/feholdexcpt.c b/sysdeps/ia64/fpu/feholdexcpt.c
index 27c9a1109e..e50fbfada5 100644
--- a/sysdeps/ia64/fpu/feholdexcpt.c
+++ b/sysdeps/ia64/fpu/feholdexcpt.c
@@ -1,5 +1,5 @@
/* Store current floating-point environment and clear exceptions.
- Copyright (C) 1997, 1999, 2000, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1997, 1999, 2000, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999
@@ -23,12 +23,20 @@
int
feholdexcept (fenv_t *envp)
{
+ fenv_t fpsr;
/* Save the current state. */
- fegetenv (envp);
+ __asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
+ *envp = fpsr;
- /* set the trap disable bit */
- __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (*envp | FE_ALL_EXCEPT));
+ /* Set the trap disable bits. */
+ fpsr |= FE_ALL_EXCEPT;
- return 1;
+ /* And clear the exception bits. */
+ fpsr &= ~(fenv_t) (FE_ALL_EXCEPT << 13);
+
+ __asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr));
+
+ /* Success. */
+ return 0;
}
libm_hidden_def (feholdexcept)
diff --git a/sysdeps/ia64/fpu/fesetround.c b/sysdeps/ia64/fpu/fesetround.c
index 351bcc2f10..13801c848b 100644
--- a/sysdeps/ia64/fpu/fesetround.c
+++ b/sysdeps/ia64/fpu/fesetround.c
@@ -1,5 +1,5 @@
/* Set current rounding direction.
- Copyright (C) 1999, 2000, 2005 Free Software Foundation, Inc.
+ Copyright (C) 1999, 2000, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
@@ -26,7 +26,7 @@ fesetround (int round)
fenv_t fpsr;
if (round & ~3)
- return 0;
+ return 1;
/* Get the current state. */
__asm__ __volatile__ ("mov.m %0=ar.fpsr" : "=r" (fpsr));
@@ -37,6 +37,6 @@ fesetround (int round)
/* Put the new state in effect. */
__asm__ __volatile__ ("mov.m ar.fpsr=%0" :: "r" (fpsr) : "memory");
- return 1;
+ return 0;
}
libm_hidden_def (fesetround)
diff --git a/sysdeps/ia64/fpu/feupdateenv.c b/sysdeps/ia64/fpu/feupdateenv.c
index 544c38485d..72f12287fa 100644
--- a/sysdeps/ia64/fpu/feupdateenv.c
+++ b/sysdeps/ia64/fpu/feupdateenv.c
@@ -1,5 +1,5 @@
/* Install given floating-point environment and raise exceptions.
- Copyright (C) 1997, 2000 Free Software Foundation, Inc.
+ Copyright (C) 1997, 2000, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Christian Boissat <Christian.Boissat@cern.ch>, 1999.
@@ -32,10 +32,8 @@ feupdateenv (const fenv_t *envp)
/* Install new environment. */
fesetenv (envp);
- /* Raise the safed exception. Incidently for us the implementation
- defined format of the values in objects of type fexcept_t is the
- same as the ones specified using the FE_* constants. */
- feraiseexcept ((int) fpsr & FE_ALL_EXCEPT);
+ /* Raise the saved exceptions. */
+ feraiseexcept ((int) (fpsr >> 13) & FE_ALL_EXCEPT);
/* Success. */
return 0;
diff --git a/sysdeps/ieee754/flt-32/s_nextafterf.c b/sysdeps/ieee754/flt-32/s_nextafterf.c
index e1568e24c9..600c14621f 100644
--- a/sysdeps/ieee754/flt-32/s_nextafterf.c
+++ b/sysdeps/ieee754/flt-32/s_nextafterf.c
@@ -18,7 +18,7 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp
#endif
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
#include <float.h>
#ifdef __STDC__
@@ -40,9 +40,12 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp
return x+y;
if(x==y) return y; /* x=y, return y */
if(ix==0) { /* x == 0 */
+ float u;
SET_FLOAT_WORD(x,(hy&0x80000000)|1);/* return +-minsubnormal */
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u*u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if(hx>hy) { /* x > y, x -= ulp */
@@ -61,15 +64,12 @@ static char rcsid[] = "$NetBSD: s_nextafterf.c,v 1.4 1995/05/10 20:48:01 jtc Exp
if(hy>=0x7f800000) {
x = x+x; /* overflow */
if (FLT_EVAL_METHOD != 0)
- asm ("" : "=m"(x) : "m"(x));
+ asm ("" : "+m"(x));
return x; /* overflow */
}
- if(hy<0x00800000) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
- SET_FLOAT_WORD(y,hx);
- return y;
- }
+ if(hy<0x00800000) {
+ float u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
SET_FLOAT_WORD(x,hx);
return x;
diff --git a/sysdeps/ieee754/ldbl-128/s_nextafterl.c b/sysdeps/ieee754/ldbl-128/s_nextafterl.c
index d3df668178..7bc869a518 100644
--- a/sysdeps/ieee754/ldbl-128/s_nextafterl.c
+++ b/sysdeps/ieee754/ldbl-128/s_nextafterl.c
@@ -25,7 +25,7 @@ static char rcsid[] = "$NetBSD: $";
*/
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
#ifdef __STDC__
long double __nextafterl(long double x, long double y)
@@ -47,9 +47,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if(x==y) return y; /* x=y, return y */
if((ix|lx)==0) { /* x == 0 */
+ long double u;
SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if(hx>hy||((hx==hy)&&(lx>ly))) { /* x > y, x -= ulp */
@@ -70,12 +73,9 @@ static char rcsid[] = "$NetBSD: $";
}
hy = hx&0x7fff000000000000LL;
if(hy==0x7fff000000000000LL) return x+x;/* overflow */
- if(hy==0) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
- SET_LDOUBLE_WORDS64(y,hx,lx);
- return y;
- }
+ if(hy==0) {
+ long double u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
SET_LDOUBLE_WORDS64(x,hx,lx);
return x;
diff --git a/sysdeps/ieee754/ldbl-128/s_nexttoward.c b/sysdeps/ieee754/ldbl-128/s_nexttoward.c
index 553e401973..178505c58f 100644
--- a/sysdeps/ieee754/ldbl-128/s_nexttoward.c
+++ b/sysdeps/ieee754/ldbl-128/s_nexttoward.c
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $";
*/
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
#include <float.h>
#ifdef __STDC__
@@ -53,10 +53,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if((ix|lx)==0) { /* x == 0 */
- double x2;
+ double u;
INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
- x2 = x*x;
- if(x2==x) return x2; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if (hy<0||(ix>>20)>(iy>>48)-0x3c00
@@ -87,16 +89,13 @@ static char rcsid[] = "$NetBSD: $";
if(hy>=0x7ff00000) {
x = x+x; /* overflow */
if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
- /* Force conversion to float. */
- asm ("" : "=m"(x) : "m"(x));
+ /* Force conversion to double. */
+ asm ("" : "+m"(x));
return x;
}
- if(hy<0x00100000) { /* underflow */
- double x2 = x*x;
- if(x2!=x) { /* raise underflow flag */
- INSERT_WORDS(x2,hx,lx);
- return x2;
- }
+ if(hy<0x00100000) {
+ double u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
INSERT_WORDS(x,hx,lx);
return x;
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
index e35ce50829..4f8aa7dec1 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nextafterl.c
@@ -24,8 +24,8 @@ static char rcsid[] = "$NetBSD: $";
* Special cases:
*/
-#include "math.h"
-#include "math_private.h"
+#include <math.h>
+#include <math_private.h>
#include <math_ldbl_opt.h>
#ifdef __STDC__
@@ -53,9 +53,12 @@ static char rcsid[] = "$NetBSD: $";
if(x==y)
return y; /* x=y, return y */
if(ihx == 0 && ilx == 0) { /* x == 0 */
+ long double u;
SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
+ u = math_opt_barrier (u);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(ihx>=0) { /* x > 0 */
if(ihx>ihy||((ihx==ihy)&&(ilx>ily))) { /* x > y, x -= ulp */
@@ -93,12 +96,9 @@ static char rcsid[] = "$NetBSD: $";
}
hy = hx&0x7ff0000000000000LL;
if(hy==0x7ff0000000000000LL) return x+x;/* overflow */
- if(hy==0) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
- SET_LDOUBLE_WORDS64(y,hx,lx);
- return y;
- }
+ if(hy==0) {
+ long double u = x * x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
SET_LDOUBLE_WORDS64(x,hx,lx);
return x;
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c b/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
index 3335100592..e2f6521f57 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttoward.c
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $";
*/
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
#include <math_ldbl_opt.h>
#include <float.h>
@@ -55,10 +55,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if((ix|lx)==0) { /* x == 0 */
- double x2;
+ double u;
INSERT_WORDS(x,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
- x2 = x*x;
- if(x2==x) return x2; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if (hy<0||(ix>>20)>(iy>>52)
@@ -89,16 +91,13 @@ static char rcsid[] = "$NetBSD: $";
if(hy>=0x7ff00000) {
x = x+x; /* overflow */
if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
- /* Force conversion to float. */
- asm ("" : "=m"(x) : "m"(x));
+ /* Force conversion to double. */
+ asm ("" : "+m"(x));
return x;
}
- if(hy<0x00100000) { /* underflow */
- double x2 = x*x;
- if(x2!=x) { /* raise underflow flag */
- INSERT_WORDS(x2,hx,lx);
- return x2;
- }
+ if(hy<0x00100000) {
+ double u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
INSERT_WORDS(x,hx,lx);
return x;
diff --git a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
index a9373ff822..cf655fad16 100644
--- a/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
+++ b/sysdeps/ieee754/ldbl-128ibm/s_nexttowardf.c
@@ -19,8 +19,9 @@ static char rcsid[] = "$NetBSD: $";
#endif
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
#include <math_ldbl_opt.h>
+#include <float.h>
#ifdef __STDC__
float __nexttowardf(float x, long double y)
@@ -46,10 +47,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if(ix==0) { /* x == 0 */
- float x2;
+ float u;
SET_FLOAT_WORD(x,(u_int32_t)((hy>>32)&0x80000000)|1);/* return +-minsub*/
- x2 = x*x;
- if(x2==x) return x2; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if(hy<0||(ix>>23)>(iy>>52)-0x380
@@ -69,13 +72,16 @@ static char rcsid[] = "$NetBSD: $";
}
}
hy = hx&0x7f800000;
- if(hy>=0x7f800000) return x+x; /* overflow */
+ if(hy>=0x7f800000) {
+ x = x+x; /* overflow */
+ if (FLT_EVAL_METHOD != 0)
+ /* Force conversion to float. */
+ asm ("" : "+m"(x));
+ return x;
+ }
if(hy<0x00800000) { /* underflow */
- float x2 = x*x;
- if(x2!=x) { /* raise underflow flag */
- SET_FLOAT_WORD(x2,hx);
- return x2;
- }
+ float u = x*x;
+ math_force_eval (u); /* raise underflow flag */
}
SET_FLOAT_WORD(x,hx);
return x;
diff --git a/sysdeps/ieee754/ldbl-96/s_nextafterl.c b/sysdeps/ieee754/ldbl-96/s_nextafterl.c
index 1798261b28..ed0877d6dd 100644
--- a/sysdeps/ieee754/ldbl-96/s_nextafterl.c
+++ b/sysdeps/ieee754/ldbl-96/s_nextafterl.c
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $";
*/
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
#ifdef __STDC__
long double __nextafterl(long double x, long double y)
@@ -48,9 +48,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if(x==y) return y; /* x=y, return y */
if((ix|hx|lx)==0) { /* x == 0 */
+ long double u;
SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
- y = x*x;
- if(y==x) return y; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(esx<0x8000) { /* x > 0 */
if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
@@ -85,13 +88,10 @@ static char rcsid[] = "$NetBSD: $";
}
}
esy = esx&0x7fff;
- if(esy==0x7fff) return x+x; /* overflow */
- if(esy==0) { /* underflow */
- y = x*x;
- if(y!=x) { /* raise underflow flag */
- SET_LDOUBLE_WORDS(y,esx,hx,lx);
- return y;
- }
+ if(esy==0x7fff) return x+x; /* overflow */
+ if(esy==0) {
+ long double u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
SET_LDOUBLE_WORDS(x,esx,hx,lx);
return x;
diff --git a/sysdeps/ieee754/ldbl-96/s_nexttoward.c b/sysdeps/ieee754/ldbl-96/s_nexttoward.c
index 7945cb5cb1..e30438482c 100644
--- a/sysdeps/ieee754/ldbl-96/s_nexttoward.c
+++ b/sysdeps/ieee754/ldbl-96/s_nexttoward.c
@@ -26,7 +26,7 @@ static char rcsid[] = "$NetBSD: $";
*/
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
#include <float.h>
#ifdef __STDC__
@@ -50,10 +50,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if((ix|lx)==0) { /* x == 0 */
- double x2;
+ double u;
INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
- x2 = x*x;
- if(x2==x) return x2; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if (esy>=0x8000||((ix>>20)&0x7ff)>iy-0x3c00
@@ -84,16 +86,13 @@ static char rcsid[] = "$NetBSD: $";
if(hy>=0x7ff00000) {
x = x+x; /* overflow */
if (FLT_EVAL_METHOD != 0 && FLT_EVAL_METHOD != 1)
- /* Force conversion to float. */
- asm ("" : "=m"(x) : "m"(x));
+ /* Force conversion to double. */
+ asm ("" : "+m"(x));
return x;
}
- if(hy<0x00100000) { /* underflow */
- double x2 = x*x;
- if(x2!=x) { /* raise underflow flag */
- INSERT_WORDS(x2,hx,lx);
- return x2;
- }
+ if(hy<0x00100000) {
+ double u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
INSERT_WORDS(x,hx,lx);
return x;
diff --git a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
index a1c38b5d4c..6357975ffc 100644
--- a/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
+++ b/sysdeps/ieee754/ldbl-96/s_nexttowardf.c
@@ -18,7 +18,8 @@ static char rcsid[] = "$NetBSD: $";
#endif
#include "math.h"
-#include "math_private.h"
+#include <math_private.h>
+#include <float.h>
#ifdef __STDC__
float __nexttowardf(float x, long double y)
@@ -41,10 +42,12 @@ static char rcsid[] = "$NetBSD: $";
return x+y;
if((long double) x==y) return y; /* x=y, return y */
if(ix==0) { /* x == 0 */
- float x2;
+ float u;
SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
- x2 = x*x;
- if(x2==x) return x2; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if(esy>=0x8000||((ix>>23)&0xff)>iy-0x3f80
@@ -64,13 +67,16 @@ static char rcsid[] = "$NetBSD: $";
}
}
hy = hx&0x7f800000;
- if(hy>=0x7f800000) return x+x; /* overflow */
- if(hy<0x00800000) { /* underflow */
- float x2 = x*x;
- if(x2!=x) { /* raise underflow flag */
- SET_FLOAT_WORD(x2,hx);
- return x2;
- }
+ if(hy>=0x7f800000) {
+ x = x+x; /* overflow */
+ if (FLT_EVAL_METHOD != 0)
+ /* Force conversion to float. */
+ asm ("" : "+m"(x));
+ return x;
+ }
+ if(hy<0x00800000) {
+ float u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
SET_FLOAT_WORD(x,hx);
return x;
diff --git a/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c b/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
index d52526f719..68027f26fa 100644
--- a/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
+++ b/sysdeps/ieee754/ldbl-opt/s_nexttowardfd.c
@@ -20,7 +20,10 @@
* Special cases:
*/
+#include <math.h>
+#include <math_private.h>
#include <math_ldbl_opt.h>
+#include <float.h>
float __nldbl_nexttowardf(float x, double y);
@@ -39,10 +42,12 @@ float __nldbl_nexttowardf(float x, double y)
return x+y;
if((double) x==y) return y; /* x=y, return y */
if(ix==0) { /* x == 0 */
- float x2;
+ float u;
SET_FLOAT_WORD(x,(u_int32_t)(hy&0x80000000)|1);/* return +-minsub*/
- x2 = x*x;
- if(x2==x) return x2; else return x; /* raise underflow flag */
+ u = math_opt_barrier (x);
+ u = u * u;
+ math_force_eval (u); /* raise underflow flag */
+ return x;
}
if(hx>=0) { /* x > 0 */
if(hy<0||(ix>>23)>(iy>>20)-0x380
@@ -60,13 +65,16 @@ float __nldbl_nexttowardf(float x, double y)
hx += 1;
}
hy = hx&0x7f800000;
- if(hy>=0x7f800000) return x+x; /* overflow */
- if(hy<0x00800000) { /* underflow */
- float x2 = x*x;
- if(x2!=x) { /* raise underflow flag */
- SET_FLOAT_WORD(x2,hx);
- return x2;
- }
+ if(hy>=0x7f800000) {
+ x = x+x; /* overflow */
+ if (FLT_EVAL_METHOD != 0)
+ /* Force conversion to float. */
+ asm ("" : "+m"(x));
+ return x;
+ }
+ if(hy<0x00800000) {
+ float u = x*x; /* underflow */
+ math_force_eval (u); /* raise underflow flag */
}
SET_FLOAT_WORD(x,hx);
return x;
diff --git a/sysdeps/unix/sysv/linux/bits/sched.h b/sysdeps/unix/sysv/linux/bits/sched.h
index 4a95a263f7..1d9c7b9f35 100644
--- a/sysdeps/unix/sysv/linux/bits/sched.h
+++ b/sysdeps/unix/sysv/linux/bits/sched.h
@@ -1,6 +1,7 @@
/* Definitions of constants and data structure for POSIX 1003.1b-1993
scheduling interface.
- Copyright (C) 1996-1999,2001-2003,2005,2006 Free Software Foundation, Inc.
+ Copyright (C) 1996-1999,2001-2003,2005,2006,2007
+ Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -127,4 +128,7 @@ typedef struct
((cpusetp)->__bits[__CPUELT (cpu)] &= ~__CPUMASK (cpu))
# define __CPU_ISSET(cpu, cpusetp) \
(((cpusetp)->__bits[__CPUELT (cpu)] & __CPUMASK (cpu)) != 0)
+extern int __sched_cpucount (size_t __setsize, cpu_set_t *__setp) __THROW;
+# define __CPU_COUNT(cpusetp) \
+ __sched_cpucount (sizeof (cpu_set_t), cpusetp)
#endif
diff --git a/sysdeps/unix/sysv/linux/sync_file_range.c b/sysdeps/unix/sysv/linux/sync_file_range.c
index 7519bb7fe6..4e267a1602 100644
--- a/sysdeps/unix/sysv/linux/sync_file_range.c
+++ b/sysdeps/unix/sysv/linux/sync_file_range.c
@@ -1,5 +1,5 @@
/* Selective file content synch'ing.
- Copyright (C) 2006 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -27,7 +27,7 @@
#ifdef __NR_sync_file_range
int
-sync_file_range (int fd, __off64_t from, __off64_t to, int flags)
+sync_file_range (int fd, __off64_t from, __off64_t to, unsigned int flags)
{
return INLINE_SYSCALL (sync_file_range, 6, fd,
__LONG_LONG_PAIR ((long) (from >> 32), (long) from),
@@ -36,7 +36,7 @@ sync_file_range (int fd, __off64_t from, __off64_t to, int flags)
}
#else
int
-sync_file_range (int fd, __off64_t from, __off64_t to, int flags)
+sync_file_range (int fd, __off64_t from, __off64_t to, unsigned int flags)
{
__set_errno (ENOSYS);
return -1;
diff --git a/sysdeps/x86_64/fpu/fedisblxcpt.c b/sysdeps/x86_64/fpu/fedisblxcpt.c
index e8157da126..261c1e877c 100644
--- a/sysdeps/x86_64/fpu/fedisblxcpt.c
+++ b/sysdeps/x86_64/fpu/fedisblxcpt.c
@@ -1,5 +1,5 @@
/* Disable floating-point exceptions.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 2001.
@@ -24,7 +24,7 @@ int
fedisableexcept (int excepts)
{
unsigned short int new_exc, old_exc;
- unsigned int new, old;
+ unsigned int new;
excepts &= FE_ALL_EXCEPT;
@@ -40,8 +40,6 @@ fedisableexcept (int excepts)
__asm__ ("stmxcsr %0" : "=m" (*&new));
/* The SSE exception masks are shifted by 7 bits. */
- old = (~new) & (FE_ALL_EXCEPT << 7);
-
new |= excepts << 7;
__asm__ ("ldmxcsr %0" : : "m" (*&new));
diff --git a/sysdeps/x86_64/fpu/feenablxcpt.c b/sysdeps/x86_64/fpu/feenablxcpt.c
index 43259d0cfb..7bbc368d27 100644
--- a/sysdeps/x86_64/fpu/feenablxcpt.c
+++ b/sysdeps/x86_64/fpu/feenablxcpt.c
@@ -1,5 +1,5 @@
/* Enable floating-point exceptions.
- Copyright (C) 2001 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Andreas Jaeger <aj@suse.de>, 2001.
@@ -24,7 +24,7 @@ int
feenableexcept (int excepts)
{
unsigned short int new_exc, old_exc;
- unsigned int new, old;
+ unsigned int new;
excepts &= FE_ALL_EXCEPT;
@@ -40,8 +40,6 @@ feenableexcept (int excepts)
__asm__ ("stmxcsr %0" : "=m" (*&new));
/* The SSE exception masks are shifted by 7 bits. */
- old = (~new) & (FE_ALL_EXCEPT << 7);
-
new &= ~(excepts << 7);
__asm__ ("ldmxcsr %0" : : "m" (*&new));
diff --git a/sysdeps/x86_64/fpu/feholdexcpt.c b/sysdeps/x86_64/fpu/feholdexcpt.c
index a9b21a3c25..d56ab163ca 100644
--- a/sysdeps/x86_64/fpu/feholdexcpt.c
+++ b/sysdeps/x86_64/fpu/feholdexcpt.c
@@ -1,5 +1,5 @@
/* Store current floating-point environment and clear exceptions.
- Copyright (C) 2001, 2005 Free Software Foundation, Inc.
+ Copyright (C) 2001, 2005, 2007 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -22,19 +22,24 @@
int
feholdexcept (fenv_t *envp)
{
- unsigned short int work;
unsigned int mxcsr;
+ fenv_t temp;
/* Store the environment. */
__asm__ ("fnstenv %0\n"
- "stmxcsr %1" : "=m" (*envp), "=m" (envp->__mxcsr));
+ "stmxcsr %1" : "=m" (temp), "=m" (temp.__mxcsr));
+ *envp = temp;
/* Now set all exceptions to non-stop, first the x87 FPU. */
- work = envp->__control_word | 0x3f;
- __asm__ ("fldcw %0" : : "m" (*&work));
+ temp.__control_word |= 0x3f;
+
+ /* And clear all exceptions. */
+ temp.__status_word &= ~0x3f;
+
+ __asm__ ("fldenv %0" : : "m" (temp));
/* Set the SSE MXCSR register. */
- mxcsr = envp->__mxcsr | 0x1f80;
+ mxcsr = (envp->__mxcsr | 0x1f80) & ~0x3f;
__asm__ ("ldmxcsr %0" : : "m" (*&mxcsr));
return 0;
diff --git a/sysdeps/x86_64/fpu/feupdateenv.c b/sysdeps/x86_64/fpu/feupdateenv.c
new file mode 100644
index 0000000000..e23f1affa6
--- /dev/null
+++ b/sysdeps/x86_64/fpu/feupdateenv.c
@@ -0,0 +1,51 @@
+/* Install given floating-point environment and raise exceptions.
+ Copyright (C) 1997,99,2000,01,07 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <fenv.h>
+
+int
+__feupdateenv (const fenv_t *envp)
+{
+ fexcept_t temp;
+ unsigned int xtemp;
+
+ /* Save current exceptions. */
+ __asm__ ("fnstsw %0\n\tstmxcsr %1" : "=m" (*&temp), "=m" (xtemp));
+ temp = (temp | xtemp) & FE_ALL_EXCEPT;
+
+ /* Install new environment. */
+ fesetenv (envp);
+
+ /* Raise the saved exception. Incidently for us the implementation
+ defined format of the values in objects of type fexcept_t is the
+ same as the ones specified using the FE_* constants. */
+ feraiseexcept ((int) temp);
+
+ /* Success. */
+ return 0;
+}
+
+#include <shlib-compat.h>
+#if SHLIB_COMPAT (libm, GLIBC_2_1, GLIBC_2_2)
+strong_alias (__feupdateenv, __old_feupdateenv)
+compat_symbol (libm, __old_feupdateenv, feupdateenv, GLIBC_2_1);
+#endif
+
+versioned_symbol (libm, __feupdateenv, feupdateenv, GLIBC_2_2);
diff --git a/sysdeps/x86_64/fpu/math_private.h b/sysdeps/x86_64/fpu/math_private.h
new file mode 100644
index 0000000000..4febcbb5ec
--- /dev/null
+++ b/sysdeps/x86_64/fpu/math_private.h
@@ -0,0 +1,21 @@
+#ifndef _MATH_PRIVATE_H
+
+#define math_opt_barrier(x) \
+({ __typeof(x) __x; \
+ if (sizeof (x) <= sizeof (double)) \
+ __asm ("" : "=x" (__x) : "0" (x)); \
+ else \
+ __asm ("" : "=t" (__x) : "0" (x)); \
+ __x; })
+#define math_force_eval(x) \
+do \
+ { \
+ if (sizeof (x) <= sizeof (double)) \
+ __asm __volatile ("" : : "x" (x)); \
+ else \
+ __asm __volatile ("" : : "f" (x)); \
+ } \
+while (0)
+
+#include <math/math_private.h>
+#endif