Print this page
5261 libm should stop using synonyms.h
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libm/i386/src/powl.s
+++ new/usr/src/lib/libm/i386/src/powl.s
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
20 20 */
21 21 /*
22 22 * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
23 23 */
24 24 /*
25 25 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
26 26 * Use is subject to license terms.
27 27 */
28 28
29 29 .file "powl.s"
30 30
31 31 / Special cases:
32 32 /
33 33 / x ** 0 is 1
34 34 / 1 ** y is 1 (C99)
35 35 / x ** NaN is NaN
36 36 / NaN ** y (except 0) is NaN
37 37 / x ** 1 is x
38 38 / +-(|x| > 1) ** +inf is +inf
39 39 / +-(|x| > 1) ** -inf is +0
40 40 / +-(|x| < 1) ** +inf is +0
41 41 / +-(|x| < 1) ** -inf is +inf
42 42 / (-1) ** +-inf is +1 (C99)
43 43 / +0 ** +y (except 0, NaN) is +0
44 44 / -0 ** +y (except 0, NaN, odd int) is +0
45 45 / +0 ** -y (except 0, NaN) is +inf (z flag)
46 46 / -0 ** -y (except 0, NaN, odd int) is +inf (z flag)
47 47 / -0 ** y (odd int) is - (+0 ** x)
↓ open down ↓ |
47 lines elided |
↑ open up ↑ |
48 48 / +inf ** +y (except 0, NaN) is +inf
49 49 / +inf ** -y (except 0, NaN) is +0
50 50 / -inf ** +-y (except 0, NaN) is -0 ** -+y (NO z flag)
51 51 / x ** -1 is 1/x
52 52 / x ** 2 is x*x
53 53 / -x ** y (an integer) is (-1)**(y) * (+x)**(y)
54 54 / x ** y (x negative & y not integer) is NaN (i flag)
55 55
56 56 #include "libm.h"
57 57 LIBM_ANSI_PRAGMA_WEAK(powl,function)
58 -#include "libm_synonyms.h"
59 58 #include "xpg6.h"
60 59
61 60 #undef fabs
62 61
63 62 .data
64 63 .align 4
65 64 negzero:
66 65 .float -0.0
67 66 half:
68 67 .float 0.5
69 68 one:
70 69 .float 1.0
71 70 negone:
72 71 .float -1.0
73 72 two:
74 73 .float 2.0
75 74 Snan:
76 75 .long 0x7f800001
77 76 pinfinity:
78 77 .long 0x7f800000
79 78 ninfinity:
80 79 .long 0xff800000
81 80
82 81
83 82 ENTRY(powl)
84 83 pushl %ebp
85 84 movl %esp,%ebp
86 85 PIC_SETUP(1)
87 86
88 87 fldt 8(%ebp) / x
89 88 fxam / determine class of x
90 89 fnstsw %ax / store status in %ax
91 90 movb %ah,%dh / %dh <- condition code of x
92 91
93 92 fldt 20(%ebp) / y , x
94 93 fxam / determine class of y
95 94 fnstsw %ax / store status in %ax
96 95 movb %ah,%dl / %dl <- condition code of y
97 96
98 97 call .pow_main /// LOCAL
99 98 PIC_WRAPUP
100 99 leave
101 100 ret
102 101
103 102 .pow_main:
104 103 / x ** 0 is 1
105 104 movb %dl,%cl
106 105 andb $0x45,%cl
107 106 cmpb $0x40,%cl / C3=1 C2=0 C1=? C0=0 when +-0
108 107 jne 1f
109 108 fstp %st(0) / x
110 109 fstp %st(0) / stack empty
111 110 fld1 / 1
112 111 ret
113 112
114 113 1: / y is not zero
115 114 PIC_G_LOAD(movzwl,__xpg6,eax)
116 115 andl $_C99SUSv3_pow_treats_Inf_as_an_even_int,%eax
117 116 cmpl $0,%eax
118 117 je 1f
119 118
120 119 / C99: 1 ** anything is 1
121 120 fld1 / 1, y, x
122 121 fucomp %st(2) / y, x
123 122 fnstsw %ax / store status in %ax
124 123 sahf / 80387 flags in %ax to 80386 flags
125 124 jp 1f / so that pow(NaN1,NaN2) returns NaN2
126 125 jne 1f
127 126 fstp %st(0) / x
128 127 ret
129 128
130 129 1:
131 130 / x ** NaN is NaN
132 131 movb %dl,%cl
133 132 andb $0x45,%cl
134 133 cmpb $0x01,%cl / C3=0 C2=0 C1=? C0=1 when +-NaN
135 134 jne 1f
136 135 fstp %st(1) / y
137 136 ret
138 137
139 138 1: / y is not NaN
140 139 / NaN ** y (except 0) is NaN
141 140 movb %dh,%cl
142 141 andb $0x45,%cl
143 142 cmpb $0x01,%cl / C3=0 C2=0 C1=? C0=1 when +-NaN
144 143 jne 1f
145 144 fstp %st(0) / x
146 145 ret
147 146
148 147 1: / x is not NaN
149 148 / x ** 1 is x
150 149 fcoms PIC_L(one) / y , x
151 150 fnstsw %ax / store status in %ax
152 151 sahf / 80387 flags in %ax to 80386 flags
153 152 jne 1f
154 153 fstp %st(0) / x
155 154 ret
156 155
157 156 1: / y is not 1
158 157 / +-(|x| > 1) ** +inf is +inf
159 158 / +-(|x| > 1) ** -inf is +0
160 159 / +-(|x| < 1) ** +inf is +0
161 160 / +-(|x| < 1) ** -inf is +inf
162 161 / +-(|x| = 1) ** +-inf is NaN
163 162 movb %dl,%cl
164 163 andb $0x47,%cl
165 164 cmpb $0x05,%cl / C3=0 C2=1 C1=0 C0=1 when +inf
166 165 je .yispinf
167 166 cmpb $0x07,%cl / C3=0 C2=1 C1=1 C0=1 when -inf
168 167 je .yisninf
169 168
170 169 / +0 ** +y (except 0, NaN) is +0
171 170 / -0 ** +y (except 0, NaN, odd int) is +0
172 171 / +0 ** -y (except 0, NaN) is +inf (z flag)
173 172 / -0 ** -y (except 0, NaN, odd int) is +inf (z flag)
174 173 / -0 ** y (odd int) is - (+0 ** x)
175 174 movb %dh,%cl
176 175 andb $0x47,%cl
177 176 cmpb $0x40,%cl / C3=1 C2=0 C1=0 C0=0 when +0
178 177 je .xispzero
179 178 cmpb $0x42,%cl / C3=1 C2=0 C1=1 C0=0 when -0
180 179 je .xisnzero
181 180
182 181 / +inf ** +y (except 0, NaN) is +inf
183 182 / +inf ** -y (except 0, NaN) is +0
184 183 / -inf ** +-y (except 0, NaN) is -0 ** -+y (NO z flag)
185 184 movb %dh,%cl
186 185 andb $0x47,%cl
187 186 cmpb $0x05,%cl / C3=0 C2=1 C1=0 C0=1 when +inf
188 187 je .xispinf
189 188 cmpb $0x07,%cl / C3=0 C2=1 C1=1 C0=1 when -inf
190 189 je .xisninf
191 190
192 191 / x ** -1 is 1/x
193 192 fcoms PIC_L(negone) / y , x
194 193 fnstsw %ax / store status in %ax
195 194 sahf / 80387 flags in %ax to 80386 flags
196 195 jne 1f
197 196 fld %st(1) / x , y , x
198 197 fdivrs PIC_L(one) / 1/x , y , x
199 198 jmp .signok / check for over/underflow
200 199
201 200 1: / y is not -1
202 201 / x ** 2 is x*x
203 202 fcoms PIC_L(two) / y , x
204 203 fnstsw %ax / store status in %ax
205 204 sahf / 80387 flags in %ax to 80386 flags
206 205 jne 1f
207 206 fld %st(1) / x , y , x
208 207 fld %st(0) / x , x , y , x
209 208 fmulp / x^2 , y , x
210 209 jmp .signok / check for over/underflow
211 210
212 211 1: / y is not 2
213 212 / x ** 1/2 is sqrt(x)
214 213 fcoms PIC_L(half) / y , x
215 214 fnstsw %ax / store status in %ax
216 215 sahf / 80387 flags in %ax to 80386 flags
217 216 jne 1f
218 217 fld %st(1) / x , y , x
219 218 fsqrt / sqrt(x) , y , x
220 219 jmp .signok / check for over/underflow
221 220
222 221 1: / y is not 1/2
223 222 / make copies of x & y
224 223 fld %st(1) / x , y , x
225 224 fld %st(1) / y , x , y , x
226 225
227 226 / -x ** y (an integer) is (-1)**(y) * (+x)**(y)
228 227 / x ** y (x negative & y not integer) is NaN
229 228 movl $0,%ecx / track whether to flip sign of result
230 229 fld %st(1) / x , y , x , y , x
231 230 ftst / compare %st(0) with 0
232 231 fnstsw %ax / store status in %ax
233 232 sahf / 80387 flags in %ax to 80386 flags
234 233 fstp %st(0) / y , x , y , x
235 234 ja .merge / x > 0
236 235 / x < 0
237 236 call .y_is_int
238 237 cmpl $0,%ecx
239 238 jne 1f
240 239 / x < 0 & y != int so x**y = NaN (i flag)
241 240 fstp %st(0) / x , y , x
242 241 fstp %st(0) / y , x
243 242 fstp %st(0) / x
244 243 fstp %st(0) / stack empty
245 244 fldz
246 245 fdiv %st,%st(0) / 0/0
247 246 ret
248 247
249 248 1: / x < 0 & y = int
250 249 fxch / x , y , y , x
251 250 fchs / px = -x , y , y , x
252 251 fxch / y , px , y , x
253 252 .merge:
254 253 / px > 0
255 254 fxch / px , y , y , x
256 255
257 256 / x**y = exp(y*ln(x))
258 257 fyl2x / t=y*log2(px) , y , x
259 258 fld %st(0) / t , t , y , x
260 259 frndint / [t] , t , y , x
261 260 fxch / t , [t] , y , x
262 261 fucom
263 262 fnstsw %ax / store status in %ax
264 263 sahf / 80387 flags in %ax to 80386 flags
265 264 je 1f / t is integral
266 265 fsub %st(1),%st / t-[t] , [t] , y , x
267 266 f2xm1 / 2**(t-[t])-1 , [t] , y , x
268 267 fadds PIC_L(one) / 2**(t-[t]) , [t] , y , x
269 268 fscale / 2**t = px**y , [t] , y , x
270 269 jmp 2f
271 270 1:
272 271 fstp %st(0) / t=[t] , y , x
273 272 fld1 / 1 , t , y , x
274 273 fscale / 1*2**t = x**y , t , y , x
275 274 2:
276 275 fstp %st(1) / x**y , y , x
277 276 cmpl $1,%ecx
278 277 jne .signok
279 278 fchs / change sign since x<0 & y=-int
280 279 .signok:
281 280 fstp %st(2) / y , x**y
282 281 fstp %st(0) / x**y
283 282 ret
284 283
285 284 / ------------------------------------------------------------------------
286 285
287 286 .xispinf:
288 287 ftst / compare %st(0) with 0
289 288 fnstsw %ax / store status in %ax
290 289 sahf / 80387 flags in %ax to 80386 flags
291 290 ja .retpinf / y > 0
292 291 jmp .retpzero / y < 0
293 292
294 293 .xisninf:
295 294 / -inf ** +-y is -0 ** -+y
296 295 fchs / -y , x
297 296 flds PIC_L(negzero) / -0 , -y , x
298 297 fstp %st(2) / -y , -0
299 298 jmp .xisnzero
300 299
301 300 .yispinf:
302 301 fld %st(1) / x , y , x
303 302 fabs / |x| , y , x
304 303 fcomps PIC_L(one) / y , x
305 304 fnstsw %ax / store status in %ax
306 305 sahf / 80387 flags in %ax to 80386 flags
307 306 je .retponeorinvalid / x == -1 C99
308 307 ja .retpinf / |x| > 1
309 308 jmp .retpzero / |x| < 1
310 309
311 310 .yisninf:
312 311 fld %st(1) / x , y , x
313 312 fabs / |x| , y , x
314 313 fcomps PIC_L(one) / y , x
315 314 fnstsw %ax / store status in %ax
316 315 sahf / 80387 flags in %ax to 80386 flags
317 316 je .retponeorinvalid / x == -1 C99
318 317 ja .retpzero / |x| > 1
319 318 jmp .retpinf / |x| < 1
320 319
321 320 .xispzero:
322 321 / y cannot be 0 or NaN ; stack has y , x
323 322 ftst / compare %st(0) with 0
324 323 fnstsw %ax / store status in %ax
325 324 sahf / 80387 flags in %ax to 80386 flags
326 325 ja .retpzero / y > 0
327 326 / x = +0 & y < 0 so x**y = +inf
328 327 jmp .retpinfzflag / ret +inf & z flag
329 328
330 329 .xisnzero:
331 330 / y cannot be 0 or NaN ; stack has y , x
332 331 call .y_is_int
333 332 cmpl $1,%ecx
334 333 jne 1f / y is not an odd integer
335 334 / y is an odd integer
336 335 ftst / compare %st(0) with 0
337 336 fnstsw %ax / store status in %ax
338 337 sahf / 80387 flags in %ax to 80386 flags
339 338 ja .retnzero / y > 0
340 339 / x = -0 & y < 0 (odd int) return -inf (z flag)
341 340 / x = -inf & y != 0 or NaN return -inf (NO z flag)
342 341 movb %dh,%cl
343 342 andb $0x45,%cl
344 343 cmpb $0x05,%cl / C3=0 C2=1 C1=? C0=1 when +-inf
345 344 je 2f
346 345 fdiv %st,%st(1) / y / x, x (raise z flag)
347 346 2:
348 347 fstp %st(0) / x
349 348 fstp %st(0) / stack empty
350 349 flds PIC_L(ninfinity) / -inf
351 350 ret
352 351
353 352 1: / y is not an odd integer
354 353 ftst / compare %st(0) with 0
355 354 fnstsw %ax / store status in %ax
356 355 sahf / 80387 flags in %ax to 80386 flags
357 356 ja .retpzero / y > 0
358 357 / x = -0 & y < 0 (not odd int) return +inf (z flag)
359 358 / x = -inf & y not 0 or NaN return +inf (NO z flag)
360 359 movb %dh,%cl
361 360 andb $0x45,%cl
362 361 cmpb $0x05,%cl / C3=0 C2=1 C1=? C0=1 when +-inf
363 362 jne .retpinfzflag / ret +inf & divide-by-0 flag
364 363 jmp .retpinf / return +inf (NO z flag)
365 364
366 365 .retpzero:
367 366 fstp %st(0) / x
368 367 fstp %st(0) / stack empty
369 368 fldz / +0
370 369 ret
371 370
372 371 .retnzero:
373 372 fstp %st(0) / x
374 373 fstp %st(0) / stack empty
375 374 flds PIC_L(negzero) / -0
376 375 ret
377 376
378 377 .retponeorinvalid:
379 378 PIC_G_LOAD(movzwl,__xpg6,eax)
380 379 andl $_C99SUSv3_pow_treats_Inf_as_an_even_int,%eax
381 380 cmpl $0,%eax
382 381 je 1f
383 382 fstp %st(0) / x
384 383 fstp %st(0) / stack empty
385 384 fld1 / 1
386 385 ret
387 386
388 387 1:
389 388 fstp %st(0) / x
390 389 fstp %st(0) / stack empty
391 390 flds PIC_L(Snan) / Q NaN (i flag)
392 391 fwait
393 392 ret
394 393
395 394 .retpinf:
396 395 fstp %st(0) / x
397 396 fstp %st(0) / stack empty
398 397 flds PIC_L(pinfinity) / +inf
399 398 ret
400 399
401 400 .retpinfzflag:
402 401 fstp %st(0) / x
403 402 fstp %st(0) / stack empty
404 403 fldz
405 404 fdivrs PIC_L(one) / 1/0
406 405 ret
407 406
408 407 / Set %ecx to 2 if y is an even integer, 1 if y is an odd integer,
409 408 / 0 otherwise. Assume y is not zero. Do not raise inexact or modify
410 409 / %edx.
411 410 .y_is_int:
412 411 movl 28(%ebp),%eax
413 412 andl $0x7fff,%eax / exponent of y
414 413 cmpl $0x403f,%eax
415 414 jae 1f / |y| >= 2^64, an even int
416 415 cmpl $0x3fff,%eax
417 416 jb 2f / |y| < 1, can't be an int
418 417 movl %eax,%ecx
419 418 subl $0x403e,%ecx
420 419 negl %ecx / 63 - unbiased exponent of y
421 420 movl 20(%ebp),%eax
422 421 bsfl %eax,%eax / index of least sig. 1 bit
423 422 jne 3f / jump if 1 bit found
424 423 movl 24(%ebp),%eax
425 424 bsfl %eax,%eax
426 425 addl $32,%eax / 32 + index of least sig. 1 bit
427 426 3:
428 427 cmpl %ecx,%eax
429 428 jb 2f
430 429 ja 1f
431 430 movl $1,%ecx
432 431 ret
433 432 1:
434 433 movl $2,%ecx
435 434 ret
436 435 2:
437 436 xorl %ecx,%ecx
438 437 ret
439 438 .align 4
440 439 SET_SIZE(powl)
↓ open down ↓ |
372 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX