Annotation of funnyos/libkern/divsi3.S, Revision 1.1.1.1
1.1 init 1: /* $Id: divsi3.S,v 1.1.1.1 2007/10/12 08:40:42 init Exp $ */
2: /* $OpenBSD: divsi3.S,v 1.2 2004/02/01 05:47:10 drahn Exp $ */
3: /* $NetBSD: divsi3.S,v 1.2 2001/11/13 20:06:40 chris Exp $ */
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 <libkern/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: #if 0
53: bl PIC_SYM(_C_LABEL(raise), PLT) /* raise it */
54: #endif
55: mov r0, #0
56: #else
57: /* XXX should cause a fatal error */
58: mvn r0, #0
59: #endif
60: #ifdef __APCS_26__
61: movs pc, lr
62: #else
63: mov pc, lr
64: #endif
65:
66: ENTRY(__udivsi3)
67: L_udivide: /* r0 = r0 / r1; r1 = r0 % r1 */
68: eor r0, r1, r0
69: eor r1, r0, r1
70: eor r0, r1, r0
71: /* r0 = r1 / r0; r1 = r1 % r0 */
72: cmp r0, #1
73: bcc L_overflow
74: beq L_divide_l0
75: mov ip, #0
76: movs r1, r1
77: bpl L_divide_l1
78: orr ip, ip, #0x20000000 /* ip bit 0x20000000 = -ve r1 */
79: movs r1, r1, lsr #1
80: orrcs ip, ip, #0x10000000 /* ip bit 0x10000000 = bit 0 of r1 */
81: b L_divide_l1
82:
83: L_divide_l0: /* r0 == 1 */
84: mov r0, r1
85: mov r1, #0
86: #ifdef __APCS_26__
87: movs pc, lr
88: #else
89: mov pc, lr
90: #endif
91:
92: ENTRY(__divsi3)
93: L_divide: /* r0 = r0 / r1; r1 = r0 % r1 */
94: eor r0, r1, r0
95: eor r1, r0, r1
96: eor r0, r1, r0
97: /* r0 = r1 / r0; r1 = r1 % r0 */
98: cmp r0, #1
99: bcc L_overflow
100: beq L_divide_l0
101: ands ip, r0, #0x80000000
102: rsbmi r0, r0, #0
103: ands r2, r1, #0x80000000
104: eor ip, ip, r2
105: rsbmi r1, r1, #0
106: orr ip, r2, ip, lsr #1 /* ip bit 0x40000000 = -ve division */
107: /* ip bit 0x80000000 = -ve remainder */
108:
109: L_divide_l1:
110: mov r2, #1
111: mov r3, #0
112:
113: /*
114: * If the highest bit of the dividend is set, we have to be
115: * careful when shifting the divisor. Test this.
116: */
117: movs r1,r1
118: bpl L_old_code
119:
120: /*
121: * At this point, the highest bit of r1 is known to be set.
122: * We abuse this below in the tst instructions.
123: */
124: tst r1, r0 /*, lsl #0 */
125: bmi L_divide_b1
126: tst r1, r0, lsl #1
127: bmi L_divide_b2
128: tst r1, r0, lsl #2
129: bmi L_divide_b3
130: tst r1, r0, lsl #3
131: bmi L_divide_b4
132: tst r1, r0, lsl #4
133: bmi L_divide_b5
134: tst r1, r0, lsl #5
135: bmi L_divide_b6
136: tst r1, r0, lsl #6
137: bmi L_divide_b7
138: tst r1, r0, lsl #7
139: bmi L_divide_b8
140: tst r1, r0, lsl #8
141: bmi L_divide_b9
142: tst r1, r0, lsl #9
143: bmi L_divide_b10
144: tst r1, r0, lsl #10
145: bmi L_divide_b11
146: tst r1, r0, lsl #11
147: bmi L_divide_b12
148: tst r1, r0, lsl #12
149: bmi L_divide_b13
150: tst r1, r0, lsl #13
151: bmi L_divide_b14
152: tst r1, r0, lsl #14
153: bmi L_divide_b15
154: tst r1, r0, lsl #15
155: bmi L_divide_b16
156: tst r1, r0, lsl #16
157: bmi L_divide_b17
158: tst r1, r0, lsl #17
159: bmi L_divide_b18
160: tst r1, r0, lsl #18
161: bmi L_divide_b19
162: tst r1, r0, lsl #19
163: bmi L_divide_b20
164: tst r1, r0, lsl #20
165: bmi L_divide_b21
166: tst r1, r0, lsl #21
167: bmi L_divide_b22
168: tst r1, r0, lsl #22
169: bmi L_divide_b23
170: tst r1, r0, lsl #23
171: bmi L_divide_b24
172: tst r1, r0, lsl #24
173: bmi L_divide_b25
174: tst r1, r0, lsl #25
175: bmi L_divide_b26
176: tst r1, r0, lsl #26
177: bmi L_divide_b27
178: tst r1, r0, lsl #27
179: bmi L_divide_b28
180: tst r1, r0, lsl #28
181: bmi L_divide_b29
182: tst r1, r0, lsl #29
183: bmi L_divide_b30
184: tst r1, r0, lsl #30
185: bmi L_divide_b31
186: /*
187: * instead of:
188: * tst r1, r0, lsl #31
189: * bmi L_divide_b32
190: */
191: b L_divide_b32
192:
193: L_old_code:
194: cmp r1, r0
195: bcc L_divide_b0
196: cmp r1, r0, lsl #1
197: bcc L_divide_b1
198: cmp r1, r0, lsl #2
199: bcc L_divide_b2
200: cmp r1, r0, lsl #3
201: bcc L_divide_b3
202: cmp r1, r0, lsl #4
203: bcc L_divide_b4
204: cmp r1, r0, lsl #5
205: bcc L_divide_b5
206: cmp r1, r0, lsl #6
207: bcc L_divide_b6
208: cmp r1, r0, lsl #7
209: bcc L_divide_b7
210: cmp r1, r0, lsl #8
211: bcc L_divide_b8
212: cmp r1, r0, lsl #9
213: bcc L_divide_b9
214: cmp r1, r0, lsl #10
215: bcc L_divide_b10
216: cmp r1, r0, lsl #11
217: bcc L_divide_b11
218: cmp r1, r0, lsl #12
219: bcc L_divide_b12
220: cmp r1, r0, lsl #13
221: bcc L_divide_b13
222: cmp r1, r0, lsl #14
223: bcc L_divide_b14
224: cmp r1, r0, lsl #15
225: bcc L_divide_b15
226: cmp r1, r0, lsl #16
227: bcc L_divide_b16
228: cmp r1, r0, lsl #17
229: bcc L_divide_b17
230: cmp r1, r0, lsl #18
231: bcc L_divide_b18
232: cmp r1, r0, lsl #19
233: bcc L_divide_b19
234: cmp r1, r0, lsl #20
235: bcc L_divide_b20
236: cmp r1, r0, lsl #21
237: bcc L_divide_b21
238: cmp r1, r0, lsl #22
239: bcc L_divide_b22
240: cmp r1, r0, lsl #23
241: bcc L_divide_b23
242: cmp r1, r0, lsl #24
243: bcc L_divide_b24
244: cmp r1, r0, lsl #25
245: bcc L_divide_b25
246: cmp r1, r0, lsl #26
247: bcc L_divide_b26
248: cmp r1, r0, lsl #27
249: bcc L_divide_b27
250: cmp r1, r0, lsl #28
251: bcc L_divide_b28
252: cmp r1, r0, lsl #29
253: bcc L_divide_b29
254: cmp r1, r0, lsl #30
255: bcc L_divide_b30
256: L_divide_b32:
257: cmp r1, r0, lsl #31
258: subhs r1, r1,r0, lsl #31
259: addhs r3, r3,r2, lsl #31
260: L_divide_b31:
261: cmp r1, r0, lsl #30
262: subhs r1, r1,r0, lsl #30
263: addhs r3, r3,r2, lsl #30
264: L_divide_b30:
265: cmp r1, r0, lsl #29
266: subhs r1, r1,r0, lsl #29
267: addhs r3, r3,r2, lsl #29
268: L_divide_b29:
269: cmp r1, r0, lsl #28
270: subhs r1, r1,r0, lsl #28
271: addhs r3, r3,r2, lsl #28
272: L_divide_b28:
273: cmp r1, r0, lsl #27
274: subhs r1, r1,r0, lsl #27
275: addhs r3, r3,r2, lsl #27
276: L_divide_b27:
277: cmp r1, r0, lsl #26
278: subhs r1, r1,r0, lsl #26
279: addhs r3, r3,r2, lsl #26
280: L_divide_b26:
281: cmp r1, r0, lsl #25
282: subhs r1, r1,r0, lsl #25
283: addhs r3, r3,r2, lsl #25
284: L_divide_b25:
285: cmp r1, r0, lsl #24
286: subhs r1, r1,r0, lsl #24
287: addhs r3, r3,r2, lsl #24
288: L_divide_b24:
289: cmp r1, r0, lsl #23
290: subhs r1, r1,r0, lsl #23
291: addhs r3, r3,r2, lsl #23
292: L_divide_b23:
293: cmp r1, r0, lsl #22
294: subhs r1, r1,r0, lsl #22
295: addhs r3, r3,r2, lsl #22
296: L_divide_b22:
297: cmp r1, r0, lsl #21
298: subhs r1, r1,r0, lsl #21
299: addhs r3, r3,r2, lsl #21
300: L_divide_b21:
301: cmp r1, r0, lsl #20
302: subhs r1, r1,r0, lsl #20
303: addhs r3, r3,r2, lsl #20
304: L_divide_b20:
305: cmp r1, r0, lsl #19
306: subhs r1, r1,r0, lsl #19
307: addhs r3, r3,r2, lsl #19
308: L_divide_b19:
309: cmp r1, r0, lsl #18
310: subhs r1, r1,r0, lsl #18
311: addhs r3, r3,r2, lsl #18
312: L_divide_b18:
313: cmp r1, r0, lsl #17
314: subhs r1, r1,r0, lsl #17
315: addhs r3, r3,r2, lsl #17
316: L_divide_b17:
317: cmp r1, r0, lsl #16
318: subhs r1, r1,r0, lsl #16
319: addhs r3, r3,r2, lsl #16
320: L_divide_b16:
321: cmp r1, r0, lsl #15
322: subhs r1, r1,r0, lsl #15
323: addhs r3, r3,r2, lsl #15
324: L_divide_b15:
325: cmp r1, r0, lsl #14
326: subhs r1, r1,r0, lsl #14
327: addhs r3, r3,r2, lsl #14
328: L_divide_b14:
329: cmp r1, r0, lsl #13
330: subhs r1, r1,r0, lsl #13
331: addhs r3, r3,r2, lsl #13
332: L_divide_b13:
333: cmp r1, r0, lsl #12
334: subhs r1, r1,r0, lsl #12
335: addhs r3, r3,r2, lsl #12
336: L_divide_b12:
337: cmp r1, r0, lsl #11
338: subhs r1, r1,r0, lsl #11
339: addhs r3, r3,r2, lsl #11
340: L_divide_b11:
341: cmp r1, r0, lsl #10
342: subhs r1, r1,r0, lsl #10
343: addhs r3, r3,r2, lsl #10
344: L_divide_b10:
345: cmp r1, r0, lsl #9
346: subhs r1, r1,r0, lsl #9
347: addhs r3, r3,r2, lsl #9
348: L_divide_b9:
349: cmp r1, r0, lsl #8
350: subhs r1, r1,r0, lsl #8
351: addhs r3, r3,r2, lsl #8
352: L_divide_b8:
353: cmp r1, r0, lsl #7
354: subhs r1, r1,r0, lsl #7
355: addhs r3, r3,r2, lsl #7
356: L_divide_b7:
357: cmp r1, r0, lsl #6
358: subhs r1, r1,r0, lsl #6
359: addhs r3, r3,r2, lsl #6
360: L_divide_b6:
361: cmp r1, r0, lsl #5
362: subhs r1, r1,r0, lsl #5
363: addhs r3, r3,r2, lsl #5
364: L_divide_b5:
365: cmp r1, r0, lsl #4
366: subhs r1, r1,r0, lsl #4
367: addhs r3, r3,r2, lsl #4
368: L_divide_b4:
369: cmp r1, r0, lsl #3
370: subhs r1, r1,r0, lsl #3
371: addhs r3, r3,r2, lsl #3
372: L_divide_b3:
373: cmp r1, r0, lsl #2
374: subhs r1, r1,r0, lsl #2
375: addhs r3, r3,r2, lsl #2
376: L_divide_b2:
377: cmp r1, r0, lsl #1
378: subhs r1, r1,r0, lsl #1
379: addhs r3, r3,r2, lsl #1
380: L_divide_b1:
381: cmp r1, r0
382: subhs r1, r1, r0
383: addhs r3, r3, r2
384: L_divide_b0:
385:
386: tst ip, #0x20000000
387: bne L_udivide_l1
388: mov r0, r3
389: cmp ip, #0
390: rsbmi r1, r1, #0
391: movs ip, ip, lsl #1
392: bicmi r0, r0, #0x80000000 /* Fix incase we divided 0x80000000 */
393: rsbmi r0, r0, #0
394: #ifdef __APCS_26__
395: movs pc, lr
396: #else
397: mov pc, lr
398: #endif
399:
400: L_udivide_l1:
401: tst ip, #0x10000000
402: mov r1, r1, lsl #1
403: orrne r1, r1, #1
404: mov r3, r3, lsl #1
405: cmp r1, r0
406: subhs r1, r1, r0
407: addhs r3, r3, r2
408: mov r0, r3
409: #ifdef __APCS_26__
410: movs pc, lr
411: #else
412: mov pc, lr
413: #endif
CVSweb