| 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: fldt 4(%esp) // x : y | 149 30: fldt 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 16 matching lines...) Expand all Loading... |
| 184 fst %st(1) // y*log2(x) : y*log2(x) | 184 fst %st(1) // y*log2(x) : y*log2(x) |
| 185 frndint // int(y*log2(x)) : y*log2(x) | 185 frndint // int(y*log2(x)) : y*log2(x) |
| 186 fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) | 186 fsubr %st, %st(1) // int(y*log2(x)) : fract(y*log2(x)) |
| 187 fxch // fract(y*log2(x)) : int(y*log2(x)) | 187 fxch // fract(y*log2(x)) : int(y*log2(x)) |
| 188 f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) | 188 f2xm1 // 2^fract(y*log2(x))-1 : int(y*log2(x)) |
| 189 faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x)) | 189 faddl MO(one) // 2^fract(y*log2(x)) : int(y*log2(x)) |
| 190 fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*l
og2(x)) | 190 fscale // 2^fract(y*log2(x))*2^int(y*log2(x)) : int(y*l
og2(x)) |
| 191 addl $8, %esp | 191 addl $8, %esp |
| 192 cfi_adjust_cfa_offset (-8) | 192 cfi_adjust_cfa_offset (-8) |
| 193 fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) | 193 fstp %st(1) // 2^fract(y*log2(x))*2^int(y*log2(x)) |
| 194 » ret | 194 » NACLRET |
| 195 | 195 |
| 196 cfi_adjust_cfa_offset (8) | 196 cfi_adjust_cfa_offset (8) |
| 197 28: fstp %st(1) // y*log2(x) | 197 28: fstp %st(1) // y*log2(x) |
| 198 fldl MO(one) // 1 : y*log2(x) | 198 fldl MO(one) // 1 : y*log2(x) |
| 199 fscale // 2^(y*log2(x)) : y*log2(x) | 199 fscale // 2^(y*log2(x)) : y*log2(x) |
| 200 addl $8, %esp | 200 addl $8, %esp |
| 201 cfi_adjust_cfa_offset (-8) | 201 cfi_adjust_cfa_offset (-8) |
| 202 fstp %st(1) // 2^(y*log2(x)) | 202 fstp %st(1) // 2^(y*log2(x)) |
| 203 » ret | 203 » NACLRET |
| 204 | 204 |
| 205 // pow(x,±0) = 1 | 205 // pow(x,±0) = 1 |
| 206 .align ALIGNARG(4) | 206 .align ALIGNARG(4) |
| 207 11: fstp %st(0) // pop y | 207 11: fstp %st(0) // pop y |
| 208 fldl MO(one) | 208 fldl MO(one) |
| 209 » ret | 209 » NACLRET |
| 210 | 210 |
| 211 // y == ±inf | 211 // y == ±inf |
| 212 .align ALIGNARG(4) | 212 .align ALIGNARG(4) |
| 213 12: fstp %st(0) // pop y | 213 12: fstp %st(0) // pop y |
| 214 fldl MO(one) // 1 | 214 fldl MO(one) // 1 |
| 215 fldt 4(%esp) // x : 1 | 215 fldt 4(%esp) // x : 1 |
| 216 fabs // abs(x) : 1 | 216 fabs // abs(x) : 1 |
| 217 fucompp // < 1, == 1, or > 1 | 217 fucompp // < 1, == 1, or > 1 |
| 218 fnstsw | 218 fnstsw |
| 219 andb $0x45, %ah | 219 andb $0x45, %ah |
| 220 cmpb $0x45, %ah | 220 cmpb $0x45, %ah |
| 221 je 13f // jump if x is NaN | 221 je 13f // jump if x is NaN |
| 222 | 222 |
| 223 cmpb $0x40, %ah | 223 cmpb $0x40, %ah |
| 224 je 14f // jump if |x| == 1 | 224 je 14f // jump if |x| == 1 |
| 225 | 225 |
| 226 shlb $1, %ah | 226 shlb $1, %ah |
| 227 xorb %ah, %dl | 227 xorb %ah, %dl |
| 228 andl $2, %edx | 228 andl $2, %edx |
| 229 fldl MOX(inf_zero, %edx, 4) | 229 fldl MOX(inf_zero, %edx, 4) |
| 230 » ret | 230 » NACLRET |
| 231 | 231 |
| 232 .align ALIGNARG(4) | 232 .align ALIGNARG(4) |
| 233 14: fldl MO(one) | 233 14: fldl MO(one) |
| 234 » ret | 234 » NACLRET |
| 235 | 235 |
| 236 .align ALIGNARG(4) | 236 .align ALIGNARG(4) |
| 237 13: fldt 4(%esp) // load x == NaN | 237 13: fldt 4(%esp) // load x == NaN |
| 238 » ret | 238 » NACLRET |
| 239 | 239 |
| 240 cfi_adjust_cfa_offset (8) | 240 cfi_adjust_cfa_offset (8) |
| 241 .align ALIGNARG(4) | 241 .align ALIGNARG(4) |
| 242 // x is ±inf | 242 // x is ±inf |
| 243 15: fstp %st(0) // y | 243 15: fstp %st(0) // y |
| 244 testb $2, %dh | 244 testb $2, %dh |
| 245 jz 16f // jump if x == +inf | 245 jz 16f // jump if x == +inf |
| 246 | 246 |
| 247 // We must find out whether y is an odd integer. | 247 // We must find out whether y is an odd integer. |
| 248 fld %st // y : y | 248 fld %st // y : y |
| 249 fistpll (%esp) // y | 249 fistpll (%esp) // y |
| 250 fildll (%esp) // int(y) : y | 250 fildll (%esp) // int(y) : y |
| 251 fucompp // <empty> | 251 fucompp // <empty> |
| 252 fnstsw | 252 fnstsw |
| 253 sahf | 253 sahf |
| 254 jne 17f | 254 jne 17f |
| 255 | 255 |
| 256 // OK, the value is an integer, but is it odd? | 256 // OK, the value is an integer, but is it odd? |
| 257 popl %eax | 257 popl %eax |
| 258 cfi_adjust_cfa_offset (-4) | 258 cfi_adjust_cfa_offset (-4) |
| 259 popl %edx | 259 popl %edx |
| 260 cfi_adjust_cfa_offset (-4) | 260 cfi_adjust_cfa_offset (-4) |
| 261 andb $1, %al | 261 andb $1, %al |
| 262 jz 18f // jump if not odd | 262 jz 18f // jump if not odd |
| 263 // It's an odd integer. | 263 // It's an odd integer. |
| 264 shrl $31, %edx | 264 shrl $31, %edx |
| 265 fldl MOX(minf_mzero, %edx, 8) | 265 fldl MOX(minf_mzero, %edx, 8) |
| 266 » ret | 266 » NACLRET |
| 267 | 267 |
| 268 cfi_adjust_cfa_offset (8) | 268 cfi_adjust_cfa_offset (8) |
| 269 .align ALIGNARG(4) | 269 .align ALIGNARG(4) |
| 270 16: fcompl MO(zero) | 270 16: fcompl MO(zero) |
| 271 addl $8, %esp | 271 addl $8, %esp |
| 272 cfi_adjust_cfa_offset (-8) | 272 cfi_adjust_cfa_offset (-8) |
| 273 fnstsw | 273 fnstsw |
| 274 shrl $5, %eax | 274 shrl $5, %eax |
| 275 andl $8, %eax | 275 andl $8, %eax |
| 276 fldl MOX(inf_zero, %eax, 1) | 276 fldl MOX(inf_zero, %eax, 1) |
| 277 » ret | 277 » NACLRET |
| 278 | 278 |
| 279 cfi_adjust_cfa_offset (8) | 279 cfi_adjust_cfa_offset (8) |
| 280 .align ALIGNARG(4) | 280 .align ALIGNARG(4) |
| 281 17: shll $30, %edx // sign bit for y in right position | 281 17: shll $30, %edx // sign bit for y in right position |
| 282 addl $8, %esp | 282 addl $8, %esp |
| 283 cfi_adjust_cfa_offset (-8) | 283 cfi_adjust_cfa_offset (-8) |
| 284 18: shrl $31, %edx | 284 18: shrl $31, %edx |
| 285 fldl MOX(inf_zero, %edx, 8) | 285 fldl MOX(inf_zero, %edx, 8) |
| 286 » ret | 286 » NACLRET |
| 287 | 287 |
| 288 cfi_adjust_cfa_offset (8) | 288 cfi_adjust_cfa_offset (8) |
| 289 .align ALIGNARG(4) | 289 .align ALIGNARG(4) |
| 290 // x is ±0 | 290 // x is ±0 |
| 291 20: fstp %st(0) // y | 291 20: fstp %st(0) // y |
| 292 testb $2, %dl | 292 testb $2, %dl |
| 293 jz 21f // y > 0 | 293 jz 21f // y > 0 |
| 294 | 294 |
| 295 // x is ±0 and y is < 0. We must find out whether y is an odd integer. | 295 // x is ±0 and y is < 0. We must find out whether y is an odd integer. |
| 296 testb $2, %dh | 296 testb $2, %dh |
| (...skipping 12 matching lines...) Expand all Loading... |
| 309 cfi_adjust_cfa_offset (-4) | 309 cfi_adjust_cfa_offset (-4) |
| 310 popl %edx | 310 popl %edx |
| 311 cfi_adjust_cfa_offset (-4) | 311 cfi_adjust_cfa_offset (-4) |
| 312 andb $1, %al | 312 andb $1, %al |
| 313 jz 27f // jump if not odd | 313 jz 27f // jump if not odd |
| 314 // It's an odd integer. | 314 // It's an odd integer. |
| 315 // Raise divide-by-zero exception and get minus infinity value. | 315 // Raise divide-by-zero exception and get minus infinity value. |
| 316 fldl MO(one) | 316 fldl MO(one) |
| 317 fdivl MO(zero) | 317 fdivl MO(zero) |
| 318 fchs | 318 fchs |
| 319 » ret | 319 » NACLRET |
| 320 | 320 |
| 321 cfi_adjust_cfa_offset (8) | 321 cfi_adjust_cfa_offset (8) |
| 322 25: fstp %st(0) | 322 25: fstp %st(0) |
| 323 26: addl $8, %esp | 323 26: addl $8, %esp |
| 324 cfi_adjust_cfa_offset (-8) | 324 cfi_adjust_cfa_offset (-8) |
| 325 27: // Raise divide-by-zero exception and get infinity value. | 325 27: // Raise divide-by-zero exception and get infinity value. |
| 326 fldl MO(one) | 326 fldl MO(one) |
| 327 fdivl MO(zero) | 327 fdivl MO(zero) |
| 328 » ret | 328 » NACLRET |
| 329 | 329 |
| 330 cfi_adjust_cfa_offset (8) | 330 cfi_adjust_cfa_offset (8) |
| 331 .align ALIGNARG(4) | 331 .align ALIGNARG(4) |
| 332 // x is ±0 and y is > 0. We must find out whether y is an odd integer. | 332 // x is ±0 and y is > 0. We must find out whether y is an odd integer. |
| 333 21: testb $2, %dh | 333 21: testb $2, %dh |
| 334 jz 22f | 334 jz 22f |
| 335 | 335 |
| 336 fld %st // y : y | 336 fld %st // y : y |
| 337 fistpll (%esp) // y | 337 fistpll (%esp) // y |
| 338 fildll (%esp) // int(y) : y | 338 fildll (%esp) // int(y) : y |
| 339 fucompp // <empty> | 339 fucompp // <empty> |
| 340 fnstsw | 340 fnstsw |
| 341 sahf | 341 sahf |
| 342 jne 23f | 342 jne 23f |
| 343 | 343 |
| 344 // OK, the value is an integer, but is it odd? | 344 // OK, the value is an integer, but is it odd? |
| 345 popl %eax | 345 popl %eax |
| 346 cfi_adjust_cfa_offset (-4) | 346 cfi_adjust_cfa_offset (-4) |
| 347 popl %edx | 347 popl %edx |
| 348 cfi_adjust_cfa_offset (-4) | 348 cfi_adjust_cfa_offset (-4) |
| 349 andb $1, %al | 349 andb $1, %al |
| 350 jz 24f // jump if not odd | 350 jz 24f // jump if not odd |
| 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_powl) | 362 END(__ieee754_powl) |
| OLD | NEW |