mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-23 11:20:07 +00:00
Use new internal libc_fe* interfaces in more functions
This commit is contained in:
parent
4855e3ddf5
commit
d9a8d0abcc
10
ChangeLog
10
ChangeLog
@ -1,5 +1,15 @@
|
|||||||
2011-10-18 Ulrich Drepper <drepper@gmail.com>
|
2011-10-18 Ulrich Drepper <drepper@gmail.com>
|
||||||
|
|
||||||
|
* math/math_private.h: Define defaults for libc_fetestexcept and
|
||||||
|
libc_feupdateenv.
|
||||||
|
* sysdeps/ieee754/dbl-64/s_fma.c: Use libc_fe* interfaces.
|
||||||
|
* sysdeps/ieee754/dbl-64/s_fmaf.c: Likewise.
|
||||||
|
* sysdeps/ieee754/flt-32/e_exp2f.c: Likewise.
|
||||||
|
* sysdeps/ieee754/flt-32/e_expf.c: Likewise.
|
||||||
|
* sysdeps/ieee754/flt-32/s_nearbyintf.c: Likewise.
|
||||||
|
* sysdeps/x86_64/fpu/math_private.h: Define special versions of
|
||||||
|
libc_fetestexcept and libc_feupdateenv.
|
||||||
|
|
||||||
* math/math_private.h: Define defaults for libc_feholdexcept_setround,
|
* math/math_private.h: Define defaults for libc_feholdexcept_setround,
|
||||||
libc_feholdexcept_setroundf, libc_feholdexcept_setroundl.
|
libc_feholdexcept_setroundf, libc_feholdexcept_setroundl.
|
||||||
* sysdeps/ieee754/dbl-64/e_exp2.c: Use libc_feholdexcept_setround.
|
* sysdeps/ieee754/dbl-64/e_exp2.c: Use libc_feholdexcept_setround.
|
||||||
|
@ -383,8 +383,16 @@ extern void __docos (double __x, double __dx, double __v[]);
|
|||||||
#define libc_feholdexcept_setroundl(e, r) \
|
#define libc_feholdexcept_setroundl(e, r) \
|
||||||
do { feholdexcept (e); fesetround (r); } while (0)
|
do { feholdexcept (e); fesetround (r); } while (0)
|
||||||
|
|
||||||
|
#define libc_fetestexcept(e) fetestexcept (e)
|
||||||
|
#define libc_fetestexceptf(e) fetestexcept (e)
|
||||||
|
#define libc_fetestexceptl(e) fetestexcept (e)
|
||||||
|
|
||||||
#define libc_fesetenv(e) (void) fesetenv (e)
|
#define libc_fesetenv(e) (void) fesetenv (e)
|
||||||
#define libc_fesetenvf(e) (void) fesetenv (e)
|
#define libc_fesetenvf(e) (void) fesetenv (e)
|
||||||
#define libc_fesetenvl(e) (void) fesetenv (e)
|
#define libc_fesetenvl(e) (void) fesetenv (e)
|
||||||
|
|
||||||
|
#define libc_feupdateenv(e) (void) feupdateenv (e)
|
||||||
|
#define libc_feupdateenvf(e) (void) feupdateenv (e)
|
||||||
|
#define libc_feupdateenvl(e) (void) feupdateenv (e)
|
||||||
|
|
||||||
#endif /* _MATH_PRIVATE_H_ */
|
#endif /* _MATH_PRIVATE_H_ */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Compute x * y + z as ternary operation.
|
/* Compute x * y + z as ternary operation.
|
||||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
|
||||||
|
|
||||||
@ -22,6 +22,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <fenv.h>
|
#include <fenv.h>
|
||||||
#include <ieee754.h>
|
#include <ieee754.h>
|
||||||
|
#include <math_private.h>
|
||||||
|
|
||||||
/* This implementation uses rounding to odd to avoid problems with
|
/* This implementation uses rounding to odd to avoid problems with
|
||||||
double rounding. See a paper by Boldo and Melquiond:
|
double rounding. See a paper by Boldo and Melquiond:
|
||||||
@ -148,34 +149,33 @@ __fma (double x, double y, double z)
|
|||||||
double a2 = t1 + t2;
|
double a2 = t1 + t2;
|
||||||
|
|
||||||
fenv_t env;
|
fenv_t env;
|
||||||
feholdexcept (&env);
|
libc_feholdexcept_setround (&env, FE_TOWARDZERO);
|
||||||
fesetround (FE_TOWARDZERO);
|
|
||||||
/* Perform m2 + a2 addition with round to odd. */
|
/* Perform m2 + a2 addition with round to odd. */
|
||||||
u.d = a2 + m2;
|
u.d = a2 + m2;
|
||||||
|
|
||||||
if (__builtin_expect (adjust == 0, 1))
|
if (__builtin_expect (adjust == 0, 1))
|
||||||
{
|
{
|
||||||
if ((u.ieee.mantissa1 & 1) == 0 && u.ieee.exponent != 0x7ff)
|
if ((u.ieee.mantissa1 & 1) == 0 && u.ieee.exponent != 0x7ff)
|
||||||
u.ieee.mantissa1 |= fetestexcept (FE_INEXACT) != 0;
|
u.ieee.mantissa1 |= libc_fetestexcept (FE_INEXACT) != 0;
|
||||||
feupdateenv (&env);
|
libc_feupdateenv (&env);
|
||||||
/* Result is a1 + u.d. */
|
/* Result is a1 + u.d. */
|
||||||
return a1 + u.d;
|
return a1 + u.d;
|
||||||
}
|
}
|
||||||
else if (__builtin_expect (adjust > 0, 1))
|
else if (__builtin_expect (adjust > 0, 1))
|
||||||
{
|
{
|
||||||
if ((u.ieee.mantissa1 & 1) == 0 && u.ieee.exponent != 0x7ff)
|
if ((u.ieee.mantissa1 & 1) == 0 && u.ieee.exponent != 0x7ff)
|
||||||
u.ieee.mantissa1 |= fetestexcept (FE_INEXACT) != 0;
|
u.ieee.mantissa1 |= libc_fetestexcept (FE_INEXACT) != 0;
|
||||||
feupdateenv (&env);
|
libc_feupdateenv (&env);
|
||||||
/* Result is a1 + u.d, scaled up. */
|
/* Result is a1 + u.d, scaled up. */
|
||||||
return (a1 + u.d) * 0x1p53;
|
return (a1 + u.d) * 0x1p53;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if ((u.ieee.mantissa1 & 1) == 0)
|
if ((u.ieee.mantissa1 & 1) == 0)
|
||||||
u.ieee.mantissa1 |= fetestexcept (FE_INEXACT) != 0;
|
u.ieee.mantissa1 |= libc_fetestexcept (FE_INEXACT) != 0;
|
||||||
v.d = a1 + u.d;
|
v.d = a1 + u.d;
|
||||||
int j = fetestexcept (FE_INEXACT) != 0;
|
int j = libc_fetestexcept (FE_INEXACT) != 0;
|
||||||
feupdateenv (&env);
|
libc_feupdateenv (&env);
|
||||||
/* Ensure the following computations are performed in default rounding
|
/* Ensure the following computations are performed in default rounding
|
||||||
mode instead of just reusing the round to zero computation. */
|
mode instead of just reusing the round to zero computation. */
|
||||||
asm volatile ("" : "=m" (u) : "m" (u));
|
asm volatile ("" : "=m" (u) : "m" (u));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Compute x * y + z as ternary operation.
|
/* Compute x * y + z as ternary operation.
|
||||||
Copyright (C) 2010 Free Software Foundation, Inc.
|
Copyright (C) 2010, 2011 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2010.
|
||||||
|
|
||||||
@ -21,6 +21,7 @@
|
|||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <fenv.h>
|
#include <fenv.h>
|
||||||
#include <ieee754.h>
|
#include <ieee754.h>
|
||||||
|
#include <math_private.h>
|
||||||
|
|
||||||
/* This implementation relies on double being more than twice as
|
/* This implementation relies on double being more than twice as
|
||||||
precise as float and uses rounding to odd in order to avoid problems
|
precise as float and uses rounding to odd in order to avoid problems
|
||||||
@ -35,13 +36,12 @@ __fmaf (float x, float y, float z)
|
|||||||
/* Multiplication is always exact. */
|
/* Multiplication is always exact. */
|
||||||
double temp = (double) x * (double) y;
|
double temp = (double) x * (double) y;
|
||||||
union ieee754_double u;
|
union ieee754_double u;
|
||||||
feholdexcept (&env);
|
libc_feholdexcept_setroundf (&env, FE_TOWARDZERO);
|
||||||
fesetround (FE_TOWARDZERO);
|
|
||||||
/* Perform addition with round to odd. */
|
/* Perform addition with round to odd. */
|
||||||
u.d = temp + (double) z;
|
u.d = temp + (double) z;
|
||||||
if ((u.ieee.mantissa1 & 1) == 0 && u.ieee.exponent != 0x7ff)
|
if ((u.ieee.mantissa1 & 1) == 0 && u.ieee.exponent != 0x7ff)
|
||||||
u.ieee.mantissa1 |= fetestexcept (FE_INEXACT) != 0;
|
u.ieee.mantissa1 |= libc_fetestexcept (FE_INEXACT) != 0;
|
||||||
feupdateenv (&env);
|
libc_feupdateenv (&env);
|
||||||
/* And finally truncation with round to nearest. */
|
/* And finally truncation with round to nearest. */
|
||||||
return (float) u.d;
|
return (float) u.d;
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,7 @@ __ieee754_exp2f (float x)
|
|||||||
union ieee754_float ex2_u, scale_u;
|
union ieee754_float ex2_u, scale_u;
|
||||||
fenv_t oldenv;
|
fenv_t oldenv;
|
||||||
|
|
||||||
feholdexcept (&oldenv);
|
libc_feholdexcept_setroundf (&oldenv, FE_TONEAREST);
|
||||||
#ifdef FE_TONEAREST
|
|
||||||
/* If we don't have this, it's too bad. */
|
|
||||||
fesetround (FE_TONEAREST);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* 1. Argument reduction.
|
/* 1. Argument reduction.
|
||||||
Choose integers ex, -128 <= t < 128, and some real
|
Choose integers ex, -128 <= t < 128, and some real
|
||||||
@ -104,7 +100,7 @@ __ieee754_exp2f (float x)
|
|||||||
x22 = (.24022656679f * x + .69314736128f) * ex2_u.f;
|
x22 = (.24022656679f * x + .69314736128f) * ex2_u.f;
|
||||||
|
|
||||||
/* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex). */
|
/* 5. Return (2^x2-1) * 2^(t/512+e+ex) + 2^(t/512+e+ex). */
|
||||||
fesetenv (&oldenv);
|
libc_fesetenv (&oldenv);
|
||||||
|
|
||||||
result = x22 * x + ex2_u.f;
|
result = x22 * x + ex2_u.f;
|
||||||
|
|
||||||
@ -116,7 +112,7 @@ __ieee754_exp2f (float x)
|
|||||||
/* Exceptional cases: */
|
/* Exceptional cases: */
|
||||||
else if (isless (x, himark))
|
else if (isless (x, himark))
|
||||||
{
|
{
|
||||||
if (__isinff (x))
|
if (__isinf_nsf (x))
|
||||||
/* e^-inf == 0, with no error. */
|
/* e^-inf == 0, with no error. */
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
|
@ -47,9 +47,6 @@
|
|||||||
to perform an 'accurate table method' expf, because of the range reduction
|
to perform an 'accurate table method' expf, because of the range reduction
|
||||||
overhead (compare exp2f).
|
overhead (compare exp2f).
|
||||||
*/
|
*/
|
||||||
#ifndef _GNU_SOURCE
|
|
||||||
#define _GNU_SOURCE
|
|
||||||
#endif
|
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
#include <ieee754.h>
|
#include <ieee754.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -60,8 +57,8 @@
|
|||||||
extern const float __exp_deltatable[178];
|
extern const float __exp_deltatable[178];
|
||||||
extern const double __exp_atable[355] /* __attribute__((mode(DF))) */;
|
extern const double __exp_atable[355] /* __attribute__((mode(DF))) */;
|
||||||
|
|
||||||
static const volatile float TWOM100 = 7.88860905e-31;
|
static const float TWOM100 = 7.88860905e-31;
|
||||||
static const volatile float TWO127 = 1.7014118346e+38;
|
static const float TWO127 = 1.7014118346e+38;
|
||||||
|
|
||||||
float
|
float
|
||||||
__ieee754_expf (float x)
|
__ieee754_expf (float x)
|
||||||
@ -86,10 +83,7 @@ __ieee754_expf (float x)
|
|||||||
union ieee754_double ex2_u;
|
union ieee754_double ex2_u;
|
||||||
fenv_t oldenv;
|
fenv_t oldenv;
|
||||||
|
|
||||||
feholdexcept (&oldenv);
|
libc_feholdexcept_setroundf (&oldenv, FE_TONEAREST);
|
||||||
#ifdef FE_TONEAREST
|
|
||||||
fesetround (FE_TONEAREST);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Calculate n. */
|
/* Calculate n. */
|
||||||
n = x * M_1_LN2 + THREEp22;
|
n = x * M_1_LN2 + THREEp22;
|
||||||
@ -119,7 +113,7 @@ __ieee754_expf (float x)
|
|||||||
x22 = (0.5000000496709180453 * dx + 1.0000001192102037084) * dx + delta;
|
x22 = (0.5000000496709180453 * dx + 1.0000001192102037084) * dx + delta;
|
||||||
|
|
||||||
/* Return result. */
|
/* Return result. */
|
||||||
fesetenv (&oldenv);
|
libc_fesetenvf (&oldenv);
|
||||||
|
|
||||||
result = x22 * ex2_u.d + ex2_u.d;
|
result = x22 * ex2_u.d + ex2_u.d;
|
||||||
return (float) result;
|
return (float) result;
|
||||||
|
@ -19,22 +19,14 @@
|
|||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "math_private.h"
|
#include "math_private.h"
|
||||||
|
|
||||||
#ifdef __STDC__
|
|
||||||
static const float
|
static const float
|
||||||
#else
|
|
||||||
static float
|
|
||||||
#endif
|
|
||||||
TWO23[2]={
|
TWO23[2]={
|
||||||
8.3886080000e+06, /* 0x4b000000 */
|
8.3886080000e+06, /* 0x4b000000 */
|
||||||
-8.3886080000e+06, /* 0xcb000000 */
|
-8.3886080000e+06, /* 0xcb000000 */
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __STDC__
|
float
|
||||||
float __nearbyintf(float x)
|
__nearbyintf(float x)
|
||||||
#else
|
|
||||||
float __nearbyintf(x)
|
|
||||||
float x;
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
fenv_t env;
|
fenv_t env;
|
||||||
int32_t i0,j0,sx;
|
int32_t i0,j0,sx;
|
||||||
@ -50,10 +42,10 @@ TWO23[2]={
|
|||||||
i0 &= 0xfff00000;
|
i0 &= 0xfff00000;
|
||||||
i0 |= ((i1|-i1)>>9)&0x400000;
|
i0 |= ((i1|-i1)>>9)&0x400000;
|
||||||
SET_FLOAT_WORD(x,i0);
|
SET_FLOAT_WORD(x,i0);
|
||||||
feholdexcept (&env);
|
libc_feholdexceptf (&env);
|
||||||
w = TWO23[sx]+x;
|
w = TWO23[sx]+x;
|
||||||
t = w-TWO23[sx];
|
t = w-TWO23[sx];
|
||||||
fesetenv (&env);
|
libc_fesetenvf (&env);
|
||||||
GET_FLOAT_WORD(i0,t);
|
GET_FLOAT_WORD(i0,t);
|
||||||
SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
|
SET_FLOAT_WORD(t,(i0&0x7fffffff)|(sx<<31));
|
||||||
return t;
|
return t;
|
||||||
@ -64,14 +56,14 @@ TWO23[2]={
|
|||||||
if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
|
if((i0&i)!=0) i0 = (i0&(~i))|((0x100000)>>j0);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(j0==0x80) return x+x; /* inf or NaN */
|
if(__builtin_expect(j0==0x80, 0)) return x+x; /* inf or NaN */
|
||||||
else return x; /* x is integral */
|
else return x; /* x is integral */
|
||||||
}
|
}
|
||||||
SET_FLOAT_WORD(x,i0);
|
SET_FLOAT_WORD(x,i0);
|
||||||
feholdexcept (&env);
|
libc_feholdexceptf (&env);
|
||||||
w = TWO23[sx]+x;
|
w = TWO23[sx]+x;
|
||||||
t = w-TWO23[sx];
|
t = w-TWO23[sx];
|
||||||
fesetenv (&env);
|
libc_fesetenvf (&env);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
weak_alias (__nearbyintf, nearbyintf)
|
weak_alias (__nearbyintf, nearbyintf)
|
||||||
|
@ -129,7 +129,8 @@ do { \
|
|||||||
asm volatile ("stmxcsr %0" : "=m" (*&mxcsr)); \
|
asm volatile ("stmxcsr %0" : "=m" (*&mxcsr)); \
|
||||||
(mxcsr & 0x6000) >> 3; \
|
(mxcsr & 0x6000) >> 3; \
|
||||||
})
|
})
|
||||||
// #define libc_fegetroundf() fegetround ()
|
#undef libc_fegetroundf
|
||||||
|
#define libc_fegetroundf() libc_fegetround ()
|
||||||
// #define libc_fegetroundl() fegetround ()
|
// #define libc_fegetroundl() fegetround ()
|
||||||
|
|
||||||
#undef libc_fesetround
|
#undef libc_fesetround
|
||||||
@ -140,7 +141,8 @@ do { \
|
|||||||
mxcsr = (mxcsr & ~0x6000) | ((r) << 3); \
|
mxcsr = (mxcsr & ~0x6000) | ((r) << 3); \
|
||||||
asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
|
asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
// #define libc_fesetroundf(r) (void) fesetround (r)
|
#undef libc_fesetroundf
|
||||||
|
#define libc_fesetroundf(r) libc_fesetround (r)
|
||||||
// #define libc_fesetroundl(r) (void) fesetround (r)
|
// #define libc_fesetroundl(r) (void) fesetround (r)
|
||||||
|
|
||||||
#undef libc_feholdexcept
|
#undef libc_feholdexcept
|
||||||
@ -152,7 +154,8 @@ do { \
|
|||||||
mxcsr = (mxcsr | 0x1f80) & ~0x3f; \
|
mxcsr = (mxcsr | 0x1f80) & ~0x3f; \
|
||||||
asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
|
asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
// #define libc_feholdexceptf(e) (void) feholdexcept (e)
|
#undef libc_feholdexceptf
|
||||||
|
#define libc_feholdexceptf(e) libc_feholdexcept (e)
|
||||||
// #define libc_feholdexceptl(e) (void) feholdexcept (e)
|
// #define libc_feholdexceptl(e) (void) feholdexcept (e)
|
||||||
|
|
||||||
#undef libc_feholdexcept_setround
|
#undef libc_feholdexcept_setround
|
||||||
@ -164,11 +167,33 @@ do { \
|
|||||||
mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | ((r) << 3); \
|
mxcsr = ((mxcsr | 0x1f80) & ~0x603f) | ((r) << 3); \
|
||||||
asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
|
asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
// #define libc_feholdexcept_setroundf(e, r) ...
|
#undef libc_feholdexcept_setroundf
|
||||||
|
#define libc_feholdexcept_setroundf(e, r) libc_feholdexcept_setround (e, r)
|
||||||
// #define libc_feholdexcept_setroundl(e, r) ...
|
// #define libc_feholdexcept_setroundl(e, r) ...
|
||||||
|
|
||||||
|
#undef libc_fetestexcept
|
||||||
|
#define libc_fetestexcept(e) \
|
||||||
|
({ unsigned int mxcsr; asm volatile ("stmxcsr %0" : "=m" (*&mxcsr)); \
|
||||||
|
mxcsr & (e) & FE_ALL_EXCEPT; })
|
||||||
|
#undef libc_fetestexceptf
|
||||||
|
#define libc_fetestexceptf(e) libc_fetestexcept (e)
|
||||||
|
// #define libc_fetestexceptl(e) fetestexcept (e)
|
||||||
|
|
||||||
#undef libc_fesetenv
|
#undef libc_fesetenv
|
||||||
#define libc_fesetenv(e) \
|
#define libc_fesetenv(e) \
|
||||||
asm volatile ("ldmxcsr %0" : : "m" ((e)->__mxcsr))
|
asm volatile ("ldmxcsr %0" : : "m" ((e)->__mxcsr))
|
||||||
// #define libc_fesetenvf(e) (void) fesetenv (e)
|
#undef libc_fesetenvf
|
||||||
|
#define libc_fesetenvf(e) libc_fesetenv (e)
|
||||||
// #define libc_fesetenvl(e) (void) fesetenv (e)
|
// #define libc_fesetenvl(e) (void) fesetenv (e)
|
||||||
|
|
||||||
|
#undef libc_feupdateenv
|
||||||
|
#define libc_feupdateenv(e) \
|
||||||
|
do { \
|
||||||
|
unsigned int mxcsr; \
|
||||||
|
asm volatile ("stmxcsr %0" : "=m" (*&mxcsr)); \
|
||||||
|
asm volatile ("ldmxcsr %0" : : "m" ((e)->__mxcsr)); \
|
||||||
|
feraiseexcept (mxcsr & FE_ALL_EXCEPT); \
|
||||||
|
} while (0)
|
||||||
|
#undef libc_feupdateenvf
|
||||||
|
#define libc_feupdateenvf(e) libc_feupdateenv (e)
|
||||||
|
// #define libc_feupdateenvl(e) (void) feupdateenv (e)
|
||||||
|
Loading…
Reference in New Issue
Block a user