aboutsummaryrefslogtreecommitdiff
path: root/sysdeps/i386/fpu/e_powl.S
diff options
context:
space:
mode:
authorJoseph Myers <joseph@codesourcery.com>2012-03-21 12:14:57 +0000
committerJoseph Myers <joseph@codesourcery.com>2012-03-21 12:16:00 +0000
commit2460d3aa21f04cdf28497683bd3e29183189f779 (patch)
treed01d4f4002b56099e0f8959e39aa5eee7dc1db10 /sysdeps/i386/fpu/e_powl.S
parenteb96ffb07d0b1b23ecfaf9520d6757c7dbea0bd1 (diff)
downloadglibc-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.S41
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