xref: /illumos-gate/usr/src/lib/libm/i386/src/nextafter.S (revision 5d9d9091)
1*5d9d9091SRichard Lowe/*
2*5d9d9091SRichard Lowe * CDDL HEADER START
3*5d9d9091SRichard Lowe *
4*5d9d9091SRichard Lowe * The contents of this file are subject to the terms of the
5*5d9d9091SRichard Lowe * Common Development and Distribution License (the "License").
6*5d9d9091SRichard Lowe * You may not use this file except in compliance with the License.
7*5d9d9091SRichard Lowe *
8*5d9d9091SRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*5d9d9091SRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*5d9d9091SRichard Lowe * See the License for the specific language governing permissions
11*5d9d9091SRichard Lowe * and limitations under the License.
12*5d9d9091SRichard Lowe *
13*5d9d9091SRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*5d9d9091SRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*5d9d9091SRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*5d9d9091SRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*5d9d9091SRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*5d9d9091SRichard Lowe *
19*5d9d9091SRichard Lowe * CDDL HEADER END
20*5d9d9091SRichard Lowe */
21*5d9d9091SRichard Lowe/*
22*5d9d9091SRichard Lowe * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
23*5d9d9091SRichard Lowe */
24*5d9d9091SRichard Lowe/*
25*5d9d9091SRichard Lowe * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
26*5d9d9091SRichard Lowe * Use is subject to license terms.
27*5d9d9091SRichard Lowe */
28*5d9d9091SRichard Lowe
29*5d9d9091SRichard Lowe        .file "nextafter.s"
30*5d9d9091SRichard Lowe
31*5d9d9091SRichard Lowe#include "libm.h"
32*5d9d9091SRichard LoweLIBM_ANSI_PRAGMA_WEAK(nextafter,function)
33*5d9d9091SRichard Lowe	.weak _nextafter
34*5d9d9091SRichard Lowe	.type _nextafter,@function
35*5d9d9091SRichard Lowe_nextafter	= __nextafter
36*5d9d9091SRichard Lowe#include "libm_protos.h"
37*5d9d9091SRichard Lowe
38*5d9d9091SRichard Lowe	.data
39*5d9d9091SRichard Lowe	.align	8
40*5d9d9091SRichard LoweFmin:	.long	0x1,0x0
41*5d9d9091SRichard Loweftmp:	.long	0,0		/// WILL WRITE INTO
42*5d9d9091SRichard Lowe
43*5d9d9091SRichard Lowe
44*5d9d9091SRichard Lowe	ENTRY(nextafter)
45*5d9d9091SRichard Lowe	pushl	%ebp
46*5d9d9091SRichard Lowe	movl	%esp,%ebp
47*5d9d9091SRichard Lowe	fldl	16(%ebp)	/ y
48*5d9d9091SRichard Lowe	subl	$8,%esp
49*5d9d9091SRichard Lowe	fldl	8(%ebp)		/ load x
50*5d9d9091SRichard Lowe	fucom			/ x : y
51*5d9d9091SRichard Lowe	fstsw	%ax
52*5d9d9091SRichard Lowe	sahf
53*5d9d9091SRichard Lowe	jp	.NaN
54*5d9d9091SRichard Lowe	je	.equal
55*5d9d9091SRichard Lowe	fstp	%st(1)		/ x
56*5d9d9091SRichard Lowe	ja	.bigger
57*5d9d9091SRichard Lowe	/ x < y
58*5d9d9091SRichard Lowe	ftst
59*5d9d9091SRichard Lowe	movl	$1,%ecx		/// Fmin
60*5d9d9091SRichard Lowe	movl	%ecx,-8(%ebp)
61*5d9d9091SRichard Lowe	movl	$0,%ecx		/// Fmin+4
62*5d9d9091SRichard Lowe	movl	%ecx,-4(%ebp)
63*5d9d9091SRichard Lowe	fnstsw	%ax
64*5d9d9091SRichard Lowe	sahf
65*5d9d9091SRichard Lowe	je	.final
66*5d9d9091SRichard Lowe	ja	.addulp
67*5d9d9091SRichard Lowe	jb	.subulp
68*5d9d9091SRichard Lowe.bigger:
69*5d9d9091SRichard Lowe	/ x > y
70*5d9d9091SRichard Lowe	ftst
71*5d9d9091SRichard Lowe	movl	$1,%ecx		/// Fmin
72*5d9d9091SRichard Lowe	movl	%ecx,-8(%ebp)
73*5d9d9091SRichard Lowe	movl	$0,%ecx		/// Fmin+4
74*5d9d9091SRichard Lowe	xorl	$0x80000000,%ecx
75*5d9d9091SRichard Lowe	movl	%ecx,-4(%ebp)
76*5d9d9091SRichard Lowe	fnstsw	%ax
77*5d9d9091SRichard Lowe	sahf
78*5d9d9091SRichard Lowe	je	.final
79*5d9d9091SRichard Lowe	jb	.addulp
80*5d9d9091SRichard Lowe.subulp:
81*5d9d9091SRichard Lowe	movl	8(%ebp),%eax	/ low x
82*5d9d9091SRichard Lowe	movl	12(%ebp),%ecx	/ high x
83*5d9d9091SRichard Lowe	subl	$1,%eax		/ low x - ulp
84*5d9d9091SRichard Lowe	movl	%eax,-8(%ebp)
85*5d9d9091SRichard Lowe	sbbl	$0x0,%ecx
86*5d9d9091SRichard Lowe	movl	%ecx,-4(%ebp)
87*5d9d9091SRichard Lowe	jmp	.final
88*5d9d9091SRichard Lowe.addulp:
89*5d9d9091SRichard Lowe	movl	8(%ebp),%eax	/ low x
90*5d9d9091SRichard Lowe	movl	12(%ebp),%ecx	/ high x
91*5d9d9091SRichard Lowe	addl	$1,%eax		/ low x + ulp
92*5d9d9091SRichard Lowe	movl	%eax,-8(%ebp)
93*5d9d9091SRichard Lowe	adcl	$0x0,%ecx
94*5d9d9091SRichard Lowe	movl	%ecx,-4(%ebp)
95*5d9d9091SRichard Lowe
96*5d9d9091SRichard Lowe.final:
97*5d9d9091SRichard Lowe	fstp	%st(0)
98*5d9d9091SRichard Lowe	fldl	-8(%ebp)
99*5d9d9091SRichard Lowe	andl	$0x7ff00000,%ecx
100*5d9d9091SRichard Lowe	jz	.underflow
101*5d9d9091SRichard Lowe	cmpl	$0x7ff00000,%ecx
102*5d9d9091SRichard Lowe	je	.overflow
103*5d9d9091SRichard Lowe	jmp	.return
104*5d9d9091SRichard Lowe.overflow:
105*5d9d9091SRichard Lowe	PIC_SETUP(1)
106*5d9d9091SRichard Lowe	pushl	$46
107*5d9d9091SRichard Lowe	fstp	%st(0)		/ stack empty
108*5d9d9091SRichard Lowe	pushl	-4(%ebp)
109*5d9d9091SRichard Lowe	pushl	-8(%ebp)
110*5d9d9091SRichard Lowe	pushl	-4(%ebp)
111*5d9d9091SRichard Lowe	pushl	-8(%ebp)
112*5d9d9091SRichard Lowe	call	PIC_F(_SVID_libm_err)
113*5d9d9091SRichard Lowe	addl	$20,%esp
114*5d9d9091SRichard Lowe	PIC_WRAPUP
115*5d9d9091SRichard Lowe	jmp	.return
116*5d9d9091SRichard Lowe.underflow:
117*5d9d9091SRichard Lowe	PIC_SETUP(2)
118*5d9d9091SRichard Lowe	fldl	PIC_L(Fmin)
119*5d9d9091SRichard Lowe	fmul	%st(0),%st
120*5d9d9091SRichard Lowe	fstpl	PIC_L(ftmp)	/ create underflow signal
121*5d9d9091SRichard Lowe	PIC_WRAPUP
122*5d9d9091SRichard Lowe	jmp	.return
123*5d9d9091SRichard Lowe.equal:
124*5d9d9091SRichard Lowe	fstp	%st(0)		/ C99 says to return y when x == y
125*5d9d9091SRichard Lowe	jmp	.return
126*5d9d9091SRichard Lowe.NaN:
127*5d9d9091SRichard Lowe	faddp	%st,%st(1)	/ x+y,x
128*5d9d9091SRichard Lowe.return:
129*5d9d9091SRichard Lowe	fwait
130*5d9d9091SRichard Lowe	leave
131*5d9d9091SRichard Lowe	ret
132*5d9d9091SRichard Lowe	.align	4
133*5d9d9091SRichard Lowe	SET_SIZE(nextafter)
134