summaryrefslogtreecommitdiff
path: root/sysdeps/i386/fpu/e_powl.S
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/i386/fpu/e_powl.S')
-rw-r--r--sysdeps/i386/fpu/e_powl.S41
1 files changed, 30 insertions, 11 deletions
diff --git a/sysdeps/i386/fpu/e_powl.S b/sysdeps/i386/fpu/e_powl.S
index 77d2abfaea..51a0c334f0 100644
--- a/sysdeps/i386/fpu/e_powl.S
+++ b/sysdeps/i386/fpu/e_powl.S
@@ -1,5 +1,5 @@
/* ix87 specific implementation of pow function.
- Copyright (C) 1996-2016 Free Software Foundation, Inc.
+ Copyright (C) 1996-2018 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
@@ -26,9 +26,9 @@
.type one,@object
one: .double 1.0
ASM_SIZE_DIRECTIVE(one)
- .type p3,@object
-p3: .byte 0, 0, 0, 0, 0, 0, 0x20, 0x40
- ASM_SIZE_DIRECTIVE(p3)
+ .type p2,@object
+p2: .byte 0, 0, 0, 0, 0, 0, 0x10, 0x40
+ ASM_SIZE_DIRECTIVE(p2)
.type p63,@object
p63: .byte 0, 0, 0, 0, 0, 0, 0xe0, 0x43
ASM_SIZE_DIRECTIVE(p63)
@@ -146,11 +146,11 @@ ENTRY(__ieee754_powl)
jmp 3f
9: /* OK, we have an integer value for y. Unless very small
- (we use < 8), use the algorithm for real exponent to avoid
+ (we use < 4), use the algorithm for real exponent to avoid
accumulation of errors. */
fld %st // y : y : x
fabs // |y| : y : x
- fcompl MO(p3) // y : x
+ fcompl MO(p2) // y : x
fnstsw
sahf
jnc 3f
@@ -201,15 +201,21 @@ ENTRY(__ieee754_powl)
fucomp %st(1) // x : y
fnstsw
sahf
- je 31f
- fxch // y : x
-31: fstp %st(1)
+ je 33f
+31: /* At least one argument NaN, and result should be NaN. */
+ faddp
+ ret
+33: jp 31b
+ /* pow (1, NaN); check if the NaN signaling. */
+ testb $0x40, 23(%esp)
+ jz 31b
+ fstp %st(1)
ret
cfi_adjust_cfa_offset (8)
32: addl $8, %esp
cfi_adjust_cfa_offset (-8)
- fstp %st(1)
+ faddp
ret
cfi_adjust_cfa_offset (8)
@@ -241,12 +247,24 @@ ENTRY(__ieee754_powl)
cfi_adjust_cfa_offset (-36)
ret
- // pow(x,±0) = 1
+ // pow(x,±0) = 1, unless x is sNaN
.align ALIGNARG(4)
11: fstp %st(0) // pop y
+ fldt 4(%esp) // x
+ fxam
+ fnstsw
+ andb $0x45, %ah
+ cmpb $0x01, %ah
+ je 112f // x is NaN
+111: fstp %st(0)
fldl MO(one)
ret
+112: testb $0x40, 11(%esp)
+ jnz 111b
+ fadd %st(0)
+ ret
+
// y == ±inf
.align ALIGNARG(4)
12: fstp %st(0) // pop y
@@ -274,6 +292,7 @@ ENTRY(__ieee754_powl)
.align ALIGNARG(4)
13: fldt 4(%esp) // load x == NaN
+ fadd %st(0)
ret
cfi_adjust_cfa_offset (8)