]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/i386/fpu/e_log2l.S
Fix log2 (1) in round-downward mode (bug 17042).
[thirdparty/glibc.git] / sysdeps / i386 / fpu / e_log2l.S
1 /*
2 * Written by J.T. Conklin <jtc@netbsd.org>.
3 * Adapted for use as log2 by Ulrich Drepper <drepper@cygnus.com>.
4 * Public domain.
5 *
6 * Changed to use fyl2xp1 for values near 1, <drepper@cygnus.com>.
7 */
8
9 #include <machine/asm.h>
10
11 .section .rodata.cst8,"aM",@progbits,8
12
13 .p2align 3
14 .type one,@object
15 one: .double 1.0
16 ASM_SIZE_DIRECTIVE(one)
17 /* It is not important that this constant is precise. It is only
18 a value which is known to be on the safe side for using the
19 fyl2xp1 instruction. */
20 .type limit,@object
21 limit: .double 0.29
22 ASM_SIZE_DIRECTIVE(limit)
23
24
25 #ifdef PIC
26 # define MO(op) op##@GOTOFF(%edx)
27 #else
28 # define MO(op) op
29 #endif
30
31 .text
32 ENTRY(__ieee754_log2l)
33 #ifdef PIC
34 LOAD_PIC_REG (dx)
35 #endif
36 fldl MO(one)
37 fldt 4(%esp) // x : 1
38 fxam
39 fnstsw
40 fld %st // x : x : 1
41 sahf
42 jc 3f // in case x is NaN or ±Inf
43 4: fsub %st(2), %st // x-1 : x : 1
44 fld %st // x-1 : x-1 : x : 1
45 fabs // |x-1| : x-1 : x : 1
46 fcompl MO(limit) // x-1 : x : 1
47 fnstsw // x-1 : x : 1
48 andb $0x45, %ah
49 jz 2f
50 fxam
51 fnstsw
52 andb $0x45, %ah
53 cmpb $0x40, %ah
54 jne 5f
55 fabs // log2(1) is +0 in all rounding modes.
56 5: fstp %st(1) // x-1 : 1
57 fyl2xp1 // log(x)
58 ret
59
60 2: fstp %st(0) // x : 1
61 fyl2x // log(x)
62 ret
63
64 3: jp 4b // in case x is ±Inf
65 fstp %st(1)
66 fstp %st(1)
67 ret
68 END (__ieee754_log2l)
69 strong_alias (__ieee754_log2l, __log2l_finite)