import less(1)
[unleashed/tickless.git] / usr / src / lib / libc / i386 / gen / _divdi3.s
blob608e8791b4812313aacdb0419a514a3bb526b6b3
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 .file "_divdi3.s"
29 #include <SYS.h>
32 * C support for 64-bit modulo and division.
33 * GNU routines callable from C (though generated by the compiler).
34 * Hand-customized compiler output - see comments for details.
39 * __udivdi3
41 * Perform division of two unsigned 64-bit quantities, returning the
42 * quotient in %edx:%eax.
44 ENTRY(__udivdi3)
45 movl 4(%esp), %eax / x, x
46 movl 8(%esp), %edx / x, x
47 pushl 16(%esp) / y
48 pushl 16(%esp)
49 call UDiv
50 addl $8, %esp
51 ret
52 SET_SIZE(__udivdi3)
55 * __umoddi3
57 * Perform division of two unsigned 64-bit quantities, returning the
58 * remainder in %edx:%eax.
60 ENTRY(__umoddi3)
61 subl $12, %esp
62 movl %esp, %ecx /, tmp65
63 movl 16(%esp), %eax / x, x
64 movl 20(%esp), %edx / x, x
65 pushl %ecx / tmp65
66 pushl 32(%esp) / y
67 pushl 32(%esp)
68 call UDivRem
69 movl 12(%esp), %eax / rem, rem
70 movl 16(%esp), %edx / rem, rem
71 addl $24, %esp
72 ret
73 SET_SIZE(__umoddi3)
76 * __divdi3
78 * Perform division of two signed 64-bit quantities, returning the
79 * quotient in %edx:%eax.
81 / int64_t
82 / __divdi3(int64_t x, int64_t y)
83 / {
84 / int negative;
85 / uint64_t xt, yt, r;
87 / if (x < 0) {
88 / xt = -(uint64_t) x;
89 / negative = 1;
90 / } else {
91 / xt = x;
92 / negative = 0;
93 / }
94 / if (y < 0) {
95 / yt = -(uint64_t) y;
96 / negative ^= 1;
97 / } else {
98 / yt = y;
99 / }
100 / r = UDiv(xt, yt);
101 / return (negative ? (int64_t) - r : r);
103 ENTRY(__divdi3)
104 pushl %ebp
105 pushl %edi
106 pushl %esi
107 subl $8, %esp
108 movl 28(%esp), %edx / x, x
109 testl %edx, %edx / x
110 movl 24(%esp), %eax / x, x
111 movl 32(%esp), %esi / y, y
112 movl 36(%esp), %edi / y, y
113 js .LL55
114 xorl %ebp, %ebp / negative
115 testl %edi, %edi / y
116 movl %eax, (%esp) / x, xt
117 movl %edx, 4(%esp) / x, xt
118 movl %esi, %eax / y, yt
119 movl %edi, %edx / y, yt
120 js .LL56
121 .LL53:
122 pushl %edx / yt
123 pushl %eax / yt
124 movl 8(%esp), %eax / xt, xt
125 movl 12(%esp), %edx / xt, xt
126 call UDiv
127 popl %ecx
128 testl %ebp, %ebp / negative
129 popl %esi
130 je .LL54
131 negl %eax / r
132 adcl $0, %edx /, r
133 negl %edx / r
134 .LL54:
135 addl $8, %esp
136 popl %esi
137 popl %edi
138 popl %ebp
140 .align 16
141 .LL55:
142 negl %eax / x
143 adcl $0, %edx /, x
144 negl %edx / x
145 testl %edi, %edi / y
146 movl %eax, (%esp) / x, xt
147 movl %edx, 4(%esp) / x, xt
148 movl $1, %ebp /, negative
149 movl %esi, %eax / y, yt
150 movl %edi, %edx / y, yt
151 jns .LL53
152 .align 16
153 .LL56:
154 negl %eax / yt
155 adcl $0, %edx /, yt
156 negl %edx / yt
157 xorl $1, %ebp /, negative
158 jmp .LL53
159 SET_SIZE(__divdi3)
162 * __moddi3
164 * Perform division of two signed 64-bit quantities, returning the
165 * quotient in %edx:%eax.
167 / int64_t
168 / __moddi3(int64_t x, int64_t y)
170 / uint64_t xt, yt, rem;
172 / if (x < 0) {
173 / xt = -(uint64_t) x;
174 / } else {
175 / xt = x;
177 / if (y < 0) {
178 / yt = -(uint64_t) y;
179 / } else {
180 / yt = y;
182 / (void) UDivRem(xt, yt, &rem);
183 / return (x < 0 ? (int64_t) - rem : rem);
185 ENTRY(__moddi3)
186 pushl %edi
187 pushl %esi
188 subl $20, %esp
189 movl 36(%esp), %ecx / x,
190 movl 32(%esp), %esi / x,
191 movl 36(%esp), %edi / x,
192 testl %ecx, %ecx
193 movl 40(%esp), %eax / y, y
194 movl 44(%esp), %edx / y, y
195 movl %esi, (%esp) /, xt
196 movl %edi, 4(%esp) /, xt
197 js .LL63
198 testl %edx, %edx / y
199 movl %eax, %esi / y, yt
200 movl %edx, %edi / y, yt
201 js .LL64
202 .LL61:
203 leal 8(%esp), %eax /, tmp66
204 pushl %eax / tmp66
205 pushl %edi / yt
206 pushl %esi / yt
207 movl 12(%esp), %eax / xt, xt
208 movl 16(%esp), %edx / xt, xt
209 call UDivRem
210 addl $12, %esp
211 movl 36(%esp), %edi / x,
212 testl %edi, %edi
213 movl 8(%esp), %eax / rem, rem
214 movl 12(%esp), %edx / rem, rem
215 js .LL65
216 addl $20, %esp
217 popl %esi
218 popl %edi
220 .align 16
221 .LL63:
222 negl %esi
223 adcl $0, %edi
224 negl %edi
225 testl %edx, %edx / y
226 movl %esi, (%esp) /, xt
227 movl %edi, 4(%esp) /, xt
228 movl %eax, %esi / y, yt
229 movl %edx, %edi / y, yt
230 jns .LL61
231 .align 16
232 .LL64:
233 negl %esi / yt
234 adcl $0, %edi /, yt
235 negl %edi / yt
236 jmp .LL61
237 .align 16
238 .LL65:
239 negl %eax / rem
240 adcl $0, %edx /, rem
241 addl $20, %esp
242 popl %esi
243 negl %edx / rem
244 popl %edi
246 SET_SIZE(__moddi3)