xref: /titanic_44/usr/src/lib/libm/i386/src/nextafter.s (revision 6d89ca534e2138511ecb76c02bcec1bcb83f685b)
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 "nextafter.s"
30
31#include "libm.h"
32LIBM_ANSI_PRAGMA_WEAK(nextafter,function)
33	.weak _nextafter
34	.type _nextafter,@function
35_nextafter	= __nextafter
36#include "libm_synonyms.h"
37#include "libm_protos.h"
38
39	.data
40	.align	8
41Fmin:	.long	0x1,0x0
42ftmp:	.long	0,0		/// WILL WRITE INTO
43
44
45	ENTRY(nextafter)
46	pushl	%ebp
47	movl	%esp,%ebp
48	fldl	16(%ebp)	/ y
49	subl	$8,%esp
50	fldl	8(%ebp)		/ load x
51	fucom			/ x : y
52	fstsw	%ax
53	sahf
54	jp	.NaN
55	je	.equal
56	fstp	%st(1)		/ x
57	ja	.bigger
58	/ x < y
59	ftst
60	movl	$1,%ecx		/// Fmin
61	movl	%ecx,-8(%ebp)
62	movl	$0,%ecx		/// Fmin+4
63	movl	%ecx,-4(%ebp)
64	fnstsw	%ax
65	sahf
66	je	.final
67	ja	.addulp
68	jb	.subulp
69.bigger:
70	/ x > y
71	ftst
72	movl	$1,%ecx		/// Fmin
73	movl	%ecx,-8(%ebp)
74	movl	$0,%ecx		/// Fmin+4
75	xorl	$0x80000000,%ecx
76	movl	%ecx,-4(%ebp)
77	fnstsw	%ax
78	sahf
79	je	.final
80	jb	.addulp
81.subulp:
82	movl	8(%ebp),%eax	/ low x
83	movl	12(%ebp),%ecx	/ high x
84	subl	$1,%eax		/ low x - ulp
85	movl	%eax,-8(%ebp)
86	sbbl	$0x0,%ecx
87	movl	%ecx,-4(%ebp)
88	jmp	.final
89.addulp:
90	movl	8(%ebp),%eax	/ low x
91	movl	12(%ebp),%ecx	/ high x
92	addl	$1,%eax		/ low x + ulp
93	movl	%eax,-8(%ebp)
94	adcl	$0x0,%ecx
95	movl	%ecx,-4(%ebp)
96
97.final:
98	fstp	%st(0)
99	fldl	-8(%ebp)
100	andl	$0x7ff00000,%ecx
101	jz	.underflow
102	cmpl	$0x7ff00000,%ecx
103	je	.overflow
104	jmp	.return
105.overflow:
106	PIC_SETUP(1)
107	pushl	$46
108	fstp	%st(0)		/ stack empty
109	pushl	-4(%ebp)
110	pushl	-8(%ebp)
111	pushl	-4(%ebp)
112	pushl	-8(%ebp)
113	call	PIC_F(_SVID_libm_err)
114	addl	$20,%esp
115	PIC_WRAPUP
116	jmp	.return
117.underflow:
118	PIC_SETUP(2)
119	fldl	PIC_L(Fmin)
120	fmul	%st(0),%st
121	fstpl	PIC_L(ftmp)	/ create underflow signal
122	PIC_WRAPUP
123	jmp	.return
124.equal:
125	fstp	%st(0)		/ C99 says to return y when x == y
126	jmp	.return
127.NaN:
128	faddp	%st,%st(1)	/ x+y,x
129.return:
130	fwait
131	leave
132	ret
133	.align	4
134	SET_SIZE(nextafter)
135