From 60e235ee2ae834bb9f7a884f1b192304b9fdcf33 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 7 Nov 2012 13:03:31 +0000 Subject: Fix spurious underflows from pow with results close to 1 (bug 14811). --- sysdeps/i386/fpu/e_powl.S | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'sysdeps/i386') diff --git a/sysdeps/i386/fpu/e_powl.S b/sysdeps/i386/fpu/e_powl.S index 933418cf82..ac4842cf63 100644 --- a/sysdeps/i386/fpu/e_powl.S +++ b/sysdeps/i386/fpu/e_powl.S @@ -38,6 +38,9 @@ p64: .byte 0, 0, 0, 0, 0, 0, 0xf0, 0x43 .type p78,@object p78: .byte 0, 0, 0, 0, 0, 0, 0xd0, 0x44 ASM_SIZE_DIRECTIVE(p78) + .type pm79,@object +pm79: .byte 0, 0, 0, 0, 0, 0, 0, 0x3b + ASM_SIZE_DIRECTIVE(pm79) .section .rodata.cst16,"aM",@progbits,16 @@ -120,9 +123,25 @@ ENTRY(__ieee754_powl) fucomp %st(1) // y : x fnstsw sahf - jne 3f + je 9f - /* OK, we have an integer value for y. */ + // If y has absolute value at most 0x1p-79, then any finite + // nonzero x will result in 1. Saturate y to those bounds to + // avoid underflow in the calculation of y*log2(x). + fld %st // y : y : x + fabs // |y| : y : x + fcompl MO(pm79) // y : x + fnstsw + sahf + jnc 3f + fstp %st(0) // pop y + fldl MO(pm79) // 0x1p-79 : x + testb $2, %dl + jnz 3f // y > 0 + fchs // -0x1p-79 : x + jmp 3f + +9: /* OK, we have an integer value for y. */ popl %eax cfi_adjust_cfa_offset (-4) popl %edx -- cgit v1.2.3