glibc/sysdeps/i386/fpu/s_log1p.S
Joseph Myers 0b7a5f9201 Fix log1p missing underflows (bug 16339).
Similar to various other bugs in this area, some log1p implementations
do not raise the underflow exception for subnormal arguments, when the
result is tiny and inexact.  This patch forces the exception in a
similar way to previous fixes.  (The ldbl-128ibm implementation
doesn't currently need any change as it already generates this
exception, albeit through code that would generate spurious exceptions
in other cases; special code for this issue will only be needed there
when fixing the spurious exceptions.)

Tested for x86_64, x86, powerpc and mips64.

	[BZ #16339]
	* sysdeps/i386/fpu/s_log1p.S (dbl_min): New object.
	(__log1p): Force underflow exception for results with small
	absolute value.
	* sysdeps/i386/fpu/s_log1pf.S (flt_min): New object.
	(__log1pf): Force underflow exception for results with small
	absolute value.
	* sysdeps/ieee754/dbl-64/s_log1p.c: Include <float.h>.
	(__log1p): Force underflow exception for results with small
	absolute value.
	* sysdeps/ieee754/flt-32/s_log1pf.c: Include <float.h>.
	(__log1pf): Force underflow exception for results with small
	absolute value.
	* sysdeps/ieee754/ldbl-128/s_log1pl.c: Include <float.h>.
	(__log1pl): Force underflow exception for results with small
	absolute value.
	* math/auto-libm-test-in: Do not allow missing underflow
	exceptions from log1p.
	* math/auto-libm-test-out: Regenerated.
2015-05-14 23:38:07 +00:00

91 lines
1.3 KiB
ArmAsm

/*
* Written by J.T. Conklin <jtc@netbsd.org>.
* Public domain.
*/
#include <machine/asm.h>
RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
.section .rodata
.align ALIGNARG(4)
/* The fyl2xp1 can only be used for values in
-1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
0.29 is a safe value.
*/
limit: .double 0.29
one: .double 1.0
.section .rodata.cst8,"aM",@progbits,8
.p2align 3
.type dbl_min,@object
dbl_min: .byte 0, 0, 0, 0, 0, 0, 0x10, 0
ASM_SIZE_DIRECTIVE(dbl_min)
/*
* Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
* otherwise fyl2x with the needed extra computation.
*/
.text
ENTRY(__log1p)
fldln2
fldl 4(%esp)
#ifdef PIC
LOAD_PIC_REG (dx)
#endif
fxam
fnstsw
fld %st
sahf
jc 3f // in case x is NaN or ±Inf
4: fabs
#ifdef PIC
fcompl limit@GOTOFF(%edx)
#else
fcompl limit
#endif
fnstsw
sahf
jc 2f
#ifdef PIC
faddl one@GOTOFF(%edx)
#else
faddl one
#endif
fyl2x
ret
2: fyl2xp1
#ifdef PIC
fldl dbl_min@GOTOFF(%edx)
#else
fldl dbl_min
#endif
fld %st(1)
fabs
fucompp
fnstsw
sahf
jnc 1f
subl $8, %esp
cfi_adjust_cfa_offset (8)
fld %st(0)
fmul %st(0)
fstpl (%esp)
addl $8, %esp
cfi_adjust_cfa_offset (-8)
1: ret
3: jp 4b // in case x is ±Inf
fstp %st(1)
fstp %st(1)
ret
END (__log1p)