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