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
6 // auf dem Stack: sp@(4), sp@(8), ... (.W-Größen belegen 4 Byte!),
8 // Register a0-a1,d0-d1 frei verwendbar,
9 // Register a2-a4,d2-d7 müssen gerettet werden.
10 // Einstellungen: intCsize=16, intDsize=32.
13 #if defined(__STDC__) || defined (__cplusplus)
14 #define C(entrypoint) _##entrypoint
16 #define C(entrypoint) _/**/entrypoint
19 #define C(entrypoint) entrypoint
22 // Befehl, der das X- und das C-Bit löscht (und evtl. d1 modifiziert):
25 #define clrx subw $d1,$d1
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
33 #define clrx andb #0x0e,$ccr
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
42 #define DECLARE_FUNCTION(name)
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)
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)
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)
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)
77 #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
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
86 movel $d1,(C(mulu32_high)) | Adressierung?? Deklaration??
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
98 divul $sp@(12),$d1:$d0 | x = d1|d0 durch y dividieren
99 movel $d1,(C(divu_32_rest)) | Rest ablegen | Adressierung?? Deklaration??
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
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
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
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
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
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
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
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
201 #if CL_DS_BIG_ENDIAN_P
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
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
229 #if CL_DS_BIG_ENDIAN_P
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
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
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
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
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
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
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
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
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
354 #if CL_DS_BIG_ENDIAN_P
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
363 movew $sp@(8+16+2),$d0
371 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
385 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
393 dbra $d0,1f | simuliere gesetzten Carry
394 moveq #-1,$d0 | d0.L=-1 für Übertrag
398 subxl $d0,$d0 | kein Carry -> d0.L=0, sonst d0.L=-1 für Übertrag
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
408 movew $sp@(8+16+2),$d0
416 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
427 movew $sp@(8+16+2),$d0
429 roxrl #1,$d1 | X-Bit initialisieren
436 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
450 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
458 dbra $d0,1f | simuliere gesetzten Carry
459 moveq #-1,$d0 | d0.L=-1 als Übertrag
462 dbcc $d0,1b | kein Carry -> Schleife abbrechen
463 subxl $d0,$d0 | kein Carry -> d0.L=0, sonst d0.L=-1 als Übertrag
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
475 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
485 1: roxlw $a0@- | Digit a0@- um 1 Bit links schieben, X-Bit als Buffer
488 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
497 movew $sp@(16+8+2),$d0
498 movew $sp@(16+12+2),$d1
499 movel $sp@(16+16),$d2
502 | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
503 | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
505 1: movel $a0@-,$d3 | d3.L = neues Digit
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
511 lsrl $d5,$d2 | neuen Übertrag bilden
512 2: dbra $d0,1b | Schleife d0.W mal durchlaufen
519 movew $sp@(16+8+2),$d0
520 movew $sp@(16+12+2),$d1
521 movel $sp@(16+16),$d2
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
528 1: movel $a0@-,$d3 | d3.L = neues Digit
529 roll $d1,$d3 | um i Bits links rotieren
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
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
549 movew $sp@(16+12+2),$d0
550 movew $sp@(16+16+2),$d1
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
557 1: movel $a0@-,$d3 | d3.L = neues Digit
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
563 lsrl $d5,$d2 | neuen Übertrag bilden
564 2: dbra $d0,1b | Schleife d0.W mal durchlaufen
572 movew $sp@(16+12+2),$d0
573 movew $sp@(16+16+2),$d1
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
580 1: movel $a0@-,$d3 | d3.L = neues Digit
581 roll $d1,$d3 | um i Bits links rotieren
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
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
600 roxrl #1,$d1 | X-Bit löschen oder setzen, je nach d1
602 1: roxrw $a0@+ | Digit a0@+ um 1 Bit rechts schieben, X-Bit als Buffer
605 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
614 movew $sp@(16+8+2),$d0
615 movew $sp@(16+12+2),$d1
618 | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
619 | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
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
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
639 movew $sp@(16+8+2),$d0
640 movew $sp@(16+12+2),$d1
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
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
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
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
670 movew $sp@(16+8+2),$d0
671 movew $sp@(16+12+2),$d1
674 | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
675 | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
677 movel $a0@,$d3 | erstes Digit
679 asrl $d1,$d3 | um i Bits rechts schieben
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
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
698 movew $sp@(16+8+2),$d0
699 movew $sp@(16+12+2),$d1
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
705 movel $a0@,$d3 | erstes Digit
707 rorl $d1,$d4 | um i Bits rechts rotieren
710 andl $d4,$d2 | obere 32-i Bits
711 asrl $d1,$d3 | erstes Digit um i Bits rechts shiften
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
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
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
737 movew $sp@(16+12+2),$d0
738 movew $sp@(16+16+2),$d1
739 movel $sp@(16+20),$d2
742 | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i
743 | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
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
750 lsrl $d1,$d3 | um i Bits rechts schieben
751 orl $d2,$d3 | und mit vorigem Übertrag kombinieren
752 movel $d3,$a1@+ | ablegen
754 2: lsll $d5,$d2 | um (32-i) Bits links geschoben, gibt neuen Übertrag
755 dbra $d0,1b | Schleife d0.W mal durchlaufen
763 movew $sp@(16+12+2),$d0
764 movew $sp@(16+16+2),$d1
765 movel $sp@(16+20),$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
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
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
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
795 movew $sp@(12+12+2),$d1
796 movel $sp@(12+16),$d2
797 addw #0,$d1 | X-Bit löschen
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
806 addxl $d2,$d0 | letzter Carry (incl. X-Bit)
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
817 movel $sp@(12+12),$a1
818 movew $sp@(12+16+2),$d1
819 subl $d2,$d2 | carry := 0, X-Bit löschen
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
828 addxl $d3,$d2 | letztes X-Bit verarbeiten
829 movel $d2,$a1@- | letzten Carry ablegen
836 movel $sp@(16+12),$a1
837 movew $sp@(16+16+2),$d1
841 1: movel $a0@-,$d3 | nächstes Digit
842 mulul $d0,$d4:$d3 | mit digit multiplizieren
843 addl $d2,$d3 | und bisherigen Carry addieren
845 movel $d3,$a1@- | Low-Digit ablegen
846 movel $d4,$d2 | High-Digit gibt neuen Carry
848 movel $d2,$a1@- | letzten Carry ablegen
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
859 movel $sp@(16+12),$a1
860 movew $sp@(16+16+2),$d1
862 subl $d2,$d2 | carry := 0, X-Bit löschen
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
868 addl $d3,$a1@- | Low-Digit zum dest-Digit addieren, X als Übertrag
869 movel $d4,$d2 | High-Digit gibt neuen Carry
871 addxl $d5,$d2 | letztes X-Bit addieren
872 movel $d2,$d0 | letzten Carry als Ergebnis
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
882 movel $sp@(16+12),$a1
883 movew $sp@(16+16+2),$d1
885 subl $d2,$d2 | carry := 0, X-Bit löschen
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
891 subl $d3,$a1@- | Low-Digit vom dest-Digit subtrahieren, X als Übertrag
892 movel $d4,$d2 | High-Digit gibt neuen Carry
895 addxl $d2,$d0 | letzter Carry und letztes X-Bit
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
905 movew $sp@(8+12+2),$d1
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
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
923 movew $sp@(8+16+2),$d1
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
936 #if !CL_DS_BIG_ENDIAN_P
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
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
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
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
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
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
1005 movew $sp@(12+2),$d0
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
1018 movew $sp@(12+2),$d0
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
1031 movew $sp@(12+2),$d0
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
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
1054 movew $sp@(12+2),$d0
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
1071 movew $sp@(4+12+2),$d0
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@-
1095 movel $sp@(8+12),$a2
1096 movew $sp@(8+16+2),$d0
1097 clrx | X-Bit löschen
1104 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
1105 moveml $sp@+,$a2/$d2
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
1114 movew $sp@(4+12+2),$d0
1115 clrx | X-Bit löschen
1122 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
1131 dbra $d0,1f | simuliere gesetzten Carry
1132 moveq #-1,$d0 | d0.L=-1 für Übertrag
1136 subxl $d0,$d0 | kein Carry -> d0.L=0, sonst d0.L=-1 für Übertrag
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@-
1145 movel $sp@(8+12),$a2
1146 movew $sp@(8+16+2),$d0
1147 clrx | X-Bit löschen
1154 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
1155 moveml $sp@+,$a2/$d2
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@-
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
1174 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
1175 moveml $sp@+,$a2/$d2
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
1183 movew $sp@(12+2),$d0
1184 clrx | X-Bit löschen
1191 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
1199 dbra $d0,1f | simuliere gesetzten Carry
1200 moveq #-1,$d0 | d0.L=-1 als Übertrag
1203 dbcc $d0,1b | kein Carry -> Schleife abbrechen
1204 subxl $d0,$d0 | kein Carry -> d0.L=0, sonst d0.L=-1 als Übertrag
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
1212 clrx | X-Bit löschen
1216 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
1224 clrx | X-Bit löschen
1230 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
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
1244 | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
1245 | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1247 1: movel $a0@,$d3 | d3.L = neues Digit
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
1253 lsrl $d5,$d2 | neuen Übertrag bilden
1254 2: dbra $d0,1b | Schleife d0.W mal durchlaufen
1256 moveml $sp@+,$d2-$d5
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
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
1270 1: movel $a0@,$d3 | d3.L = neues Digit
1271 roll $d1,$d3 | um i Bits links rotieren
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
1280 moveml $sp@+,$d2-$d5
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
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
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
1301 1: movel $a0@+,$d3 | d3.L = neues Digit
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
1307 lsrl $d5,$d2 | neuen Übertrag bilden
1308 2: dbra $d0,1b | Schleife d0.W mal durchlaufen
1310 moveml $sp@+,$d2-$d5
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
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
1324 1: movel $a0@+,$d3 | d3.L = neues Digit
1325 roll $d1,$d3 | um i Bits links rotieren
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
1334 moveml $sp@+,$d2-$d5
1338 #if !CL_DS_BIG_ENDIAN_P
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
1346 roxrl #1,$d1 | X-Bit löschen oder setzen, je nach d1
1352 subxl $d0,$d0 | -1 falls X gesetzt, 0 falls X gelöscht
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
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
1365 | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
1366 | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
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
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
1381 moveml $sp@+,$d2-$d5
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
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
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
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
1407 moveml $sp@+,$d2-$d5
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
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
1421 | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
1422 | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
1424 movel $a0@-,$d3 | erstes Digit
1426 asrl $d1,$d3 | um i Bits rechts schieben
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
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
1440 moveml $sp@+,$d2-$d5
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
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
1452 movel $a0@-,$d3 | erstes Digit
1454 rorl $d1,$d4 | um i Bits rechts rotieren
1457 andl $d4,$d2 | obere 32-i Bits
1458 asrl $d1,$d3 | erstes Digit um i Bits rechts shiften
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
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
1473 moveml $sp@+,$d2-$d5
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
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
1489 | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i
1490 | d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
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
1497 lsrl $d1,$d3 | um i Bits rechts schieben
1498 orl $d2,$d3 | und mit vorigem Übertrag kombinieren
1499 movel $d3,$a1@- | ablegen
1501 2: lsll $d5,$d2 | um (32-i) Bits links geschoben, gibt neuen Übertrag
1502 dbra $d0,1b | Schleife d0.W mal durchlaufen
1504 moveml $sp@+,$d2-$d5
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
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
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
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
1532 moveml $sp@+,$d2-$d5
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
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
1553 addxl $d2,$d0 | letzter Carry (incl. X-Bit)
1554 moveml $sp@+,$d2-$d4
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
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
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
1575 addxl $d3,$d2 | letztes X-Bit verarbeiten
1576 movel $d2,$a1@+ | letzten Carry ablegen
1577 moveml $sp@+,$d2-$d4
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
1588 1: movel $a0@+,$d3 | nächstes Digit
1589 mulul $d0,$d4:$d3 | mit digit multiplizieren
1590 addl $d2,$d3 | und bisherigen Carry addieren
1592 movel $d3,$a1@+ | Low-Digit ablegen
1593 movel $d4,$d2 | High-Digit gibt neuen Carry
1595 movel $d2,$a1@+ | letzten Carry ablegen
1596 moveml $sp@+,$d2-$d5
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
1609 subl $d2,$d2 | carry := 0, X-Bit löschen
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
1615 addl $d3,$a1@+ | Low-Digit zum dest-Digit addieren, X als Übertrag
1616 movel $d4,$d2 | High-Digit gibt neuen Carry
1618 addxl $d5,$d2 | letztes X-Bit addieren
1619 movel $d2,$d0 | letzten Carry als Ergebnis
1620 moveml $sp@+,$d2-$d5
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
1632 subl $d2,$d2 | carry := 0, X-Bit löschen
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
1638 subl $d3,$a1@+ | Low-Digit vom dest-Digit subtrahieren, X als Übertrag
1639 movel $d4,$d2 | High-Digit gibt neuen Carry
1642 addxl $d2,$d0 | letzter Carry und letztes X-Bit
1643 moveml $sp@+,$d2-$d5
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@-
1652 movew $sp@(8+12+2),$d1
1653 clrl $d2 | Rest := 0
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
1659 movel $d2,$d0 | Rest
1660 moveml $sp@+,$d2-$d3
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@-
1669 movel $sp@(8+12),$a1
1670 movew $sp@(8+16+2),$d1
1671 clrl $d2 | Rest := 0
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
1677 movel $d2,$d0 | Rest
1678 moveml $sp@+,$d2-$d3
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
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
1697 1: movel $a1@+,$d3 | d3.L = neues Digit
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
1703 lsrl $d5,$d2 | neuen Übertrag bilden
1704 2: dbra $d0,1b | Schleife d0.W mal durchlaufen
1706 moveml $sp@+,$d2-$d5