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 >
Text File  |  1996-06-11  |  30KB  |  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.