xref: /titanic_41/usr/src/lib/libm/i386/src/nextafterl.s (revision 3ecb07e488de89fd5a51a630f598c1e8f7542ff7)
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	"nextafterl.s"
30
31#include "libm.h"
32LIBM_ANSI_PRAGMA_WEAK(nextafterl,function)
33#include "libm_synonyms.h"
34
35	.section .rodata
36	.align	4
37.LFmaxl:	.long	0xffffffff,0xffffffff,0x00007ffe
38.LFminl:	.long	0x1,0x0,0x0
39
40
41	ENTRY(nextafterl)
42	pushl	%ebp
43	movl	%esp,%ebp
44	fldt	20(%ebp)	/ y
45	subl	$12,%esp
46	fldt	8(%ebp)		/ load x
47	fucom			/ x : y
48	fstsw	%ax
49	sahf
50	jp	.LNaN
51	je	.Lequal
52	fstp	%st(1)		/ x
53	ja	.Lbigger
54	/ x < y
55	ftst
56	movl	$1,-12(%ebp)	/// -12(%ebp) contains Fminl
57	movl	$0,-8(%ebp)
58	movl	$0,%ecx			/// final needs this
59	movl	%ecx,-4(%ebp)
60	fnstsw	%ax
61	sahf
62	je	.Lfinal
63	ja	.Laddulp
64	jb	.Lsubulp
65.Lbigger:
66	/ x > y
67	ftst
68	movl	$1,-12(%ebp)	/// -12(%ebp) contains -Fminl
69	movl	$0,-8(%ebp)
70	movl	$0x00008000,%ecx	/// final needs this
71	movl	%ecx,-4(%ebp)
72	fnstsw	%ax
73	sahf
74	je	.Lfinal
75	jb	.Laddulp
76.Lsubulp:
77	movl	12(%ebp),%edx	/ high word of significand of x
78	movl	16(%ebp),%ecx	/ x's exponent
79	andl	$0x0000ffff,%ecx
80	movl	%edx,%eax
81	not	%eax
82	andl	$0x80000000,%eax	/ look at explicit leading bit
83	orl	%ecx,%eax
84	andl	$0x80007fff,%eax
85	jnz	.Lnot_pseudonormal	/ zero value implies pseudonormal
86	addl	$1,%ecx		/ if pseudonormal, turn into equivalent normal
87.Lnot_pseudonormal:
88	movl	8(%ebp),%eax	/ low x
89	subl	$1,%eax		/ low x - ulp
90	movl	%eax,-12(%ebp)
91	cmpl	$0xffffffff,%eax	/ this means low x was 0
92	jz	.Lborrow
93	movl	%edx,-8(%ebp)
94	movl	%ecx,-4(%ebp)
95	jmp	.Lfinal
96.Lborrow:
97	cmpl	$0x80000000,%edx	/ look at high x
98	je	.Lsecond_borrow
99	subl	$1,%edx
100	movl	%edx,-8(%ebp)
101	movl	%ecx,-4(%ebp)
102	jmp	.Lfinal
103.Lsecond_borrow:
104	movl	%ecx,%eax
105	andl	$0x7fff,%eax	/ look at exp x without sign bit
106	cmpl	$1,%eax
107	jbe	.Lsubnormal_result	/ exp > 1 ==> result will be normal
108	movl	$0xffffffff,-8(%ebp)
109	subl	$1,%ecx
110	movl	%ecx,-4(%ebp)
111	jmp	.Lfinal
112.Lsubnormal_result:
113	movl	$0x7fffffff,-8(%ebp)
114	movl	%ecx,%eax
115	andl	$0x8000,%eax	/ look at sign bit
116	jz	.Lpositive
117	movl	$0x8000,%ecx
118	movl	%ecx,-4(%ebp)
119	jmp	.Lfinal
120.Lpositive:
121	movl	$0,%ecx
122	movl	%ecx,-4(%ebp)
123	jmp	.Lfinal
124.Laddulp:
125	movl	12(%ebp),%edx	/ high x
126	movl	16(%ebp),%ecx	/ x's exponent
127	andl	$0x0000ffff,%ecx
128	movl	%edx,%eax
129	not	%eax
130	andl	$0x80000000,%eax	/ look at explicit leading bit
131	orl	%ecx,%eax
132	andl	$0x80007fff,%eax
133	jnz	.Lnot_pseudonormal_2	/ zero value implies pseudonormal
134	addl	$1,%ecx
135.Lnot_pseudonormal_2:
136	movl	8(%ebp),%eax	/ low x
137	addl	$1,%eax		/ low x + ulp
138	movl	%eax,-12(%ebp)
139	jz	.Lcarry		/ jump if the content of %eax is 0
140	movl	%edx,-8(%ebp)
141	movl	%ecx,-4(%ebp)
142	jmp .Lfinal
143.Lcarry:
144	movl	%edx,%eax
145	andl	$0x7fffffff,%eax
146	cmpl	$0x7fffffff,%eax	/ look at high x
147	je	.Lsecond_carry
148	addl	$1,%edx
149	movl	%edx,-8(%ebp)
150	movl	%ecx,-4(%ebp)
151	jmp	.Lfinal
152.Lsecond_carry:
153	movl	$0x80000000,-8(%ebp)
154	addl	$1,%ecx
155	movl	%ecx,-4(%ebp)
156.Lfinal:
157	fstp	%st(0)
158	fldt	-12(%ebp)
159	andl	$0x00007fff,%ecx
160	jz	.Lunderflow
161	cmpw	$0x7fff,%cx
162	je	.Loverflow
163	jmp	.Lreturn
164.Loverflow:
165	PIC_SETUP(1)
166	fldt	PIC_L(.LFmaxl)
167	PIC_WRAPUP
168	fmulp	%st,%st(0)	/ create overflow signal
169	jmp	.Lreturn
170.Lunderflow:
171	PIC_SETUP(2)
172	fldt	PIC_L(.LFminl)
173	PIC_WRAPUP
174	fmulp	%st,%st(0)	/ create underflow signal
175	jmp	.Lreturn
176.Lequal:
177	fstp	%st(0)		/ C99 says to return y when x == y
178	jmp	.Lreturn
179.LNaN:
180	faddp	%st,%st(1)	/ x+y,x
181.Lreturn:
182	fwait
183	leave
184	ret
185	.align	4
186	SET_SIZE(nextafterl)
187