Fix log1p missing underflows (bug 16339).
[glibc.git] / sysdeps / i386 / fpu / s_log1p.S
blobc2559a3f1899f610287d77b12947110292af9f0d
1 /*
2  * Written by J.T. Conklin <jtc@netbsd.org>.
3  * Public domain.
4  */
6 #include <machine/asm.h>
8 RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
10         .section .rodata
12         .align ALIGNARG(4)
13         /* The fyl2xp1 can only be used for values in
14                 -1 + sqrt(2) / 2 <= x <= 1 - sqrt(2) / 2
15            0.29 is a safe value.
16         */
17 limit:  .double 0.29
18 one:    .double 1.0
20         .section .rodata.cst8,"aM",@progbits,8
22         .p2align 3
23         .type dbl_min,@object
24 dbl_min:        .byte 0, 0, 0, 0, 0, 0, 0x10, 0
25         ASM_SIZE_DIRECTIVE(dbl_min)
28  * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
29  * otherwise fyl2x with the needed extra computation.
30  */
31         .text
32 ENTRY(__log1p)
33         fldln2
35         fldl    4(%esp)
37 #ifdef  PIC
38         LOAD_PIC_REG (dx)
39 #endif
41         fxam
42         fnstsw
43         fld     %st
44         sahf
45         jc      3f              // in case x is NaN or ±Inf
46 4:      fabs
47 #ifdef PIC
48         fcompl  limit@GOTOFF(%edx)
49 #else
50         fcompl  limit
51 #endif
52         fnstsw
53         sahf
54         jc      2f
56 #ifdef PIC
57         faddl   one@GOTOFF(%edx)
58 #else
59         faddl   one
60 #endif
61         fyl2x
62         ret
64 2:      fyl2xp1
65 #ifdef PIC
66         fldl    dbl_min@GOTOFF(%edx)
67 #else
68         fldl    dbl_min
69 #endif
70         fld     %st(1)
71         fabs
72         fucompp
73         fnstsw
74         sahf
75         jnc     1f
76         subl    $8, %esp
77         cfi_adjust_cfa_offset (8)
78         fld     %st(0)
79         fmul    %st(0)
80         fstpl   (%esp)
81         addl    $8, %esp
82         cfi_adjust_cfa_offset (-8)
83 1:      ret
85 3:      jp      4b              // in case x is ±Inf
86         fstp    %st(1)
87         fstp    %st(1)
88         ret
90 END (__log1p)