]> www.ginac.de Git - cln.git/blob - cl_asm_m68k_.cc
50a0a9b6465ff70763d2023ef9c390c1f39a44f8
[cln.git] / cl_asm_m68k_.cc
1 // Externe Routinen zu ARILEV1.D
2 // Prozessor: 680x0 mit x>=2
3 // Assembler-Syntax: meist "$" streichen, auf A/UX "$" durch "%" ersetzen
4 // Compiler: CC oder GNU-C auf SUN3 oder AMIGA oder A/UX
5 // Parameter-Übergabe:
6 //   auf dem Stack: sp@(4), sp@(8), ... (.W-Größen belegen 4 Byte!),
7 //   Rückgabewert in d0.
8 // Register a0-a1,d0-d1 frei verwendbar,
9 // Register a2-a4,d2-d7 müssen gerettet werden.
10 // Einstellungen: intCsize=16, intDsize=32.
11
12   #ifdef ASM_UNDERSCORE
13     #if defined(__STDC__) || defined (__cplusplus)
14       #define C(entrypoint) _##entrypoint
15     #else
16       #define C(entrypoint) _/**/entrypoint
17     #endif
18   #else
19     #define C(entrypoint) entrypoint
20   #endif
21
22   // Befehl, der das X- und das C-Bit löscht (und evtl. d1 modifiziert):
23   #if defined(sun)
24     // SUN-Assembler
25     #define clrx   subw $d1,$d1
26   #else
27     // GNU-Assembler
28     #if defined(__STDC__) || defined (__cplusplus)
29       // Some preprocessors keep the backslash in place, some don't.
30       // In any case, we will filter it out later.
31       #define clrx   andb \#0x0e,$ccr
32     #else
33       #define clrx   andb #0x0e,$ccr
34     #endif
35   #endif
36
37   // When this file is compiled into a shared library, ELF linkers need to
38   // know which symbols are functions.
39   #if defined(__NetBSD__) || defined(__OpenBSD__) || defined(__ELF__) || defined(__svr4__)
40     #define DECLARE_FUNCTION(name) .type C(name),@function
41   #else
42     #define DECLARE_FUNCTION(name)
43   #endif
44
45            .text
46
47            .globl C(copy_loop_up),C(copy_loop_down),C(fill_loop_up),C(fill_loop_down)
48            .globl C(clear_loop_up),C(clear_loop_down)
49            .globl C(test_loop_up),C(test_loop_down)
50            .globl C(xor_loop_up),C(compare_loop_up),C(shiftleftcopy_loop_up),C(shiftxor_loop_up)
51 #if CL_DS_BIG_ENDIAN_P
52            .globl C(or_loop_up),C(and_loop_up),C(eqv_loop_up)
53            .globl C(nand_loop_up),C(nor_loop_up),C(andc2_loop_up),C(orc2_loop_up)
54            .globl C(not_loop_up)
55            .globl C(and_test_loop_up)
56            .globl C(add_loop_down),C(addto_loop_down),C(inc_loop_down)
57            .globl C(sub_loop_down),C(subx_loop_down),C(subfrom_loop_down),C(dec_loop_down)
58            .globl C(neg_loop_down)
59            .globl C(shift1left_loop_down),C(shiftleft_loop_down),C(shiftleftcopy_loop_down)
60            .globl C(shift1right_loop_up),C(shiftright_loop_up),C(shiftrightsigned_loop_up),C(shiftrightcopy_loop_up)
61            .globl C(mulusmall_loop_down),C(mulu_loop_down),C(muluadd_loop_down),C(mulusub_loop_down)
62            .globl C(divu_loop_up),C(divucopy_loop_up)
63 #else
64            .globl C(or_loop_down),C(xor_loop_down),C(and_loop_down),C(eqv_loop_down)
65            .globl C(nand_loop_down),C(nor_loop_down),C(andc2_loop_down),C(orc2_loop_down)
66            .globl C(not_loop_down)
67            .globl C(and_test_loop_down),C(compare_loop_down)
68            .globl C(add_loop_up),C(addto_loop_up),C(inc_loop_up)
69            .globl C(sub_loop_up),C(subx_loop_up),C(subfrom_loop_up),C(dec_loop_up)
70            .globl C(neg_loop_up)
71            .globl C(shift1left_loop_up),C(shiftleft_loop_up)
72            .globl C(shift1right_loop_down),C(shiftright_loop_down),C(shiftrightsigned_loop_down),C(shiftrightcopy_loop_down)
73            .globl C(mulusmall_loop_up),C(mulu_loop_up),C(muluadd_loop_up),C(mulusub_loop_up)
74            .globl C(divu_loop_down),C(divucopy_loop_down)
75 #endif
76
77 #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
78            .globl C(mulu32_)
79 | extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
80 | 2^32*hi+lo := arg1*arg2.
81            DECLARE_FUNCTION(mulu32_)
82 C(mulu32_:) | Input in d0,d1, Output in d0,mulu32_high
83            movel $sp@(4),$d0
84            movel $sp@(8),$d1
85            mulul $d1,$d1:$d0
86            movel $d1,(C(mulu32_high)) | Adressierung?? Deklaration??
87            rts
88 #endif
89
90 #ifndef __GNUC__ /* mit GNU-C machen wir divu_6432_3232() als Macro, der inline dividiert */
91            .globl C(divu_6432_3232_)
92 | extern struct { uint32 q; uint32 r; } divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y);
93 | x = 2^32*xhi+xlo = q*y+r schreiben. Sei bekannt, daß 0 <= x < 2^32*y .
94            DECLARE_FUNCTION(divu_6432_3232_)
95 C(divu_6432_3232_:) | Input in d1,d0,d2, Output in d0,divu_32_rest
96            movel $sp@(4),$d1
97            movel $sp@(8),$d0
98            divul $sp@(12),$d1:$d0 | x = d1|d0 durch y dividieren
99            movel $d1,(C(divu_32_rest)) | Rest ablegen | Adressierung?? Deklaration??
100            rts
101 #endif
102
103 | extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
104            DECLARE_FUNCTION(copy_loop_up)
105 C(copy_loop_up:) | Input in a0,a1,d0.W, Output in d0
106            movel $sp@(4),$a0
107            movel $sp@(8),$a1
108            movew $sp@(12+2),$d0
109            bras 2f
110     1:       movel $a0@+,$a1@+
111     2:       dbra $d0,1b
112            movel $a1,$d0
113            rts
114
115 | extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
116            DECLARE_FUNCTION(copy_loop_down)
117 C(copy_loop_down:) | Input in a0,a1,d0.W, Output in d0
118            movel $sp@(4),$a0
119            movel $sp@(8),$a1
120            movew $sp@(12+2),$d0
121            bras 2f
122     1:       movel $a0@-,$a1@-
123     2:       dbra $d0,1b
124            movel $a1,$d0
125            rts
126
127 | extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
128            DECLARE_FUNCTION(fill_loop_up)
129 C(fill_loop_up:) | Input in a0,d0.W,d1, Output in d0
130            movel $sp@(4),$a0
131            movew $sp@(8+2),$d0
132            movel $sp@(12),$d1
133            bras 2f
134     1:       movel $d1,$a0@+
135     2:       dbra $d0,1b
136            movel $a0,$d0
137            rts
138
139 | extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
140            DECLARE_FUNCTION(fill_loop_down)
141 C(fill_loop_down:) | Input in a0,d0.W,d1, Output in d0
142            movel $sp@(4),$a0
143            movew $sp@(8+2),$d0
144            movel $sp@(12),$d1
145            bras 2f
146     1:       movel $d1,$a0@-
147     2:       dbra $d0,1b
148            movel $a0,$d0
149            rts
150
151 | extern uintD* clear_loop_up (uintD* destptr, uintC count);
152            DECLARE_FUNCTION(clear_loop_up)
153 C(clear_loop_up:) | Input in a0,d0.W, Output in d0
154            movel $sp@(4),$a0
155            movew $sp@(8+2),$d0
156            bras 2f
157     1:       clrl $a0@+
158     2:       dbra $d0,1b
159            movel $a0,$d0
160            rts
161
162 | extern uintD* clear_loop_down (uintD* destptr, uintC count);
163            DECLARE_FUNCTION(clear_loop_down)
164 C(clear_loop_down:) | Input in a0,d0.W, Output in d0
165            movel $sp@(4),$a0
166            movew $sp@(8+2),$d0
167            bras 2f
168     1:       clrl $a0@-
169     2:       dbra $d0,1b
170            movel $a0,$d0
171            rts
172
173 | extern boolean test_loop_up (uintD* ptr, uintC count);
174            DECLARE_FUNCTION(test_loop_up)
175 C(test_loop_up:) | Input in a0,d0.W, Output in d0.W=d0.L
176            movel $sp@(4),$a0
177            movew $sp@(8+2),$d0
178            bras 2f
179     1:       tstl $a0@+
180              bnes 3f
181     2:       dbra $d0,1b
182            clrl $d0
183            rts
184     3:     moveq #1,$d0
185            rts
186
187 | extern boolean test_loop_down (uintD* ptr, uintC count);
188            DECLARE_FUNCTION(test_loop_down)
189 C(test_loop_down:) | Input in a0,d0.W, Output in d0.W=d0.L
190            movel $sp@(4),$a0
191            movew $sp@(8+2),$d0
192            bras 2f
193     1:       tstl $a0@-
194              bnes 3f
195     2:       dbra $d0,1b
196            clrl $d0
197            rts
198     3:     moveq #1,$d0
199            rts
200
201 #if CL_DS_BIG_ENDIAN_P
202
203 | extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
204            DECLARE_FUNCTION(or_loop_up)
205 C(or_loop_up:) | Input in a0,a1,d0.W, verändert d1
206            movel $sp@(4),$a0
207            movel $sp@(8),$a1
208            movew $sp@(12+2),$d0
209            bras 2f
210     1:       movel $a1@+,$d1
211              orl $d1,$a0@+
212     2:       dbra $d0,1b
213            rts
214
215 #endif
216
217 | extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
218            DECLARE_FUNCTION(xor_loop_up)
219 C(xor_loop_up:) | Input in a0,a1,d0.W, verändert d1
220            movel $sp@(4),$a0
221            movel $sp@(8),$a1
222            movew $sp@(12+2),$d0
223            bras 2f
224     1:       movel $a1@+,$d1
225              eorl $d1,$a0@+
226     2:       dbra $d0,1b
227            rts
228
229 #if CL_DS_BIG_ENDIAN_P
230
231 | extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
232            DECLARE_FUNCTION(and_loop_up)
233 C(and_loop_up:) | Input in a0,a1,d0.W, verändert d1
234            movel $sp@(4),$a0
235            movel $sp@(8),$a1
236            movew $sp@(12+2),$d0
237            bras 2f
238     1:       movel $a1@+,$d1
239              andl $d1,$a0@+
240     2:       dbra $d0,1b
241            rts
242
243 | extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
244            DECLARE_FUNCTION(eqv_loop_up)
245 C(eqv_loop_up:) | Input in a0,a1,d0.W, verändert d1
246            movel $sp@(4),$a0
247            movel $sp@(8),$a1
248            movew $sp@(12+2),$d0
249            bras 2f
250     1:       movel $a1@+,$d1
251              eorl $d1,$a0@
252              notl $a0@+
253     2:       dbra $d0,1b
254            rts
255
256 | extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
257            DECLARE_FUNCTION(nand_loop_up)
258 C(nand_loop_up:) | Input in a0,a1,d0.W, verändert d1
259            movel $sp@(4),$a0
260            movel $sp@(8),$a1
261            movew $sp@(12+2),$d0
262            bras 2f
263     1:       movel $a1@+,$d1
264              andl $d1,$a0@
265              notl $a0@+
266     2:       dbra $d0,1b
267            rts
268
269 | extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
270            DECLARE_FUNCTION(nor_loop_up)
271 C(nor_loop_up:) | Input in a0,a1,d0.W, verändert d1
272            movel $sp@(4),$a0
273            movel $sp@(8),$a1
274            movew $sp@(12+2),$d0
275            bras 2f
276     1:       movel $a1@+,$d1
277              orl $d1,$a0@
278              notl $a0@+
279     2:       dbra $d0,1b
280            rts
281
282 | extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
283            DECLARE_FUNCTION(andc2_loop_up)
284 C(andc2_loop_up:) | Input in a0,a1,d0.W, verändert d1
285            movel $sp@(4),$a0
286            movel $sp@(8),$a1
287            movew $sp@(12+2),$d0
288            bras 2f
289     1:       movel $a1@+,$d1
290              notl $d1
291              andl $d1,$a0@+
292     2:       dbra $d0,1b
293            rts
294
295 | extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
296            DECLARE_FUNCTION(orc2_loop_up)
297 C(orc2_loop_up:) | Input in a0,a1,d0.W, verändert d1
298            movel $sp@(4),$a0
299            movel $sp@(8),$a1
300            movew $sp@(12+2),$d0
301            bras 2f
302     1:       movel $a1@+,$d1
303              notl $d1
304              orl $d1,$a0@+
305     2:       dbra $d0,1b
306            rts
307
308 | extern void not_loop_up (uintD* xptr, uintC count);
309            DECLARE_FUNCTION(not_loop_up)
310 C(not_loop_up:) | Input in a0,d0.W
311            movel $sp@(4),$a0
312            movew $sp@(8+2),$d0
313            bras 2f
314     1:       notl $a0@+
315     2:       dbra $d0,1b
316            rts
317
318 | extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
319            DECLARE_FUNCTION(and_test_loop_up)
320 C(and_test_loop_up:) | Input in a0,a1,d0.W, verändert d1, Output in d0.W=d0.L
321            movel $sp@(4),$a0
322            movel $sp@(8),$a1
323            movew $sp@(12+2),$d0
324            bras 2f
325     1:       movel $a0@+,$d1
326              andl $a1@+,$d1
327              bnes 3f
328     2:       dbra $d0,1b
329            clrl $d0
330            rts
331     3:     moveq #1,$d0
332            rts
333
334 #endif
335
336 | extern cl_signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
337            DECLARE_FUNCTION(compare_loop_up)
338 C(compare_loop_up:) | Input in a0,a1,d0.W, Output in d0.W=d0.L
339            movel $sp@(4),$a0
340            movel $sp@(8),$a1
341            movew $sp@(12+2),$d0
342            bras 2f
343     1:       cmpml $a1@+,$a0@+
344              bnes 3f
345     2:       dbra $d0,1b
346            clrl $d0
347            rts
348     3:     bcss 4f
349            moveq #1,$d0
350            rts
351     4:     moveq #-1,$d0
352            rts
353
354 #if CL_DS_BIG_ENDIAN_P
355
356 | extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
357            DECLARE_FUNCTION(add_loop_down)
358 C(add_loop_down:) | Input in a0,a1,a2,d0.W, verändert d1,d2, Output in d0
359            moveml $a2/$d2,$sp@-
360            movel $sp@(8+4),$a0
361            movel $sp@(8+8),$a1
362            movel $sp@(8+12),$a2
363            movew $sp@(8+16+2),$d0
364            clrx   | X-Bit löschen
365            bras 2f
366     1:       movel $a0@-,$d1
367              movel $a1@-,$d2
368              addxl $d2,$d1
369              movel $d1,$a2@-
370     2:       dbra $d0,1b
371            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
372            moveml $sp@+,$a2/$d2
373            rts
374
375 | extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
376            DECLARE_FUNCTION(addto_loop_down)
377 C(addto_loop_down:) | Input in a0,a1,d0.W, Output in d0
378            movel $sp@(4),$a0
379            movel $sp@(8),$a1
380            movew $sp@(12+2),$d0
381            clrx   | X-Bit löschen
382            bras 2f
383     1:       addxl $a0@-,$a1@-
384     2:       dbra $d0,1b
385            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
386            rts
387
388 | extern uintD inc_loop_down (uintD* ptr, uintC count);
389            DECLARE_FUNCTION(inc_loop_down)
390 C(inc_loop_down:) | Input in a0,d0.W, Output in d0
391            movel $sp@(4),$a0
392            movew $sp@(8+2),$d0
393            dbra $d0,1f          | simuliere gesetzten Carry
394            moveq #-1,$d0     | d0.L=-1 für Übertrag
395            rts
396     1:       addql #1,$a0@-
397              dbcc $d0,1b
398            subxl $d0,$d0       | kein Carry -> d0.L=0, sonst d0.L=-1 für Übertrag
399            rts
400
401 | extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
402            DECLARE_FUNCTION(sub_loop_down)
403 C(sub_loop_down:) | Input in a0,a1,a2,d0.W, verändert d1,d2, Output in d0
404            moveml $a2/$d2,$sp@-
405            movel $sp@(8+4),$a0
406            movel $sp@(8+8),$a1
407            movel $sp@(8+12),$a2
408            movew $sp@(8+16+2),$d0
409            clrx   | X-Bit löschen
410            bras 2f
411     1:       movel $a0@-,$d1
412              movel $a1@-,$d2
413              subxl $d2,$d1
414              movel $d1,$a2@-
415     2:       dbra $d0,1b
416            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
417            moveml $sp@+,$a2/$d2
418            rts
419
420 | extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
421            DECLARE_FUNCTION(subx_loop_down)
422 C(subx_loop_down:) | Input in a0,a1,a2,d0.W,d1, verändert d2, Output in d0
423            moveml $a2/$d2,$sp@-
424            movel $sp@(8+4),$a0
425            movel $sp@(8+8),$a1
426            movel $sp@(8+12),$a2
427            movew $sp@(8+16+2),$d0
428            movel $sp@(8+20),$d1
429            roxrl #1,$d1      | X-Bit initialisieren
430            bras 2f
431     1:       movel $a0@-,$d1
432              movel $a1@-,$d2
433              subxl $d2,$d1
434              movel $d1,$a2@-
435     2:       dbra $d0,1b
436            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
437            moveml $sp@+,$a2/$d2
438            rts
439
440 | extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
441            DECLARE_FUNCTION(subfrom_loop_down)
442 C(subfrom_loop_down:) | Input in a0,a1,d0.W, Output in d0
443            movel $sp@(4),$a0
444            movel $sp@(8),$a1
445            movew $sp@(12+2),$d0
446            clrx   | X-Bit löschen
447            bras 2f
448     1:       subxl $a0@-,$a1@-
449     2:       dbra $d0,1b
450            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
451            rts
452
453 | extern uintD dec_loop_down (uintD* ptr, uintC count);
454            DECLARE_FUNCTION(dec_loop_down)
455 C(dec_loop_down:) | Input in a0,d0.W, Output in d0
456            movel $sp@(4),$a0
457            movew $sp@(8+2),$d0
458            dbra $d0,1f          | simuliere gesetzten Carry
459            moveq #-1,$d0     | d0.L=-1 als Übertrag
460            rts
461     1:       subql #1,$a0@-
462              dbcc $d0,1b       | kein Carry -> Schleife abbrechen
463            subxl $d0,$d0       | kein Carry -> d0.L=0, sonst d0.L=-1 als Übertrag
464            rts
465
466 | extern uintD neg_loop_down (uintD* ptr, uintC count);
467            DECLARE_FUNCTION(neg_loop_down)
468 C(neg_loop_down:) | Input in a0,d0.W, Output in d0
469            movel $sp@(4),$a0
470            movew $sp@(8+2),$d0
471            clrx   | X-Bit löschen
472            bras 2f
473     1:       negxl $a0@-
474     2:       dbra $d0,1b
475            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
476            rts
477
478 | extern uintD shift1left_loop_down (uintD* ptr, uintC count);
479            DECLARE_FUNCTION(shift1left_loop_down)
480 C(shift1left_loop_down:) | Input in a0,d0.W, Output in d0.L
481            movel $sp@(4),$a0
482            movew $sp@(8+2),$d0
483            clrx   | X-Bit löschen
484            bras 2f
485     1:       roxlw $a0@-     | Digit a0@- um 1 Bit links schieben, X-Bit als Buffer
486              roxlw $a0@-
487     2:       dbra $d0,1b
488            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
489            rts
490
491 | extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
492            DECLARE_FUNCTION(shiftleft_loop_down)
493 C(shiftleft_loop_down:) | Input in a0,d0.W,d1.W,d2, Output in d0
494 #if 1
495            moveml $d2-$d5,$sp@-
496            movel $sp@(16+4),$a0
497            movew $sp@(16+8+2),$d0
498            movew $sp@(16+12+2),$d1
499            movel $sp@(16+16),$d2
500            moveq #32,$d5
501            subw $d1,$d5
502            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
503            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
504            bras 2f
505     1:       movel $a0@-,$d3  | d3.L = neues Digit
506              movel $d3,$d4
507              lsll $d1,$d4      | um i Bits nach links schieben
508              orl $d2,$d4       | mit vorigem Übertrag kombinieren
509              movel $d4,$a0@   | 32 Bits ablegen
510              movel $d3,$d2
511              lsrl $d5,$d2      | neuen Übertrag bilden
512     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
513            movel $d2,$d0
514            moveml $sp@+,$d2-$d5
515            rts
516 #else
517            moveml $d2-$d5,$sp@-
518            movel $sp@(16+4),$a0
519            movew $sp@(16+8+2),$d0
520            movew $sp@(16+12+2),$d1
521            movel $sp@(16+16),$d2
522            moveq #1,$d5
523            lsll $d1,$d5
524            subql #1,$d5
525            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^i-1
526            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
527            bras 2f
528     1:       movel $a0@-,$d3  | d3.L = neues Digit
529              roll $d1,$d3      | um i Bits links rotieren
530              movel $d3,$d4
531              andl $d5,$d3      | untere i Bits in d3
532              eorl $d3,$d4      | obere 32-i Bits in d4
533              orl $d2,$d4       | mit vorigem übertrag kombinieren
534              movel $d4,$a0@   | 32 Bits ablegen
535              movel $d3,$d2     | neuer Übertrag
536     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
537            movel $d2,$d0
538            moveml $sp@+,$d2-$d5
539            rts
540 #endif
541
542 | extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
543            DECLARE_FUNCTION(shiftleftcopy_loop_down)
544 C(shiftleftcopy_loop_down:) | Input in a0,a1,d0.W,d1.W, Output in d0
545 #if 1
546            moveml $d2-$d5,$sp@-
547            movel $sp@(16+4),$a0
548            movel $sp@(16+8),$a1
549            movew $sp@(16+12+2),$d0
550            movew $sp@(16+16+2),$d1
551            moveq #32,$d5
552            subw $d1,$d5
553            clrl $d2
554            | a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i, d5.W = 32-i,
555            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
556            bras 2f
557     1:       movel $a0@-,$d3  | d3.L = neues Digit
558              movel $d3,$d4
559              lsll $d1,$d4      | um i Bits nach links schieben
560              orl $d2,$d4       | mit vorigem Übertrag kombinieren
561              movel $d4,$a1@-  | 32 Bits ablegen
562              movel $d3,$d2
563              lsrl $d5,$d2      | neuen Übertrag bilden
564     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
565            movel $d2,$d0
566            moveml $sp@+,$d2-$d5
567            rts
568 #else
569            moveml $d2-$d5,$sp@-
570            movel $sp@(16+4),$a0
571            movel $sp@(16+8),$a1
572            movew $sp@(16+12+2),$d0
573            movew $sp@(16+16+2),$d1
574            moveq #1,$d5
575            lsll $d1,$d5
576            subql #1,$d5
577            | a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i, d5.L = 2^i-1
578            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
579            bras 2f
580     1:       movel $a0@-,$d3  | d3.L = neues Digit
581              roll $d1,$d3      | um i Bits links rotieren
582              movel $d3,$d4
583              andl $d5,$d3      | untere i Bits in d3
584              eorl $d3,$d4      | obere 32-i Bits in d4
585              orl $d2,$d4       | mit vorigem übertrag kombinieren
586              movel $d4,$a1@-  | 32 Bits ablegen
587              movel $d3,$d2     | neuer Übertrag
588     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
589            movel $d2,$d0
590            moveml $sp@+,$d2-$d5
591            rts
592 #endif
593
594 | extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
595            DECLARE_FUNCTION(shift1right_loop_up)
596 C(shift1right_loop_up:) | Input in a0,d0.W,d1, Output in d0
597            movel $sp@(4),$a0
598            movew $sp@(8+2),$d0
599            movel $sp@(12),$d1
600            roxrl #1,$d1       | X-Bit löschen oder setzen, je nach d1
601            bras 2f
602     1:       roxrw $a0@+     | Digit a0@+ um 1 Bit rechts schieben, X-Bit als Buffer
603              roxrw $a0@+
604     2:       dbra $d0,1b
605            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
606            rts
607
608 | extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
609            DECLARE_FUNCTION(shiftright_loop_up)
610 C(shiftright_loop_up:) | Input in a0,d0.W,d1.W, Output in d0
611 #if 1
612            moveml $d2-$d5,$sp@-
613            movel $sp@(16+4),$a0
614            movew $sp@(16+8+2),$d0
615            movew $sp@(16+12+2),$d1
616            moveq #32,$d5
617            subw $d1,$d5
618            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
619            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
620            clrl $d2
621            bras 2f
622     1:       | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i,
623              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
624              | d3.L = Schiebe-Akku
625              movel $a0@,$d3   | neue Daten
626              movel $d3,$d4
627              lsrl $d1,$d3      | um i Bits rechts schieben
628              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
629              movel $d3,$a0@+  | ablegen
630              lsll $d5,$d4      | um (32-i) Bits links geschoben
631              movel $d4,$d2     | liefert neuen Übertrag
632     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
633            movel $d2,$d0
634            moveml $sp@+,$d2-$d5
635            rts
636 #else
637            moveml $d2-$d5,$sp@-
638            movel $sp@(16+4),$a0
639            movew $sp@(16+8+2),$d0
640            movew $sp@(16+12+2),$d1
641            moveq #-1,$d5
642            lsrl $d1,$d5
643            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1,
644            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
645            clrl $d2
646            bras 2f
647     1:       | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1,
648              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
649              | d3.L = Schiebe-Akku
650              movel $a0@,$d3   | neue Daten
651              rorl $d1,$d3      | um i Bits rechts rotieren
652              movel $d3,$d4
653              andl $d5,$d3      | untere 32-i Bits
654              eorl $d3,$d4      | obere i Bits
655              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
656              movel $d4,$d2     | neuer Übertrag
657              movel $d3,$a0@+  | ablegen
658     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
659            movel $d2,$d0
660            moveml $sp@+,$d2-$d5
661            rts
662 #endif
663
664 | extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
665            DECLARE_FUNCTION(shiftrightsigned_loop_up)
666 C(shiftrightsigned_loop_up:) | Input in a0,d0.W,d1.W, Output in d0
667 #if 1
668            moveml $d2-$d5,$sp@-
669            movel $sp@(16+4),$a0
670            movew $sp@(16+8+2),$d0
671            movew $sp@(16+12+2),$d1
672            moveq #32,$d5
673            subw $d1,$d5
674            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
675            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
676            subqw #1,$d0
677            movel $a0@,$d3     | erstes Digit
678            movel $d3,$d4
679            asrl $d1,$d3        | um i Bits rechts schieben
680            bras 2f
681     1:       | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i,
682              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
683              | d3.L = Schiebe-Akku
684              movel $a0@,$d3   | neue Daten
685              movel $d3,$d4
686              lsrl $d1,$d3      | um i Bits rechts schieben
687              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
688     2:       movel $d3,$a0@+  | ablegen
689              lsll $d5,$d4      | um (32-i) Bits links geschoben
690              movel $d4,$d2     | liefert neuen Übertrag
691              dbra $d0,1b        | Schleife d0.W mal durchlaufen
692            movel $d2,$d0
693            moveml $sp@+,$d2-$d5
694            rts
695 #else
696            moveml $d2-$d5,$sp@-
697            movel $sp@(16+4),$a0
698            movew $sp@(16+8+2),$d0
699            movew $sp@(16+12+2),$d1
700            moveq #-1,$d5
701            lsrl $d1,$d5
702            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1,
703            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
704            subqw #1,$d0
705            movel $a0@,$d3     | erstes Digit
706            movel $d3,$d4
707            rorl $d1,$d4        | um i Bits rechts rotieren
708            movel $d5,$d2
709            notl $d2
710            andl $d4,$d2        | obere 32-i Bits
711            asrl $d1,$d3        | erstes Digit um i Bits rechts shiften
712            bras 2f
713     1:       | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1,
714              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
715              | d3.L = Schiebe-Akku
716              movel $a0@,$d3   | neue Daten
717              rorl $d1,$d3      | um i Bits rechts rotieren
718              movel $d3,$d4
719              andl $d5,$d3      | untere 32-i Bits
720              eorl $d3,$d4      | obere i Bits
721              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
722              movel $d4,$d2     | neuer Übertrag
723     2:       movel $d3,$a0@+  | ablegen
724              dbra $d0,1b        | Schleife d0.W mal durchlaufen
725            movel $d2,$d0
726            moveml $sp@+,$d2-$d5
727            rts
728 #endif
729
730 | extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
731            DECLARE_FUNCTION(shiftrightcopy_loop_up)
732 C(shiftrightcopy_loop_up:) | Input in a0,a1,d0.W,d1.W,d2, Output in d0
733 #if 1
734            moveml $d2-$d5,$sp@-
735            movel $sp@(16+4),$a0
736            movel $sp@(16+8),$a1
737            movew $sp@(16+12+2),$d0
738            movew $sp@(16+16+2),$d1
739            movel $sp@(16+20),$d2
740            moveq #32,$d5
741            subw $d1,$d5
742            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i
743            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
744            bras 2f
745     1:       | a0,a1 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i
746              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
747              | d3.L = Schiebe-Akku
748              movel $a0@+,$d3  | neue Daten
749              movel $d3,$d4
750              lsrl $d1,$d3      | um i Bits rechts schieben
751              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
752              movel $d3,$a1@+  | ablegen
753              movel $d4,$d2
754     2:       lsll $d5,$d2      | um (32-i) Bits links geschoben, gibt neuen Übertrag
755              dbra $d0,1b        | Schleife d0.W mal durchlaufen
756            movel $d2,$d0
757            moveml $sp@+,$d2-$d5
758            rts
759 #else
760            moveml $d2-$d5,$sp@-
761            movel $sp@(16+4),$a0
762            movel $sp@(16+8),$a1
763            movew $sp@(16+12+2),$d0
764            movew $sp@(16+16+2),$d1
765            movel $sp@(16+20),$d2
766            moveq #-1,$d5
767            lsrl $d1,$d5
768            rorl $d1,$d2
769            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1
770            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
771            bras 2f
772     1:       | a0,a1 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1
773              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
774              | d3.L = Schiebe-Akku
775              movel $a0@+,$d3  | neue Daten
776              rorl $d1,$d3      | um i Bits rechts rotieren
777              movel $d3,$d4
778              andl $d5,$d3      | untere 32-i Bits
779              eorl $d3,$d4      | obere i Bits
780              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
781              movel $d4,$d2     | neuer Übertrag
782              movel $d3,$a1@+  | ablegen
783     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
784            movel $d2,$d0
785            moveml $sp@+,$d2-$d5
786            rts
787 #endif
788
789 | extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
790            DECLARE_FUNCTION(mulusmall_loop_down)
791 C(mulusmall_loop_down:) | Input in d0,a0,d1.W,d2, Output in d0
792            moveml $d2-$d4,$sp@-
793            movel $sp@(12+4),$d0
794            movel $sp@(12+8),$a0
795            movew $sp@(12+12+2),$d1
796            movel $sp@(12+16),$d2
797            addw #0,$d1        | X-Bit löschen
798            bras 2f
799     1:       movel $a0@-,$d3  | nächstes Digit
800              mulul $d0,$d4:$d3  | mit digit multiplizieren
801              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
802              movel $d3,$a0@   | Low-Digit ablegen
803              movel $d4,$d2     | High-Digit gibt neuen Carry
804     2:       dbra $d1,1b
805            clrl $d0
806            addxl $d2,$d0       | letzter Carry (incl. X-Bit)
807            moveml $sp@+,$d2-$d4
808            rts
809
810 | extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
811            DECLARE_FUNCTION(mulu_loop_down)
812 C(mulu_loop_down:) | Input in d0,a0,a1,d1.W
813 #if 1
814            moveml $d2-$d4,$sp@-
815            movel $sp@(12+4),$d0
816            movel $sp@(12+8),$a0
817            movel $sp@(12+12),$a1
818            movew $sp@(12+16+2),$d1
819            subl $d2,$d2        | carry := 0, X-Bit löschen
820            bras 2f
821     1:       movel $a0@-,$d3  | nächstes Digit
822              mulul $d0,$d4:$d3  | mit digit multiplizieren
823              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
824              movel $d3,$a1@-  | Low-Digit ablegen
825              movel $d4,$d2     | High-Digit gibt neuen Carry
826     2:       dbra $d1,1b
827            clrl $d3
828            addxl $d3,$d2       | letztes X-Bit verarbeiten
829            movel $d2,$a1@-    | letzten Carry ablegen
830            moveml $sp@+,$d2-$d4
831            rts
832 #else
833            moveml $d2-$d5,$sp@-
834            movel $sp@(16+4),$d0
835            movel $sp@(16+8),$a0
836            movel $sp@(16+12),$a1
837            movew $sp@(16+16+2),$d1
838            clrl $d5           | 0
839            clrl $d2           | carry
840            bras 2f
841     1:       movel $a0@-,$d3  | nächstes Digit
842              mulul $d0,$d4:$d3  | mit digit multiplizieren
843              addl $d2,$d3      | und bisherigen Carry addieren
844              addxl $d5,$d4
845              movel $d3,$a1@-  | Low-Digit ablegen
846              movel $d4,$d2     | High-Digit gibt neuen Carry
847     2:       dbra $d1,1b
848            movel $d2,$a1@-    | letzten Carry ablegen
849            moveml $sp@+,$d2-$d5
850            rts
851 #endif
852
853 | extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
854            DECLARE_FUNCTION(muluadd_loop_down)
855 C(muluadd_loop_down:) | Input in d0,a0,a1,d1.W, Output in d0
856            moveml $d2-$d5,$sp@-
857            movel $sp@(16+4),$d0
858            movel $sp@(16+8),$a0
859            movel $sp@(16+12),$a1
860            movew $sp@(16+16+2),$d1
861            clrl $d5           | 0
862            subl $d2,$d2        | carry := 0, X-Bit löschen
863            bras 2f
864     1:       movel $a0@-,$d3  | nächstes Digit
865              mulul $d0,$d4:$d3  | mit digit multiplizieren
866              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
867              addxl $d5,$d4
868              addl $d3,$a1@-   | Low-Digit zum dest-Digit addieren, X als Übertrag
869              movel $d4,$d2     | High-Digit gibt neuen Carry
870     2:       dbra $d1,1b
871            addxl $d5,$d2       | letztes X-Bit addieren
872            movel $d2,$d0       | letzten Carry als Ergebnis
873            moveml $sp@+,$d2-$d5
874            rts
875
876 | extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
877            DECLARE_FUNCTION(mulusub_loop_down)
878 C(mulusub_loop_down:) | Input in d0,a0,a1,d1.W, Output in d0
879            moveml $d2-$d5,$sp@-
880            movel $sp@(16+4),$d0
881            movel $sp@(16+8),$a0
882            movel $sp@(16+12),$a1
883            movew $sp@(16+16+2),$d1
884            clrl $d5           | 0
885            subl $d2,$d2        | carry := 0, X-Bit löschen
886            bras 2f
887     1:       movel $a0@-,$d3  | nächstes Digit
888              mulul $d0,$d4:$d3  | mit digit multiplizieren
889              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
890              addxl $d5,$d4
891              subl $d3,$a1@-   | Low-Digit vom dest-Digit subtrahieren, X als Übertrag
892              movel $d4,$d2     | High-Digit gibt neuen Carry
893     2:       dbra $d1,1b
894            clrl $d0
895            addxl $d2,$d0       | letzter Carry und letztes X-Bit
896            moveml $sp@+,$d2-$d5
897            rts
898
899 | extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
900            DECLARE_FUNCTION(divu_loop_up)
901 C(divu_loop_up:) | Input in d0,a0,d1.W, Output in d0
902            moveml $d2-$d3,$sp@-
903            movel $sp@(8+4),$d0
904            movel $sp@(8+8),$a0
905            movew $sp@(8+12+2),$d1
906            clrl $d2           | Rest := 0
907            bras 2f
908     1:       movel $a0@,$d3   | nächst-niedriges Digit
909              divul $d0,$d2:$d3  | mit Rest kombinieren und durch digit dividieren
910              movel $d3,$a0@+  | Quotient ablegen, Rest in d2
911     2:       dbra $d1,1b
912            movel $d2,$d0       | Rest
913            moveml $sp@+,$d2-$d3
914            rts
915
916 | extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
917            DECLARE_FUNCTION(divucopy_loop_up)
918 C(divucopy_loop_up:) | Input in d0,a0,a1,d1.W, Output in d0
919            moveml $d2-$d3,$sp@-
920            movel $sp@(8+4),$d0
921            movel $sp@(8+8),$a0
922            movel $sp@(8+12),$a1
923            movew $sp@(8+16+2),$d1
924            clrl $d2           | Rest := 0
925            bras 2f
926     1:       movel $a0@+,$d3  | nächst-niedriges Digit
927              divul $d0,$d2:$d3  | mit Rest kombinieren und durch digit dividieren
928              movel $d3,$a1@+  | Quotient ablegen, Rest in d2
929     2:       dbra $d1,1b
930            movel $d2,$d0       | Rest
931            moveml $sp@+,$d2-$d3
932            rts
933
934 #endif
935
936 #if !CL_DS_BIG_ENDIAN_P
937
938 | extern void or_loop_down (uintD* xptr, uintD* yptr, uintC count);
939            DECLARE_FUNCTION(or_loop_down)
940 C(or_loop_down:) | Input in a0,a1,d0.W, verändert d1
941            movel $sp@(4),$a0
942            movel $sp@(8),$a1
943            movew $sp@(12+2),$d0
944            bras 2f
945     1:       movel $a1@-,$d1
946              orl $d1,$a0@-
947     2:       dbra $d0,1b
948            rts
949
950 | extern void xor_loop_down (uintD* xptr, uintD* yptr, uintC count);
951            DECLARE_FUNCTION(xor_loop_down)
952 C(xor_loop_down:) | Input in a0,a1,d0.W, verändert d1
953            movel $sp@(4),$a0
954            movel $sp@(8),$a1
955            movew $sp@(12+2),$d0
956            bras 2f
957     1:       movel $a1@-,$d1
958              eorl $d1,$a0@-
959     2:       dbra $d0,1b
960            rts
961
962 | extern void and_loop_down (uintD* xptr, uintD* yptr, uintC count);
963            DECLARE_FUNCTION(and_loop_down)
964 C(and_loop_down:) | Input in a0,a1,d0.W, verändert d1
965            movel $sp@(4),$a0
966            movel $sp@(8),$a1
967            movew $sp@(12+2),$d0
968            bras 2f
969     1:       movel $a1@-,$d1
970              andl $d1,$a0@-
971     2:       dbra $d0,1b
972            rts
973
974 | extern void eqv_loop_down (uintD* xptr, uintD* yptr, uintC count);
975            DECLARE_FUNCTION(eqv_loop_down)
976 C(eqv_loop_down:) | Input in a0,a1,d0.W, verändert d1
977            movel $sp@(4),$a0
978            movel $sp@(8),$a1
979            movew $sp@(12+2),$d0
980            bras 2f
981     1:       movel $a1@-,$d1
982              eorl $d1,$a0@-
983              notl $a0@
984     2:       dbra $d0,1b
985            rts
986
987 | extern void nand_loop_down (uintD* xptr, uintD* yptr, uintC count);
988            DECLARE_FUNCTION(nand_loop_down)
989 C(nand_loop_down:) | Input in a0,a1,d0.W, verändert d1
990            movel $sp@(4),$a0
991            movel $sp@(8),$a1
992            movew $sp@(12+2),$d0
993            bras 2f
994     1:       movel $a1@-,$d1
995              andl $d1,$a0@-
996              notl $a0@
997     2:       dbra $d0,1b
998            rts
999
1000 | extern void nor_loop_down (uintD* xptr, uintD* yptr, uintC count);
1001            DECLARE_FUNCTION(nor_loop_down)
1002 C(nor_loop_down:) | Input in a0,a1,d0.W, verändert d1
1003            movel $sp@(4),$a0
1004            movel $sp@(8),$a1
1005            movew $sp@(12+2),$d0
1006            bras 2f
1007     1:       movel $a1@-,$d1
1008              orl $d1,$a0@-
1009              notl $a0@
1010     2:       dbra $d0,1b
1011            rts
1012
1013 | extern void andc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
1014            DECLARE_FUNCTION(andc2_loop_down)
1015 C(andc2_loop_down:) | Input in a0,a1,d0.W, verändert d1
1016            movel $sp@(4),$a0
1017            movel $sp@(8),$a1
1018            movew $sp@(12+2),$d0
1019            bras 2f
1020     1:       movel $a1@-,$d1
1021              notl $d1
1022              andl $d1,$a0@-
1023     2:       dbra $d0,1b
1024            rts
1025
1026 | extern void orc2_loop_down (uintD* xptr, uintD* yptr, uintC count);
1027            DECLARE_FUNCTION(orc2_loop_down)
1028 C(orc2_loop_down:) | Input in a0,a1,d0.W, verändert d1
1029            movel $sp@(4),$a0
1030            movel $sp@(8),$a1
1031            movew $sp@(12+2),$d0
1032            bras 2f
1033     1:       movel $a1@-,$d1
1034              notl $d1
1035              orl $d1,$a0@-
1036     2:       dbra $d0,1b
1037            rts
1038
1039 | extern void not_loop_down (uintD* xptr, uintC count);
1040            DECLARE_FUNCTION(not_loop_down)
1041 C(not_loop_down:) | Input in a0,d0.W
1042            movel $sp@(4),$a0
1043            movew $sp@(8+2),$d0
1044            bras 2f
1045     1:       notl $a0@-
1046     2:       dbra $d0,1b
1047            rts
1048
1049 | extern boolean and_test_loop_down (uintD* xptr, uintD* yptr, uintC count);
1050            DECLARE_FUNCTION(and_test_loop_down)
1051 C(and_test_loop_down:) | Input in a0,a1,d0.W, verändert d1, Output in d0.W=d0.L
1052            movel $sp@(4),$a0
1053            movel $sp@(8),$a1
1054            movew $sp@(12+2),$d0
1055            bras 2f
1056     1:       movel $a0@-,$d1
1057              andl $a1@-,$d1
1058              bnes 3f
1059     2:       dbra $d0,1b
1060            clrl $d0
1061            rts
1062     3:     moveq #1,$d0
1063            rts
1064
1065 | extern cl_signean compare_loop_down (uintD* xptr, uintD* yptr, uintC count);
1066            DECLARE_FUNCTION(compare_loop_down)
1067 C(compare_loop_down:) | Input in a0,a1,d0.W, verändert d1,d2, Output in d0.W=d0.L
1068            movel $d2,$sp@-
1069            movel $sp@(4+4),$a0
1070            movel $sp@(4+8),$a1
1071            movew $sp@(4+12+2),$d0
1072            bras 2f
1073     1:       movel $a0@-,$d1
1074              movel $a1@-,$d2
1075              cmpl $d2,$d1
1076              bnes 3f
1077     2:       dbra $d0,1b
1078            clrl $d0
1079            movel $sp@+,$d2
1080            rts
1081     3:     bcss 4f
1082            moveq #1,$d0
1083            movel $sp@+,$d2
1084            rts
1085     4:     moveq #-1,$d0
1086            movel $sp@+,$d2
1087            rts
1088
1089 | extern uintD add_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
1090            DECLARE_FUNCTION(add_loop_up)
1091 C(add_loop_up:) | Input in a0,a1,a2,d0.W, verändert d1,d2, Output in d0
1092            moveml $a2/$d2,$sp@-
1093            movel $sp@(8+4),$a0
1094            movel $sp@(8+8),$a1
1095            movel $sp@(8+12),$a2
1096            movew $sp@(8+16+2),$d0
1097            clrx   | X-Bit löschen
1098            bras 2f
1099     1:       movel $a0@+,$d1
1100              movel $a1@+,$d2
1101              addxl $d2,$d1
1102              movel $d1,$a2@+
1103     2:       dbra $d0,1b
1104            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
1105            moveml $sp@+,$a2/$d2
1106            rts
1107
1108 | extern uintD addto_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
1109            DECLARE_FUNCTION(addto_loop_up)
1110 C(addto_loop_up:) | Input in a0,a1,d0.W, verändert d1,d2, Output in d0
1111            movel $d2,$sp@-
1112            movel $sp@(4+4),$a0
1113            movel $sp@(4+8),$a1
1114            movew $sp@(4+12+2),$d0
1115            clrx   | X-Bit löschen
1116            bras 2f
1117     1:       movel $a0@+,$d1
1118              movel $a1@,$d2
1119              addxl $d1,$d2
1120              movel $d2,$a1@+
1121     2:       dbra $d0,1b
1122            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
1123            movel $sp@+,$d2
1124            rts
1125
1126 | extern uintD inc_loop_up (uintD* ptr, uintC count);
1127            DECLARE_FUNCTION(inc_loop_up)
1128 C(inc_loop_up:) | Input in a0,d0.W, Output in d0
1129            movel $sp@(4),$a0
1130            movew $sp@(8+2),$d0
1131            dbra $d0,1f          | simuliere gesetzten Carry
1132            moveq #-1,$d0     | d0.L=-1 für Übertrag
1133            rts
1134     1:       addql #1,$a0@+
1135              dbcc $d0,1b
1136            subxl $d0,$d0       | kein Carry -> d0.L=0, sonst d0.L=-1 für Übertrag
1137            rts
1138
1139 | extern uintD sub_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
1140            DECLARE_FUNCTION(sub_loop_up)
1141 C(sub_loop_up:) | Input in a0,a1,a2,d0.W, verändert d1,d2, Output in d0
1142            moveml $a2/$d2,$sp@-
1143            movel $sp@(8+4),$a0
1144            movel $sp@(8+8),$a1
1145            movel $sp@(8+12),$a2
1146            movew $sp@(8+16+2),$d0
1147            clrx   | X-Bit löschen
1148            bras 2f
1149     1:       movel $a0@+,$d1
1150              movel $a1@+,$d2
1151              subxl $d2,$d1
1152              movel $d1,$a2@+
1153     2:       dbra $d0,1b
1154            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
1155            moveml $sp@+,$a2/$d2
1156            rts
1157
1158 | extern uintD subx_loop_up (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
1159            DECLARE_FUNCTION(subx_loop_up)
1160 C(subx_loop_up:) | Input in a0,a1,a2,d0.W,d1, verändert d2, Output in d0
1161            moveml $a2/$d2,$sp@-
1162            movel $sp@(8+4),$a0
1163            movel $sp@(8+8),$a1
1164            movel $sp@(8+12),$a2
1165            movew $sp@(8+16+2),$d0
1166            movel $sp@(8+20),$d1
1167            roxrl #1,$d1      | X-Bit initialisieren
1168            bras 2f
1169     1:       movel $a0@+,$d1
1170              movel $a1@+,$d2
1171              subxl $d2,$d1
1172              movel $d1,$a2@+
1173     2:       dbra $d0,1b
1174            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
1175            moveml $sp@+,$a2/$d2
1176            rts
1177
1178 | extern uintD subfrom_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
1179            DECLARE_FUNCTION(subfrom_loop_up)
1180 C(subfrom_loop_up:) | Input in a0,a1,d0.W, Output in d0
1181            movel $sp@(4),$a0
1182            movel $sp@(8),$a1
1183            movew $sp@(12+2),$d0
1184            clrx   | X-Bit löschen
1185            bras 2f
1186     1:       movel $a0@+,$d1
1187              movel $a1@,$d2
1188              subxl $d1,$d2
1189              movel $d2,$a1@+
1190     2:       dbra $d0,1b
1191            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
1192            rts
1193
1194 | extern uintD dec_loop_up (uintD* ptr, uintC count);
1195            DECLARE_FUNCTION(dec_loop_up)
1196 C(dec_loop_up:) | Input in a0,d0.W, Output in d0
1197            movel $sp@(4),$a0
1198            movew $sp@(8+2),$d0
1199            dbra $d0,1f          | simuliere gesetzten Carry
1200            moveq #-1,$d0     | d0.L=-1 als Übertrag
1201            rts
1202     1:       subql #1,$a0@+
1203              dbcc $d0,1b       | kein Carry -> Schleife abbrechen
1204            subxl $d0,$d0       | kein Carry -> d0.L=0, sonst d0.L=-1 als Übertrag
1205            rts
1206
1207 | extern uintD neg_loop_up (uintD* ptr, uintC count);
1208            DECLARE_FUNCTION(neg_loop_up)
1209 C(neg_loop_up:) | Input in a0,d0.W, Output in d0
1210            movel $sp@(4),$a0
1211            movew $sp@(8+2),$d0
1212            clrx   | X-Bit löschen
1213            bras 2f
1214     1:       negxl $a0@+
1215     2:       dbra $d0,1b
1216            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
1217            rts
1218
1219 | extern uintD shift1left_loop_up (uintD* ptr, uintC count);
1220            DECLARE_FUNCTION(shift1left_loop_up)
1221 C(shift1left_loop_up:) | Input in a0,d0.W, verändert d1, Output in d0.L
1222            movel $sp@(4),$a0
1223            movew $sp@(8+2),$d0
1224            clrx   | X-Bit löschen
1225            bras 2f
1226     1:       movel $a0@,$d1
1227              roxll #1,$d1
1228              movel $d1,$a0@+
1229     2:       dbra $d0,1b
1230            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
1231            rts
1232
1233 | extern uintD shiftleft_loop_up (uintD* ptr, uintC count, uintC i, uintD carry);
1234            DECLARE_FUNCTION(shiftleft_loop_up)
1235 C(shiftleft_loop_up:) | Input in a0,d0.W,d1.W,d2, Output in d0
1236 #if 1
1237            moveml $d2-$d5,$sp@-
1238            movel $sp@(16+4),$a0
1239            movew $sp@(16+8+2),$d0
1240            movew $sp@(16+12+2),$d1
1241            movel $sp@(16+16),$d2
1242            moveq #32,$d5
1243            subw $d1,$d5
1244            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
1245            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1246            bras 2f
1247     1:       movel $a0@,$d3  | d3.L = neues Digit
1248              movel $d3,$d4
1249              lsll $d1,$d4      | um i Bits nach links schieben
1250              orl $d2,$d4       | mit vorigem Übertrag kombinieren
1251              movel $d4,$a0@+   | 32 Bits ablegen
1252              movel $d3,$d2
1253              lsrl $d5,$d2      | neuen Übertrag bilden
1254     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
1255            movel $d2,$d0
1256            moveml $sp@+,$d2-$d5
1257            rts
1258 #else
1259            moveml $d2-$d5,$sp@-
1260            movel $sp@(16+4),$a0
1261            movew $sp@(16+8+2),$d0
1262            movew $sp@(16+12+2),$d1
1263            movel $sp@(16+16),$d2
1264            moveq #1,$d5
1265            lsll $d1,$d5
1266            subql #1,$d5
1267            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^i-1
1268            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1269            bras 2f
1270     1:       movel $a0@,$d3  | d3.L = neues Digit
1271              roll $d1,$d3      | um i Bits links rotieren
1272              movel $d3,$d4
1273              andl $d5,$d3      | untere i Bits in d3
1274              eorl $d3,$d4      | obere 32-i Bits in d4
1275              orl $d2,$d4       | mit vorigem übertrag kombinieren
1276              movel $d4,$a0@+   | 32 Bits ablegen
1277              movel $d3,$d2     | neuer Übertrag
1278     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
1279            movel $d2,$d0
1280            moveml $sp@+,$d2-$d5
1281            rts
1282 #endif
1283
1284 #endif
1285
1286 | extern uintD shiftleftcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
1287            DECLARE_FUNCTION(shiftleftcopy_loop_up)
1288 C(shiftleftcopy_loop_up:) | Input in a0,a1,d0.W,d1.W, Output in d0
1289 #if 1
1290            moveml $d2-$d5,$sp@-
1291            movel $sp@(16+4),$a0
1292            movel $sp@(16+8),$a1
1293            movew $sp@(16+12+2),$d0
1294            movew $sp@(16+16+2),$d1
1295            moveq #32,$d5
1296            subw $d1,$d5
1297            clrl $d2
1298            | a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i, d5.W = 32-i,
1299            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1300            bras 2f
1301     1:       movel $a0@+,$d3  | d3.L = neues Digit
1302              movel $d3,$d4
1303              lsll $d1,$d4      | um i Bits nach links schieben
1304              orl $d2,$d4       | mit vorigem Übertrag kombinieren
1305              movel $d4,$a1@+  | 32 Bits ablegen
1306              movel $d3,$d2
1307              lsrl $d5,$d2      | neuen Übertrag bilden
1308     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
1309            movel $d2,$d0
1310            moveml $sp@+,$d2-$d5
1311            rts
1312 #else
1313            moveml $d2-$d5,$sp@-
1314            movel $sp@(16+4),$a0
1315            movel $sp@(16+8),$a1
1316            movew $sp@(16+12+2),$d0
1317            movew $sp@(16+16+2),$d1
1318            moveq #1,$d5
1319            lsll $d1,$d5
1320            subql #1,$d5
1321            | a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i, d5.L = 2^i-1
1322            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1323            bras 2f
1324     1:       movel $a0@+,$d3  | d3.L = neues Digit
1325              roll $d1,$d3      | um i Bits links rotieren
1326              movel $d3,$d4
1327              andl $d5,$d3      | untere i Bits in d3
1328              eorl $d3,$d4      | obere 32-i Bits in d4
1329              orl $d2,$d4       | mit vorigem übertrag kombinieren
1330              movel $d4,$a1@+  | 32 Bits ablegen
1331              movel $d3,$d2     | neuer Übertrag
1332     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
1333            movel $d2,$d0
1334            moveml $sp@+,$d2-$d5
1335            rts
1336 #endif
1337
1338 #if !CL_DS_BIG_ENDIAN_P
1339
1340 | extern uintD shift1right_loop_down (uintD* ptr, uintC count, uintD carry);
1341            DECLARE_FUNCTION(shift1right_loop_down)
1342 C(shift1right_loop_down:) | Input in a0,d0.W,d1, Output in d0
1343            movel $sp@(4),$a0
1344            movew $sp@(8+2),$d0
1345            movel $sp@(12),$d1
1346            roxrl #1,$d1       | X-Bit löschen oder setzen, je nach d1
1347            bras 2f
1348     1:       movel $a0@-,$d1
1349              roxrl #1,$d1
1350              movel $d1,$a0@
1351     2:       dbra $d0,1b
1352            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gelöscht
1353            rts
1354
1355 | extern uintD shiftright_loop_down (uintD* ptr, uintC count, uintC i);
1356            DECLARE_FUNCTION(shiftright_loop_down)
1357 C(shiftright_loop_down:) | Input in a0,d0.W,d1.W, Output in d0
1358 #if 1
1359            moveml $d2-$d5,$sp@-
1360            movel $sp@(16+4),$a0
1361            movew $sp@(16+8+2),$d0
1362            movew $sp@(16+12+2),$d1
1363            moveq #32,$d5
1364            subw $d1,$d5
1365            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
1366            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1367            clrl $d2
1368            bras 2f
1369     1:       | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i,
1370              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
1371              | d3.L = Schiebe-Akku
1372              movel $a0@-,$d3   | neue Daten
1373              movel $d3,$d4
1374              lsrl $d1,$d3      | um i Bits rechts schieben
1375              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
1376              movel $d3,$a0@  | ablegen
1377              lsll $d5,$d4      | um (32-i) Bits links geschoben
1378              movel $d4,$d2     | liefert neuen Übertrag
1379     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
1380            movel $d2,$d0
1381            moveml $sp@+,$d2-$d5
1382            rts
1383 #else
1384            moveml $d2-$d5,$sp@-
1385            movel $sp@(16+4),$a0
1386            movew $sp@(16+8+2),$d0
1387            movew $sp@(16+12+2),$d1
1388            moveq #-1,$d5
1389            lsrl $d1,$d5
1390            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1,
1391            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1392            clrl $d2
1393            bras 2f
1394     1:       | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1,
1395              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
1396              | d3.L = Schiebe-Akku
1397              movel $a0@-,$d3   | neue Daten
1398              rorl $d1,$d3      | um i Bits rechts rotieren
1399              movel $d3,$d4
1400              andl $d5,$d3      | untere 32-i Bits
1401              eorl $d3,$d4      | obere i Bits
1402              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
1403              movel $d4,$d2     | neuer Übertrag
1404              movel $d3,$a0@  | ablegen
1405     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
1406            movel $d2,$d0
1407            moveml $sp@+,$d2-$d5
1408            rts
1409 #endif
1410
1411 | extern uintD shiftrightsigned_loop_down (uintD* ptr, uintC count, uintC i);
1412            DECLARE_FUNCTION(shiftrightsigned_loop_down)
1413 C(shiftrightsigned_loop_down:) | Input in a0,d0.W,d1.W, Output in d0
1414 #if 1
1415            moveml $d2-$d5,$sp@-
1416            movel $sp@(16+4),$a0
1417            movew $sp@(16+8+2),$d0
1418            movew $sp@(16+12+2),$d1
1419            moveq #32,$d5
1420            subw $d1,$d5
1421            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
1422            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1423            subqw #1,$d0
1424            movel $a0@-,$d3     | erstes Digit
1425            movel $d3,$d4
1426            asrl $d1,$d3        | um i Bits rechts schieben
1427            bras 2f
1428     1:       | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i,
1429              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
1430              | d3.L = Schiebe-Akku
1431              movel $a0@-,$d3   | neue Daten
1432              movel $d3,$d4
1433              lsrl $d1,$d3      | um i Bits rechts schieben
1434              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
1435     2:       movel $d3,$a0@  | ablegen
1436              lsll $d5,$d4      | um (32-i) Bits links geschoben
1437              movel $d4,$d2     | liefert neuen Übertrag
1438              dbra $d0,1b        | Schleife d0.W mal durchlaufen
1439            movel $d2,$d0
1440            moveml $sp@+,$d2-$d5
1441            rts
1442 #else
1443            moveml $d2-$d5,$sp@-
1444            movel $sp@(16+4),$a0
1445            movew $sp@(16+8+2),$d0
1446            movew $sp@(16+12+2),$d1
1447            moveq #-1,$d5
1448            lsrl $d1,$d5
1449            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1,
1450            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1451            subqw #1,$d0
1452            movel $a0@-,$d3     | erstes Digit
1453            movel $d3,$d4
1454            rorl $d1,$d4        | um i Bits rechts rotieren
1455            movel $d5,$d2
1456            notl $d2
1457            andl $d4,$d2        | obere 32-i Bits
1458            asrl $d1,$d3        | erstes Digit um i Bits rechts shiften
1459            bras 2f
1460     1:       | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1,
1461              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
1462              | d3.L = Schiebe-Akku
1463              movel $a0@-,$d3   | neue Daten
1464              rorl $d1,$d3      | um i Bits rechts rotieren
1465              movel $d3,$d4
1466              andl $d5,$d3      | untere 32-i Bits
1467              eorl $d3,$d4      | obere i Bits
1468              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
1469              movel $d4,$d2     | neuer Übertrag
1470     2:       movel $d3,$a0@  | ablegen
1471              dbra $d0,1b        | Schleife d0.W mal durchlaufen
1472            movel $d2,$d0
1473            moveml $sp@+,$d2-$d5
1474            rts
1475 #endif
1476
1477 | extern uintD shiftrightcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
1478            DECLARE_FUNCTION(shiftrightcopy_loop_down)
1479 C(shiftrightcopy_loop_down:) | Input in a0,a1,d0.W,d1.W,d2, Output in d0
1480 #if 1
1481            moveml $d2-$d5,$sp@-
1482            movel $sp@(16+4),$a0
1483            movel $sp@(16+8),$a1
1484            movew $sp@(16+12+2),$d0
1485            movew $sp@(16+16+2),$d1
1486            movel $sp@(16+20),$d2
1487            moveq #32,$d5
1488            subw $d1,$d5
1489            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i
1490            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1491            bras 2f
1492     1:       | a0,a1 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i
1493              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
1494              | d3.L = Schiebe-Akku
1495              movel $a0@-,$d3  | neue Daten
1496              movel $d3,$d4
1497              lsrl $d1,$d3      | um i Bits rechts schieben
1498              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
1499              movel $d3,$a1@-  | ablegen
1500              movel $d4,$d2
1501     2:       lsll $d5,$d2      | um (32-i) Bits links geschoben, gibt neuen Übertrag
1502              dbra $d0,1b        | Schleife d0.W mal durchlaufen
1503            movel $d2,$d0
1504            moveml $sp@+,$d2-$d5
1505            rts
1506 #else
1507            moveml $d2-$d5,$sp@-
1508            movel $sp@(16+4),$a0
1509            movel $sp@(16+8),$a1
1510            movew $sp@(16+12+2),$d0
1511            movew $sp@(16+16+2),$d1
1512            movel $sp@(16+20),$d2
1513            moveq #-1,$d5
1514            lsrl $d1,$d5
1515            rorl $d1,$d2
1516            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1
1517            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1518            bras 2f
1519     1:       | a0,a1 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1
1520              | d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
1521              | d3.L = Schiebe-Akku
1522              movel $a0@-,$d3  | neue Daten
1523              rorl $d1,$d3      | um i Bits rechts rotieren
1524              movel $d3,$d4
1525              andl $d5,$d3      | untere 32-i Bits
1526              eorl $d3,$d4      | obere i Bits
1527              orl $d2,$d3       | und mit vorigem Übertrag kombinieren
1528              movel $d4,$d2     | neuer Übertrag
1529              movel $d3,$a1@-  | ablegen
1530     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
1531            movel $d2,$d0
1532            moveml $sp@+,$d2-$d5
1533            rts
1534 #endif
1535
1536 | extern uintD mulusmall_loop_up (uintD digit, uintD* ptr, uintC len, uintD newdigit);
1537            DECLARE_FUNCTION(mulusmall_loop_up)
1538 C(mulusmall_loop_up:) | Input in d0,a0,d1.W,d2, Output in d0
1539            moveml $d2-$d4,$sp@-
1540            movel $sp@(12+4),$d0
1541            movel $sp@(12+8),$a0
1542            movew $sp@(12+12+2),$d1
1543            movel $sp@(12+16),$d2
1544            addw #0,$d1        | X-Bit löschen
1545            bras 2f
1546     1:       movel $a0@,$d3  | nächstes Digit
1547              mulul $d0,$d4:$d3  | mit digit multiplizieren
1548              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
1549              movel $d3,$a0@+   | Low-Digit ablegen
1550              movel $d4,$d2     | High-Digit gibt neuen Carry
1551     2:       dbra $d1,1b
1552            clrl $d0
1553            addxl $d2,$d0       | letzter Carry (incl. X-Bit)
1554            moveml $sp@+,$d2-$d4
1555            rts
1556
1557 | extern void mulu_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1558            DECLARE_FUNCTION(mulu_loop_up)
1559 C(mulu_loop_up:) | Input in d0,a0,a1,d1.W
1560 #if 1
1561            moveml $d2-$d4,$sp@-
1562            movel $sp@(12+4),$d0
1563            movel $sp@(12+8),$a0
1564            movel $sp@(12+12),$a1
1565            movew $sp@(12+16+2),$d1
1566            subl $d2,$d2        | carry := 0, X-Bit löschen
1567            bras 2f
1568     1:       movel $a0@+,$d3  | nächstes Digit
1569              mulul $d0,$d4:$d3  | mit digit multiplizieren
1570              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
1571              movel $d3,$a1@+  | Low-Digit ablegen
1572              movel $d4,$d2     | High-Digit gibt neuen Carry
1573     2:       dbra $d1,1b
1574            clrl $d3
1575            addxl $d3,$d2       | letztes X-Bit verarbeiten
1576            movel $d2,$a1@+    | letzten Carry ablegen
1577            moveml $sp@+,$d2-$d4
1578            rts
1579 #else
1580            moveml $d2-$d5,$sp@-
1581            movel $sp@(16+4),$d0
1582            movel $sp@(16+8),$a0
1583            movel $sp@(16+12),$a1
1584            movew $sp@(16+16+2),$d1
1585            clrl $d5           | 0
1586            clrl $d2           | carry
1587            bras 2f
1588     1:       movel $a0@+,$d3  | nächstes Digit
1589              mulul $d0,$d4:$d3  | mit digit multiplizieren
1590              addl $d2,$d3      | und bisherigen Carry addieren
1591              addxl $d5,$d4
1592              movel $d3,$a1@+  | Low-Digit ablegen
1593              movel $d4,$d2     | High-Digit gibt neuen Carry
1594     2:       dbra $d1,1b
1595            movel $d2,$a1@+    | letzten Carry ablegen
1596            moveml $sp@+,$d2-$d5
1597            rts
1598 #endif
1599
1600 | extern uintD muluadd_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1601            DECLARE_FUNCTION(muluadd_loop_up)
1602 C(muluadd_loop_up:) | Input in d0,a0,a1,d1.W, Output in d0
1603            moveml $d2-$d5,$sp@-
1604            movel $sp@(16+4),$d0
1605            movel $sp@(16+8),$a0
1606            movel $sp@(16+12),$a1
1607            movew $sp@(16+16+2),$d1
1608            clrl $d5           | 0
1609            subl $d2,$d2        | carry := 0, X-Bit löschen
1610            bras 2f
1611     1:       movel $a0@+,$d3  | nächstes Digit
1612              mulul $d0,$d4:$d3  | mit digit multiplizieren
1613              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
1614              addxl $d5,$d4
1615              addl $d3,$a1@+   | Low-Digit zum dest-Digit addieren, X als Übertrag
1616              movel $d4,$d2     | High-Digit gibt neuen Carry
1617     2:       dbra $d1,1b
1618            addxl $d5,$d2       | letztes X-Bit addieren
1619            movel $d2,$d0       | letzten Carry als Ergebnis
1620            moveml $sp@+,$d2-$d5
1621            rts
1622
1623 | extern uintD mulusub_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1624            DECLARE_FUNCTION(mulusub_loop_up)
1625 C(mulusub_loop_up:) | Input in d0,a0,a1,d1.W, Output in d0
1626            moveml $d2-$d5,$sp@-
1627            movel $sp@(16+4),$d0
1628            movel $sp@(16+8),$a0
1629            movel $sp@(16+12),$a1
1630            movew $sp@(16+16+2),$d1
1631            clrl $d5           | 0
1632            subl $d2,$d2        | carry := 0, X-Bit löschen
1633            bras 2f
1634     1:       movel $a0@+,$d3  | nächstes Digit
1635              mulul $d0,$d4:$d3  | mit digit multiplizieren
1636              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
1637              addxl $d5,$d4
1638              subl $d3,$a1@+   | Low-Digit vom dest-Digit subtrahieren, X als Übertrag
1639              movel $d4,$d2     | High-Digit gibt neuen Carry
1640     2:       dbra $d1,1b
1641            clrl $d0
1642            addxl $d2,$d0       | letzter Carry und letztes X-Bit
1643            moveml $sp@+,$d2-$d5
1644            rts
1645
1646 | extern uintD divu_loop_down (uintD digit, uintD* ptr, uintC len);
1647            DECLARE_FUNCTION(divu_loop_down)
1648 C(divu_loop_down:) | Input in d0,a0,d1.W, Output in d0
1649            moveml $d2-$d3,$sp@-
1650            movel $sp@(8+4),$d0
1651            movel $sp@(8+8),$a0
1652            movew $sp@(8+12+2),$d1
1653            clrl $d2           | Rest := 0
1654            bras 2f
1655     1:       movel $a0@-,$d3   | nächst-niedriges Digit
1656              divul $d0,$d2:$d3  | mit Rest kombinieren und durch digit dividieren
1657              movel $d3,$a0@  | Quotient ablegen, Rest in d2
1658     2:       dbra $d1,1b
1659            movel $d2,$d0       | Rest
1660            moveml $sp@+,$d2-$d3
1661            rts
1662
1663 | extern uintD divucopy_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
1664            DECLARE_FUNCTION(divucopy_loop_down)
1665 C(divucopy_loop_down:) | Input in d0,a0,a1,d1.W, Output in d0
1666            moveml $d2-$d3,$sp@-
1667            movel $sp@(8+4),$d0
1668            movel $sp@(8+8),$a0
1669            movel $sp@(8+12),$a1
1670            movew $sp@(8+16+2),$d1
1671            clrl $d2           | Rest := 0
1672            bras 2f
1673     1:       movel $a0@-,$d3  | nächst-niedriges Digit
1674              divul $d0,$d2:$d3  | mit Rest kombinieren und durch digit dividieren
1675              movel $d3,$a1@-  | Quotient ablegen, Rest in d2
1676     2:       dbra $d1,1b
1677            movel $d2,$d0       | Rest
1678            moveml $sp@+,$d2-$d3
1679            rts
1680
1681 #endif
1682
1683 | extern void shiftxor_loop_up (uintD* xptr, const uintD* yptr, uintC count, uintC i);
1684            DECLARE_FUNCTION(shiftxor_loop_up)
1685 C(shiftxor_loop_up:) | Input in a0,a1,d0.W,d1.W
1686            moveml $d2-$d5,$sp@-
1687            movel $sp@(16+4),$a0
1688            movel $sp@(16+8),$a1
1689            movew $sp@(16+12+2),$d0
1690            movew $sp@(16+16+2),$d1
1691            moveq #32,$d5
1692            subw $d1,$d5
1693            clrl $d2
1694            | a0 = xptr, a1 = yptr, d0.W = count, d1.W = i, d5.W = 32-i,
1695            | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1696            bras 2f
1697     1:       movel $a1@+,$d3  | d3.L = neues Digit
1698              movel $d3,$d4
1699              lsll $d1,$d4      | um i Bits nach links schieben
1700              orl $d2,$d4       | mit vorigem Übertrag kombinieren
1701              eorl $d4,$a0@+  | 32 Bits ablegen
1702              movel $d3,$d2
1703              lsrl $d5,$d2      | neuen Übertrag bilden
1704     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
1705            eorl $d2,$a0@
1706            moveml $sp@+,$d2-$d5
1707            rts