Annotation of sys/lib/libkern/arch/arm/divsi3.S, Revision 1.1.1.1
1.1 nbrk 1: /* $OpenBSD: divsi3.S,v 1.2 2004/02/01 05:47:10 drahn Exp $ */
2: /* $NetBSD: divsi3.S,v 1.2 2001/11/13 20:06:40 chris Exp $ */
3:
4: /*
5: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
6: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
7: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
8: * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
9: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
10: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
11: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
12: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
13: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
14: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
15: * SUCH DAMAGE.
16: */
17:
18: #include <machine/asm.h>
19:
20: /*
21: * stack is aligned as there's a possibility of branching to L_overflow
22: * which makes a C call
23: */
24:
25: ENTRY(__umodsi3)
26: stmfd sp!, {lr}
27: sub sp, sp, #4 /* align stack */
28: bl L_udivide
29: add sp, sp, #4 /* unalign stack */
30: mov r0, r1
31: #ifdef __APCS_26__
32: ldmfd sp!, {pc}^
33: #else /* APCS-32 */
34: ldmfd sp!, {pc}
35: #endif
36:
37: ENTRY(__modsi3)
38: stmfd sp!, {lr}
39: sub sp, sp, #4 /* align stack */
40: bl L_divide
41: add sp, sp, #4 /* unalign stack */
42: mov r0, r1
43: #ifdef __APCS_26__
44: ldmfd sp!, {pc}^
45: #else
46: ldmfd sp!, {pc}
47: #endif
48:
49: L_overflow:
50: #if !defined(_KERNEL) && !defined(_STANDALONE)
51: mov r0, #8 /* SIGFPE */
52: bl PIC_SYM(_C_LABEL(raise), PLT) /* raise it */
53: mov r0, #0
54: #else
55: /* XXX should cause a fatal error */
56: mvn r0, #0
57: #endif
58: #ifdef __APCS_26__
59: movs pc, lr
60: #else
61: mov pc, lr
62: #endif
63:
64: ENTRY(__udivsi3)
65: L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */
66: eor r0, r1, r0
67: eor r1, r0, r1
68: eor r0, r1, r0
69: /* r0 = r1 / r0; r1 = r1 % r0 */
70: cmp r0, #1
71: bcc L_overflow
72: beq L_divide_l0
73: mov ip, #0
74: movs r1, r1
75: bpl L_divide_l1
76: orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
77: movs r1, r1, lsr #1
78: orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
79: b L_divide_l1
80:
81: L_divide_l0: /* r0 == 1 */
82: mov r0, r1
83: mov r1, #0
84: #ifdef __APCS_26__
85: movs pc, lr
86: #else
87: mov pc, lr
88: #endif
89:
90: ENTRY(__divsi3)
91: L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */
92: eor r0, r1, r0
93: eor r1, r0, r1
94: eor r0, r1, r0
95: /* r0 = r1 / r0; r1 = r1 % r0 */
96: cmp r0, #1
97: bcc L_overflow
98: beq L_divide_l0
99: ands ip, r0, #0x80000000
100: rsbmi r0, r0, #0
101: ands r2, r1, #0x80000000
102: eor ip, ip, r2
103: rsbmi r1, r1, #0
104: orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
105: /* ip bit 0x80000000 = -ve remainder */
106:
107: L_divide_l1:
108: mov r2, #1
109: mov r3, #0
110:
111: /*
112: * If the highest bit of the dividend is set, we have to be
113: * careful when shifting the divisor. Test this.
114: */
115: movs r1,r1
116: bpl L_old_code
117:
118: /*
119: * At this point, the highest bit of r1 is known to be set.
120: * We abuse this below in the tst instructions.
121: */
122: tst r1, r0 /*, lsl #0 */
123: bmi L_divide_b1
124: tst r1, r0, lsl #1
125: bmi L_divide_b2
126: tst r1, r0, lsl #2
127: bmi L_divide_b3
128: tst r1, r0, lsl #3
129: bmi L_divide_b4
130: tst r1, r0, lsl #4
131: bmi L_divide_b5
132: tst r1, r0, lsl #5
133: bmi L_divide_b6
134: tst r1, r0, lsl #6
135: bmi L_divide_b7
136: tst r1, r0, lsl #7
137: bmi L_divide_b8
138: tst r1, r0, lsl #8
139: bmi L_divide_b9
140: tst r1, r0, lsl #9
141: bmi L_divide_b10
142: tst r1, r0, lsl #10
143: bmi L_divide_b11
144: tst r1, r0, lsl #11
145: bmi L_divide_b12
146: tst r1, r0, lsl #12
147: bmi L_divide_b13
148: tst r1, r0, lsl #13
149: bmi L_divide_b14
150: tst r1, r0, lsl #14
151: bmi L_divide_b15
152: tst r1, r0, lsl #15
153: bmi L_divide_b16
154: tst r1, r0, lsl #16
155: bmi L_divide_b17
156: tst r1, r0, lsl #17
157: bmi L_divide_b18
158: tst r1, r0, lsl #18
159: bmi L_divide_b19
160: tst r1, r0, lsl #19
161: bmi L_divide_b20
162: tst r1, r0, lsl #20
163: bmi L_divide_b21
164: tst r1, r0, lsl #21
165: bmi L_divide_b22
166: tst r1, r0, lsl #22
167: bmi L_divide_b23
168: tst r1, r0, lsl #23
169: bmi L_divide_b24
170: tst r1, r0, lsl #24
171: bmi L_divide_b25
172: tst r1, r0, lsl #25
173: bmi L_divide_b26
174: tst r1, r0, lsl #26
175: bmi L_divide_b27
176: tst r1, r0, lsl #27
177: bmi L_divide_b28
178: tst r1, r0, lsl #28
179: bmi L_divide_b29
180: tst r1, r0, lsl #29
181: bmi L_divide_b30
182: tst r1, r0, lsl #30
183: bmi L_divide_b31
184: /*
185: * instead of:
186: * tst r1, r0, lsl #31
187: * bmi L_divide_b32
188: */
189: b L_divide_b32
190:
191: L_old_code:
192: cmp r1, r0
193: bcc L_divide_b0
194: cmp r1, r0, lsl #1
195: bcc L_divide_b1
196: cmp r1, r0, lsl #2
197: bcc L_divide_b2
198: cmp r1, r0, lsl #3
199: bcc L_divide_b3
200: cmp r1, r0, lsl #4
201: bcc L_divide_b4
202: cmp r1, r0, lsl #5
203: bcc L_divide_b5
204: cmp r1, r0, lsl #6
205: bcc L_divide_b6
206: cmp r1, r0, lsl #7
207: bcc L_divide_b7
208: cmp r1, r0, lsl #8
209: bcc L_divide_b8
210: cmp r1, r0, lsl #9
211: bcc L_divide_b9
212: cmp r1, r0, lsl #10
213: bcc L_divide_b10
214: cmp r1, r0, lsl #11
215: bcc L_divide_b11
216: cmp r1, r0, lsl #12
217: bcc L_divide_b12
218: cmp r1, r0, lsl #13
219: bcc L_divide_b13
220: cmp r1, r0, lsl #14
221: bcc L_divide_b14
222: cmp r1, r0, lsl #15
223: bcc L_divide_b15
224: cmp r1, r0, lsl #16
225: bcc L_divide_b16
226: cmp r1, r0, lsl #17
227: bcc L_divide_b17
228: cmp r1, r0, lsl #18
229: bcc L_divide_b18
230: cmp r1, r0, lsl #19
231: bcc L_divide_b19
232: cmp r1, r0, lsl #20
233: bcc L_divide_b20
234: cmp r1, r0, lsl #21
235: bcc L_divide_b21
236: cmp r1, r0, lsl #22
237: bcc L_divide_b22
238: cmp r1, r0, lsl #23
239: bcc L_divide_b23
240: cmp r1, r0, lsl #24
241: bcc L_divide_b24
242: cmp r1, r0, lsl #25
243: bcc L_divide_b25
244: cmp r1, r0, lsl #26
245: bcc L_divide_b26
246: cmp r1, r0, lsl #27
247: bcc L_divide_b27
248: cmp r1, r0, lsl #28
249: bcc L_divide_b28
250: cmp r1, r0, lsl #29
251: bcc L_divide_b29
252: cmp r1, r0, lsl #30
253: bcc L_divide_b30
254: L_divide_b32:
255: cmp r1, r0, lsl #31
256: subhs r1, r1,r0, lsl #31
257: addhs r3, r3,r2, lsl #31
258: L_divide_b31:
259: cmp r1, r0, lsl #30
260: subhs r1, r1,r0, lsl #30
261: addhs r3, r3,r2, lsl #30
262: L_divide_b30:
263: cmp r1, r0, lsl #29
264: subhs r1, r1,r0, lsl #29
265: addhs r3, r3,r2, lsl #29
266: L_divide_b29:
267: cmp r1, r0, lsl #28
268: subhs r1, r1,r0, lsl #28
269: addhs r3, r3,r2, lsl #28
270: L_divide_b28:
271: cmp r1, r0, lsl #27
272: subhs r1, r1,r0, lsl #27
273: addhs r3, r3,r2, lsl #27
274: L_divide_b27:
275: cmp r1, r0, lsl #26
276: subhs r1, r1,r0, lsl #26
277: addhs r3, r3,r2, lsl #26
278: L_divide_b26:
279: cmp r1, r0, lsl #25
280: subhs r1, r1,r0, lsl #25
281: addhs r3, r3,r2, lsl #25
282: L_divide_b25:
283: cmp r1, r0, lsl #24
284: subhs r1, r1,r0, lsl #24
285: addhs r3, r3,r2, lsl #24
286: L_divide_b24:
287: cmp r1, r0, lsl #23
288: subhs r1, r1,r0, lsl #23
289: addhs r3, r3,r2, lsl #23
290: L_divide_b23:
291: cmp r1, r0, lsl #22
292: subhs r1, r1,r0, lsl #22
293: addhs r3, r3,r2, lsl #22
294: L_divide_b22:
295: cmp r1, r0, lsl #21
296: subhs r1, r1,r0, lsl #21
297: addhs r3, r3,r2, lsl #21
298: L_divide_b21:
299: cmp r1, r0, lsl #20
300: subhs r1, r1,r0, lsl #20
301: addhs r3, r3,r2, lsl #20
302: L_divide_b20:
303: cmp r1, r0, lsl #19
304: subhs r1, r1,r0, lsl #19
305: addhs r3, r3,r2, lsl #19
306: L_divide_b19:
307: cmp r1, r0, lsl #18
308: subhs r1, r1,r0, lsl #18
309: addhs r3, r3,r2, lsl #18
310: L_divide_b18:
311: cmp r1, r0, lsl #17
312: subhs r1, r1,r0, lsl #17
313: addhs r3, r3,r2, lsl #17
314: L_divide_b17:
315: cmp r1, r0, lsl #16
316: subhs r1, r1,r0, lsl #16
317: addhs r3, r3,r2, lsl #16
318: L_divide_b16:
319: cmp r1, r0, lsl #15
320: subhs r1, r1,r0, lsl #15
321: addhs r3, r3,r2, lsl #15
322: L_divide_b15:
323: cmp r1, r0, lsl #14
324: subhs r1, r1,r0, lsl #14
325: addhs r3, r3,r2, lsl #14
326: L_divide_b14:
327: cmp r1, r0, lsl #13
328: subhs r1, r1,r0, lsl #13
329: addhs r3, r3,r2, lsl #13
330: L_divide_b13:
331: cmp r1, r0, lsl #12
332: subhs r1, r1,r0, lsl #12
333: addhs r3, r3,r2, lsl #12
334: L_divide_b12:
335: cmp r1, r0, lsl #11
336: subhs r1, r1,r0, lsl #11
337: addhs r3, r3,r2, lsl #11
338: L_divide_b11:
339: cmp r1, r0, lsl #10
340: subhs r1, r1,r0, lsl #10
341: addhs r3, r3,r2, lsl #10
342: L_divide_b10:
343: cmp r1, r0, lsl #9
344: subhs r1, r1,r0, lsl #9
345: addhs r3, r3,r2, lsl #9
346: L_divide_b9:
347: cmp r1, r0, lsl #8
348: subhs r1, r1,r0, lsl #8
349: addhs r3, r3,r2, lsl #8
350: L_divide_b8:
351: cmp r1, r0, lsl #7
352: subhs r1, r1,r0, lsl #7
353: addhs r3, r3,r2, lsl #7
354: L_divide_b7:
355: cmp r1, r0, lsl #6
356: subhs r1, r1,r0, lsl #6
357: addhs r3, r3,r2, lsl #6
358: L_divide_b6:
359: cmp r1, r0, lsl #5
360: subhs r1, r1,r0, lsl #5
361: addhs r3, r3,r2, lsl #5
362: L_divide_b5:
363: cmp r1, r0, lsl #4
364: subhs r1, r1,r0, lsl #4
365: addhs r3, r3,r2, lsl #4
366: L_divide_b4:
367: cmp r1, r0, lsl #3
368: subhs r1, r1,r0, lsl #3
369: addhs r3, r3,r2, lsl #3
370: L_divide_b3:
371: cmp r1, r0, lsl #2
372: subhs r1, r1,r0, lsl #2
373: addhs r3, r3,r2, lsl #2
374: L_divide_b2:
375: cmp r1, r0, lsl #1
376: subhs r1, r1,r0, lsl #1
377: addhs r3, r3,r2, lsl #1
378: L_divide_b1:
379: cmp r1, r0
380: subhs r1, r1, r0
381: addhs r3, r3, r2
382: L_divide_b0:
383:
384: tst ip, #0x20000000
385: bne L_udivide_l1
386: mov r0, r3
387: cmp ip, #0
388: rsbmi r1, r1, #0
389: movs ip, ip, lsl #1
390: bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
391: rsbmi r0, r0, #0
392: #ifdef __APCS_26__
393: movs pc, lr
394: #else
395: mov pc, lr
396: #endif
397:
398: L_udivide_l1:
399: tst ip, #0x10000000
400: mov r1, r1, lsl #1
401: orrne r1, r1, #1
402: mov r3, r3, lsl #1
403: cmp r1, r0
404: subhs r1, r1, r0
405: addhs r3, r3, r2
406: mov r0, r3
407: #ifdef __APCS_26__
408: movs pc, lr
409: #else
410: mov pc, lr
411: #endif
CVSweb