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 * Adapted for x86-64 by Andreas Jaeger <aj@suse.de>. 8 */ 9 10#include <machine/asm.h> 11 12#ifdef __ELF__ 13 .section .rodata 14#else 15 .text 16#endif 17 .align ALIGNARG(4) 18 ASM_TYPE_DIRECTIVE(one,@object) 19one: .double 1.0 20 ASM_SIZE_DIRECTIVE(one) 21 /* It is not important that this constant is precise. It is only 22 a value which is known to be on the safe side for using the 23 fyl2xp1 instruction. */ 24 ASM_TYPE_DIRECTIVE(limit,@object) 25limit: .double 0.29 26 ASM_SIZE_DIRECTIVE(limit) 27 28 29#ifdef PIC 30#define MO(op) op##(%rip) 31#else 32#define MO(op) op 33#endif 34 35 .text 36ENTRY(__ieee754_log2l) 37 fldl MO(one) 38 fldt 8(%rsp) // x : 1 39 fxam 40 fnstsw 41 fld %st // x : x : 1 42 testb $1, %ah 43 jnz 3f // in case x is NaN or �Inf 444: fsub %st(2), %st // x-1 : x : 1 45 fld %st // x-1 : x-1 : x : 1 46 fabs // |x-1| : x-1 : x : 1 47 fcompl MO(limit) // x-1 : x : 1 48 fnstsw // x-1 : x : 1 49 andb $0x45, %ah 50 jz 2f 51 fstp %st(1) // x-1 : 1 52 fyl2xp1 // log(x) 53 ret 54 552: fstp %st(0) // x : 1 56 fyl2x // log(x) 57 ret 58 593: testb $4, %ah 60 jnz 4b // in case x is �Inf 61 fstp %st(1) 62 fstp %st(1) 63 ret 64END (__ieee754_log2l) 65