diff options
Diffstat (limited to 'sysdeps/i386/fpu/e_pow.S')
-rw-r--r-- | sysdeps/i386/fpu/e_pow.S | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/sysdeps/i386/fpu/e_pow.S b/sysdeps/i386/fpu/e_pow.S index 63c44f1357..1abedf6284 100644 --- a/sysdeps/i386/fpu/e_pow.S +++ b/sysdeps/i386/fpu/e_pow.S @@ -230,6 +230,16 @@ ENTRY(__ieee754_pow) testb $2, %dh jz 16f // jump if x == +inf + // fistpll raises invalid exception for |y| >= 1L<<63, so test + // that (in which case y is certainly even) before testing + // whether y is odd. + fld %st // y : y + fabs // |y| : y + fcompl MO(p63) // y + fnstsw + sahf + jnc 16f + // We must find out whether y is an odd integer. fld %st // y : y fistpll (%esp) // y @@ -239,20 +249,13 @@ ENTRY(__ieee754_pow) sahf jne 17f - // OK, the value is an integer, but is the number of bits small - // enough so that all are coming from the mantissa? + // OK, the value is an integer. popl %eax cfi_adjust_cfa_offset (-4) popl %edx cfi_adjust_cfa_offset (-4) andb $1, %al jz 18f // jump if not odd - movl %edx, %eax - orl %edx, %edx - jns 155f - negl %eax -155: cmpl $0x00200000, %eax - ja 18f // does not fit in mantissa bits // It's an odd integer. shrl $31, %edx fldl MOX(minf_mzero, %edx, 8) @@ -289,6 +292,16 @@ ENTRY(__ieee754_pow) testb $2, %dh jz 25f + // fistpll raises invalid exception for |y| >= 1L<<63, so test + // that (in which case y is certainly even) before testing + // whether y is odd. + fld %st // y : y + fabs // |y| : y + fcompl MO(p63) // y + fnstsw + sahf + jnc 25f + fld %st // y : y fistpll (%esp) // y fildll (%esp) // int(y) : y @@ -297,16 +310,13 @@ ENTRY(__ieee754_pow) sahf jne 26f - // OK, the value is an integer, but is the number of bits small - // enough so that all are coming from the mantissa? + // OK, the value is an integer. popl %eax cfi_adjust_cfa_offset (-4) popl %edx cfi_adjust_cfa_offset (-4) andb $1, %al jz 27f // jump if not odd - cmpl $0xffe00000, %edx - jbe 27f // does not fit in mantissa bits // It's an odd integer. // Raise divide-by-zero exception and get minus infinity value. fldl MO(one) @@ -329,6 +339,14 @@ ENTRY(__ieee754_pow) 21: testb $2, %dh jz 22f + // fistpll raises invalid exception for |y| >= 1L<<63, so test + // that (in which case y is certainly even) before testing + // whether y is odd. + fcoml MO(p63) // y + fnstsw + sahf + jnc 22f + fld %st // y : y fistpll (%esp) // y fildll (%esp) // int(y) : y @@ -337,16 +355,13 @@ ENTRY(__ieee754_pow) sahf jne 23f - // OK, the value is an integer, but is the number of bits small - // enough so that all are coming from the mantissa? + // OK, the value is an integer. popl %eax cfi_adjust_cfa_offset (-4) popl %edx cfi_adjust_cfa_offset (-4) andb $1, %al jz 24f // jump if not odd - cmpl $0xffe00000, %edx - jae 24f // does not fit in mantissa bits // It's an odd integer. fldl MO(mzero) ret |