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