xref: /illumos-gate/usr/src/lib/libm/i386/src/log.S (revision 20a7641f9918de8574b8b3b47dbe35c4bfc78df1)
1/*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21/*
22 * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
23 */
24/*
25 * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
26 * Use is subject to license terms.
27 */
28
29	.file "log.s"
30
31#include "libm.h"
32LIBM_ANSI_PRAGMA_WEAK(log,function)
33#include "libm_protos.h"
34
35	ENTRY(log)
36	fldln2				/ loge(2)
37	movl	8(%esp),%eax		/ eax <-- hi_32(x)
38	testl	$0x80000000,%eax
39	jnz	.maybe_0_or_less
40	testl	$0x7fffffff,%eax
41	jz	.maybe_0
42	fldl	4(%esp)			/ arg, loge(2)
43	fyl2x				/ loge(2)*log2(arg); ln(arg)
44	ret
45
46.maybe_0:
47	movl	4(%esp),%ecx		/ ecx <-- lo_32(x)
48	cmpl	$0,%ecx
49	je	.zero			/ no branch if x is +denormal
50.neg_nan_reentry:
51	fldl	4(%esp)			/ arg, loge(2)
52	fyl2x				/ loge(2)*log2(arg); ln(arg)
53	ret
54
55.zero_or_less:
56	/ x =< 0
57	testl	$0x7fffffff,%eax
58	jnz	.less_than_0
59	movl	4(%esp),%ecx		/ ecx <-- lo_32(x)
60	cmpl	$0,%ecx
61	jne	.less_than_0		/ branch if x is -denormal
62.zero:
63	/ x = +/-0
64	pushl	%ebp
65	movl	%esp,%ebp
66	PIC_SETUP(1)
67	pushl	$16
68	jmp	.merge
69
70.maybe_0_or_less:
71	cmpl	$0xfff00000,%eax	/ -INF below hi_32(x)?
72	ja	.neg_nan_reentry
73	jb	.zero_or_less
74	movl	4(%esp),%ecx		/ ecx <-- lo_32(x)
75	cmpl	$0,%ecx			/ is x NaN or -INF?
76	jne	.neg_nan_reentry	/ branch if x is NaN with signbit = 1
77	/ x = -INF
78.less_than_0:
79	pushl	%ebp
80	movl	%esp,%ebp
81	PIC_SETUP(2)
82	pushl	$17
83.merge:
84	fstp	%st(0)			/ stack empty
85	pushl	12(%ebp)
86	pushl	8(%ebp)
87	pushl	12(%ebp)
88	pushl	8(%ebp)
89	call	PIC_F(_SVID_libm_err)
90	addl	$20,%esp
91	PIC_WRAPUP
92	leave
93	ret
94	.align	4
95	SET_SIZE(log)
96