Print this page
5262 libm needs to be carefully unifdef'd
5268 libm doesn't need to hide symbols which are already local
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/common/Q/powl.c
+++ new/usr/src/lib/libm/common/Q/powl.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
20 20 */
21 21
22 22 /*
23 23 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
24 24 */
25 25 /*
26 26 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
27 27 * Use is subject to license terms.
28 28 */
29 29
30 -#if defined(ELFOBJ)
31 30 #pragma weak powl = __powl
32 -#endif
33 31
34 32 #include "libm.h"
35 33 #include "xpg6.h" /* __xpg6 */
36 34 #define _C99SUSv3_pow _C99SUSv3_pow_treats_Inf_as_an_even_int
37 35
38 36 #if defined(__sparc)
39 37 #define i0 0
40 38 #define i1 1
41 39 #define i2 2
42 40 #define i3 3
43 41
44 42 static const long double zero = 0.0L, one = 1.0L, two = 2.0L;
45 43
46 44 extern const long double _TBL_logl_hi[], _TBL_logl_lo[];
47 45
48 46 static const long double
49 47 two113 = 10384593717069655257060992658440192.0L,
50 48 ln2hi = 6.931471805599453094172319547495844850203e-0001L,
51 49 ln2lo = 1.667085920830552208890449330400379754169e-0025L,
52 50 A2 = 6.666666666666666666666666666666091393804e-0001L,
53 51 A3 = 4.000000000000000000000000407167070220671e-0001L,
54 52 A4 = 2.857142857142857142730077490612903681164e-0001L,
55 53 A5 = 2.222222222222242577702836920812882605099e-0001L,
56 54 A6 = 1.818181816435493395985912667105885828356e-0001L,
57 55 A7 = 1.538537835211839751112067512805496931725e-0001L,
58 56 B1 = 6.666666666666666666666666666666666667787e-0001L,
59 57 B2 = 3.999999999999999999999999999999848524411e-0001L,
60 58 B3 = 2.857142857142857142857142865084581075070e-0001L,
61 59 B4 = 2.222222222222222222222010781800643808497e-0001L,
62 60 B5 = 1.818181818181818185051442171337036403674e-0001L,
63 61 B6 = 1.538461538461508363540720286292008207673e-0001L,
64 62 B7 = 1.333333333506731842033180638329317108428e-0001L,
65 63 B8 = 1.176469984587418890634302788283946761670e-0001L,
66 64 B9 = 1.053794891561452331722969901564862497132e-0001L;
67 65
68 66 static long double
69 67 logl_x(long double x, long double *w) {
70 68 long double f, f1, v, s, z, qn, h, t;
71 69 int *px = (int *) &x;
72 70 int *pz = (int *) &z;
73 71 int i, j, ix, n;
74 72
75 73 n = 0;
76 74 ix = px[i0];
77 75 if (ix > 0x3ffef03f && ix < 0x3fff0820) { /* 65/63 > x > 63/65 */
78 76 f = x - one;
79 77 z = f * f;
80 78 if (((ix - 0x3fff0000) | px[i1] | px[i2] | px[i3]) == 0) {
81 79 *w = zero;
82 80 return (zero); /* log(1)= +0 */
83 81 }
84 82 qn = one / (two + f);
85 83 s = f * qn; /* |s|<2**-6 */
86 84 v = s * s;
87 85 h = (long double) (2.0 * (double) s);
88 86 f1 = (long double) ((double) f);
89 87 t = ((two * (f - h) - h * f1) - h * (f - f1)) * qn +
90 88 s * (v * (B1 + v * (B2 + v * (B3 + v * (B4 +
91 89 v * (B5 + v * (B6 + v * (B7 + v * (B8 + v * B9)))))))));
92 90 s = (long double) ((double) (h + t));
93 91 *w = t - (s - h);
94 92 return (s);
95 93 }
96 94 if (ix < 0x00010000) { /* subnormal x */
97 95 x *= two113;
98 96 n = -113;
99 97 ix = px[i0];
100 98 }
101 99 /* LARGE_N */
102 100 n += ((ix + 0x200) >> 16) - 0x3fff;
103 101 ix = (ix & 0x0000ffff) | 0x3fff0000; /* scale x to [1,2] */
104 102 px[i0] = ix;
105 103 i = ix + 0x200;
106 104 pz[i0] = i & 0xfffffc00;
107 105 pz[i1] = pz[i2] = pz[i3] = 0;
108 106 qn = one / (x + z);
109 107 f = x - z;
110 108 s = f * qn;
111 109 f1 = (long double) ((double) f);
112 110 h = (long double) (2.0 * (double) s);
113 111 t = qn * ((two * (f - z * h) - h * f1) - h * (f - f1));
114 112 j = (i >> 10) & 0x3f;
115 113 v = s * s;
116 114 qn = (long double) n;
117 115 t += qn * ln2lo + _TBL_logl_lo[j];
118 116 t += s * (v * (A2 + v * (A3 + v * (A4 + v * (A5 + v * (A6 +
119 117 v * A7))))));
120 118 v = qn * ln2hi + _TBL_logl_hi[j];
121 119 s = h + v;
122 120 t += (h - (s - v));
123 121 z = (long double) ((double) (s + t));
124 122 *w = t - (z - s);
125 123 return (z);
126 124 }
127 125
128 126 extern const long double _TBL_expl_hi[], _TBL_expl_lo[];
129 127 static const long double
130 128 invln2_32 = 4.616624130844682903551758979206054839765e+1L,
131 129 ln2_32hi = 2.166084939249829091928849858592451515688e-2L,
132 130 ln2_32lo = 5.209643502595475652782654157501186731779e-27L,
133 131 ln2_64 = 1.083042469624914545964425189778400898568e-2L;
134 132
135 133 long double
136 134 powl(long double x, long double y) {
137 135 long double z, ax;
138 136 long double y1, y2, w1, w2;
139 137 int sbx, sby, j, k, yisint, m;
140 138 int hx, lx, hy, ly, ahx, ahy;
141 139 int *pz = (int *) &z;
142 140 int *px = (int *) &x;
143 141 int *py = (int *) &y;
144 142
145 143 hx = px[i0];
146 144 lx = px[i1] | px[i2] | px[i3];
147 145 hy = py[i0];
148 146 ly = py[i1] | py[i2] | py[i3];
149 147 ahx = hx & ~0x80000000;
150 148 ahy = hy & ~0x80000000;
151 149
152 150 if ((ahy | ly) == 0)
153 151 return (one); /* x**+-0 = 1 */
154 152 else if (hx == 0x3fff0000 && lx == 0 &&
155 153 (__xpg6 & _C99SUSv3_pow) != 0)
156 154 return (one); /* C99: 1**anything = 1 */
157 155 else if (ahx > 0x7fff0000 || (ahx == 0x7fff0000 && lx != 0) ||
158 156 ahy > 0x7fff0000 || (ahy == 0x7fff0000 && ly != 0))
159 157 return (x + y); /* +-NaN return x+y */
160 158 /* includes Sun: 1**NaN = NaN */
161 159 sbx = (unsigned) hx >> 31;
162 160 sby = (unsigned) hy >> 31;
163 161 ax = fabsl(x);
164 162 /*
165 163 * determine if y is an odd int when x < 0
166 164 * yisint = 0 ... y is not an integer
167 165 * yisint = 1 ... y is an odd int
168 166 * yisint = 2 ... y is an even int
169 167 */
170 168 yisint = 0;
171 169 if (sbx) {
172 170 if (ahy >= 0x40700000) /* if |y|>=2**113 */
173 171 yisint = 2; /* even integer y */
174 172 else if (ahy >= 0x3fff0000) {
175 173 k = (ahy >> 16) - 0x3fff; /* exponent */
176 174 if (k > 80) {
177 175 j = ((unsigned) py[i3]) >> (112 - k);
178 176 if ((j << (112 - k)) == py[i3])
179 177 yisint = 2 - (j & 1);
180 178 } else if (k > 48) {
181 179 j = ((unsigned) py[i2]) >> (80 - k);
182 180 if ((j << (80 - k)) == py[i2])
183 181 yisint = 2 - (j & 1);
184 182 } else if (k > 16) {
185 183 j = ((unsigned) py[i1]) >> (48 - k);
186 184 if ((j << (48 - k)) == py[i1])
187 185 yisint = 2 - (j & 1);
188 186 } else if (ly == 0) {
189 187 j = ahy >> (16 - k);
190 188 if ((j << (16 - k)) == ahy)
191 189 yisint = 2 - (j & 1);
192 190 }
193 191 }
194 192 }
195 193
196 194 /* special value of y */
197 195 if (ly == 0) {
198 196 if (ahy == 0x7fff0000) { /* y is +-inf */
199 197 if (((ahx - 0x3fff0000) | lx) == 0) {
200 198 if ((__xpg6 & _C99SUSv3_pow) != 0)
201 199 return (one);
202 200 /* C99: (-1)**+-inf = 1 */
203 201 else
204 202 return (y - y);
205 203 /* Sun: (+-1)**+-inf = NaN */
206 204 } else if (ahx >= 0x3fff0000)
207 205 /* (|x|>1)**+,-inf = inf,0 */
208 206 return (sby == 0 ? y : zero);
209 207 else /* (|x|<1)**-,+inf = inf,0 */
210 208 return (sby != 0 ? -y : zero);
211 209 } else if (ahy == 0x3fff0000) { /* y is +-1 */
212 210 if (sby != 0)
213 211 return (one / x);
214 212 else
215 213 return (x);
216 214 } else if (hy == 0x40000000) /* y is 2 */
217 215 return (x * x);
218 216 else if (hy == 0x3ffe0000) { /* y is 0.5 */
219 217 if (!((ahx | lx) == 0 || ((ahx - 0x7fff0000) | lx) ==
220 218 0))
221 219 return (sqrtl(x));
222 220 }
223 221 }
224 222
225 223 /* special value of x */
226 224 if (lx == 0) {
227 225 if (ahx == 0x7fff0000 || ahx == 0 || ahx == 0x3fff0000) {
228 226 /* x is +-0,+-inf,+-1 */
229 227 z = ax;
230 228 if (sby == 1)
231 229 z = one / z; /* z = 1/|x| if y is negative */
232 230 if (sbx == 1) {
233 231 if (ahx == 0x3fff0000 && yisint == 0)
234 232 z = zero / zero;
235 233 /* (-1)**non-int is NaN */
236 234 else if (yisint == 1)
237 235 z = -z; /* (x<0)**odd = -(|x|**odd) */
238 236 }
239 237 return (z);
240 238 }
241 239 }
242 240
243 241 /* (x<0)**(non-int) is NaN */
244 242 if (sbx == 1 && yisint == 0)
245 243 return (zero / zero); /* should be volatile */
246 244
247 245 /* Now ax is finite, y is finite */
248 246 /* first compute log(ax) = w1+w2, with 53 bits w1 */
249 247 w1 = logl_x(ax, &w2);
250 248
251 249 /* split up y into y1+y2 and compute (y1+y2)*(w1+w2) */
252 250 if (ly == 0 || ahy >= 0x43fe0000) {
253 251 y1 = y * w1;
254 252 y2 = y * w2;
255 253 } else {
256 254 y1 = (long double) ((double) y);
257 255 y2 = (y - y1) * w1 + y * w2;
258 256 y1 *= w1;
259 257 }
260 258 z = y1 + y2;
261 259 j = pz[i0];
262 260 if ((unsigned) j >= 0xffff0000) { /* NaN or -inf */
263 261 if (sbx == 1 && yisint == 1)
264 262 return (one / z);
265 263 else
266 264 return (-one / z);
267 265 } else if ((j & ~0x80000000) < 0x3fc30000) { /* |x|<2^-60 */
268 266 if (sbx == 1 && yisint == 1)
269 267 return (-one - z);
270 268 else
271 269 return (one + z);
272 270 } else if (j > 0) {
273 271 if (j > 0x400d0000) {
274 272 if (sbx == 1 && yisint == 1)
275 273 return (scalbnl(-one, 20000));
276 274 else
277 275 return (scalbnl(one, 20000));
278 276 }
279 277 k = (int) (invln2_32 * (z + ln2_64));
280 278 } else {
281 279 if ((unsigned) j > 0xc00d0000) {
282 280 if (sbx == 1 && yisint == 1)
283 281 return (scalbnl(-one, -20000));
284 282 else
285 283 return (scalbnl(one, -20000));
286 284 }
287 285 k = (int) (invln2_32 * (z - ln2_64));
288 286 }
289 287 j = k & 0x1f;
290 288 m = k >> 5;
291 289 {
292 290 /* rational approximation coeffs for [-(ln2)/64,(ln2)/64] */
293 291 long double
294 292 t1 = 1.666666666666666666666666666660876387437e-1L,
295 293 t2 = -2.777777777777777777777707812093173478756e-3L,
296 294 t3 = 6.613756613756613482074280932874221202424e-5L,
297 295 t4 = -1.653439153392139954169609822742235851120e-6L,
298 296 t5 = 4.175314851769539751387852116610973796053e-8L;
299 297 long double t = (long double) k;
300 298
301 299 w1 = (y2 - (t * ln2_32hi - y1)) - t * ln2_32lo;
302 300 t = w1 * w1;
303 301 w2 = (w1 - t * (t1 + t * (t2 + t * (t3 + t * (t4 + t * t5))))) -
304 302 two;
305 303 z = _TBL_expl_hi[j] - ((_TBL_expl_hi[j] * (w1 + w1)) / w2 -
306 304 _TBL_expl_lo[j]);
307 305 }
308 306 j = m + (pz[i0] >> 16);
309 307 if (j && (unsigned) j < 0x7fff)
310 308 pz[i0] += m << 16;
311 309 else
312 310 z = scalbnl(z, m);
313 311
314 312 if (sbx == 1 && yisint == 1)
315 313 z = -z; /* (-ve)**(odd int) */
316 314 return (z);
317 315 }
318 316 #else
319 317 #error Unsupported Architecture
320 318 #endif /* defined(__sparc) */
↓ open down ↓ |
278 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX