| OLD | NEW |
| 1 /* ix87 specific implementation of pow function. | 1 /* ix87 specific implementation of pow function. |
| 2 Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007 | 2 Copyright (C) 1996, 1997, 1998, 1999, 2001, 2004, 2005, 2007 |
| 3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
| 4 This file is part of the GNU C Library. | 4 This file is part of the GNU C Library. |
| 5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. | 5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996. |
| 6 | 6 |
| 7 The GNU C Library is free software; you can redistribute it and/or | 7 The GNU C Library is free software; you can redistribute it and/or |
| 8 modify it under the terms of the GNU Lesser General Public | 8 modify it under the terms of the GNU Lesser General Public |
| 9 License as published by the Free Software Foundation; either | 9 License as published by the Free Software Foundation; either |
| 10 version 2.1 of the License, or (at your option) any later version. | 10 version 2.1 of the License, or (at your option) any later version. |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 jnc 5f | 136 jnc 5f |
| 137 fxch | 137 fxch |
| 138 fmul %st(1) // x : ST*x | 138 fmul %st(1) // x : ST*x |
| 139 fxch | 139 fxch |
| 140 5: fmul %st(0), %st // x*x : ST*x | 140 5: fmul %st(0), %st // x*x : ST*x |
| 141 shrl $1, %edx | 141 shrl $1, %edx |
| 142 movl %eax, %ecx | 142 movl %eax, %ecx |
| 143 orl %edx, %ecx | 143 orl %edx, %ecx |
| 144 jnz 6b | 144 jnz 6b |
| 145 fstp %st(0) // ST*x | 145 fstp %st(0) // ST*x |
| 146 » ret | 146 » NACLRET |
| 147 | 147 |
| 148 /* y is ±NAN */ | 148 /* y is ±NAN */ |
| 149 30: fldl 4(%esp) // x : y | 149 30: fldl 4(%esp) // x : y |
| 150 fldl MO(one) // 1.0 : x : y | 150 fldl MO(one) // 1.0 : x : y |
| 151 fucomp %st(1) // x : y | 151 fucomp %st(1) // x : y |
| 152 fnstsw | 152 fnstsw |
| 153 sahf | 153 sahf |
| 154 je 31f | 154 je 31f |
| 155 fxch // y : x | 155 fxch // y : x |
| 156 31: fstp %st(1) | 156 31: fstp %st(1) |
| 157 » ret | 157 » NACLRET |
| 158 | 158 |
| 159 cfi_adjust_cfa_offset (8) | 159 cfi_adjust_cfa_offset (8) |
| 160 .align ALIGNARG(4) | 160 .align ALIGNARG(4) |
| 161 2: /* y is a real number. */ | 161 2: /* y is a real number. */ |
| 162 fxch // x : y | 162 fxch // x : y |
| 163 fldl MO(one) // 1.0 : x : y | 163 fldl MO(one) // 1.0 : x : y |
| 164 fldl MO(limit) // 0.29 : 1.0 : x : y | 164 fldl MO(limit) // 0.29 : 1.0 : x : y |
| 165 fld %st(2) // x : 0.29 : 1.0 : x : y | 165 fld %st(2) // x : 0.29 : 1.0 : x : y |
| 166 fsub %st(2) // x-1 : 0.29 : 1.0 : x : y | 166 fsub %st(2) // x-1 : 0.29 : 1.0 : x : y |
| 167 fabs // |x-1| : 0.29 : 1.0 : x : y | 167 fabs // |x-1| : 0.29 : 1.0 : x : y |
| (...skipping 11 matching lines...) Expand all Loading... |
| 179 fst %st(1) // y*log2(x) : y*log2(x) | 179 fst %st(1) // y*log2(x) : y*log2(x) |
| 180 frndint // int(y*log2(x)) : y*log2(x) | 180 frndint // int(y*log2(x)) : y*log2(x) |
| 181 fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) | 181 fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) |
| 182 fxch // fract(y*log2(x)) : int(y*log2(x)) | 182 fxch // fract(y*log2(x)) : int(y*log2(x)) |
| 183 f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) | 183 f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) |
| 184 faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x)) | 184 faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x)) |
| 185 fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*l
og2(x)) | 185 fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*l
og2(x)) |
| 186 addl $8, %esp | 186 addl $8, %esp |
| 187 cfi_adjust_cfa_offset (-8) | 187 cfi_adjust_cfa_offset (-8) |
| 188 fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) | 188 fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) |
| 189 » ret | 189 » NACLRET |
| 190 | 190 |
| 191 | 191 |
| 192 // pow(x,±0) = 1 | 192 // pow(x,±0) = 1 |
| 193 .align ALIGNARG(4) | 193 .align ALIGNARG(4) |
| 194 11: fstp %st(0) // pop y | 194 11: fstp %st(0) // pop y |
| 195 fldl MO(one) | 195 fldl MO(one) |
| 196 » ret | 196 » NACLRET |
| 197 | 197 |
| 198 // y == ±inf | 198 // y == ±inf |
| 199 .align ALIGNARG(4) | 199 .align ALIGNARG(4) |
| 200 12: fstp %st(0) // pop y | 200 12: fstp %st(0) // pop y |
| 201 fldl MO(one) // 1 | 201 fldl MO(one) // 1 |
| 202 fldl 4(%esp) // x : 1 | 202 fldl 4(%esp) // x : 1 |
| 203 fabs // abs(x) : 1 | 203 fabs // abs(x) : 1 |
| 204 fucompp // < 1, == 1, or > 1 | 204 fucompp // < 1, == 1, or > 1 |
| 205 fnstsw | 205 fnstsw |
| 206 andb $0x45, %ah | 206 andb $0x45, %ah |
| 207 cmpb $0x45, %ah | 207 cmpb $0x45, %ah |
| 208 je 13f // jump if x is NaN | 208 je 13f // jump if x is NaN |
| 209 | 209 |
| 210 cmpb $0x40, %ah | 210 cmpb $0x40, %ah |
| 211 je 14f // jump if |x| == 1 | 211 je 14f // jump if |x| == 1 |
| 212 | 212 |
| 213 shlb $1, %ah | 213 shlb $1, %ah |
| 214 xorb %ah, %dl | 214 xorb %ah, %dl |
| 215 andl $2, %edx | 215 andl $2, %edx |
| 216 fldl MOX(inf_zero, %edx, 4) | 216 fldl MOX(inf_zero, %edx, 4) |
| 217 » ret | 217 » NACLRET |
| 218 | 218 |
| 219 .align ALIGNARG(4) | 219 .align ALIGNARG(4) |
| 220 14: fldl MO(one) | 220 14: fldl MO(one) |
| 221 » ret | 221 » NACLRET |
| 222 | 222 |
| 223 .align ALIGNARG(4) | 223 .align ALIGNARG(4) |
| 224 13: fldl 4(%esp) // load x == NaN | 224 13: fldl 4(%esp) // load x == NaN |
| 225 » ret | 225 » NACLRET |
| 226 | 226 |
| 227 cfi_adjust_cfa_offset (8) | 227 cfi_adjust_cfa_offset (8) |
| 228 .align ALIGNARG(4) | 228 .align ALIGNARG(4) |
| 229 // x is ±inf | 229 // x is ±inf |
| 230 15: fstp %st(0) // y | 230 15: fstp %st(0) // y |
| 231 testb $2, %dh | 231 testb $2, %dh |
| 232 jz 16f // jump if x == +inf | 232 jz 16f // jump if x == +inf |
| 233 | 233 |
| 234 // We must find out whether y is an odd integer. | 234 // We must find out whether y is an odd integer. |
| 235 fld %st // y : y | 235 fld %st // y : y |
| (...skipping 14 matching lines...) Expand all Loading... |
| 250 jz 18f // jump if not odd | 250 jz 18f // jump if not odd |
| 251 movl %edx, %eax | 251 movl %edx, %eax |
| 252 orl %edx, %edx | 252 orl %edx, %edx |
| 253 jns 155f | 253 jns 155f |
| 254 negl %eax | 254 negl %eax |
| 255 155: cmpl $0x00200000, %eax | 255 155: cmpl $0x00200000, %eax |
| 256 ja 18f // does not fit in mantissa bits | 256 ja 18f // does not fit in mantissa bits |
| 257 // It's an odd integer. | 257 // It's an odd integer. |
| 258 shrl $31, %edx | 258 shrl $31, %edx |
| 259 fldl MOX(minf_mzero, %edx, 8) | 259 fldl MOX(minf_mzero, %edx, 8) |
| 260 » ret | 260 » NACLRET |
| 261 | 261 |
| 262 cfi_adjust_cfa_offset (8) | 262 cfi_adjust_cfa_offset (8) |
| 263 .align ALIGNARG(4) | 263 .align ALIGNARG(4) |
| 264 16: fcompl MO(zero) | 264 16: fcompl MO(zero) |
| 265 addl $8, %esp | 265 addl $8, %esp |
| 266 cfi_adjust_cfa_offset (-8) | 266 cfi_adjust_cfa_offset (-8) |
| 267 fnstsw | 267 fnstsw |
| 268 shrl $5, %eax | 268 shrl $5, %eax |
| 269 andl $8, %eax | 269 andl $8, %eax |
| 270 fldl MOX(inf_zero, %eax, 1) | 270 fldl MOX(inf_zero, %eax, 1) |
| 271 » ret | 271 » NACLRET |
| 272 | 272 |
| 273 cfi_adjust_cfa_offset (8) | 273 cfi_adjust_cfa_offset (8) |
| 274 .align ALIGNARG(4) | 274 .align ALIGNARG(4) |
| 275 17: shll $30, %edx // sign bit for y in right position | 275 17: shll $30, %edx // sign bit for y in right position |
| 276 addl $8, %esp | 276 addl $8, %esp |
| 277 cfi_adjust_cfa_offset (-8) | 277 cfi_adjust_cfa_offset (-8) |
| 278 18: shrl $31, %edx | 278 18: shrl $31, %edx |
| 279 fldl MOX(inf_zero, %edx, 8) | 279 fldl MOX(inf_zero, %edx, 8) |
| 280 » ret | 280 » NACLRET |
| 281 | 281 |
| 282 cfi_adjust_cfa_offset (8) | 282 cfi_adjust_cfa_offset (8) |
| 283 .align ALIGNARG(4) | 283 .align ALIGNARG(4) |
| 284 // x is ±0 | 284 // x is ±0 |
| 285 20: fstp %st(0) // y | 285 20: fstp %st(0) // y |
| 286 testb $2, %dl | 286 testb $2, %dl |
| 287 jz 21f // y > 0 | 287 jz 21f // y > 0 |
| 288 | 288 |
| 289 // x is ±0 and y is < 0. We must find out whether y is an odd integer. | 289 // x is ±0 and y is < 0. We must find out whether y is an odd integer. |
| 290 testb $2, %dh | 290 testb $2, %dh |
| (...skipping 15 matching lines...) Expand all Loading... |
| 306 cfi_adjust_cfa_offset (-4) | 306 cfi_adjust_cfa_offset (-4) |
| 307 andb $1, %al | 307 andb $1, %al |
| 308 jz 27f // jump if not odd | 308 jz 27f // jump if not odd |
| 309 cmpl $0xffe00000, %edx | 309 cmpl $0xffe00000, %edx |
| 310 jbe 27f // does not fit in mantissa bits | 310 jbe 27f // does not fit in mantissa bits |
| 311 // It's an odd integer. | 311 // It's an odd integer. |
| 312 // Raise divide-by-zero exception and get minus infinity value. | 312 // Raise divide-by-zero exception and get minus infinity value. |
| 313 fldl MO(one) | 313 fldl MO(one) |
| 314 fdivl MO(zero) | 314 fdivl MO(zero) |
| 315 fchs | 315 fchs |
| 316 » ret | 316 » NACLRET |
| 317 | 317 |
| 318 cfi_adjust_cfa_offset (8) | 318 cfi_adjust_cfa_offset (8) |
| 319 25: fstp %st(0) | 319 25: fstp %st(0) |
| 320 26: addl $8, %esp | 320 26: addl $8, %esp |
| 321 cfi_adjust_cfa_offset (-8) | 321 cfi_adjust_cfa_offset (-8) |
| 322 27: // Raise divide-by-zero exception and get infinity value. | 322 27: // Raise divide-by-zero exception and get infinity value. |
| 323 fldl MO(one) | 323 fldl MO(one) |
| 324 fdivl MO(zero) | 324 fdivl MO(zero) |
| 325 » ret | 325 » NACLRET |
| 326 | 326 |
| 327 cfi_adjust_cfa_offset (8) | 327 cfi_adjust_cfa_offset (8) |
| 328 .align ALIGNARG(4) | 328 .align ALIGNARG(4) |
| 329 // x is ±0 and y is > 0. We must find out whether y is an odd integer. | 329 // x is ±0 and y is > 0. We must find out whether y is an odd integer. |
| 330 21: testb $2, %dh | 330 21: testb $2, %dh |
| 331 jz 22f | 331 jz 22f |
| 332 | 332 |
| 333 fld %st // y : y | 333 fld %st // y : y |
| 334 fistpll (%esp) // y | 334 fistpll (%esp) // y |
| 335 fildll (%esp) // int(y) : y | 335 fildll (%esp) // int(y) : y |
| 336 fucompp // <empty> | 336 fucompp // <empty> |
| 337 fnstsw | 337 fnstsw |
| 338 sahf | 338 sahf |
| 339 jne 23f | 339 jne 23f |
| 340 | 340 |
| 341 // OK, the value is an integer, but is the number of bits small | 341 // OK, the value is an integer, but is the number of bits small |
| 342 // enough so that all are coming from the mantissa? | 342 // enough so that all are coming from the mantissa? |
| 343 popl %eax | 343 popl %eax |
| 344 cfi_adjust_cfa_offset (-4) | 344 cfi_adjust_cfa_offset (-4) |
| 345 popl %edx | 345 popl %edx |
| 346 cfi_adjust_cfa_offset (-4) | 346 cfi_adjust_cfa_offset (-4) |
| 347 andb $1, %al | 347 andb $1, %al |
| 348 jz 24f // jump if not odd | 348 jz 24f // jump if not odd |
| 349 cmpl $0xffe00000, %edx | 349 cmpl $0xffe00000, %edx |
| 350 jae 24f // does not fit in mantissa bits | 350 jae 24f // does not fit in mantissa bits |
| 351 // It's an odd integer. | 351 // It's an odd integer. |
| 352 fldl MO(mzero) | 352 fldl MO(mzero) |
| 353 » ret | 353 » NACLRET |
| 354 | 354 |
| 355 cfi_adjust_cfa_offset (8) | 355 cfi_adjust_cfa_offset (8) |
| 356 22: fstp %st(0) | 356 22: fstp %st(0) |
| 357 23: addl $8, %esp // Don't use 2 x pop | 357 23: addl $8, %esp // Don't use 2 x pop |
| 358 cfi_adjust_cfa_offset (-8) | 358 cfi_adjust_cfa_offset (-8) |
| 359 24: fldl MO(zero) | 359 24: fldl MO(zero) |
| 360 » ret | 360 » NACLRET |
| 361 | 361 |
| 362 END(__ieee754_pow) | 362 END(__ieee754_pow) |
| OLD | NEW |