diff options
Diffstat (limited to 'sysdeps/x86_64/fpu/e_powl.S')
-rw-r--r-- | sysdeps/x86_64/fpu/e_powl.S | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/sysdeps/x86_64/fpu/e_powl.S b/sysdeps/x86_64/fpu/e_powl.S index 1f68cf0102..f32228104e 100644 --- a/sysdeps/x86_64/fpu/e_powl.S +++ b/sysdeps/x86_64/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) @@ -136,12 +136,12 @@ 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. */ - fldl MO(p3) // 8 : y : x - fld %st(1) // y : 8 : y : x - fabs // |y| : 8 : y : x - fcomip %st(1), %st // 8 : y : x + fldl MO(p2) // 4 : y : x + fld %st(1) // y : 4 : y : x + fabs // |y| : 4 : y : x + fcomip %st(1), %st // 4 : y : x fstp %st(0) // y : x jnc 3f mov -8(%rsp),%eax @@ -184,9 +184,15 @@ ENTRY(__ieee754_powl) 30: fldt 8(%rsp) // x : y fldl MO(one) // 1.0 : x : y fucomip %st(1),%st // x : y - je 31f - fxch // y : x -31: fstp %st(1) + je 32f +31: /* At least one argument NaN, and result should be NaN. */ + faddp + ret +32: jc 31b + /* pow (1, NaN); check if the NaN signaling. */ + testb $0x40, 31(%rsp) + jz 31b + fstp %st(1) ret .align ALIGNARG(4) @@ -217,12 +223,24 @@ ENTRY(__ieee754_powl) cfi_adjust_cfa_offset (-40) ret - // pow(x,±0) = 1 + // pow(x,±0) = 1, unless x is sNaN .align ALIGNARG(4) 11: fstp %st(0) // pop y + fldt 8(%rsp) // 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, 15(%rsp) + jnz 111b + fadd %st(0) + ret + // y == ±inf .align ALIGNARG(4) 12: fstp %st(0) // pop y @@ -255,6 +273,7 @@ ENTRY(__ieee754_powl) .align ALIGNARG(4) 13: fldt 8(%rsp) // load x == NaN + fadd %st(0) ret .align ALIGNARG(4) |