initial import
[glibc.git] / sysdeps / sparc / urem.S
blob9f64c8859ec7be2533c296504d327e84cf567255
1    /* This file is generated from divrem.m4; DO NOT EDIT! */
2 /*
3  * Division and remainder, from Appendix E of the Sparc Version 8
4  * Architecture Manual, with fixes from Gordon Irlam.
5  */
7 /*
8  * Input: dividend and divisor in %o0 and %o1 respectively.
9  *
10  * m4 parameters:
11  *  .urem       name of function to generate
12  *  rem         rem=div => %o0 / %o1; rem=rem => %o0 % %o1
13  *  false               false=true => signed; false=false => unsigned
14  *
15  * Algorithm parameters:
16  *  N           how many bits per iteration we try to get (4)
17  *  WORDSIZE    total number of bits (32)
18  *
19  * Derived constants:
20  *  TOPBITS     number of bits in the top decade of a number
21  *
22  * Important variables:
23  *  Q           the partial quotient under development (initially 0)
24  *  R           the remainder so far, initially the dividend
25  *  ITER        number of main division loop iterations required;
26  *              equal to ceil(log2(quotient) / N).  Note that this
27  *              is the log base (2^N) of the quotient.
28  *  V           the current comparand, initially divisor*2^(ITER*N-1)
29  *
30  * Cost:
31  *  Current estimate for non-large dividend is
32  *      ceil(log2(quotient) / N) * (10 + 7N/2) + C
33  *  A large dividend is one greater than 2^(31-TOPBITS) and takes a
34  *  different path, as the upper bits of the quotient must be developed
35  *  one bit at a time.
36  */
40 #include "DEFS.h"
41 #ifdef __svr4__
42 #include <sys/trap.h>
43 #else
44 #include <machine/trap.h>
45 #endif
47 FUNC(.urem)
49         ! Ready to divide.  Compute size of quotient; scale comparand.
50         orcc    %o1, %g0, %o5
51         bne     1f
52         mov     %o0, %o3
54                 ! Divide by zero trap.  If it returns, return 0 (about as
55                 ! wrong as possible, but that is what SunOS does...).
56                 ta      ST_DIV0
57                 retl
58                 clr     %o0
61         cmp     %o3, %o5                        ! if %o1 exceeds %o0, done
62         blu     Lgot_result             ! (and algorithm fails otherwise)
63         clr     %o2
64         sethi   %hi(1 << (32 - 4 - 1)), %g1
65         cmp     %o3, %g1
66         blu     Lnot_really_big
67         clr     %o4
69         ! Here the dividend is >= 2**(31-N) or so.  We must be careful here,
70         ! as our usual N-at-a-shot divide step will cause overflow and havoc.
71         ! The number of bits in the result here is N*ITER+SC, where SC <= N.
72         ! Compute ITER in an unorthodox manner: know we need to shift V into
73         ! the top decade: so do not even bother to compare to R.
74         1:
75                 cmp     %o5, %g1
76                 bgeu    3f
77                 mov     1, %g7
78                 sll     %o5, 4, %o5
79                 b       1b
80                 add     %o4, 1, %o4
82         ! Now compute %g7.
83         2:      addcc   %o5, %o5, %o5
84                 bcc     Lnot_too_big
85                 add     %g7, 1, %g7
87                 ! We get here if the %o1 overflowed while shifting.
88                 ! This means that %o3 has the high-order bit set.
89                 ! Restore %o5 and subtract from %o3.
90                 sll     %g1, 4, %g1     ! high order bit
91                 srl     %o5, 1, %o5             ! rest of %o5
92                 add     %o5, %g1, %o5
93                 b       Ldo_single_div
94                 sub     %g7, 1, %g7
96         Lnot_too_big:
97         3:      cmp     %o5, %o3
98                 blu     2b
99                 nop
100                 be      Ldo_single_div
101                 nop
102         /* NB: these are commented out in the V8-Sparc manual as well */
103         /* (I do not understand this) */
104         ! %o5 > %o3: went too far: back up 1 step
105         !       srl     %o5, 1, %o5
106         !       dec     %g7
107         ! do single-bit divide steps
108         !
109         ! We have to be careful here.  We know that %o3 >= %o5, so we can do the
110         ! first divide step without thinking.  BUT, the others are conditional,
111         ! and are only done if %o3 >= 0.  Because both %o3 and %o5 may have the high-
112         ! order bit set in the first step, just falling into the regular
113         ! division loop will mess up the first time around.
114         ! So we unroll slightly...
115         Ldo_single_div:
116                 subcc   %g7, 1, %g7
117                 bl      Lend_regular_divide
118                 nop
119                 sub     %o3, %o5, %o3
120                 mov     1, %o2
121                 b       Lend_single_divloop
122                 nop
123         Lsingle_divloop:
124                 sll     %o2, 1, %o2
125                 bl      1f
126                 srl     %o5, 1, %o5
127                 ! %o3 >= 0
128                 sub     %o3, %o5, %o3
129                 b       2f
130                 add     %o2, 1, %o2
131         1:      ! %o3 < 0
132                 add     %o3, %o5, %o3
133                 sub     %o2, 1, %o2
134         2:
135         Lend_single_divloop:
136                 subcc   %g7, 1, %g7
137                 bge     Lsingle_divloop
138                 tst     %o3
139                 b,a     Lend_regular_divide
141 Lnot_really_big:
143         sll     %o5, 4, %o5
144         cmp     %o5, %o3
145         bleu    1b
146         addcc   %o4, 1, %o4
147         be      Lgot_result
148         sub     %o4, 1, %o4
150         tst     %o3     ! set up for initial iteration
151 Ldivloop:
152         sll     %o2, 4, %o2
153                 ! depth 1, accumulated bits 0
154         bl      L.1.16
155         srl     %o5,1,%o5
156         ! remainder is positive
157         subcc   %o3,%o5,%o3
158                         ! depth 2, accumulated bits 1
159         bl      L.2.17
160         srl     %o5,1,%o5
161         ! remainder is positive
162         subcc   %o3,%o5,%o3
163                         ! depth 3, accumulated bits 3
164         bl      L.3.19
165         srl     %o5,1,%o5
166         ! remainder is positive
167         subcc   %o3,%o5,%o3
168                         ! depth 4, accumulated bits 7
169         bl      L.4.23
170         srl     %o5,1,%o5
171         ! remainder is positive
172         subcc   %o3,%o5,%o3
173                 b       9f
174                 add     %o2, (7*2+1), %o2
175         
176 L.4.23:
177         ! remainder is negative
178         addcc   %o3,%o5,%o3
179                 b       9f
180                 add     %o2, (7*2-1), %o2
181         
182         
183 L.3.19:
184         ! remainder is negative
185         addcc   %o3,%o5,%o3
186                         ! depth 4, accumulated bits 5
187         bl      L.4.21
188         srl     %o5,1,%o5
189         ! remainder is positive
190         subcc   %o3,%o5,%o3
191                 b       9f
192                 add     %o2, (5*2+1), %o2
193         
194 L.4.21:
195         ! remainder is negative
196         addcc   %o3,%o5,%o3
197                 b       9f
198                 add     %o2, (5*2-1), %o2
199         
200         
201         
202 L.2.17:
203         ! remainder is negative
204         addcc   %o3,%o5,%o3
205                         ! depth 3, accumulated bits 1
206         bl      L.3.17
207         srl     %o5,1,%o5
208         ! remainder is positive
209         subcc   %o3,%o5,%o3
210                         ! depth 4, accumulated bits 3
211         bl      L.4.19
212         srl     %o5,1,%o5
213         ! remainder is positive
214         subcc   %o3,%o5,%o3
215                 b       9f
216                 add     %o2, (3*2+1), %o2
217         
218 L.4.19:
219         ! remainder is negative
220         addcc   %o3,%o5,%o3
221                 b       9f
222                 add     %o2, (3*2-1), %o2
223         
224         
225 L.3.17:
226         ! remainder is negative
227         addcc   %o3,%o5,%o3
228                         ! depth 4, accumulated bits 1
229         bl      L.4.17
230         srl     %o5,1,%o5
231         ! remainder is positive
232         subcc   %o3,%o5,%o3
233                 b       9f
234                 add     %o2, (1*2+1), %o2
235         
236 L.4.17:
237         ! remainder is negative
238         addcc   %o3,%o5,%o3
239                 b       9f
240                 add     %o2, (1*2-1), %o2
241         
242         
243         
244         
245 L.1.16:
246         ! remainder is negative
247         addcc   %o3,%o5,%o3
248                         ! depth 2, accumulated bits -1
249         bl      L.2.15
250         srl     %o5,1,%o5
251         ! remainder is positive
252         subcc   %o3,%o5,%o3
253                         ! depth 3, accumulated bits -1
254         bl      L.3.15
255         srl     %o5,1,%o5
256         ! remainder is positive
257         subcc   %o3,%o5,%o3
258                         ! depth 4, accumulated bits -1
259         bl      L.4.15
260         srl     %o5,1,%o5
261         ! remainder is positive
262         subcc   %o3,%o5,%o3
263                 b       9f
264                 add     %o2, (-1*2+1), %o2
265         
266 L.4.15:
267         ! remainder is negative
268         addcc   %o3,%o5,%o3
269                 b       9f
270                 add     %o2, (-1*2-1), %o2
271         
272         
273 L.3.15:
274         ! remainder is negative
275         addcc   %o3,%o5,%o3
276                         ! depth 4, accumulated bits -3
277         bl      L.4.13
278         srl     %o5,1,%o5
279         ! remainder is positive
280         subcc   %o3,%o5,%o3
281                 b       9f
282                 add     %o2, (-3*2+1), %o2
283         
284 L.4.13:
285         ! remainder is negative
286         addcc   %o3,%o5,%o3
287                 b       9f
288                 add     %o2, (-3*2-1), %o2
289         
290         
291         
292 L.2.15:
293         ! remainder is negative
294         addcc   %o3,%o5,%o3
295                         ! depth 3, accumulated bits -3
296         bl      L.3.13
297         srl     %o5,1,%o5
298         ! remainder is positive
299         subcc   %o3,%o5,%o3
300                         ! depth 4, accumulated bits -5
301         bl      L.4.11
302         srl     %o5,1,%o5
303         ! remainder is positive
304         subcc   %o3,%o5,%o3
305                 b       9f
306                 add     %o2, (-5*2+1), %o2
307         
308 L.4.11:
309         ! remainder is negative
310         addcc   %o3,%o5,%o3
311                 b       9f
312                 add     %o2, (-5*2-1), %o2
313         
314         
315 L.3.13:
316         ! remainder is negative
317         addcc   %o3,%o5,%o3
318                         ! depth 4, accumulated bits -7
319         bl      L.4.9
320         srl     %o5,1,%o5
321         ! remainder is positive
322         subcc   %o3,%o5,%o3
323                 b       9f
324                 add     %o2, (-7*2+1), %o2
325         
326 L.4.9:
327         ! remainder is negative
328         addcc   %o3,%o5,%o3
329                 b       9f
330                 add     %o2, (-7*2-1), %o2
331         
332         
333         
334         
335         9:
336 Lend_regular_divide:
337         subcc   %o4, 1, %o4
338         bge     Ldivloop
339         tst     %o3
340         bl,a    Lgot_result
341         ! non-restoring fixup here (one instruction only!)
342         add     %o3, %o1, %o3
345 Lgot_result:
347         retl
348         mov %o3, %o0