|
|
1.1 root 1: /* This is an assembly language implementation of libgcc1.c for the sparc
2: processor.
3:
4: These routines are derived from the Sparc Architecture Manual, version 8,
5: slightly edited to match the desired calling convention, and also to
6: optimize them for our purposes. */
7:
8: #ifdef L_mulsi3
9: .text
10: .align 4
11: .global .umul
12: .proc 4
13: .umul:
14: or %o0, %o1, %o4 ! logical or of multiplier and multiplicand
15: mov %o0, %y ! multiplier to Y register
16: andncc %o4, 0xfff, %o5 ! mask out lower 12 bits
17: be mul_shortway ! can do it the short way
18: andcc %g0, %g0, %o4 ! zero the partial product and clear NV cc
19: !
20: ! long multiply
21: !
22: mulscc %o4, %o1, %o4 ! first iteration of 33
23: mulscc %o4, %o1, %o4
24: mulscc %o4, %o1, %o4
25: mulscc %o4, %o1, %o4
26: mulscc %o4, %o1, %o4
27: mulscc %o4, %o1, %o4
28: mulscc %o4, %o1, %o4
29: mulscc %o4, %o1, %o4
30: mulscc %o4, %o1, %o4
31: mulscc %o4, %o1, %o4
32: mulscc %o4, %o1, %o4
33: mulscc %o4, %o1, %o4
34: mulscc %o4, %o1, %o4
35: mulscc %o4, %o1, %o4
36: mulscc %o4, %o1, %o4
37: mulscc %o4, %o1, %o4
38: mulscc %o4, %o1, %o4
39: mulscc %o4, %o1, %o4
40: mulscc %o4, %o1, %o4
41: mulscc %o4, %o1, %o4
42: mulscc %o4, %o1, %o4
43: mulscc %o4, %o1, %o4
44: mulscc %o4, %o1, %o4
45: mulscc %o4, %o1, %o4
46: mulscc %o4, %o1, %o4
47: mulscc %o4, %o1, %o4
48: mulscc %o4, %o1, %o4
49: mulscc %o4, %o1, %o4
50: mulscc %o4, %o1, %o4
51: mulscc %o4, %o1, %o4
52: mulscc %o4, %o1, %o4
53: mulscc %o4, %o1, %o4 ! 32nd iteration
54: mulscc %o4, %g0, %o4 ! last iteration only shifts
55: ! the upper 32 bits of product are wrong, but we do not care
56: retl
57: rd %y, %o0
58: !
59: ! short multiply
60: !
61: mul_shortway:
62: mulscc %o4, %o1, %o4 ! first iteration of 13
63: mulscc %o4, %o1, %o4
64: mulscc %o4, %o1, %o4
65: mulscc %o4, %o1, %o4
66: mulscc %o4, %o1, %o4
67: mulscc %o4, %o1, %o4
68: mulscc %o4, %o1, %o4
69: mulscc %o4, %o1, %o4
70: mulscc %o4, %o1, %o4
71: mulscc %o4, %o1, %o4
72: mulscc %o4, %o1, %o4
73: mulscc %o4, %o1, %o4 ! 12th iteration
74: mulscc %o4, %g0, %o4 ! last iteration only shifts
75: rd %y, %o5
76: sll %o4, 12, %o4 ! left shift partial product by 12 bits
77: srl %o5, 20, %o5 ! right shift partial product by 20 bits
78: retl
79: or %o5, %o4, %o0 ! merge for true product
80: #endif
81:
82: #ifdef L_divsi3
83: .text
84: .align 4
85: .global .udiv
86: .proc 4
87: .udiv:
88: save %sp, -64, %sp
89: b divide
90: mov 0, %i2 ! result always positive
91: .global .div
92: .proc 4
93: .div:
94: save %sp, -64, %sp
95: orcc %i1, %i0, %g0 ! is either operand negative
96: bge divide ! if not, skip this junk
97: xor %i1, %i0, %i2 ! record sign of result in sign of %i2
98: tst %i1
99: bge 2f
100: tst %i0
101: ! %i1 < 0
102: bge divide
103: neg %i1
104: 2: ! %i0 < 0
105: neg %i0
106: ! FALL THROUGH
107: divide:
108: ! Compute size of quotient, scale comparand.
109: orcc %i1, %g0, %l1 ! movcc %i1, %l1
110: te 2 ! if %i1 = 0
111: mov %i0, %i3
112: mov 0, %i2
113: sethi %hi(1<<(32-2-1)), %l3
114: cmp %i3, %l3
115: blu not_really_big
116: mov 0, %l0
117: !
118: ! Here, the %i0 is >= 2^(31-3) or so. We must be careful here,
119: ! as our usual 3-at-a-shot divide step will cause overflow and havoc.
120: ! The total number of bits in the result here is 3*%l0+%l4, where
121: ! %l4 <= 3.
122: ! Compute %l0 in an unorthodox manner: know we need to Shift %l1 into
123: ! the top decade: so do not even bother to compare to %i3.
124: 1: cmp %l1, %l3
125: bgeu 3f
126: mov 1, %l4
127: sll %l1, 3, %l1
128: b 1b
129: inc %l0
130: !
131: ! Now compute %l4
132: !
133: 2: addcc %l1, %l1, %l1
134: bcc not_too_big
135: add %l4, 1, %l4
136: !
137: ! We are here if the %i1 overflowed when Shifting.
138: ! This means that %i3 has the high-order bit set.
139: ! Restore %l1 and subtract from %i3.
140: sll %l3, 2, %l3
141: srl %l1, 1, %l1
142: add %l1, %l3, %l1
143: b do_single_div
144: dec %l4
145: not_too_big:
146: 3: cmp %l1, %i3
147: blu 2b
148: nop
149: be do_single_div
150: nop
151: ! %l1 > %i3: went too far: back up 1 step
152: ! srl %l1, 1, %l1
153: ! dec %l4
154: ! do single-bit divide steps
155: !
156: ! We have to be careful here. We know that %i3 >= %l1, so we can do the
157: ! first divide step without thinking. BUT, the others are conditional,
158: ! and are only done if %i3 >= 0. Because both %i3 and %l1 may have the
159: ! high-order bit set in the first step, just falling into the regular
160: ! division loop will mess up the first time around.
161: ! So we unroll slightly...
162: do_single_div:
163: deccc %l4
164: bl end_regular_divide
165: nop
166: sub %i3, %l1, %i3
167: mov 1, %i2
168: b end_single_divloop
169: nop
170: single_divloop:
171: sll %i2, 1, %i2
172: bl 1f
173: srl %l1, 1, %l1
174: ! %i3 >= 0
175: sub %i3, %l1, %i3
176: b 2f
177: inc %i2
178: 1: ! %i3 < 0
179: add %i3, %l1, %i3
180: dec %i2
181: end_single_divloop:
182: 2: deccc %l4
183: bge single_divloop
184: tst %i3
185: b end_regular_divide
186: nop
187: not_really_big:
188: 1: sll %l1, 3, %l1
189: cmp %l1, %i3
190: bleu 1b
191: inccc %l0
192: be got_result
193: dec %l0
194: do_regular_divide:
195: ! Do the main division iteration
196: tst %i3
197: ! Fall through into divide loop
198: divloop:
199: sll %i2, 3, %i2
200: ! depth 1, accumulated bits 0
201: bl L.1.8
202: srl %l1,1,%l1
203: ! remainder is positive
204: subcc %i3,%l1,%i3
205: ! depth 2, accumulated bits 1
206: bl L.2.9
207: srl %l1,1,%l1
208: ! remainder is positive
209: subcc %i3,%l1,%i3
210: ! depth 3, accumulated bits 3
211: bl L.3.11
212: srl %l1,1,%l1
213: ! remainder is positive
214: subcc %i3,%l1,%i3
215: b 9f
216: add %i2, (3*2+1), %i2
217: L.3.11: ! remainder is negative
218: addcc %i3,%l1,%i3
219: b 9f
220: add %i2, (3*2-1), %i2
221: L.2.9: ! remainder is negative
222: addcc %i3,%l1,%i3
223: ! depth 3, accumulated bits 1
224: bl L.3.9
225: srl %l1,1,%l1
226: ! remainder is positive
227: subcc %i3,%l1,%i3
228: b 9f
229: add %i2, (1*2+1), %i2
230: L.3.9: ! remainder is negative
231: addcc %i3,%l1,%i3
232: b 9f
233: add %i2, (1*2-1), %i2
234: L.1.8: ! remainder is negative
235: addcc %i3,%l1,%i3
236: ! depth 2, accumulated bits -1
237: bl L.2.7
238: srl %l1,1,%l1
239: ! remainder is positive
240: subcc %i3,%l1,%i3
241: ! depth 3, accumulated bits -1
242: bl L.3.7
243: srl %l1,1,%l1
244: ! remainder is positive
245: subcc %i3,%l1,%i3
246: b 9f
247: add %i2, (-1*2+1), %i2
248: L.3.7: ! remainder is negative
249: addcc %i3,%l1,%i3
250: b 9f
251: add %i2, (-1*2-1), %i2
252: L.2.7: ! remainder is negative
253: addcc %i3,%l1,%i3
254: ! depth 3, accumulated bits -3
255: bl L.3.5
256: srl %l1,1,%l1
257: ! remainder is positive
258: subcc %i3,%l1,%i3
259: b 9f
260: add %i2, (-3*2+1), %i2
261: L.3.5: ! remainder is negative
262: addcc %i3,%l1,%i3
263: b 9f
264: add %i2, (-3*2-1), %i2
265: end_regular_divide:
266: 9: deccc %l0
267: bge divloop
268: tst %i3
269: bge got_result
270: nop
271: ! non-restoring fixup here
272: dec %i2
273: got_result:
274: tst %i2
275: bge 1f
276: restore
277: ! answer < 0
278: retl ! leaf-routine return
279: neg %o2, %o0 ! quotient <- -%i2
280: 1: retl ! leaf-routine return
281: mov %o2, %o0 ! quotient <- %i2
282: #endif
283:
284: #ifdef L_modsi3
285: .text
286: .align 4
287: .global .urem
288: .proc 4
289: .urem:
290: save %sp, -64, %sp
291: b divide
292: mov 0, %i2 ! result always positive
293: .global .rem
294: .proc 4
295: .rem:
296: save %sp, -64, %sp
297: orcc %i1, %i0, %g0 ! is either operand negative
298: bge divide ! if not, skip this junk
299: mov %i0, %i2 ! record sign of result in sign of %i2
300: tst %i1
301: bge 2f
302: tst %i0
303: ! %i1 < 0
304: bge divide
305: neg %i1
306: 2: ! %i0 < 0
307: neg %i0
308: ! FALL THROUGH
309: divide:
310: ! Compute size of quotient, scale comparand.
311: orcc %i1, %g0, %l1 ! movcc %i1, %l1
312: te 2 ! if %i1 = 0
313: mov %i0, %i3
314: mov 0, %i2
315: sethi %hi(1<<(32-2-1)), %l3
316: cmp %i3, %l3
317: blu not_really_big
318: mov 0, %l0
319: !
320: ! Here, the %i0 is >= 2^(31-3) or so. We must be careful here,
321: ! as our usual 3-at-a-shot divide step will cause overflow and havoc.
322: ! The total number of bits in the result here is 3*%l0+%l4, where
323: ! %l4 <= 3.
324: ! Compute %l0 in an unorthodox manner: know we need to Shift %l1 into
325: ! the top decade: so do not even bother to compare to %i3.
326: 1: cmp %l1, %l3
327: bgeu 3f
328: mov 1, %l4
329: sll %l1, 3, %l1
330: b 1b
331: inc %l0
332: !
333: ! Now compute %l4
334: !
335: 2: addcc %l1, %l1, %l1
336: bcc not_too_big
337: add %l4, 1, %l4
338: !
339: ! We are here if the %i1 overflowed when Shifting.
340: ! This means that %i3 has the high-order bit set.
341: ! Restore %l1 and subtract from %i3.
342: sll %l3, 2, %l3
343: srl %l1, 1, %l1
344: add %l1, %l3, %l1
345: b do_single_div
346: dec %l4
347: not_too_big:
348: 3: cmp %l1, %i3
349: blu 2b
350: nop
351: be do_single_div
352: nop
353: ! %l1 > %i3: went too far: back up 1 step
354: ! srl %l1, 1, %l1
355: ! dec %l4
356: ! do single-bit divide steps
357: !
358: ! We have to be careful here. We know that %i3 >= %l1, so we can do the
359: ! first divide step without thinking. BUT, the others are conditional,
360: ! and are only done if %i3 >= 0. Because both %i3 and %l1 may have the
361: ! high-order bit set in the first step, just falling into the regular
362: ! division loop will mess up the first time around.
363: ! So we unroll slightly...
364: do_single_div:
365: deccc %l4
366: bl end_regular_divide
367: nop
368: sub %i3, %l1, %i3
369: mov 1, %i2
370: b end_single_divloop
371: nop
372: single_divloop:
373: sll %i2, 1, %i2
374: bl 1f
375: srl %l1, 1, %l1
376: ! %i3 >= 0
377: sub %i3, %l1, %i3
378: b 2f
379: inc %i2
380: 1: ! %i3 < 0
381: add %i3, %l1, %i3
382: dec %i2
383: end_single_divloop:
384: 2: deccc %l4
385: bge single_divloop
386: tst %i3
387: b end_regular_divide
388: nop
389: not_really_big:
390: 1: sll %l1, 3, %l1
391: cmp %l1, %i3
392: bleu 1b
393: inccc %l0
394: be got_result
395: dec %l0
396: do_regular_divide:
397: ! Do the main division iteration
398: tst %i3
399: ! Fall through into divide loop
400: divloop:
401: sll %i2, 3, %i2
402: ! depth 1, accumulated bits 0
403: bl L.1.8
404: srl %l1,1,%l1
405: ! remainder is positive
406: subcc %i3,%l1,%i3
407: ! depth 2, accumulated bits 1
408: bl L.2.9
409: srl %l1,1,%l1
410: ! remainder is positive
411: subcc %i3,%l1,%i3
412: ! depth 3, accumulated bits 3
413: bl L.3.11
414: srl %l1,1,%l1
415: ! remainder is positive
416: subcc %i3,%l1,%i3
417: b 9f
418: add %i2, (3*2+1), %i2
419: L.3.11: ! remainder is negative
420: addcc %i3,%l1,%i3
421: b 9f
422: add %i2, (3*2-1), %i2
423: L.2.9: ! remainder is negative
424: addcc %i3,%l1,%i3
425: ! depth 3, accumulated bits 1
426: bl L.3.9
427: srl %l1,1,%l1
428: ! remainder is positive
429: subcc %i3,%l1,%i3
430: b 9f
431: add %i2, (1*2+1), %i2
432: L.3.9: ! remainder is negative
433: addcc %i3,%l1,%i3
434: b 9f
435: add %i2, (1*2-1), %i2
436: L.1.8: ! remainder is negative
437: addcc %i3,%l1,%i3
438: ! depth 2, accumulated bits -1
439: bl L.2.7
440: srl %l1,1,%l1
441: ! remainder is positive
442: subcc %i3,%l1,%i3
443: ! depth 3, accumulated bits -1
444: bl L.3.7
445: srl %l1,1,%l1
446: ! remainder is positive
447: subcc %i3,%l1,%i3
448: b 9f
449: add %i2, (-1*2+1), %i2
450: L.3.7: ! remainder is negative
451: addcc %i3,%l1,%i3
452: b 9f
453: add %i2, (-1*2-1), %i2
454: L.2.7: ! remainder is negative
455: addcc %i3,%l1,%i3
456: ! depth 3, accumulated bits -3
457: bl L.3.5
458: srl %l1,1,%l1
459: ! remainder is positive
460: subcc %i3,%l1,%i3
461: b 9f
462: add %i2, (-3*2+1), %i2
463: L.3.5: ! remainder is negative
464: addcc %i3,%l1,%i3
465: b 9f
466: add %i2, (-3*2-1), %i2
467: end_regular_divide:
468: 9: deccc %l0
469: bge divloop
470: tst %i3
471: bge got_result
472: nop
473: ! non-restoring fixup here
474: add %i3, %i1, %i3
475: got_result:
476: tst %i2
477: bge 1f
478: restore
479: ! answer < 0
480: retl ! leaf-routine return
481: neg %o3, %o0 ! remainder <- -%i3
482: 1: retl ! leaf-routine return
483: mov %o3, %o0 ! remainder <- %i3
484: #endif
485:
486:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.