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