xref: /titanic_53/usr/src/lib/libm/i386/src/nexttowardl.s (revision ddc0e0b53c661f6e439e3b7072b3ef353eadb4af)
1*25c28e83SPiotr Jasiukajtis/*
2*25c28e83SPiotr Jasiukajtis * CDDL HEADER START
3*25c28e83SPiotr Jasiukajtis *
4*25c28e83SPiotr Jasiukajtis * The contents of this file are subject to the terms of the
5*25c28e83SPiotr Jasiukajtis * Common Development and Distribution License (the "License").
6*25c28e83SPiotr Jasiukajtis * You may not use this file except in compliance with the License.
7*25c28e83SPiotr Jasiukajtis *
8*25c28e83SPiotr Jasiukajtis * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*25c28e83SPiotr Jasiukajtis * or http://www.opensolaris.org/os/licensing.
10*25c28e83SPiotr Jasiukajtis * See the License for the specific language governing permissions
11*25c28e83SPiotr Jasiukajtis * and limitations under the License.
12*25c28e83SPiotr Jasiukajtis *
13*25c28e83SPiotr Jasiukajtis * When distributing Covered Code, include this CDDL HEADER in each
14*25c28e83SPiotr Jasiukajtis * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*25c28e83SPiotr Jasiukajtis * If applicable, add the following below this CDDL HEADER, with the
16*25c28e83SPiotr Jasiukajtis * fields enclosed by brackets "[]" replaced with your own identifying
17*25c28e83SPiotr Jasiukajtis * information: Portions Copyright [yyyy] [name of copyright owner]
18*25c28e83SPiotr Jasiukajtis *
19*25c28e83SPiotr Jasiukajtis * CDDL HEADER END
20*25c28e83SPiotr Jasiukajtis */
21*25c28e83SPiotr Jasiukajtis/*
22*25c28e83SPiotr Jasiukajtis * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
23*25c28e83SPiotr Jasiukajtis */
24*25c28e83SPiotr Jasiukajtis/*
25*25c28e83SPiotr Jasiukajtis * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
26*25c28e83SPiotr Jasiukajtis * Use is subject to license terms.
27*25c28e83SPiotr Jasiukajtis */
28*25c28e83SPiotr Jasiukajtis
29*25c28e83SPiotr Jasiukajtis	.file	"nexttowardl.s"
30*25c28e83SPiotr Jasiukajtis
31*25c28e83SPiotr Jasiukajtis#include "libm.h"
32*25c28e83SPiotr JasiukajtisLIBM_ANSI_PRAGMA_WEAK(nexttowardl,function)
33*25c28e83SPiotr Jasiukajtis
34*25c28e83SPiotr Jasiukajtis	.section .rodata
35*25c28e83SPiotr Jasiukajtis	.align	4
36*25c28e83SPiotr Jasiukajtis.LFmaxl:	.long	0xffffffff,0xffffffff,0x00007ffe
37*25c28e83SPiotr Jasiukajtis.LFminl:	.long	0x1,0x0,0x0
38*25c28e83SPiotr Jasiukajtis
39*25c28e83SPiotr Jasiukajtis
40*25c28e83SPiotr Jasiukajtis	ENTRY(nexttowardl)
41*25c28e83SPiotr Jasiukajtis	pushl	%ebp
42*25c28e83SPiotr Jasiukajtis	movl	%esp,%ebp
43*25c28e83SPiotr Jasiukajtis	fldt	20(%ebp)	/ y
44*25c28e83SPiotr Jasiukajtis	subl	$12,%esp
45*25c28e83SPiotr Jasiukajtis	fldt	8(%ebp)		/ load x
46*25c28e83SPiotr Jasiukajtis	fucom			/ x : y
47*25c28e83SPiotr Jasiukajtis	fstsw	%ax
48*25c28e83SPiotr Jasiukajtis	sahf
49*25c28e83SPiotr Jasiukajtis	jp	.LNaN
50*25c28e83SPiotr Jasiukajtis	je	.Lequal
51*25c28e83SPiotr Jasiukajtis	fstp	%st(1)		/ x
52*25c28e83SPiotr Jasiukajtis	ja	.Lbigger
53*25c28e83SPiotr Jasiukajtis	/ x < y
54*25c28e83SPiotr Jasiukajtis	ftst
55*25c28e83SPiotr Jasiukajtis	movl	$1,-12(%ebp)	/// -12(%ebp) contains Fminl
56*25c28e83SPiotr Jasiukajtis	movl	$0,-8(%ebp)
57*25c28e83SPiotr Jasiukajtis	movl	$0,%ecx			/// final needs this
58*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
59*25c28e83SPiotr Jasiukajtis	fnstsw	%ax
60*25c28e83SPiotr Jasiukajtis	sahf
61*25c28e83SPiotr Jasiukajtis	je	.Lfinal
62*25c28e83SPiotr Jasiukajtis	ja	.Laddulp
63*25c28e83SPiotr Jasiukajtis	jb	.Lsubulp
64*25c28e83SPiotr Jasiukajtis.Lbigger:
65*25c28e83SPiotr Jasiukajtis	/ x > y
66*25c28e83SPiotr Jasiukajtis	ftst
67*25c28e83SPiotr Jasiukajtis	movl	$1,-12(%ebp)	/// -12(%ebp) contains -Fminl
68*25c28e83SPiotr Jasiukajtis	movl	$0,-8(%ebp)
69*25c28e83SPiotr Jasiukajtis	movl	$0x00008000,%ecx	/// final needs this
70*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
71*25c28e83SPiotr Jasiukajtis	fnstsw	%ax
72*25c28e83SPiotr Jasiukajtis	sahf
73*25c28e83SPiotr Jasiukajtis	je	.Lfinal
74*25c28e83SPiotr Jasiukajtis	jb	.Laddulp
75*25c28e83SPiotr Jasiukajtis.Lsubulp:
76*25c28e83SPiotr Jasiukajtis	movl	12(%ebp),%edx	/ high word of significand of x
77*25c28e83SPiotr Jasiukajtis	movl	16(%ebp),%ecx	/ x's exponent
78*25c28e83SPiotr Jasiukajtis	andl	$0x0000ffff,%ecx
79*25c28e83SPiotr Jasiukajtis	movl	%edx,%eax
80*25c28e83SPiotr Jasiukajtis	not	%eax
81*25c28e83SPiotr Jasiukajtis	andl	$0x80000000,%eax	/ look at explicit leading bit
82*25c28e83SPiotr Jasiukajtis	orl	%ecx,%eax
83*25c28e83SPiotr Jasiukajtis	andl	$0x80007fff,%eax
84*25c28e83SPiotr Jasiukajtis	jnz	.Lnot_pseudonormal	/ zero value implies pseudonormal
85*25c28e83SPiotr Jasiukajtis	addl	$1,%ecx		/ if pseudonormal, turn into equivalent normal
86*25c28e83SPiotr Jasiukajtis.Lnot_pseudonormal:
87*25c28e83SPiotr Jasiukajtis	movl	8(%ebp),%eax	/ low x
88*25c28e83SPiotr Jasiukajtis	subl	$1,%eax		/ low x - ulp
89*25c28e83SPiotr Jasiukajtis	movl	%eax,-12(%ebp)
90*25c28e83SPiotr Jasiukajtis	cmpl	$0xffffffff,%eax	/ this means low x was 0
91*25c28e83SPiotr Jasiukajtis	jz	.Lborrow
92*25c28e83SPiotr Jasiukajtis	movl	%edx,-8(%ebp)
93*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
94*25c28e83SPiotr Jasiukajtis	jmp	.Lfinal
95*25c28e83SPiotr Jasiukajtis.Lborrow:
96*25c28e83SPiotr Jasiukajtis	cmpl	$0x80000000,%edx	/ look at high x
97*25c28e83SPiotr Jasiukajtis	je	.Lsecond_borrow
98*25c28e83SPiotr Jasiukajtis	subl	$1,%edx
99*25c28e83SPiotr Jasiukajtis	movl	%edx,-8(%ebp)
100*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
101*25c28e83SPiotr Jasiukajtis	jmp	.Lfinal
102*25c28e83SPiotr Jasiukajtis.Lsecond_borrow:
103*25c28e83SPiotr Jasiukajtis	movl	%ecx,%eax
104*25c28e83SPiotr Jasiukajtis	andl	$0x7fff,%eax	/ look at exp x without sign bit
105*25c28e83SPiotr Jasiukajtis	cmpl	$1,%eax
106*25c28e83SPiotr Jasiukajtis	jbe	.Lsubnormal_result	/ exp > 1 ==> result will be normal
107*25c28e83SPiotr Jasiukajtis	movl	$0xffffffff,-8(%ebp)
108*25c28e83SPiotr Jasiukajtis	subl	$1,%ecx
109*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
110*25c28e83SPiotr Jasiukajtis	jmp	.Lfinal
111*25c28e83SPiotr Jasiukajtis.Lsubnormal_result:
112*25c28e83SPiotr Jasiukajtis	movl	$0x7fffffff,-8(%ebp)
113*25c28e83SPiotr Jasiukajtis	movl	%ecx,%eax
114*25c28e83SPiotr Jasiukajtis	andl	$0x8000,%eax	/ look at sign bit
115*25c28e83SPiotr Jasiukajtis	jz	.Lpositive
116*25c28e83SPiotr Jasiukajtis	movl	$0x8000,%ecx
117*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
118*25c28e83SPiotr Jasiukajtis	jmp	.Lfinal
119*25c28e83SPiotr Jasiukajtis.Lpositive:
120*25c28e83SPiotr Jasiukajtis	movl	$0,%ecx
121*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
122*25c28e83SPiotr Jasiukajtis	jmp	.Lfinal
123*25c28e83SPiotr Jasiukajtis.Laddulp:
124*25c28e83SPiotr Jasiukajtis	movl	12(%ebp),%edx	/ high x
125*25c28e83SPiotr Jasiukajtis	movl	16(%ebp),%ecx	/ x's exponent
126*25c28e83SPiotr Jasiukajtis	andl	$0x0000ffff,%ecx
127*25c28e83SPiotr Jasiukajtis	movl	%edx,%eax
128*25c28e83SPiotr Jasiukajtis	not	%eax
129*25c28e83SPiotr Jasiukajtis	andl	$0x80000000,%eax	/ look at explicit leading bit
130*25c28e83SPiotr Jasiukajtis	orl	%ecx,%eax
131*25c28e83SPiotr Jasiukajtis	andl	$0x80007fff,%eax
132*25c28e83SPiotr Jasiukajtis	jnz	.Lnot_pseudonormal_2	/ zero value implies pseudonormal
133*25c28e83SPiotr Jasiukajtis	addl	$1,%ecx
134*25c28e83SPiotr Jasiukajtis.Lnot_pseudonormal_2:
135*25c28e83SPiotr Jasiukajtis	movl	8(%ebp),%eax	/ low x
136*25c28e83SPiotr Jasiukajtis	addl	$1,%eax		/ low x + ulp
137*25c28e83SPiotr Jasiukajtis	movl	%eax,-12(%ebp)
138*25c28e83SPiotr Jasiukajtis	jz	.Lcarry		/ jump if the content of %eax is 0
139*25c28e83SPiotr Jasiukajtis	movl	%edx,-8(%ebp)
140*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
141*25c28e83SPiotr Jasiukajtis	jmp .Lfinal
142*25c28e83SPiotr Jasiukajtis.Lcarry:
143*25c28e83SPiotr Jasiukajtis	movl	%edx,%eax
144*25c28e83SPiotr Jasiukajtis	andl	$0x7fffffff,%eax
145*25c28e83SPiotr Jasiukajtis	cmpl	$0x7fffffff,%eax	/ look at high x
146*25c28e83SPiotr Jasiukajtis	je	.Lsecond_carry
147*25c28e83SPiotr Jasiukajtis	addl	$1,%edx
148*25c28e83SPiotr Jasiukajtis	movl	%edx,-8(%ebp)
149*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
150*25c28e83SPiotr Jasiukajtis	jmp	.Lfinal
151*25c28e83SPiotr Jasiukajtis.Lsecond_carry:
152*25c28e83SPiotr Jasiukajtis	movl	$0x80000000,-8(%ebp)
153*25c28e83SPiotr Jasiukajtis	addl	$1,%ecx
154*25c28e83SPiotr Jasiukajtis	movl	%ecx,-4(%ebp)
155*25c28e83SPiotr Jasiukajtis.Lfinal:
156*25c28e83SPiotr Jasiukajtis	fstp	%st(0)
157*25c28e83SPiotr Jasiukajtis	fldt	-12(%ebp)
158*25c28e83SPiotr Jasiukajtis	andl	$0x00007fff,%ecx
159*25c28e83SPiotr Jasiukajtis	jz	.Lunderflow
160*25c28e83SPiotr Jasiukajtis	cmpw	$0x7fff,%cx
161*25c28e83SPiotr Jasiukajtis	je	.Loverflow
162*25c28e83SPiotr Jasiukajtis	jmp	.Lreturn
163*25c28e83SPiotr Jasiukajtis.Loverflow:
164*25c28e83SPiotr Jasiukajtis	PIC_SETUP(1)
165*25c28e83SPiotr Jasiukajtis	fldt	PIC_L(.LFmaxl)
166*25c28e83SPiotr Jasiukajtis	PIC_WRAPUP
167*25c28e83SPiotr Jasiukajtis	fmulp	%st,%st(0)	/ create overflow signal
168*25c28e83SPiotr Jasiukajtis	jmp	.Lreturn
169*25c28e83SPiotr Jasiukajtis.Lunderflow:
170*25c28e83SPiotr Jasiukajtis	PIC_SETUP(2)
171*25c28e83SPiotr Jasiukajtis	fldt	PIC_L(.LFminl)
172*25c28e83SPiotr Jasiukajtis	PIC_WRAPUP
173*25c28e83SPiotr Jasiukajtis	fmulp	%st,%st(0)	/ create underflow signal
174*25c28e83SPiotr Jasiukajtis	jmp	.Lreturn
175*25c28e83SPiotr Jasiukajtis.Lequal:
176*25c28e83SPiotr Jasiukajtis	fstp	%st(0)		/ C99 says to return y when x == y
177*25c28e83SPiotr Jasiukajtis	jmp	.Lreturn
178*25c28e83SPiotr Jasiukajtis.LNaN:
179*25c28e83SPiotr Jasiukajtis	faddp	%st,%st(1)	/ x+y,x
180*25c28e83SPiotr Jasiukajtis.Lreturn:
181*25c28e83SPiotr Jasiukajtis	fwait
182*25c28e83SPiotr Jasiukajtis	leave
183*25c28e83SPiotr Jasiukajtis	ret
184*25c28e83SPiotr Jasiukajtis	.align	4
185*25c28e83SPiotr Jasiukajtis	SET_SIZE(nexttowardl)
186