home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga MA Magazine 1998 #6
/
amigamamagazinepolishissue1998.iso
/
coders
/
jËzyki_programowania
/
clisp
/
src
/
archive
/
clisp.src.lha
/
src
/
ari68020.d
< prev
next >
Wrap
Text File
|
1996-06-11
|
30KB
|
859 lines
# Externe Routinen zu ARILEV1.D
# Prozessor: 680x0 mit x>=2
# Assembler-Syntax: meist "$" streichen, auf A/UX "$" durch "%" ersetzen
# Compiler: CC oder GNU-C auf SUN3 oder AMIGA oder A/UX
# Parameter-Übergabe:
# auf dem Stack: sp@(4), sp@(8), ... (.W-Größen belegen 4 Byte!),
# Rückgabewert in d0.
# Register a0-a1,d0-d1 frei verwendbar,
# Register a2-a4,d2-d7 müssen gerettet werden.
# Einstellungen: intCsize=16, intDsize=32.
#ifdef INCLUDED_FROM_C
#define COPY_LOOPS
#define FILL_LOOPS
#define CLEAR_LOOPS
#define LOG_LOOPS
#define TEST_LOOPS
#define ADDSUB_LOOPS
#define SHIFT_LOOPS
#define MUL_LOOPS
#define DIV_LOOPS
#else
#ifdef UNDERSCORE
#ifdef __STDC__
#define C(entrypoint) _##entrypoint
#else
#define C(entrypoint) _/**/entrypoint
#endif
#else
#define C(entrypoint) entrypoint
#endif
# Befehl, der das X- und das C-Bit löscht (und evtl. d1 modifiziert):
#if defined(sun)
# SUN-Assembler
#define clrx subw d1,d1
#else
# GNU-Assembler
#ifdef __STDC__
#define clrx andb \#0x0e,ccr
#else
#define clrx andb #0x0e,ccr
#endif
#endif
.text
.globl C(copy_loop_up),C(copy_loop_down),C(fill_loop_up),C(fill_loop_down)
.globl C(clear_loop_up),C(clear_loop_down)
.globl C(or_loop_up),C(xor_loop_up),C(and_loop_up),C(eqv_loop_up)
.globl C(nand_loop_up),C(nor_loop_up),C(andc2_loop_up),C(orc2_loop_up)
.globl C(not_loop_up)
.globl C(and_test_loop_up),C(test_loop_up),C(compare_loop_up)
.globl C(add_loop_down),C(addto_loop_down),C(inc_loop_down)
.globl C(sub_loop_down),C(subx_loop_down),C(subfrom_loop_down),C(dec_loop_down)
.globl C(neg_loop_down)
.globl C(shift1left_loop_down),C(shiftleft_loop_down),C(shiftleftcopy_loop_down)
.globl C(shift1right_loop_up),C(shiftright_loop_up),C(shiftrightsigned_loop_up),C(shiftrightcopy_loop_up)
.globl C(mulusmall_loop_down),C(mulu_loop_down),C(muluadd_loop_down),C(mulusub_loop_down)
.globl C(divu_loop_up),C(divucopy_loop_up)
#ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
.globl C(mulu32_)
! extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
! 2^32*hi+lo := arg1*arg2.
C(mulu32_:) ! Input in d0,d1, Output in d0,mulu32_high
movel sp@(4),d0
movel sp@(8),d1
mulul d1,d1:d0
movel d1,(C(mulu32_high)) ! Adressierung?? Deklaration??
rts
#endif
#ifndef __GNUC__ /* mit GNU-C machen wir divu_6432_3232() als Macro, der inline dividiert */
.globl C(divu_6432_3232_)
! extern struct { uint32 q; uint32 r; } divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y);
! x = 2^32*xhi+xlo = q*y+r schreiben. Sei bekannt, daß 0 <= x < 2^32*y .
C(divu_6432_3232_:) ! Input in d1,d0,d2, Output in d0,divu_32_rest
movel sp@(4),d1
movel sp@(8),d0
divul sp@(12),d1:d0 ! x = d1|d0 durch y dividieren
movel d1,(C(divu_32_rest)) ! Rest ablegen ! Adressierung?? Deklaration??
rts
#endif
| extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
C(copy_loop_up:) | Input in a0,a1,d0.W, Output in d0
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a0@+,a1@+
2: dbra d0,1b
movel a1,d0
rts
| extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
C(copy_loop_down:) | Input in a0,a1,d0.W, Output in d0
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a0@-,a1@-
2: dbra d0,1b
movel a1,d0
rts
| extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
C(fill_loop_up:) | Input in a0,d0.W,d1, Output in d0
movel sp@(4),a0
movew sp@(8+2),d0
movel sp@(12),d1
bras 2f
1: movel d1,a0@+
2: dbra d0,1b
movel a0,d0
rts
| extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
C(fill_loop_down:) | Input in a0,d0.W,d1, Output in d0
movel sp@(4),a0
movew sp@(8+2),d0
movel sp@(12),d1
bras 2f
1: movel d1,a0@-
2: dbra d0,1b
movel a0,d0
rts
| extern uintD* clear_loop_up (uintD* destptr, uintC count);
C(clear_loop_up:) | Input in a0,d0.W, Output in d0
movel sp@(4),a0
movew sp@(8+2),d0
bras 2f
1: clrl a0@+
2: dbra d0,1b
movel a0,d0
rts
| extern uintD* clear_loop_down (uintD* destptr, uintC count);
C(clear_loop_down:) | Input in a0,d0.W, Output in d0
movel sp@(4),a0
movew sp@(8+2),d0
bras 2f
1: clrl a0@-
2: dbra d0,1b
movel a0,d0
rts
| extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(or_loop_up:) | Input in a0,a1,d0.W, verändert d1
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a1@+,d1
orl d1,a0@+
2: dbra d0,1b
rts
| extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(xor_loop_up:) | Input in a0,a1,d0.W, verändert d1
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a1@+,d1
eorl d1,a0@+
2: dbra d0,1b
rts
| extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(and_loop_up:) | Input in a0,a1,d0.W, verändert d1
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a1@+,d1
andl d1,a0@+
2: dbra d0,1b
rts
| extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(eqv_loop_up:) | Input in a0,a1,d0.W, verändert d1
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a1@+,d1
eorl d1,a0@
notl a0@+
2: dbra d0,1b
rts
| extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(nand_loop_up:) | Input in a0,a1,d0.W, verändert d1
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a1@+,d1
andl d1,a0@
notl a0@+
2: dbra d0,1b
rts
| extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(nor_loop_up:) | Input in a0,a1,d0.W, verändert d1
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a1@+,d1
orl d1,a0@
notl a0@+
2: dbra d0,1b
rts
| extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(andc2_loop_up:) | Input in a0,a1,d0.W, verändert d1
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a1@+,d1
notl d1
andl d1,a0@+
2: dbra d0,1b
rts
| extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(orc2_loop_up:) | Input in a0,a1,d0.W, verändert d1
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a1@+,d1
notl d1
orl d1,a0@+
2: dbra d0,1b
rts
| extern void not_loop_up (uintD* xptr, uintC count);
C(not_loop_up:) | Input in a0,d0.W
movel sp@(4),a0
movew sp@(8+2),d0
bras 2f
1: notl a0@+
2: dbra d0,1b
rts
| extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(and_test_loop_up:) | Input in a0,a1,d0.W, verändert d1, Output in d0.W=d0.L
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: movel a0@+,d1
andl a1@+,d1
bnes 3f
2: dbra d0,1b
clrl d0
rts
3: moveq #1,d0
rts
| extern boolean test_loop_up (uintD* ptr, uintC count);
C(test_loop_up:) | Input in a0,d0.W, Output in d0.W=d0.L
movel sp@(4),a0
movew sp@(8+2),d0
bras 2f
1: tstl a0@+
bnes 3f
2: dbra d0,1b
clrl d0
rts
3: moveq #1,d0
rts
| extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
C(compare_loop_up:) | Input in a0,a1,d0.W, Output in d0.W=d0.L
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
bras 2f
1: cmpml a1@+,a0@+
bnes 3f
2: dbra d0,1b
clrl d0
rts
3: bcss 4f
moveq #1,d0
rts
4: moveq #-1,d0
rts
| extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
C(add_loop_down:) | Input in a0,a1,a2,d0.W, verändert d1,d2, Output in d0
moveml a2/d2,sp@-
movel sp@(8+4),a0
movel sp@(8+8),a1
movel sp@(8+12),a2
movew sp@(8+16+2),d0
clrx | X-Bit löschen
bras 2f
1: movel a0@-,d1
movel a1@-,d2
addxl d2,d1
movel d1,a2@-
2: dbra d0,1b
subxl d0,d0 | -1 falls X gesetzt, 0 falls X gelöscht
moveml sp@+,a2/d2
rts
| extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
C(addto_loop_down:) | Input in a0,a1,d0.W, Output in d0
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
clrx | X-Bit löschen
bras 2f
1: addxl a0@-,a1@-
2: dbra d0,1b
subxl d0,d0 | -1 falls X gesetzt, 0 falls X gelöscht
rts
| extern uintD inc_loop_down (uintD* ptr, uintC count);
C(inc_loop_down:) | Input in a0,d0.W, Output in d0
movel sp@(4),a0
movew sp@(8+2),d0
dbra d0,1f | simuliere gesetzten Carry
moveq #-1,d0 | d0.L=-1 für Übertrag
rts
1: addql #1,a0@-
dbcc d0,1b
subxl d0,d0 | kein Carry -> d0.L=0, sonst d0.L=-1 für Übertrag
rts
| extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
C(sub_loop_down:) | Input in a0,a1,a2,d0.W, verändert d1,d2, Output in d0
moveml a2/d2,sp@-
movel sp@(8+4),a0
movel sp@(8+8),a1
movel sp@(8+12),a2
movew sp@(8+16+2),d0
clrx | X-Bit löschen
bras 2f
1: movel a0@-,d1
movel a1@-,d2
subxl d2,d1
movel d1,a2@-
2: dbra d0,1b
subxl d0,d0 | -1 falls X gesetzt, 0 falls X gelöscht
moveml sp@+,a2/d2
rts
| extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
C(subx_loop_down:) | Input in a0,a1,a2,d0.W,d1, verändert d2, Output in d0
moveml a2/d2,sp@-
movel sp@(8+4),a0
movel sp@(8+8),a1
movel sp@(8+12),a2
movew sp@(8+16+2),d0
movel sp@(8+20),d1
roxrl #1,d1 | X-Bit initialisieren
bras 2f
1: movel a0@-,d1
movel a1@-,d2
subxl d2,d1
movel d1,a2@-
2: dbra d0,1b
subxl d0,d0 | -1 falls X gesetzt, 0 falls X gelöscht
moveml sp@+,a2/d2
rts
| extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
C(subfrom_loop_down:) | Input in a0,a1,d0.W, Output in d0
movel sp@(4),a0
movel sp@(8),a1
movew sp@(12+2),d0
clrx | X-Bit löschen
bras 2f
1: subxl a0@-,a1@-
2: dbra d0,1b
subxl d0,d0 | -1 falls X gesetzt, 0 falls X gelöscht
rts
| extern uintD dec_loop_down (uintD* ptr, uintC count);
C(dec_loop_down:) | Input in a0,d0.W, Output in d0
movel sp@(4),a0
movew sp@(8+2),d0
dbra d0,1f | simuliere gesetzten Carry
moveq #-1,d0 | d0.L=-1 als Übertrag
rts
1: subql #1,a0@-
dbcc d0,1b | kein Carry -> Schleife abbrechen
subxl d0,d0 | kein Carry -> d0.L=0, sonst d0.L=-1 als Übertrag
rts
| extern uintD neg_loop_down (uintD* ptr, uintC count);
C(neg_loop_down:) | Input in a0,d0.W, Output in d0
movel sp@(4),a0
movew sp@(8+2),d0
clrx | X-Bit löschen
bras 2f
1: negxl a0@-
2: dbra d0,1b
subxl d0,d0 | -1 falls X gesetzt, 0 falls X gelöscht
rts
| extern uintD shift1left_loop_down (uintD* ptr, uintC count);
C(shift1left_loop_down:) | Input in a0,d0.W, Output in d0.L
movel sp@(4),a0
movew sp@(8+2),d0
clrx | X-Bit löschen
bras 2f
1: roxlw a0@- | Digit a0@- um 1 Bit links schieben, X-Bit als Buffer
roxlw a0@-
2: dbra d0,1b
subxl d0,d0 | -1 falls X gesetzt, 0 falls X gelöscht
rts
| extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
C(shiftleft_loop_down:) | Input in a0,d0.W,d1.W,d2, Output in d0
#if 1
moveml d2-d5,sp@-
movel sp@(16+4),a0
movew sp@(16+8+2),d0
movew sp@(16+12+2),d1
movel sp@(16+16),d2
moveq #32,d5
subw d1,d5
| a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
bras 2f
1: movel a0@-,d3 | d3.L = neues Digit
movel d3,d4
lsll d1,d4 | um i Bits nach links schieben
orl d2,d4 | mit vorigem Übertrag kombinieren
movel d4,a0@ | 32 Bits ablegen
movel d3,d2
lsrl d5,d2 | neuen Übertrag bilden
2: dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#else
moveml d2-d5,sp@-
movel sp@(16+4),a0
movew sp@(16+8+2),d0
movew sp@(16+12+2),d1
movel sp@(16+16),d2
moveq #1,d5
lsll d1,d5
subql #1,d5
| a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^i-1
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
bras 2f
1: movel a0@-,d3 | d3.L = neues Digit
roll d1,d3 | um i Bits links rotieren
movel d3,d4
andl d5,d3 | untere i Bits in d3
eorl d3,d4 | obere 32-i Bits in d4
orl d2,d4 | mit vorigem übertrag kombinieren
movel d4,a0@ | 32 Bits ablegen
movel d3,d2 | neuer Übertrag
2: dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#endif
| extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
C(shiftleftcopy_loop_down:) | Input in a0,a1,d0.W,d1.W, Output in d0
#if 1
moveml d2-d5,sp@-
movel sp@(16+4),a0
movel sp@(16+8),a1
movew sp@(16+12+2),d0
movew sp@(16+16+2),d1
moveq #32,d5
subw d1,d5
clrl d2
| a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i, d5.W = 32-i,
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
bras 2f
1: movel a0@-,d3 | d3.L = neues Digit
movel d3,d4
lsll d1,d4 | um i Bits nach links schieben
orl d2,d4 | mit vorigem Übertrag kombinieren
movel d4,a1@- | 32 Bits ablegen
movel d3,d2
lsrl d5,d2 | neuen Übertrag bilden
2: dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#else
moveml d2-d5,sp@-
movel sp@(16+4),a0
movel sp@(16+8),a1
movew sp@(16+12+2),d0
movew sp@(16+16+2),d1
moveq #1,d5
lsll d1,d5
subql #1,d5
| a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i, d5.L = 2^i-1
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
bras 2f
1: movel a0@-,d3 | d3.L = neues Digit
roll d1,d3 | um i Bits links rotieren
movel d3,d4
andl d5,d3 | untere i Bits in d3
eorl d3,d4 | obere 32-i Bits in d4
orl d2,d4 | mit vorigem übertrag kombinieren
movel d4,a1@- | 32 Bits ablegen
movel d3,d2 | neuer Übertrag
2: dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#endif
| extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
C(shift1right_loop_up:) | Input in a0,d0.W,d1, Output in d0
movel sp@(4),a0
movew sp@(8+2),d0
movel sp@(12),d1
roxrl #1,d1 | X-Bit löschen oder setzen, je nach d1
bras 2f
1: roxrw a0@+ | Digit a0@+ um 1 Bit rechts schieben, X-Bit als Buffer
roxrw a0@+
2: dbra d0,1b
subxl d0,d0 | -1 falls X gesetzt, 0 falls X gelöscht
rts
| extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
C(shiftright_loop_up:) | Input in a0,d0.W,d1.W, Output in d0
#if 1
moveml d2-d5,sp@-
movel sp@(16+4),a0
movew sp@(16+8+2),d0
movew sp@(16+12+2),d1
moveq #32,d5
subw d1,d5
| a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
clrl d2
bras 2f
1: | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i,
| d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
| d3.L = Schiebe-Akku
movel a0@,d3 | neue Daten
movel d3,d4
lsrl d1,d3 | um i Bits rechts schieben
orl d2,d3 | und mit vorigem Übertrag kombinieren
movel d3,a0@+ | ablegen
lsll d5,d4 | um (32-i) Bits links geschoben
movel d4,d2 | liefert neuen Übertrag
2: dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#else
moveml d2-d5,sp@-
movel sp@(16+4),a0
movew sp@(16+8+2),d0
movew sp@(16+12+2),d1
moveq #-1,d5
lsrl d1,d5
| a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1,
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
clrl d2
bras 2f
1: | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1,
| d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
| d3.L = Schiebe-Akku
movel a0@,d3 | neue Daten
rorl d1,d3 | um i Bits rechts rotieren
movel d3,d4
andl d5,d3 | untere 32-i Bits
eorl d3,d4 | obere i Bits
orl d2,d3 | und mit vorigem Übertrag kombinieren
movel d4,d2 | neuer Übertrag
movel d3,a0@+ | ablegen
2: dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#endif
| extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
C(shiftrightsigned_loop_up:) | Input in a0,d0.W,d1.W, Output in d0
#if 1
moveml d2-d5,sp@-
movel sp@(16+4),a0
movew sp@(16+8+2),d0
movew sp@(16+12+2),d1
moveq #32,d5
subw d1,d5
| a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
subqw #1,d0
movel a0@,d3 | erstes Digit
movel d3,d4
asrl d1,d3 | um i Bits rechts schieben
bras 2f
1: | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i,
| d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
| d3.L = Schiebe-Akku
movel a0@,d3 | neue Daten
movel d3,d4
lsrl d1,d3 | um i Bits rechts schieben
orl d2,d3 | und mit vorigem Übertrag kombinieren
2: movel d3,a0@+ | ablegen
lsll d5,d4 | um (32-i) Bits links geschoben
movel d4,d2 | liefert neuen Übertrag
dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#else
moveml d2-d5,sp@-
movel sp@(16+4),a0
movew sp@(16+8+2),d0
movew sp@(16+12+2),d1
moveq #-1,d5
lsrl d1,d5
| a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1,
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
subqw #1,d0
movel a0@,d3 | erstes Digit
movel d3,d4
rorl d1,d4 | um i Bits rechts rotieren
movel d5,d2
notl d2
andl d4,d2 | obere 32-i Bits
asrl d1,d3 | erstes Digit um i Bits rechts shiften
bras 2f
1: | a0 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1,
| d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
| d3.L = Schiebe-Akku
movel a0@,d3 | neue Daten
rorl d1,d3 | um i Bits rechts rotieren
movel d3,d4
andl d5,d3 | untere 32-i Bits
eorl d3,d4 | obere i Bits
orl d2,d3 | und mit vorigem Übertrag kombinieren
movel d4,d2 | neuer Übertrag
2: movel d3,a0@+ | ablegen
dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#endif
| extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
C(shiftrightcopy_loop_up:) | Input in a0,a1,d0.W,d1.W,d2, Output in d0
#if 1
moveml d2-d5,sp@-
movel sp@(16+4),a0
movel sp@(16+8),a1
movew sp@(16+12+2),d0
movew sp@(16+16+2),d1
movel sp@(16+20),d2
moveq #32,d5
subw d1,d5
| a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
bras 2f
1: | a0,a1 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.W = 32-i
| d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
| d3.L = Schiebe-Akku
movel a0@+,d3 | neue Daten
movel d3,d4
lsrl d1,d3 | um i Bits rechts schieben
orl d2,d3 | und mit vorigem Übertrag kombinieren
movel d3,a1@+ | ablegen
movel d4,d2
2: lsll d5,d2 | um (32-i) Bits links geschoben, gibt neuen Übertrag
dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#else
moveml d2-d5,sp@-
movel sp@(16+4),a0
movel sp@(16+8),a1
movew sp@(16+12+2),d0
movew sp@(16+16+2),d1
movel sp@(16+20),d2
moveq #-1,d5
lsrl d1,d5
rorl d1,d2
| a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1
| d2.L = Schiebe-Übertrag (i Bits), d3.L = Schiebe-Akku
bras 2f
1: | a0,a1 = Aufwärtszähler Adresse, d0.W = Herabzähler, d1.W = i, d5.L = 2^(32-i)-1
| d2.L = Schiebe-Übertrag (obere i Bits, restliche 32-i Bits sind 0)
| d3.L = Schiebe-Akku
movel a0@+,d3 | neue Daten
rorl d1,d3 | um i Bits rechts rotieren
movel d3,d4
andl d5,d3 | untere 32-i Bits
eorl d3,d4 | obere i Bits
orl d2,d3 | und mit vorigem Übertrag kombinieren
movel d4,d2 | neuer Übertrag
movel d3,a1@+ | ablegen
2: dbra d0,1b | Schleife d0.W mal durchlaufen
movel d2,d0
moveml sp@+,d2-d5
rts
#endif
| extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
C(mulusmall_loop_down:) # Input in d0,a0,d1.W,d2, Output in d0
moveml d2-d4,sp@-
movel sp@(12+4),d0
movel sp@(12+8),a0
movew sp@(12+12+2),d1
movel sp@(12+16),d2
addw #0,d1 | X-Bit löschen
bras 2f
1: movel a0@-,d3 | nächstes Digit
mulul d0,d4:d3 | mit digit multiplizieren
addxl d2,d3 | und bisherigen Carry und X-Bit addieren
movel d3,a0@ | Low-Digit ablegen
movel d4,d2 | High-Digit gibt neuen Carry
2: dbra d1,1b
clrl d0
addxl d2,d0 | letzter Carry (incl. X-Bit)
moveml sp@+,d2-d4
rts
| extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
C(mulu_loop_down:) | Input in d0,a0,a1,d1.W
#if 1
moveml d2-d4,sp@-
movel sp@(12+4),d0
movel sp@(12+8),a0
movel sp@(12+12),a1
movew sp@(12+16+2),d1
subl d2,d2 | carry := 0, X-Bit löschen
bras 2f
1: movel a0@-,d3 | nächstes Digit
mulul d0,d4:d3 | mit digit multiplizieren
addxl d2,d3 | und bisherigen Carry und X-Bit addieren
movel d3,a1@- | Low-Digit ablegen
movel d4,d2 | High-Digit gibt neuen Carry
2: dbra d1,1b
clrl d3
addxl d3,d2 | letztes X-Bit verarbeiten
movel d2,a1@- | letzten Carry ablegen
moveml sp@+,d2-d4
rts
#else
moveml d2-d5,sp@-
movel sp@(16+4),d0
movel sp@(16+8),a0
movel sp@(16+12),a1
movew sp@(16+16+2),d1
clrl d5 | 0
clrl d2 | carry
bras 2f
1: movel a0@-,d3 | nächstes Digit
mulul d0,d4:d3 | mit digit multiplizieren
addl d2,d3 | und bisherigen Carry addieren
addxl d5,d4
movel d3,a1@- | Low-Digit ablegen
movel d4,d2 | High-Digit gibt neuen Carry
2: dbra d1,1b
movel d2,a1@- | letzten Carry ablegen
moveml sp@+,d2-d5
rts
#endif
| extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
C(muluadd_loop_down:) | Input in d0,a0,a1,d1.W, Output in d0
moveml d2-d5,sp@-
movel sp@(16+4),d0
movel sp@(16+8),a0
movel sp@(16+12),a1
movew sp@(16+16+2),d1
clrl d5 | 0
subl d2,d2 | carry := 0, X-Bit löschen
bras 2f
1: movel a0@-,d3 | nächstes Digit
mulul d0,d4:d3 | mit digit multiplizieren
addxl d2,d3 | und bisherigen Carry und X-Bit addieren
addxl d5,d4
addl d3,a1@- | Low-Digit zum dest-Digit addieren, X als Übertrag
movel d4,d2 | High-Digit gibt neuen Carry
2: dbra d1,1b
addxl d5,d2 | letztes X-Bit addieren
movel d2,d0 | letzten Carry als Ergebnis
moveml sp@+,d2-d5
rts
| extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
C(mulusub_loop_down:) | Input in d0,a0,a1,d1.W, Output in d0
moveml d2-d5,sp@-
movel sp@(16+4),d0
movel sp@(16+8),a0
movel sp@(16+12),a1
movew sp@(16+16+2),d1
clrl d5 | 0
subl d2,d2 | carry := 0, X-Bit löschen
bras 2f
1: movel a0@-,d3 | nächstes Digit
mulul d0,d4:d3 | mit digit multiplizieren
addxl d2,d3 | und bisherigen Carry und X-Bit addieren
addxl d5,d4
subl d3,a1@- | Low-Digit vom dest-Digit subtrahieren, X als Übertrag
movel d4,d2 | High-Digit gibt neuen Carry
2: dbra d1,1b
clrl d0
addxl d2,d0 | letzter Carry und letztes X-Bit
moveml sp@+,d2-d5
rts
| extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
C(divu_loop_up:) # Input in d0,a0,d1.W, Output in d0
moveml d2-d3,sp@-
movel sp@(8+4),d0
movel sp@(8+8),a0
movew sp@(8+12+2),d1
clrl d2 | Rest := 0
bras 2f
1: movel a0@,d3 | nächst-niedriges Digit
divul d0,d2:d3 | mit Rest kombinieren und durch digit dividieren
movel d3,a0@+ | Quotient ablegen, Rest in d2
2: dbra d1,1b
movel d2,d0 | Rest
moveml sp@+,d2-d3
rts
| extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
C(divucopy_loop_up:) # Input in d0,a0,a1,d1.W, Output in d0
moveml d2-d3,sp@-
movel sp@(8+4),d0
movel sp@(8+8),a0
movel sp@(8+12),a1
movew sp@(8+16+2),d1
clrl d2 | Rest := 0
bras 2f
1: movel a0@+,d3 | nächst-niedriges Digit
divul d0,d2:d3 | mit Rest kombinieren und durch digit dividieren
movel d3,a1@+ | Quotient ablegen, Rest in d2
2: dbra d1,1b
movel d2,d0 | Rest
moveml sp@+,d2-d3
rts
#endif