home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / ari68020.mit.d < prev    next >
Encoding:
Text File  |  1993-10-17  |  30.7 KB  |  859 lines

  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 INCLUDED_FROM_C
  13.  
  14.   #define COPY_LOOPS
  15.   #define FILL_LOOPS
  16.   #define CLEAR_LOOPS
  17.   #define LOG_LOOPS
  18.   #define TEST_LOOPS
  19.   #define ADDSUB_LOOPS
  20.   #define SHIFT_LOOPS
  21.   #define MUL_LOOPS
  22.   #define DIV_LOOPS
  23.  
  24. #else
  25.  
  26.   #ifdef UNDERSCORE
  27.     #ifdef __STDC__
  28.       #define C(entrypoint) _##entrypoint
  29.     #else
  30.       #define C(entrypoint) _/**/entrypoint
  31.     #endif
  32.   #else
  33.     #define C(entrypoint) entrypoint
  34.   #endif
  35.  
  36.   # Befehl, der das X- und das C-Bit l÷scht (und evtl. d1 modifiziert):
  37.   #if defined(sun)
  38.     # SUN-Assembler
  39.     #define clrx   subw $d1,$d1
  40.   #else
  41.     # GNU-Assembler
  42.     #ifdef __STDC__
  43.       #define clrx   andb \#0x0e,$ccr
  44.     #else
  45.       #define clrx   andb #0x0e,$ccr
  46.     #endif
  47.   #endif
  48.  
  49.            .text
  50.  
  51.            .globl C(copy_loop_up),C(copy_loop_down),C(fill_loop_up),C(fill_loop_down)
  52.            .globl C(clear_loop_up),C(clear_loop_down)
  53.            .globl C(or_loop_up),C(xor_loop_up),C(and_loop_up),C(eqv_loop_up)
  54.            .globl C(nand_loop_up),C(nor_loop_up),C(andc2_loop_up),C(orc2_loop_up)
  55.            .globl C(not_loop_up)
  56.            .globl C(and_test_loop_up),C(test_loop_up),C(compare_loop_up)
  57.            .globl C(add_loop_down),C(addto_loop_down),C(inc_loop_down)
  58.            .globl C(sub_loop_down),C(subx_loop_down),C(subfrom_loop_down),C(dec_loop_down)
  59.            .globl C(neg_loop_down)
  60.            .globl C(shift1left_loop_down),C(shiftleft_loop_down),C(shiftleftcopy_loop_down)
  61.            .globl C(shift1right_loop_up),C(shiftright_loop_up),C(shiftrightsigned_loop_up),C(shiftrightcopy_loop_up)
  62.            .globl C(mulusmall_loop_down),C(mulu_loop_down),C(muluadd_loop_down),C(mulusub_loop_down)
  63.            .globl C(divu_loop_up),C(divucopy_loop_up)
  64.  
  65. #ifndef __GNUC__ /* mit GNU-C machen wir mulu32() als Macro, der inline multipliziert */
  66.            .globl C(mulu32_)
  67. ! extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
  68. ! 2^32*hi+lo := arg1*arg2.
  69. C(mulu32_:) ! Input in d0,d1, Output in d0,mulu32_high
  70.            movel $sp@(4),$d0
  71.            movel $sp@(8),$d1
  72.            mulul $d1,$d1:$d0
  73.            movel $d1,(C(mulu32_high)) ! Adressierung?? Deklaration??
  74.            rts
  75. #endif
  76.  
  77. #ifndef __GNUC__ /* mit GNU-C machen wir divu_6432_3232() als Macro, der inline dividiert */
  78.            .globl C(divu_6432_3232_)
  79. ! extern struct { uint32 q; uint32 r; } divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y);
  80. ! x = 2^32*xhi+xlo = q*y+r schreiben. Sei bekannt, da▀ 0 <= x < 2^32*y .
  81. C(divu_6432_3232_:) ! Input in d1,d0,d2, Output in d0,divu_32_rest
  82.            movel $sp@(4),$d1
  83.            movel $sp@(8),$d0
  84.            divul $sp@(12),$d1:$d0 ! x = d1|d0 durch y dividieren
  85.            movel $d1,(C(divu_32_rest)) ! Rest ablegen ! Adressierung?? Deklaration??
  86.            rts
  87. #endif
  88.  
  89. | extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
  90. C(copy_loop_up:) | Input in a0,a1,d0.W, Output in d0
  91.            movel $sp@(4),$a0
  92.            movel $sp@(8),$a1
  93.            movew $sp@(12+2),$d0
  94.            bras 2f
  95.     1:       movel $a0@+,$a1@+
  96.     2:       dbra $d0,1b
  97.            movel $a1,$d0
  98.            rts
  99.  
  100. | extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  101. C(copy_loop_down:) | Input in a0,a1,d0.W, Output in d0
  102.            movel $sp@(4),$a0
  103.            movel $sp@(8),$a1
  104.            movew $sp@(12+2),$d0
  105.            bras 2f
  106.     1:       movel $a0@-,$a1@-
  107.     2:       dbra $d0,1b
  108.            movel $a1,$d0
  109.            rts
  110.  
  111. | extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
  112. C(fill_loop_up:) | Input in a0,d0.W,d1, Output in d0
  113.            movel $sp@(4),$a0
  114.            movew $sp@(8+2),$d0
  115.            movel $sp@(12),$d1
  116.            bras 2f
  117.     1:       movel $d1,$a0@+
  118.     2:       dbra $d0,1b
  119.            movel $a0,$d0
  120.            rts
  121.  
  122. | extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
  123. C(fill_loop_down:) | Input in a0,d0.W,d1, Output in d0
  124.            movel $sp@(4),$a0
  125.            movew $sp@(8+2),$d0
  126.            movel $sp@(12),$d1
  127.            bras 2f
  128.     1:       movel $d1,$a0@-
  129.     2:       dbra $d0,1b
  130.            movel $a0,$d0
  131.            rts
  132.  
  133. | extern uintD* clear_loop_up (uintD* destptr, uintC count);
  134. C(clear_loop_up:) | Input in a0,d0.W, Output in d0
  135.            movel $sp@(4),$a0
  136.            movew $sp@(8+2),$d0
  137.            bras 2f
  138.     1:       clrl $a0@+
  139.     2:       dbra $d0,1b
  140.            movel $a0,$d0
  141.            rts
  142.  
  143. | extern uintD* clear_loop_down (uintD* destptr, uintC count);
  144. C(clear_loop_down:) | Input in a0,d0.W, Output in d0
  145.            movel $sp@(4),$a0
  146.            movew $sp@(8+2),$d0
  147.            bras 2f
  148.     1:       clrl $a0@-
  149.     2:       dbra $d0,1b
  150.            movel $a0,$d0
  151.            rts
  152.  
  153. | extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
  154. C(or_loop_up:) | Input in a0,a1,d0.W, verΣndert d1
  155.            movel $sp@(4),$a0
  156.            movel $sp@(8),$a1
  157.            movew $sp@(12+2),$d0
  158.            bras 2f
  159.     1:       movel $a1@+,$d1
  160.              orl $d1,$a0@+
  161.     2:       dbra $d0,1b
  162.            rts
  163.  
  164. | extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  165. C(xor_loop_up:) | Input in a0,a1,d0.W, verΣndert d1
  166.            movel $sp@(4),$a0
  167.            movel $sp@(8),$a1
  168.            movew $sp@(12+2),$d0
  169.            bras 2f
  170.     1:       movel $a1@+,$d1
  171.              eorl $d1,$a0@+
  172.     2:       dbra $d0,1b
  173.            rts
  174.  
  175. | extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
  176. C(and_loop_up:) | Input in a0,a1,d0.W, verΣndert d1
  177.            movel $sp@(4),$a0
  178.            movel $sp@(8),$a1
  179.            movew $sp@(12+2),$d0
  180.            bras 2f
  181.     1:       movel $a1@+,$d1
  182.              andl $d1,$a0@+
  183.     2:       dbra $d0,1b
  184.            rts
  185.  
  186. | extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
  187. C(eqv_loop_up:) | Input in a0,a1,d0.W, verΣndert d1
  188.            movel $sp@(4),$a0
  189.            movel $sp@(8),$a1
  190.            movew $sp@(12+2),$d0
  191.            bras 2f
  192.     1:       movel $a1@+,$d1
  193.              eorl $d1,$a0@
  194.              notl $a0@+
  195.     2:       dbra $d0,1b
  196.            rts
  197.  
  198. | extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
  199. C(nand_loop_up:) | Input in a0,a1,d0.W, verΣndert d1
  200.            movel $sp@(4),$a0
  201.            movel $sp@(8),$a1
  202.            movew $sp@(12+2),$d0
  203.            bras 2f
  204.     1:       movel $a1@+,$d1
  205.              andl $d1,$a0@
  206.              notl $a0@+
  207.     2:       dbra $d0,1b
  208.            rts
  209.  
  210. | extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  211. C(nor_loop_up:) | Input in a0,a1,d0.W, verΣndert d1
  212.            movel $sp@(4),$a0
  213.            movel $sp@(8),$a1
  214.            movew $sp@(12+2),$d0
  215.            bras 2f
  216.     1:       movel $a1@+,$d1
  217.              orl $d1,$a0@
  218.              notl $a0@+
  219.     2:       dbra $d0,1b
  220.            rts
  221.  
  222. | extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  223. C(andc2_loop_up:) | Input in a0,a1,d0.W, verΣndert d1
  224.            movel $sp@(4),$a0
  225.            movel $sp@(8),$a1
  226.            movew $sp@(12+2),$d0
  227.            bras 2f
  228.     1:       movel $a1@+,$d1
  229.              notl $d1
  230.              andl $d1,$a0@+
  231.     2:       dbra $d0,1b
  232.            rts
  233.  
  234. | extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  235. C(orc2_loop_up:) | Input in a0,a1,d0.W, verΣndert d1
  236.            movel $sp@(4),$a0
  237.            movel $sp@(8),$a1
  238.            movew $sp@(12+2),$d0
  239.            bras 2f
  240.     1:       movel $a1@+,$d1
  241.              notl $d1
  242.              orl $d1,$a0@+
  243.     2:       dbra $d0,1b
  244.            rts
  245.  
  246. | extern void not_loop_up (uintD* xptr, uintC count);
  247. C(not_loop_up:) | Input in a0,d0.W
  248.            movel $sp@(4),$a0
  249.            movew $sp@(8+2),$d0
  250.            bras 2f
  251.     1:       notl $a0@+
  252.     2:       dbra $d0,1b
  253.            rts
  254.  
  255. | extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
  256. C(and_test_loop_up:) | Input in a0,a1,d0.W, verΣndert d1, Output in d0.W=d0.L
  257.            movel $sp@(4),$a0
  258.            movel $sp@(8),$a1
  259.            movew $sp@(12+2),$d0
  260.            bras 2f
  261.     1:       movel $a0@+,$d1
  262.              andl $a1@+,$d1
  263.              bnes 3f
  264.     2:       dbra $d0,1b
  265.            clrl $d0
  266.            rts
  267.     3:     moveq #1,$d0
  268.            rts
  269.  
  270. | extern boolean test_loop_up (uintD* ptr, uintC count);
  271. C(test_loop_up:) | Input in a0,d0.W, Output in d0.W=d0.L
  272.            movel $sp@(4),$a0
  273.            movew $sp@(8+2),$d0
  274.            bras 2f
  275.     1:       tstl $a0@+
  276.              bnes 3f
  277.     2:       dbra $d0,1b
  278.            clrl $d0
  279.            rts
  280.     3:     moveq #1,$d0
  281.            rts
  282.  
  283. | extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
  284. C(compare_loop_up:) | Input in a0,a1,d0.W, Output in d0.W=d0.L
  285.            movel $sp@(4),$a0
  286.            movel $sp@(8),$a1
  287.            movew $sp@(12+2),$d0
  288.            bras 2f
  289.     1:       cmpml $a1@+,$a0@+
  290.              bnes 3f
  291.     2:       dbra $d0,1b
  292.            clrl $d0
  293.            rts
  294.     3:     bcss 4f
  295.            moveq #1,$d0
  296.            rts
  297.     4:     moveq #-1,$d0
  298.            rts
  299.  
  300. | extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  301. C(add_loop_down:) | Input in a0,a1,a2,d0.W, verΣndert d1,d2, Output in d0
  302.            moveml $a2/$d2,$sp@-
  303.            movel $sp@(8+4),$a0
  304.            movel $sp@(8+8),$a1
  305.            movel $sp@(8+12),$a2
  306.            movew $sp@(8+16+2),$d0
  307.            clrx   | X-Bit l÷schen
  308.            bras 2f
  309.     1:       movel $a0@-,$d1
  310.              movel $a1@-,$d2
  311.              addxl $d2,$d1
  312.              movel $d1,$a2@-
  313.     2:       dbra $d0,1b
  314.            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  315.            moveml $sp@+,$a2/$d2
  316.            rts
  317.  
  318. | extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  319. C(addto_loop_down:) | Input in a0,a1,d0.W, Output in d0
  320.            movel $sp@(4),$a0
  321.            movel $sp@(8),$a1
  322.            movew $sp@(12+2),$d0
  323.            clrx   | X-Bit l÷schen
  324.            bras 2f
  325.     1:       addxl $a0@-,$a1@-
  326.     2:       dbra $d0,1b
  327.            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  328.            rts
  329.  
  330. | extern uintD inc_loop_down (uintD* ptr, uintC count);
  331. C(inc_loop_down:) | Input in a0,d0.W, Output in d0
  332.            movel $sp@(4),$a0
  333.            movew $sp@(8+2),$d0
  334.            dbra $d0,1f          | simuliere gesetzten Carry
  335.            moveq #-1,$d0     | d0.L=-1 fⁿr ▄bertrag
  336.            rts
  337.     1:       addql #1,$a0@-
  338.              dbcc $d0,1b
  339.            subxl $d0,$d0       | kein Carry -> d0.L=0, sonst d0.L=-1 fⁿr ▄bertrag
  340.            rts
  341.  
  342. | extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  343. C(sub_loop_down:) | Input in a0,a1,a2,d0.W, verΣndert d1,d2, Output in d0
  344.            moveml $a2/$d2,$sp@-
  345.            movel $sp@(8+4),$a0
  346.            movel $sp@(8+8),$a1
  347.            movel $sp@(8+12),$a2
  348.            movew $sp@(8+16+2),$d0
  349.            clrx   | X-Bit l÷schen
  350.            bras 2f
  351.     1:       movel $a0@-,$d1
  352.              movel $a1@-,$d2
  353.              subxl $d2,$d1
  354.              movel $d1,$a2@-
  355.     2:       dbra $d0,1b
  356.            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  357.            moveml $sp@+,$a2/$d2
  358.            rts
  359.  
  360. | extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
  361. C(subx_loop_down:) | Input in a0,a1,a2,d0.W,d1, verΣndert d2, Output in d0
  362.            moveml $a2/$d2,$sp@-
  363.            movel $sp@(8+4),$a0
  364.            movel $sp@(8+8),$a1
  365.            movel $sp@(8+12),$a2
  366.            movew $sp@(8+16+2),$d0
  367.            movel $sp@(8+20),$d1
  368.            roxrl #1,$d1      | X-Bit initialisieren
  369.            bras 2f
  370.     1:       movel $a0@-,$d1
  371.              movel $a1@-,$d2
  372.              subxl $d2,$d1
  373.              movel $d1,$a2@-
  374.     2:       dbra $d0,1b
  375.            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  376.            moveml $sp@+,$a2/$d2
  377.            rts
  378.  
  379. | extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  380. C(subfrom_loop_down:) | Input in a0,a1,d0.W, Output in d0
  381.            movel $sp@(4),$a0
  382.            movel $sp@(8),$a1
  383.            movew $sp@(12+2),$d0
  384.            clrx   | X-Bit l÷schen
  385.            bras 2f
  386.     1:       subxl $a0@-,$a1@-
  387.     2:       dbra $d0,1b
  388.            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  389.            rts
  390.  
  391. | extern uintD dec_loop_down (uintD* ptr, uintC count);
  392. C(dec_loop_down:) | Input in a0,d0.W, Output in d0
  393.            movel $sp@(4),$a0
  394.            movew $sp@(8+2),$d0
  395.            dbra $d0,1f          | simuliere gesetzten Carry
  396.            moveq #-1,$d0     | d0.L=-1 als ▄bertrag
  397.            rts
  398.     1:       subql #1,$a0@-
  399.              dbcc $d0,1b       | kein Carry -> Schleife abbrechen
  400.            subxl $d0,$d0       | kein Carry -> d0.L=0, sonst d0.L=-1 als ▄bertrag
  401.            rts
  402.  
  403. | extern uintD neg_loop_down (uintD* ptr, uintC count);
  404. C(neg_loop_down:) | Input in a0,d0.W, Output in d0
  405.            movel $sp@(4),$a0
  406.            movew $sp@(8+2),$d0
  407.            clrx   | X-Bit l÷schen
  408.            bras 2f
  409.     1:       negxl $a0@-
  410.     2:       dbra $d0,1b
  411.            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  412.            rts
  413.  
  414. | extern uintD shift1left_loop_down (uintD* ptr, uintC count);
  415. C(shift1left_loop_down:) | Input in a0,d0.W, Output in d0.L
  416.            movel $sp@(4),$a0
  417.            movew $sp@(8+2),$d0
  418.            clrx   | X-Bit l÷schen
  419.            bras 2f
  420.     1:       roxlw $a0@-     | Digit a0@- um 1 Bit links schieben, X-Bit als Buffer
  421.              roxlw $a0@-
  422.     2:       dbra $d0,1b
  423.            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  424.            rts
  425.  
  426. | extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
  427. C(shiftleft_loop_down:) | Input in a0,d0.W,d1.W,d2, Output in d0
  428. #if 1
  429.            moveml $d2-$d5,$sp@-
  430.            movel $sp@(16+4),$a0
  431.            movew $sp@(16+8+2),$d0
  432.            movew $sp@(16+12+2),$d1
  433.            movel $sp@(16+16),$d2
  434.            moveq #32,$d5
  435.            subw $d1,$d5
  436.            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
  437.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  438.            bras 2f
  439.     1:       movel $a0@-,$d3  | d3.L = neues Digit
  440.              movel $d3,$d4
  441.              lsll $d1,$d4      | um i Bits nach links schieben
  442.              orl $d2,$d4       | mit vorigem ▄bertrag kombinieren
  443.              movel $d4,$a0@   | 32 Bits ablegen
  444.              movel $d3,$d2
  445.              lsrl $d5,$d2      | neuen ▄bertrag bilden
  446.     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
  447.            movel $d2,$d0
  448.            moveml $sp@+,$d2-$d5
  449.            rts
  450. #else
  451.            moveml $d2-$d5,$sp@-
  452.            movel $sp@(16+4),$a0
  453.            movew $sp@(16+8+2),$d0
  454.            movew $sp@(16+12+2),$d1
  455.            movel $sp@(16+16),$d2
  456.            moveq #1,$d5
  457.            lsll $d1,$d5
  458.            subql #1,$d5
  459.            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^i-1
  460.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  461.            bras 2f
  462.     1:       movel $a0@-,$d3  | d3.L = neues Digit
  463.              roll $d1,$d3      | um i Bits links rotieren
  464.              movel $d3,$d4
  465.              andl $d5,$d3      | untere i Bits in d3
  466.              eorl $d3,$d4      | obere 32-i Bits in d4
  467.              orl $d2,$d4       | mit vorigem ⁿbertrag kombinieren
  468.              movel $d4,$a0@   | 32 Bits ablegen
  469.              movel $d3,$d2     | neuer ▄bertrag
  470.     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
  471.            movel $d2,$d0
  472.            moveml $sp@+,$d2-$d5
  473.            rts
  474. #endif
  475.  
  476. | extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
  477. C(shiftleftcopy_loop_down:) | Input in a0,a1,d0.W,d1.W, Output in d0
  478. #if 1
  479.            moveml $d2-$d5,$sp@-
  480.            movel $sp@(16+4),$a0
  481.            movel $sp@(16+8),$a1
  482.            movew $sp@(16+12+2),$d0
  483.            movew $sp@(16+16+2),$d1
  484.            moveq #32,$d5
  485.            subw $d1,$d5
  486.            clrl $d2
  487.            | a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i, d5.W = 32-i,
  488.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  489.            bras 2f
  490.     1:       movel $a0@-,$d3  | d3.L = neues Digit
  491.              movel $d3,$d4
  492.              lsll $d1,$d4      | um i Bits nach links schieben
  493.              orl $d2,$d4       | mit vorigem ▄bertrag kombinieren
  494.              movel $d4,$a1@-  | 32 Bits ablegen
  495.              movel $d3,$d2
  496.              lsrl $d5,$d2      | neuen ▄bertrag bilden
  497.     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
  498.            movel $d2,$d0
  499.            moveml $sp@+,$d2-$d5
  500.            rts
  501. #else
  502.            moveml $d2-$d5,$sp@-
  503.            movel $sp@(16+4),$a0
  504.            movel $sp@(16+8),$a1
  505.            movew $sp@(16+12+2),$d0
  506.            movew $sp@(16+16+2),$d1
  507.            moveq #1,$d5
  508.            lsll $d1,$d5
  509.            subql #1,$d5
  510.            | a0 = sourceptr, a1 = destptr, d0.W = count, d1.W = i, d5.L = 2^i-1
  511.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  512.            bras 2f
  513.     1:       movel $a0@-,$d3  | d3.L = neues Digit
  514.              roll $d1,$d3      | um i Bits links rotieren
  515.              movel $d3,$d4
  516.              andl $d5,$d3      | untere i Bits in d3
  517.              eorl $d3,$d4      | obere 32-i Bits in d4
  518.              orl $d2,$d4       | mit vorigem ⁿbertrag kombinieren
  519.              movel $d4,$a1@-  | 32 Bits ablegen
  520.              movel $d3,$d2     | neuer ▄bertrag
  521.     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
  522.            movel $d2,$d0
  523.            moveml $sp@+,$d2-$d5
  524.            rts
  525. #endif
  526.  
  527. | extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
  528. C(shift1right_loop_up:) | Input in a0,d0.W,d1, Output in d0
  529.            movel $sp@(4),$a0
  530.            movew $sp@(8+2),$d0
  531.            movel $sp@(12),$d1
  532.            roxrl #1,$d1       | X-Bit l÷schen oder setzen, je nach d1
  533.            bras 2f
  534.     1:       roxrw $a0@+     | Digit a0@+ um 1 Bit rechts schieben, X-Bit als Buffer
  535.              roxrw $a0@+
  536.     2:       dbra $d0,1b
  537.            subxl $d0,$d0       | -1 falls X gesetzt, 0 falls X gel÷scht
  538.            rts
  539.  
  540. | extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
  541. C(shiftright_loop_up:) | Input in a0,d0.W,d1.W, Output in d0
  542. #if 1
  543.            moveml $d2-$d5,$sp@-
  544.            movel $sp@(16+4),$a0
  545.            movew $sp@(16+8+2),$d0
  546.            movew $sp@(16+12+2),$d1
  547.            moveq #32,$d5
  548.            subw $d1,$d5
  549.            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
  550.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  551.            clrl $d2
  552.            bras 2f
  553.     1:       | a0 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i, d5.W = 32-i,
  554.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  555.              | d3.L = Schiebe-Akku
  556.              movel $a0@,$d3   | neue Daten
  557.              movel $d3,$d4
  558.              lsrl $d1,$d3      | um i Bits rechts schieben
  559.              orl $d2,$d3       | und mit vorigem ▄bertrag kombinieren
  560.              movel $d3,$a0@+  | ablegen
  561.              lsll $d5,$d4      | um (32-i) Bits links geschoben
  562.              movel $d4,$d2     | liefert neuen ▄bertrag
  563.     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
  564.            movel $d2,$d0
  565.            moveml $sp@+,$d2-$d5
  566.            rts
  567. #else
  568.            moveml $d2-$d5,$sp@-
  569.            movel $sp@(16+4),$a0
  570.            movew $sp@(16+8+2),$d0
  571.            movew $sp@(16+12+2),$d1
  572.            moveq #-1,$d5
  573.            lsrl $d1,$d5
  574.            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1,
  575.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  576.            clrl $d2
  577.            bras 2f
  578.     1:       | a0 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i, d5.L = 2^(32-i)-1,
  579.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  580.              | d3.L = Schiebe-Akku
  581.              movel $a0@,$d3   | neue Daten
  582.              rorl $d1,$d3      | um i Bits rechts rotieren
  583.              movel $d3,$d4
  584.              andl $d5,$d3      | untere 32-i Bits
  585.              eorl $d3,$d4      | obere i Bits
  586.              orl $d2,$d3       | und mit vorigem ▄bertrag kombinieren
  587.              movel $d4,$d2     | neuer ▄bertrag
  588.              movel $d3,$a0@+  | ablegen
  589.     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
  590.            movel $d2,$d0
  591.            moveml $sp@+,$d2-$d5
  592.            rts
  593. #endif
  594.  
  595. | extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
  596. C(shiftrightsigned_loop_up:) | Input in a0,d0.W,d1.W, Output in d0
  597. #if 1
  598.            moveml $d2-$d5,$sp@-
  599.            movel $sp@(16+4),$a0
  600.            movew $sp@(16+8+2),$d0
  601.            movew $sp@(16+12+2),$d1
  602.            moveq #32,$d5
  603.            subw $d1,$d5
  604.            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i,
  605.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  606.            subqw #1,$d0
  607.            movel $a0@,$d3     | erstes Digit
  608.            movel $d3,$d4
  609.            asrl $d1,$d3        | um i Bits rechts schieben
  610.            bras 2f
  611.     1:       | a0 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i, d5.W = 32-i,
  612.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  613.              | d3.L = Schiebe-Akku
  614.              movel $a0@,$d3   | neue Daten
  615.              movel $d3,$d4
  616.              lsrl $d1,$d3      | um i Bits rechts schieben
  617.              orl $d2,$d3       | und mit vorigem ▄bertrag kombinieren
  618.     2:       movel $d3,$a0@+  | ablegen
  619.              lsll $d5,$d4      | um (32-i) Bits links geschoben
  620.              movel $d4,$d2     | liefert neuen ▄bertrag
  621.              dbra $d0,1b        | Schleife d0.W mal durchlaufen
  622.            movel $d2,$d0
  623.            moveml $sp@+,$d2-$d5
  624.            rts
  625. #else
  626.            moveml $d2-$d5,$sp@-
  627.            movel $sp@(16+4),$a0
  628.            movew $sp@(16+8+2),$d0
  629.            movew $sp@(16+12+2),$d1
  630.            moveq #-1,$d5
  631.            lsrl $d1,$d5
  632.            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1,
  633.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  634.            subqw #1,$d0
  635.            movel $a0@,$d3     | erstes Digit
  636.            movel $d3,$d4
  637.            rorl $d1,$d4        | um i Bits rechts rotieren
  638.            movel $d5,$d2
  639.            notl $d2
  640.            andl $d4,$d2        | obere 32-i Bits
  641.            asrl $d1,$d3        | erstes Digit um i Bits rechts shiften
  642.            bras 2f
  643.     1:       | a0 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i, d5.L = 2^(32-i)-1,
  644.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  645.              | d3.L = Schiebe-Akku
  646.              movel $a0@,$d3   | neue Daten
  647.              rorl $d1,$d3      | um i Bits rechts rotieren
  648.              movel $d3,$d4
  649.              andl $d5,$d3      | untere 32-i Bits
  650.              eorl $d3,$d4      | obere i Bits
  651.              orl $d2,$d3       | und mit vorigem ▄bertrag kombinieren
  652.              movel $d4,$d2     | neuer ▄bertrag
  653.     2:       movel $d3,$a0@+  | ablegen
  654.              dbra $d0,1b        | Schleife d0.W mal durchlaufen
  655.            movel $d2,$d0
  656.            moveml $sp@+,$d2-$d5
  657.            rts
  658. #endif
  659.  
  660. | extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
  661. C(shiftrightcopy_loop_up:) | Input in a0,a1,d0.W,d1.W,d2, Output in d0
  662. #if 1
  663.            moveml $d2-$d5,$sp@-
  664.            movel $sp@(16+4),$a0
  665.            movel $sp@(16+8),$a1
  666.            movew $sp@(16+12+2),$d0
  667.            movew $sp@(16+16+2),$d1
  668.            movel $sp@(16+20),$d2
  669.            moveq #32,$d5
  670.            subw $d1,$d5
  671.            | a0 = ptr, d0.W = count, d1.W = i, d5.W = 32-i
  672.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  673.            bras 2f
  674.     1:       | a0,a1 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i, d5.W = 32-i
  675.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  676.              | d3.L = Schiebe-Akku
  677.              movel $a0@+,$d3  | neue Daten
  678.              movel $d3,$d4
  679.              lsrl $d1,$d3      | um i Bits rechts schieben
  680.              orl $d2,$d3       | und mit vorigem ▄bertrag kombinieren
  681.              movel $d3,$a1@+  | ablegen
  682.              movel $d4,$d2
  683.     2:       lsll $d5,$d2      | um (32-i) Bits links geschoben, gibt neuen ▄bertrag
  684.              dbra $d0,1b        | Schleife d0.W mal durchlaufen
  685.            movel $d2,$d0
  686.            moveml $sp@+,$d2-$d5
  687.            rts
  688. #else
  689.            moveml $d2-$d5,$sp@-
  690.            movel $sp@(16+4),$a0
  691.            movel $sp@(16+8),$a1
  692.            movew $sp@(16+12+2),$d0
  693.            movew $sp@(16+16+2),$d1
  694.            movel $sp@(16+20),$d2
  695.            moveq #-1,$d5
  696.            lsrl $d1,$d5
  697.            rorl $d1,$d2
  698.            | a0 = ptr, d0.W = count, d1.W = i, d5.L = 2^(32-i)-1
  699.            | d2.L = Schiebe-▄bertrag (i Bits), d3.L = Schiebe-Akku
  700.            bras 2f
  701.     1:       | a0,a1 = AufwΣrtszΣhler Adresse, d0.W = HerabzΣhler, d1.W = i, d5.L = 2^(32-i)-1
  702.              | d2.L = Schiebe-▄bertrag (obere i Bits, restliche 32-i Bits sind 0)
  703.              | d3.L = Schiebe-Akku
  704.              movel $a0@+,$d3  | neue Daten
  705.              rorl $d1,$d3      | um i Bits rechts rotieren
  706.              movel $d3,$d4
  707.              andl $d5,$d3      | untere 32-i Bits
  708.              eorl $d3,$d4      | obere i Bits
  709.              orl $d2,$d3       | und mit vorigem ▄bertrag kombinieren
  710.              movel $d4,$d2     | neuer ▄bertrag
  711.              movel $d3,$a1@+  | ablegen
  712.     2:       dbra $d0,1b        | Schleife d0.W mal durchlaufen
  713.            movel $d2,$d0
  714.            moveml $sp@+,$d2-$d5
  715.            rts
  716. #endif
  717.  
  718. | extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
  719. C(mulusmall_loop_down:) # Input in d0,a0,d1.W,d2, Output in d0
  720.            moveml $d2-$d4,$sp@-
  721.            movel $sp@(12+4),$d0
  722.            movel $sp@(12+8),$a0
  723.            movew $sp@(12+12+2),$d1
  724.            movel $sp@(12+16),$d2
  725.            addw #0,$d1        | X-Bit l÷schen
  726.            bras 2f
  727.     1:       movel $a0@-,$d3  | nΣchstes Digit
  728.              mulul $d0,$d4:$d3  | mit digit multiplizieren
  729.              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
  730.              movel $d3,$a0@   | Low-Digit ablegen
  731.              movel $d4,$d2     | High-Digit gibt neuen Carry
  732.     2:       dbra $d1,1b
  733.            clrl $d0
  734.            addxl $d2,$d0       | letzter Carry (incl. X-Bit)
  735.            moveml $sp@+,$d2-$d4
  736.            rts
  737.  
  738. | extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  739. C(mulu_loop_down:) | Input in d0,a0,a1,d1.W
  740. #if 1
  741.            moveml $d2-$d4,$sp@-
  742.            movel $sp@(12+4),$d0
  743.            movel $sp@(12+8),$a0
  744.            movel $sp@(12+12),$a1
  745.            movew $sp@(12+16+2),$d1
  746.            subl $d2,$d2        | carry := 0, X-Bit l÷schen
  747.            bras 2f
  748.     1:       movel $a0@-,$d3  | nΣchstes Digit
  749.              mulul $d0,$d4:$d3  | mit digit multiplizieren
  750.              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
  751.              movel $d3,$a1@-  | Low-Digit ablegen
  752.              movel $d4,$d2     | High-Digit gibt neuen Carry
  753.     2:       dbra $d1,1b
  754.            clrl $d3
  755.            addxl $d3,$d2       | letztes X-Bit verarbeiten
  756.            movel $d2,$a1@-    | letzten Carry ablegen
  757.            moveml $sp@+,$d2-$d4
  758.            rts
  759. #else
  760.            moveml $d2-$d5,$sp@-
  761.            movel $sp@(16+4),$d0
  762.            movel $sp@(16+8),$a0
  763.            movel $sp@(16+12),$a1
  764.            movew $sp@(16+16+2),$d1
  765.            clrl $d5           | 0
  766.            clrl $d2           | carry
  767.            bras 2f
  768.     1:       movel $a0@-,$d3  | nΣchstes Digit
  769.              mulul $d0,$d4:$d3  | mit digit multiplizieren
  770.              addl $d2,$d3      | und bisherigen Carry addieren
  771.              addxl $d5,$d4
  772.              movel $d3,$a1@-  | Low-Digit ablegen
  773.              movel $d4,$d2     | High-Digit gibt neuen Carry
  774.     2:       dbra $d1,1b
  775.            movel $d2,$a1@-    | letzten Carry ablegen
  776.            moveml $sp@+,$d2-$d5
  777.            rts
  778. #endif
  779.  
  780. | extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  781. C(muluadd_loop_down:) | Input in d0,a0,a1,d1.W, Output in d0
  782.            moveml $d2-$d5,$sp@-
  783.            movel $sp@(16+4),$d0
  784.            movel $sp@(16+8),$a0
  785.            movel $sp@(16+12),$a1
  786.            movew $sp@(16+16+2),$d1
  787.            clrl $d5           | 0
  788.            subl $d2,$d2        | carry := 0, X-Bit l÷schen
  789.            bras 2f
  790.     1:       movel $a0@-,$d3  | nΣchstes Digit
  791.              mulul $d0,$d4:$d3  | mit digit multiplizieren
  792.              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
  793.              addxl $d5,$d4
  794.              addl $d3,$a1@-   | Low-Digit zum dest-Digit addieren, X als ▄bertrag
  795.              movel $d4,$d2     | High-Digit gibt neuen Carry
  796.     2:       dbra $d1,1b
  797.            addxl $d5,$d2       | letztes X-Bit addieren
  798.            movel $d2,$d0       | letzten Carry als Ergebnis
  799.            moveml $sp@+,$d2-$d5
  800.            rts
  801.  
  802. | extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  803. C(mulusub_loop_down:) | Input in d0,a0,a1,d1.W, Output in d0
  804.            moveml $d2-$d5,$sp@-
  805.            movel $sp@(16+4),$d0
  806.            movel $sp@(16+8),$a0
  807.            movel $sp@(16+12),$a1
  808.            movew $sp@(16+16+2),$d1
  809.            clrl $d5           | 0
  810.            subl $d2,$d2        | carry := 0, X-Bit l÷schen
  811.            bras 2f
  812.     1:       movel $a0@-,$d3  | nΣchstes Digit
  813.              mulul $d0,$d4:$d3  | mit digit multiplizieren
  814.              addxl $d2,$d3     | und bisherigen Carry und X-Bit addieren
  815.              addxl $d5,$d4
  816.              subl $d3,$a1@-   | Low-Digit vom dest-Digit subtrahieren, X als ▄bertrag
  817.              movel $d4,$d2     | High-Digit gibt neuen Carry
  818.     2:       dbra $d1,1b
  819.            clrl $d0
  820.            addxl $d2,$d0       | letzter Carry und letztes X-Bit
  821.            moveml $sp@+,$d2-$d5
  822.            rts
  823.  
  824. | extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
  825. C(divu_loop_up:) # Input in d0,a0,d1.W, Output in d0
  826.            moveml $d2-$d3,$sp@-
  827.            movel $sp@(8+4),$d0
  828.            movel $sp@(8+8),$a0
  829.            movew $sp@(8+12+2),$d1
  830.            clrl $d2           | Rest := 0
  831.            bras 2f
  832.     1:       movel $a0@,$d3   | nΣchst-niedriges Digit
  833.              divul $d0,$d2:$d3  | mit Rest kombinieren und durch digit dividieren
  834.              movel $d3,$a0@+  | Quotient ablegen, Rest in d2
  835.     2:       dbra $d1,1b
  836.            movel $d2,$d0       | Rest
  837.            moveml $sp@+,$d2-$d3
  838.            rts
  839.  
  840. | extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  841. C(divucopy_loop_up:) # Input in d0,a0,a1,d1.W, Output in d0
  842.            moveml $d2-$d3,$sp@-
  843.            movel $sp@(8+4),$d0
  844.            movel $sp@(8+8),$a0
  845.            movel $sp@(8+12),$a1
  846.            movew $sp@(8+16+2),$d1
  847.            clrl $d2           | Rest := 0
  848.            bras 2f
  849.     1:       movel $a0@+,$d3  | nΣchst-niedriges Digit
  850.              divul $d0,$d2:$d3  | mit Rest kombinieren und durch digit dividieren
  851.              movel $d3,$a1@+  | Quotient ablegen, Rest in d2
  852.     2:       dbra $d1,1b
  853.            movel $d2,$d0       | Rest
  854.            moveml $sp@+,$d2-$d3
  855.            rts
  856.  
  857. #endif
  858.  
  859.