5261 libm should stop using synonyms.h
5298 fabs is 0-sized, confuses dis(1) and others
Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
Approved by: Gordon Ross <gwr@nexenta.com>
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 "nexttowardl.s"
30
31 #include "libm.h"
32 LIBM_ANSI_PRAGMA_WEAK(nexttowardl,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(nexttowardl)
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(nexttowardl)
--- EOF ---