1/*
2 * Public domain.
3 *
4 */
5
6#include <machine/asm.h>
7
8RCSID("$NetBSD: s_log1p.S,v 1.7 1995/05/09 00:10:58 jtc Exp $")
9
10 .section .rodata
11
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 */
17limit: .tfloat 0.29
18 /* Please note: we use a double value here. Since 1.0 has
19 an exact representation this does not effect the accuracy
20 but it helps to optimize the code. */
21one: .double 1.0
22
23/*
24 * Use the fyl2xp1 function when the argument is in the range -0.29 to 0.29,
25 * otherwise fyl2x with the needed extra computation.
26 */
27#ifdef PIC
28#define MO(op) op##(%rip)
29#else
30#define MO(op) op
31#endif
32
33 .text
34ENTRY(__log1pl)
35 fldln2
36
37 fldt 8(%rsp)
38
39 fxam
40 fnstsw
41 fld %st
42 testb $1, %ah
43 jnz 3f // in case x is NaN or ħInf
444:
45 fabs
46 fldt MO(limit)
47 fcompp
48 fnstsw
49 andb $1,%ah
50 jz 2f
51
52 movzwl 8+8(%rsp), %eax
53 xorb $0x80, %ah
54 cmpl $0xc040, %eax
55 jae 5f
56
57 faddl MO(one)
585: fyl2x
59 ret
60
612: fyl2xp1
62 ret
63
643: testb $4, %ah
65 jnz 4b // in case x is ħInf
66 fstp %st(1)
67 fstp %st(1)
68 fadd %st(0)
69 ret
70
71END (__log1pl)
72

source code of glibc/sysdeps/x86_64/fpu/s_log1pl.S