diff options
author | Joseph Myers <joseph@codesourcery.com> | 2012-03-21 12:14:57 +0000 |
---|---|---|
committer | Joseph Myers <joseph@codesourcery.com> | 2012-03-21 12:16:00 +0000 |
commit | 2460d3aa21f04cdf28497683bd3e29183189f779 (patch) | |
tree | d01d4f4002b56099e0f8959e39aa5eee7dc1db10 /sysdeps/i386/fpu/e_powl.S | |
parent | eb96ffb07d0b1b23ecfaf9520d6757c7dbea0bd1 (diff) | |
download | glibc-2460d3aa21f04cdf28497683bd3e29183189f779.tar glibc-2460d3aa21f04cdf28497683bd3e29183189f779.tar.gz glibc-2460d3aa21f04cdf28497683bd3e29183189f779.tar.bz2 glibc-2460d3aa21f04cdf28497683bd3e29183189f779.zip |
Fix pow of zero and infinity to large powers.
Diffstat (limited to 'sysdeps/i386/fpu/e_powl.S')
-rw-r--r-- | sysdeps/i386/fpu/e_powl.S | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/sysdeps/i386/fpu/e_powl.S b/sysdeps/i386/fpu/e_powl.S index 5d850897c5..c0aa194c62 100644 --- a/sysdeps/i386/fpu/e_powl.S +++ b/sysdeps/i386/fpu/e_powl.S @@ -32,6 +32,9 @@ limit: .double 0.29 ASM_TYPE_DIRECTIVE(p63,@object) p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43 ASM_SIZE_DIRECTIVE(p63) + ASM_TYPE_DIRECTIVE(p64,@object) +p64: .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43 + ASM_SIZE_DIRECTIVE(p64) .section .rodata.cst16,"aM",@progbits,16 @@ -243,6 +246,19 @@ ENTRY(__ieee754_powl) testb $2, %dh jz 16f // jump if x == +inf + // fistpll raises invalid exception for |y| >= 1L<<63, but y + // may be odd unless we know |y| >= 1L<<64. + fld %st // y : y + fabs // |y| : y + fcompl MO(p64) // y + fnstsw + sahf + jnc 16f + fldl MO(p63) // p63 : y + fxch // y : p63 + fprem // y%p63 : p63 + fstp %st(1) // y%p63 + // We must find out whether y is an odd integer. fld %st // y : y fistpll (%esp) // y @@ -295,6 +311,19 @@ ENTRY(__ieee754_powl) testb $2, %dh jz 25f + // fistpll raises invalid exception for |y| >= 1L<<63, but y + // may be odd unless we know |y| >= 1L<<64. + fld %st // y : y + fabs // |y| : y + fcompl MO(p64) // y + fnstsw + sahf + jnc 25f + fldl MO(p63) // p63 : y + fxch // y : p63 + fprem // y%p63 : p63 + fstp %st(1) // y%p63 + fld %st // y : y fistpll (%esp) // y fildll (%esp) // int(y) : y @@ -332,6 +361,18 @@ ENTRY(__ieee754_powl) 21: testb $2, %dh jz 22f + // fistpll raises invalid exception for |y| >= 1L<<63, but y + // may be odd unless we know |y| >= 1L<<64. + fld %st // y : y + fcompl MO(p64) // y + fnstsw + sahf + jnc 22f + fldl MO(p63) // p63 : y + fxch // y : p63 + fprem // y%p63 : p63 + fstp %st(1) // y%p63 + fld %st // y : y fistpll (%esp) // y fildll (%esp) // int(y) : y |