glibc: Backport hotfixes from RHEL6.
[people/teissler/ipfire-2.x.git] / src / patches / glibc / glibc-rh966775.patch
1 diff -pruN glibc-2.12-2-gc4ccff1/math/math_private.h glibc-2.12-2-gc4ccff1.new/math/math_private.h
2 --- glibc-2.12-2-gc4ccff1/math/math_private.h 2013-06-07 08:35:52.785442441 -0400
3 +++ glibc-2.12-2-gc4ccff1.new/math/math_private.h 2013-06-07 08:29:35.621042340 -0400
4 @@ -394,4 +394,31 @@ extern void __docos (double __x, double
5 #define libc_feupdateenvf(e) (void) feupdateenv (e)
6 #define libc_feupdateenvl(e) (void) feupdateenv (e)
7
8 +/* Save and set the rounding mode. The use of fenv_t to store the old mode
9 + allows a target-specific version of this function to avoid converting the
10 + rounding mode from the fpu format. By default we have no choice but to
11 + manipulate the entire env. */
12 +
13 +#ifndef libc_feholdsetround
14 +# define libc_feholdsetround(e, r, c) libc_feholdexcept_setround(e, r)
15 +#endif
16 +#ifndef libc_feholdsetroundf
17 +# define libc_feholdsetroundf(e, r, c) libc_feholdexcept_setroundf(e, r)
18 +#endif
19 +#ifndef libc_feholdsetroundl
20 +# define libc_feholdsetroundl(e, r, c) libc_feholdexcept_setroundl(e, r)
21 +#endif
22 +
23 +/* ... and the reverse. */
24 +
25 +#ifndef libc_feresetround
26 +# define libc_feresetround(e, c) libc_feupdateenv(e)
27 +#endif
28 +#ifndef libc_feresetroundf
29 +# define libc_feresetroundf(e, c) libc_feupdateenvf(e)
30 +#endif
31 +#ifndef libc_feresetroundl
32 +# define libc_feresetroundl(e, c) libc_feupdateenvl(e)
33 +#endif
34 +
35 #endif /* _MATH_PRIVATE_H_ */
36 diff -pruN glibc-2.12-2-gc4ccff1/sysdeps/ieee754/dbl-64/e_exp.c glibc-2.12-2-gc4ccff1.new/sysdeps/ieee754/dbl-64/e_exp.c
37 --- glibc-2.12-2-gc4ccff1/sysdeps/ieee754/dbl-64/e_exp.c 2013-06-07 08:35:52.785442441 -0400
38 +++ glibc-2.12-2-gc4ccff1.new/sysdeps/ieee754/dbl-64/e_exp.c 2013-06-07 08:30:21.976222459 -0400
39 @@ -57,7 +57,8 @@ double __ieee754_exp(double x) {
40 fenv_t env;
41 double retval;
42
43 - libc_feholdexcept_setround (&env, FE_TONEAREST);
44 + int changed;
45 + libc_feholdsetround (&env, FE_TONEAREST, changed);
46
47 junk1.x = x;
48 m = junk1.i[HIGH_HALF];
49 @@ -152,7 +153,7 @@ double __ieee754_exp(double x) {
50 else { retval = __slowexp(x); goto ret; }
51 }
52 ret:
53 - libc_feupdateenv (&env);
54 + libc_feresetround (&env, changed);
55 return retval;
56 }
57
58 diff -pruN glibc-2.12-2-gc4ccff1/sysdeps/ieee754/dbl-64/e_pow.c glibc-2.12-2-gc4ccff1.new/sysdeps/ieee754/dbl-64/e_pow.c
59 --- glibc-2.12-2-gc4ccff1/sysdeps/ieee754/dbl-64/e_pow.c 2013-06-07 08:35:52.785442441 -0400
60 +++ glibc-2.12-2-gc4ccff1.new/sysdeps/ieee754/dbl-64/e_pow.c 2013-06-07 08:31:00.294939087 -0400
61 @@ -83,7 +83,8 @@ double __ieee754_pow(double x, double y)
62 fenv_t env;
63 double retval;
64
65 - libc_feholdexcept_setround (&env, FE_TONEAREST);
66 + int changed;
67 + libc_feholdsetround (&env, FE_TONEAREST, changed);
68
69 z = log1(x,&aa,&error); /* x^y =e^(y log (X)) */
70 t = y*134217729.0;
71 @@ -100,7 +101,7 @@ double __ieee754_pow(double x, double y)
72 t = __exp1(a1,a2,1.9e16*error); /* return -10 or 0 if wasn't computed exactly */
73 retval = (t>0)?t:power1(x,y);
74
75 - libc_feupdateenv (&env);
76 + libc_feresetround (&env, changed);
77 return retval;
78 }
79
80 diff -pruN glibc-2.12-2-gc4ccff1/sysdeps/ieee754/dbl-64/s_sin.c glibc-2.12-2-gc4ccff1.new/sysdeps/ieee754/dbl-64/s_sin.c
81 --- glibc-2.12-2-gc4ccff1/sysdeps/ieee754/dbl-64/s_sin.c 2013-06-07 08:35:52.786442462 -0400
82 +++ glibc-2.12-2-gc4ccff1.new/sysdeps/ieee754/dbl-64/s_sin.c 2013-06-07 08:32:08.254822633 -0400
83 @@ -101,7 +101,8 @@ double __sin(double x){
84 fenv_t env;
85 double retval = 0;
86
87 - libc_feholdexcept_setround (&env, FE_TONEAREST);
88 + int changed;
89 + libc_feholdsetround (&env, FE_TONEAREST, changed);
90
91 u.x = x;
92 m = u.i[HIGH_HALF];
93 @@ -355,7 +356,7 @@ double __sin(double x){
94 }
95
96 ret:
97 - libc_feupdateenv (&env);
98 + libc_feresetround (&env, changed);
99 return retval;
100 }
101
102 @@ -374,7 +375,8 @@ double __cos(double x)
103 fenv_t env;
104 double retval = 0;
105
106 - libc_feholdexcept_setround (&env, FE_TONEAREST);
107 + int changed;
108 + libc_feholdsetround (&env, FE_TONEAREST, changed);
109
110 u.x = x;
111 m = u.i[HIGH_HALF];
112 @@ -623,7 +625,7 @@ double __cos(double x)
113 }
114
115 ret:
116 - libc_feupdateenv (&env);
117 + libc_feresetround (&env, changed);
118 return retval;
119 }
120
121 diff -pruN glibc-2.12-2-gc4ccff1/sysdeps/ieee754/dbl-64/s_tan.c glibc-2.12-2-gc4ccff1.new/sysdeps/ieee754/dbl-64/s_tan.c
122 --- glibc-2.12-2-gc4ccff1/sysdeps/ieee754/dbl-64/s_tan.c 2013-06-07 08:35:52.786442462 -0400
123 +++ glibc-2.12-2-gc4ccff1.new/sysdeps/ieee754/dbl-64/s_tan.c 2013-06-07 08:32:39.736162619 -0400
124 @@ -66,7 +66,8 @@ double tan(double x) {
125 int __branred(double, double *, double *);
126 int __mpranred(double, mp_no *, int);
127
128 - libc_feholdexcept_setround (&env, FE_TONEAREST);
129 + int changed;
130 + libc_feholdsetround (&env, FE_TONEAREST, changed);
131
132 /* x=+-INF, x=NaN */
133 num.d = x; ux = num.i[HIGH_HALF];
134 @@ -495,7 +496,7 @@ double tan(double x) {
135 goto ret;
136
137 ret:
138 - libc_feupdateenv (&env);
139 + libc_feresetround (&env, changed);
140 return retval;
141 }
142
143 diff -pruN glibc-2.12-2-gc4ccff1/sysdeps/x86_64/fpu/math_private.h glibc-2.12-2-gc4ccff1.new/sysdeps/x86_64/fpu/math_private.h
144 --- glibc-2.12-2-gc4ccff1/sysdeps/x86_64/fpu/math_private.h 2013-06-07 08:35:52.787442488 -0400
145 +++ glibc-2.12-2-gc4ccff1.new/sysdeps/x86_64/fpu/math_private.h 2013-06-07 08:34:35.370109759 -0400
146 @@ -139,3 +139,31 @@ do { \
147 #undef libc_feupdateenvf
148 #define libc_feupdateenvf(e) libc_feupdateenv (e)
149 // #define libc_feupdateenvl(e) (void) feupdateenv (e)
150 +
151 +#undef libc_feholdsetround
152 +#define libc_feholdsetround(e, r, c) \
153 +({ \
154 + unsigned int mxcsr, new_mxcsr; \
155 + asm ("stmxcsr %0" : "=m" (*&mxcsr)); \
156 + new_mxcsr = (mxcsr & ~0x6000) | ((r) << 3); \
157 + if (__builtin_expect (new_mxcsr != mxcsr, 0)) \
158 + { \
159 + (e)->__mxcsr = mxcsr; \
160 + asm volatile ("ldmxcsr %0" : : "m" (*&new_mxcsr)); \
161 + c = 1; \
162 + } \
163 + else \
164 + c = 0; \
165 +})
166 +
167 +#undef libc_feresetround
168 +#define libc_feresetround(e, c) \
169 +({ \
170 + if (__builtin_expect (c, 0)) \
171 + { \
172 + unsigned int mxcsr; \
173 + asm ("stmxcsr %0" : "=m" (*&mxcsr)); \
174 + mxcsr = (mxcsr & ~0x6000) | ((e)->__mxcsr & 0x6000); \
175 + asm volatile ("ldmxcsr %0" : : "m" (*&mxcsr)); \
176 + } \
177 +})