home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / CLISP-1.LHA / CLISP960530-sr.lha / src / arilev1i.d < prev    next >
Encoding:
Text File  |  1996-04-15  |  33.6 KB  |  989 lines

  1. # Definitionen und portabler C-Code zu ARILEV1.D, Inline-Version
  2.  
  3. #ifndef COPY_LOOPS
  4.  
  5. # Kopierschleife:
  6. # destptr = copy_loop_up(sourceptr,destptr,count);
  7. # kopiert count (uintC>=0) Digits aufwärts von sourceptr nach destptr
  8. # und liefert das neue destptr.
  9.   local uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
  10.   inline local uintD* copy_loop_up(sourceptr,destptr,count)
  11.     var reg2 uintD* sourceptr;
  12.     var reg1 uintD* destptr;
  13.     var reg3 uintC count;
  14.     { dotimesC(count,count, { *destptr++ = *sourceptr++; } );
  15.       return destptr;
  16.     }
  17.  
  18. # Kopierschleife:
  19. # destptr = copy_loop_down(sourceptr,destptr,count);
  20. # kopiert count (uintC>=0) Digits abwärts von sourceptr nach destptr
  21. # und liefert das neue destptr.
  22.   local uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  23.   inline local uintD* copy_loop_down(sourceptr,destptr,count)
  24.     var reg2 uintD* sourceptr;
  25.     var reg1 uintD* destptr;
  26.     var reg3 uintC count;
  27.     { dotimesC(count,count, { *--destptr = *--sourceptr; } );
  28.       return destptr;
  29.     }
  30.  
  31. #endif
  32.  
  33. #ifndef FILL_LOOPS
  34.  
  35. # Füllschleife:
  36. # destptr = fill_loop_up(destptr,count,filler);
  37. # kopiert count (uintC>=0) mal das Digit filler aufwärts nach destptr
  38. # und liefert das neue destptr.
  39.   local uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
  40.   inline local uintD* fill_loop_up(destptr,count,filler)
  41.     var reg1 uintD* destptr;
  42.     var reg3 uintC count;
  43.     var reg2 uintD filler;
  44.     { dotimesC(count,count, { *destptr++ = filler; } );
  45.       return destptr;
  46.     }
  47.  
  48. # Füllschleife:
  49. # destptr = fill_loop_down(destptr,count,filler);
  50. # kopiert count (uintC>=0) mal das Digit filler abwärts nach destptr
  51. # und liefert das neue destptr.
  52.   local uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
  53.   inline local uintD* fill_loop_down(destptr,count,filler)
  54.     var reg1 uintD* destptr;
  55.     var reg3 uintC count;
  56.     var reg2 uintD filler;
  57.     { dotimesC(count,count, { *--destptr = filler; } );
  58.       return destptr;
  59.     }
  60.  
  61. #endif
  62.  
  63. #ifndef CLEAR_LOOPS
  64.  
  65. # Lösch-Schleife:
  66. # destptr = clear_loop_up(destptr,count);
  67. # löscht count (uintC>=0) Digits aufwärts ab destptr
  68. # und liefert das neue destptr.
  69.   local uintD* clear_loop_up (uintD* destptr, uintC count);
  70.   inline local uintD* clear_loop_up(destptr,count)
  71.     var reg1 uintD* destptr;
  72.     var reg2 uintC count;
  73.     { dotimesC(count,count, { *destptr++ = 0; } );
  74.       return destptr;
  75.     }
  76.  
  77. # Lösch-Schleife:
  78. # destptr = clear_loop_down(destptr,count);
  79. # löscht count (uintC>=0) Digits abwärts ab destptr
  80. # und liefert das neue destptr.
  81.   local uintD* clear_loop_down (uintD* destptr, uintC count);
  82.   inline local uintD* clear_loop_down(destptr,count)
  83.     var reg1 uintD* destptr;
  84.     var reg2 uintC count;
  85.     { dotimesC(count,count, { *--destptr = 0; } );
  86.       return destptr;
  87.     }
  88.  
  89. #endif
  90.  
  91. #ifndef LOG_LOOPS
  92.  
  93. # OR-Schleife:
  94. # or_loop_up(xptr,yptr,count);
  95. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr
  96. # mit Ziel ab xptr durch OR.
  97.   local void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
  98.   inline local void or_loop_up(xptr,yptr,count)
  99.     var reg1 uintD* xptr;
  100.     var reg2 uintD* yptr;
  101.     var reg3 uintC count;
  102.     { dotimesC(count,count, { *xptr++ |= *yptr++; } ); }
  103.  
  104. # XOR-Schleife:
  105. # xor_loop_up(xptr,yptr,count);
  106. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr
  107. # mit Ziel ab xptr durch XOR.
  108.   local void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  109.   inline local void xor_loop_up(xptr,yptr,count)
  110.     var reg1 uintD* xptr;
  111.     var reg2 uintD* yptr;
  112.     var reg3 uintC count;
  113.     { dotimesC(count,count, { *xptr++ ^= *yptr++; } ); }
  114.  
  115. # AND-Schleife:
  116. # and_loop_up(xptr,yptr,count);
  117. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr
  118. # mit Ziel ab xptr durch AND.
  119.   local void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
  120.   inline local void and_loop_up(xptr,yptr,count)
  121.     var reg1 uintD* xptr;
  122.     var reg2 uintD* yptr;
  123.     var reg3 uintC count;
  124.     { dotimesC(count,count, { *xptr++ &= *yptr++; } ); }
  125.  
  126. # EQV-Schleife:
  127. # eqv_loop_up(xptr,yptr,count);
  128. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr
  129. # mit Ziel ab xptr durch EQV (NOT XOR).
  130.   local void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
  131.   inline local void eqv_loop_up(xptr,yptr,count)
  132.     var reg1 uintD* xptr;
  133.     var reg2 uintD* yptr;
  134.     var reg3 uintC count;
  135.     { dotimesC(count,count,
  136.         {var reg4 uintD temp = ~ (*xptr ^ *yptr++); *xptr++ = temp; }
  137.         );
  138.     }
  139.  
  140. # NAND-Schleife:
  141. # nand_loop_up(xptr,yptr,count);
  142. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr
  143. # mit Ziel ab xptr durch NAND (NOT AND).
  144.   local void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
  145.   inline local void nand_loop_up(xptr,yptr,count)
  146.     var reg1 uintD* xptr;
  147.     var reg2 uintD* yptr;
  148.     var reg3 uintC count;
  149.     { dotimesC(count,count,
  150.         {var reg4 uintD temp = ~ (*xptr & *yptr++); *xptr++ = temp; }
  151.         );
  152.     }
  153.  
  154. # NOR-Schleife:
  155. # nor_loop_up(xptr,yptr,count);
  156. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr
  157. # mit Ziel ab xptr durch NOR (NOT OR).
  158.   local void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  159.   inline local void nor_loop_up(xptr,yptr,count)
  160.     var reg1 uintD* xptr;
  161.     var reg2 uintD* yptr;
  162.     var reg3 uintC count;
  163.     { dotimesC(count,count,
  164.         {var reg4 uintD temp = ~ (*xptr | *yptr++); *xptr++ = temp; }
  165.         );
  166.     }
  167.  
  168. # ANDC2-Schleife:
  169. # andc2_loop_up(xptr,yptr,count);
  170. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr
  171. # mit Ziel ab xptr durch ANDC2 (AND NOT).
  172.   local void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  173.   inline local void andc2_loop_up(xptr,yptr,count)
  174.     var reg1 uintD* xptr;
  175.     var reg2 uintD* yptr;
  176.     var reg3 uintC count;
  177.     { dotimesC(count,count, { *xptr++ &= ~(*yptr++); } ); }
  178.  
  179. # ORC2-Schleife:
  180. # orc2_loop_up(xptr,yptr,count);
  181. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr
  182. # mit Ziel ab xptr durch ORC2 (OR NOT).
  183.   local void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  184.   inline local void orc2_loop_up(xptr,yptr,count)
  185.     var reg1 uintD* xptr;
  186.     var reg2 uintD* yptr;
  187.     var reg3 uintC count;
  188.     { dotimesC(count,count, { *xptr++ |= ~(*yptr++); } ); }
  189.  
  190. # NOT-Schleife:
  191. # not_loop_up(xptr,count);
  192. # verknüpft count (uintC>0) Digits aufwärts ab xptr mit Ziel ab xptr
  193. # durch NOT.
  194.   local void not_loop_up (uintD* xptr, uintC count);
  195.   inline local void not_loop_up(xptr,count)
  196.     var reg1 uintD* xptr;
  197.     var reg2 uintC count;
  198.     { dotimespC(count,count,
  199.         {var reg3 uintD temp = ~ (*xptr); *xptr++ = temp; }
  200.         );
  201.     }
  202.  
  203. #endif
  204.  
  205. #ifndef TEST_LOOPS
  206.  
  207. # AND-Test-Schleife:
  208. # and_test_loop_up(xptr,yptr,count);
  209. # verknüpft count (uintC>=0) Digits aufwärts ab xptr und ab yptr durch AND
  210. # und testet, ob sich dabei ein Digit /=0 ergibt. Ergebnis /=0, falls ja.
  211.   local boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
  212.   inline local boolean and_test_loop_up(xptr,yptr,count)
  213.     var reg1 uintD* xptr;
  214.     var reg2 uintD* yptr;
  215.     var reg3 uintC count;
  216.     { dotimesC(count,count, { if (*xptr++ & *yptr++) return TRUE; } );
  217.       return FALSE;
  218.     }
  219.  
  220. # Test-Schleife:
  221. # test_loop_up(ptr,count)
  222. # bzw.  if_test_loop_up(ptr,count, statement1, statement2)
  223. # testet count (uintC>=0) Digits aufwärts ab ptr, ob darunter eines /=0 ist.
  224. # Ergebnis /=0, falls ja.
  225.   local boolean test_loop_up (uintD* ptr, uintC count);
  226.   inline local boolean test_loop_up(ptr,count)
  227.     var reg2 uintD* ptr;
  228.     var reg3 uintC count;
  229.     { dotimesC(count,count, { if (*ptr++) return TRUE; } );
  230.       return FALSE;
  231.     }
  232.  
  233. # Vergleichsschleife:
  234. # result = compare_loop_up(xptr,yptr,count);
  235. # vergleicht nacheinander xptr[0] mit yptr[0], xptr[1] mit yptr[1], usw.,
  236. # insgesamt count Digits, und liefert 0 falls alle gleich sind,
  237. # +1 falls zuerst ein xptr[i]>yptr[i] ist,
  238. # -1 falls zuerst ein xptr[i]<yptr[i] ist.
  239.   local signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
  240.   inline local signean compare_loop_up(xptr,yptr,count)
  241.     var reg1 uintD* xptr;
  242.     var reg1 uintD* yptr;
  243.     var reg2 uintC count;
  244.     { dotimesC(count,count,
  245.         { if (!(*xptr++ == *yptr++))
  246.             # verschiedene Digits gefunden
  247.             return (*--xptr > *--yptr ? signean_plus : signean_minus);
  248.         });
  249.       return signean_null; # alle Digits gleich
  250.     }
  251.  
  252. #endif
  253.  
  254. #ifndef ADDSUB_LOOPS
  255.  
  256. # Additionsschleife:
  257. # übertrag = add_loop_down(sourceptr1,sourceptr2,destptr,count);
  258. # addiert count (uintC>=0) Digits abwärts von sourceptr1, von sourceptr2
  259. # abwärts nach destptr und liefert den Übertrag (0 oder /=0, was 1 bedeutet).
  260.   local uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  261.   inline local uintD add_loop_down(sourceptr1,sourceptr2,destptr,count)
  262.     var reg3 uintD* sourceptr1;
  263.     var reg3 uintD* sourceptr2;
  264.     var reg2 uintD* destptr;
  265.     var reg4 uintC count;
  266.     { if (!(count==0))
  267.       do { var reg1 uintD source1 = *--sourceptr1;
  268.            var reg1 uintD source2 = *--sourceptr2;
  269.            *--destptr = source1 + source2;
  270.            if (source1 > (uintD)(~source2)) goto carry_1;
  271.            carry_0:
  272.            count--;
  273.          }
  274.          until (count==0);
  275.       return 0;
  276.       do { var reg1 uintD source1 = *--sourceptr1;
  277.            var reg1 uintD source2 = *--sourceptr2;
  278.            *--destptr = source1 + source2 + 1;
  279.            if (source1 < (uintD)(~source2)) goto carry_0;
  280.            carry_1:
  281.            count--;
  282.          }
  283.          until (count==0);
  284.       return 1;
  285.     }
  286.  
  287. # Additionsschleife:
  288. # übertrag = addto_loop_down(sourceptr,destptr,count);
  289. # addiert count (uintC>=0) Digits abwärts von sourceptr, von destptr
  290. # abwärts nach destptr und liefert den Übertrag (0 oder /=0, was 1 bedeutet).
  291.   local uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  292.   inline local uintD addto_loop_down(sourceptr,destptr,count)
  293.     var reg3 uintD* sourceptr;
  294.     var reg2 uintD* destptr;
  295.     var reg4 uintC count;
  296.     { if (!(count==0))
  297.       do { var reg1 uintD source1 = *--sourceptr;
  298.            var reg1 uintD source2 = *--destptr;
  299.            *destptr = source1 + source2;
  300.            if (source1 > (uintD)(~source2)) goto carry_1;
  301.            carry_0:
  302.            count--;
  303.          }
  304.          until (count==0);
  305.       return 0;
  306.       do { var reg1 uintD source1 = *--sourceptr;
  307.            var reg1 uintD source2 = *--destptr;
  308.            *destptr = source1 + source2 + 1;
  309.            if (source1 < (uintD)(~source2)) goto carry_0;
  310.            carry_1:
  311.            count--;
  312.          }
  313.          until (count==0);
  314.       return 1;
  315.     }
  316.  
  317. # Incrementierschleife:
  318. # übertrag = inc_loop_down(ptr,count);
  319. # incrementiert count (uintC>=0) Digits abwärts von ptr, so lange bis kein
  320. # Übertrag mehr auftritt und liefert den Übertrag (0 oder /=0, was 1 bedeutet).
  321.   local uintD inc_loop_down (uintD* ptr, uintC count);
  322.   inline local uintD inc_loop_down(ptr,count)
  323.     var reg1 uintD* ptr;
  324.     var reg2 uintC count;
  325.     { dotimesC(count,count,
  326.         { if (!( ++(*--ptr) == 0 )) return 0; } # kein weiterer Übertrag
  327.         );
  328.       return 1; # weiterer Übertrag
  329.     }
  330.  
  331. # Subtraktionsschleife:
  332. # übertrag = sub_loop_down(sourceptr1,sourceptr2,destptr,count);
  333. # subtrahiert count (uintC>=0) Digits abwärts von sourceptr1, von sourceptr2
  334. # abwärts nach destptr und liefert den Übertrag (0 oder /=0, was -1 bedeutet).
  335.   local uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  336.   inline local uintD sub_loop_down(sourceptr1,sourceptr2,destptr,count)
  337.     var reg3 uintD* sourceptr1;
  338.     var reg3 uintD* sourceptr2;
  339.     var reg2 uintD* destptr;
  340.     var reg4 uintC count;
  341.     { if (!(count==0))
  342.       do { var reg1 uintD source1 = *--sourceptr1;
  343.            var reg1 uintD source2 = *--sourceptr2;
  344.            *--destptr = source1 - source2;
  345.            if (source1 < source2) goto carry_1;
  346.            carry_0:
  347.            count--;
  348.          }
  349.          until (count==0);
  350.       return 0;
  351.       do { var reg1 uintD source1 = *--sourceptr1;
  352.            var reg1 uintD source2 = *--sourceptr2;
  353.            *--destptr = source1 - source2 - 1;
  354.            if (source1 > source2) goto carry_0;
  355.            carry_1:
  356.            count--;
  357.          }
  358.          until (count==0);
  359.       return -1;
  360.     }
  361.  
  362. # Subtraktionsschleife:
  363. # übertrag = subx_loop_down(sourceptr1,sourceptr2,destptr,count,carry);
  364. # subtrahiert count (uintC>=0) Digits abwärts von sourceptr1 und addiert
  365. # einen Carry (0 oder -1), von sourceptr2 abwärts nach destptr und
  366. # liefert den Übertrag (0 oder /=0, was -1 bedeutet).
  367.   local uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
  368.   inline local uintD subx_loop_down(sourceptr1,sourceptr2,destptr,count,carry)
  369.     var reg2 uintD* sourceptr1;
  370.     var reg3 uintD* sourceptr2;
  371.     var reg2 uintD* destptr;
  372.     var reg4 uintC count;
  373.     var reg5 uintD carry;
  374.     { if (carry==0)
  375.         { if (!(count==0))
  376.             do { var reg1 uintD source1 = *--sourceptr1;
  377.                  var reg1 uintD source2 = *--sourceptr2;
  378.                  *--destptr = source1 - source2;
  379.                  if (source1 < source2) goto carry_1;
  380.                  carry_0:
  381.                  count--;
  382.                }
  383.                until (count==0);
  384.           return 0;
  385.         }
  386.         else
  387.         { if (!(count==0))
  388.             do { var reg1 uintD source1 = *--sourceptr1;
  389.                  var reg1 uintD source2 = *--sourceptr2;
  390.                  *--destptr = source1 - source2 - 1;
  391.                  if (source1 > source2) goto carry_0;
  392.                  carry_1:
  393.                  count--;
  394.                }
  395.                until (count==0);
  396.           return -1;
  397.     }   }
  398.  
  399. # Subtraktionsschleife:
  400. # übertrag = subfrom_loop_down(sourceptr,destptr,count);
  401. # subtrahiert count (uintC>=0) Digits abwärts von sourceptr, von destptr
  402. # abwärts nach destptr (dest := dest - source)
  403. # und liefert den Übertrag (0 oder /=0, was -1 bedeutet).
  404.   local uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  405.   inline local uintD subfrom_loop_down(sourceptr,destptr,count)
  406.     var reg3 uintD* sourceptr;
  407.     var reg2 uintD* destptr;
  408.     var reg4 uintC count;
  409.     { if (!(count==0))
  410.       do { var reg1 uintD source1 = *--destptr;
  411.            var reg1 uintD source2 = *--sourceptr;
  412.            *destptr = source1 - source2;
  413.            if (source1 < source2) goto carry_1;
  414.            carry_0:
  415.            count--;
  416.          }
  417.          until (count==0);
  418.       return 0;
  419.       do { var reg1 uintD source1 = *--destptr;
  420.            var reg1 uintD source2 = *--sourceptr;
  421.            *destptr = source1 - source2 - 1;
  422.            if (source1 > source2) goto carry_0;
  423.            carry_1:
  424.            count--;
  425.          }
  426.          until (count==0);
  427.       return -1;
  428.     }
  429.  
  430. # Decrementierschleife:
  431. # übertrag = dec_loop_down(ptr,count);
  432. # decrementiert count (uintC>=0) Digits abwärts von ptr, so lange bis kein
  433. # Übertrag mehr auftritt und liefert den Übertrag (0 oder -1).
  434.   local uintD dec_loop_down (uintD* ptr, uintC count);
  435.   inline local uintD dec_loop_down(ptr,count)
  436.     var reg1 uintD* ptr;
  437.     var reg2 uintC count;
  438.     { dotimesC(count,count,
  439.         { if (!( (*--ptr)-- == 0 )) return 0; } # kein weiterer Übertrag
  440.         );
  441.       return -1; # weiterer Übertrag
  442.     }
  443.  
  444. # Negierschleife:
  445. # übertrag = neg_loop_down(ptr,count);
  446. # negiert count (uintC>=0) Digits abwärts von ptr,
  447. # und liefert den Übertrag (0 oder -1).
  448.   local uintD neg_loop_down (uintD* ptr, uintC count);
  449.   inline local uintD neg_loop_down(ptr,count)
  450.     var reg1 uintD* ptr;
  451.     var reg2 uintC count;
  452.     { # erstes Digit /=0 suchen:
  453.       until (count==0) { if (!(*--ptr == 0)) goto L1; count--; }
  454.       return 0;
  455.       L1: # erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
  456.       *ptr = - *ptr; count--; # 1 Digit negieren
  457.       dotimesC(count,count, { --ptr; *ptr = ~ *ptr; } ); # alle anderen Digits invertieren
  458.       return -1;
  459.     }
  460.  
  461. #endif
  462.  
  463. #ifndef SHIFT_LOOPS
  464.  
  465. # Schiebeschleife um 1 Bit nach links:
  466. # übertrag = shift1left_loop_down(ptr,count);
  467. # schiebt count (uintC>=0) Digits abwärts von ptr um 1 Bit nach links,
  468. # und liefert den Übertrag (0 oder /=0, was 1 bedeutet).
  469.   local uintD shift1left_loop_down (uintD* ptr, uintC count);
  470.   #if HAVE_DD
  471.   inline local uintD shift1left_loop_down(ptr,count)
  472.     var reg2 uintD* ptr;
  473.     var reg3 uintC count;
  474.     { var reg1 uintDD accu = 0;
  475.       dotimesC(count,count,
  476.         { accu = ((uintDD)(*--ptr)<<1)+accu; *ptr = lowD(accu);
  477.           accu = (uintDD)(highD(accu));
  478.         });
  479.       return (uintD)accu;
  480.     }
  481.   #else
  482.   inline local uintD shift1left_loop_down(ptr,count)
  483.     var reg2 uintD* ptr;
  484.     var reg4 uintC count;
  485.     { var reg3 uintD carry = 0;
  486.       dotimesC(count,count,
  487.         { var reg1 uintD accu = *--ptr;
  488.           *ptr = (accu<<1) | carry;
  489.           carry = accu>>(intDsize-1);
  490.         });
  491.       return carry;
  492.     }
  493.   #endif
  494.  
  495. # Schiebeschleife um i Bits nach links:
  496. # übertrag = shiftleft_loop_down(ptr,count,i,übertrag_init);
  497. # schiebt count (uintC>=0) Digits abwärts von ptr um i Bits (0<i<intDsize)
  498. # nach links, schiebt dabei die i Bits aus übertrag_init rechts rein,
  499. # und liefert den Übertrag (was links rauskommt, >=0, <2^i).
  500.   local uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
  501.   #if HAVE_DD
  502.   inline local uintD shiftleft_loop_down(ptr,count,i,carry)
  503.     var reg2 uintD* ptr;
  504.     var reg3 uintC count;
  505.     var reg4 uintC i;
  506.     var reg5 uintD carry;
  507.     { var reg1 uintDD accu = (uintDD)carry;
  508.       dotimesC(count,count,
  509.         { accu = ((uintDD)(*--ptr)<<i)+accu; *ptr = lowD(accu);
  510.           accu = (uintDD)(highD(accu));
  511.         });
  512.       return (uintD)accu;
  513.     }
  514.   #else
  515.   inline local uintD shiftleft_loop_down(ptr,count,i,carry)
  516.     var reg2 uintD* ptr;
  517.     var reg4 uintC count;
  518.     var reg5 uintC i;
  519.     var reg3 uintD carry;
  520.     { var reg6 uintC j = intDsize-i;
  521.       dotimesC(count,count,
  522.         { var reg1 uintD accu = *--ptr;
  523.           *ptr = (accu<<i) | carry;
  524.           carry = accu>>j;
  525.         });
  526.       return carry;
  527.     }
  528.   #endif
  529.  
  530. # Schiebe- und Kopierschleife um i Bits nach links:
  531. # übertrag = shiftleftcopy_loop_down(sourceptr,destptr,count,i);
  532. # kopiert count (uintC>=0) Digits abwärts von sourceptr nach destptr
  533. # und schiebt sie dabei um i Bits (0<i<intDsize) nach links,
  534. # wobei ganz rechts mit i Nullbits aufgefüllt wird,
  535. # und liefert den Übertrag (was links rauskommt, >=0, <2^i).
  536.   local uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
  537.   #if HAVE_DD
  538.   inline local uintD shiftleftcopy_loop_down(sourceptr,destptr,count,i)
  539.     var reg3 uintD* sourceptr;
  540.     var reg2 uintD* destptr;
  541.     var reg4 uintC count;
  542.     var reg5 uintC i;
  543.     { var reg1 uintDD accu = 0;
  544.       dotimesC(count,count,
  545.         { accu = ((uintDD)(*--sourceptr)<<i)+accu; *--destptr = lowD(accu);
  546.           accu = (uintDD)(highD(accu));
  547.         });
  548.       return (uintD)accu;
  549.     }
  550.   #else
  551.   inline local uintD shiftleftcopy_loop_down(sourceptr,destptr,count,i)
  552.     var reg3 uintD* sourceptr;
  553.     var reg2 uintD* destptr;
  554.     var reg5 uintC count;
  555.     var reg6 uintC i;
  556.     { var reg7 uintC j = intDsize-i;
  557.       var reg4 uintD carry = 0;
  558.       dotimesC(count,count,
  559.         { var reg1 uintD accu = *--sourceptr;
  560.           *--destptr = (accu<<i) | carry;
  561.           carry = accu>>j;
  562.         });
  563.       return carry;
  564.     }
  565.   #endif
  566.  
  567. # Schiebeschleife um 1 Bit nach rechts:
  568. # übertrag = shift1right_loop_up(ptr,count,übertrag_init);
  569. # schiebt count (uintC>=0) Digits aufwärts von ptr um 1 Bit nach rechts,
  570. # wobei links das Bit übertrag_init (sollte =0 oder =-1 sein) hineingeschoben
  571. # wird, und liefert den Übertrag (0 oder /=0, was 1 bedeutet).
  572.   local uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
  573.   #if HAVE_DD
  574.   inline local uintD shift1right_loop_up(ptr,count,carry)
  575.     var reg2 uintD* ptr;
  576.     var reg3 uintC count;
  577.     var reg4 uintD carry;
  578.     { var reg1 uintDD accu = (sintDD)(sintD)carry & ((uintDD)1 << (2*intDsize-1)); # 0 oder bit(2*intDsize-1)
  579.       dotimesC(count,count,
  580.         { accu = (highlowDD_0(*ptr)>>1)+accu; *ptr++ = highD(accu);
  581.           accu = highlowDD_0(lowD(accu));
  582.         });
  583.       return highD(accu);
  584.     }
  585.   #else
  586.   inline local uintD shift1right_loop_up(ptr,count,carry)
  587.     var reg2 uintD* ptr;
  588.     var reg3 uintC count;
  589.     var reg4 uintD carry;
  590.     { carry = carry << (intDsize-1); # carry zu einem einzigen Bit machen
  591.       dotimesC(count,count,
  592.         { var reg1 uintD accu = *ptr;
  593.           *ptr++ = (accu >> 1) | carry;
  594.           carry = accu << (intDsize-1);
  595.         });
  596.       return carry;
  597.     }
  598.   #endif
  599.  
  600. # Schiebeschleife um i Bits nach rechts:
  601. # übertrag = shiftright_loop_up(ptr,count,i);
  602. # schiebt count (uintC>=0) Digits aufwärts von ptr um i Bits (0<i<intDsize)
  603. # nach rechts, wobei links Nullen eingeschoben werden,
  604. # und liefert den Übertrag (was rechts rauskommt, als Bits intDsize-1..intDsize-i).
  605.   local uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
  606.   #if HAVE_DD
  607.   inline local uintD shiftright_loop_up(ptr,count,i)
  608.     var reg2 uintD* ptr;
  609.     var reg3 uintC count;
  610.     var reg4 uintC i;
  611.     { var reg1 uintDD accu = 0;
  612.       dotimesC(count,count,
  613.         { # Die oberen i Bits von (uintD)accu bilden hier den Übertrag.
  614.           accu = highlowDD_0(lowD(accu));
  615.           # Die oberen i Bits von (uintDD)accu bilden hier den Übertrag.
  616.           accu = (highlowDD_0(*ptr)>>i)+accu; *ptr++ = highD(accu);
  617.         });
  618.       return lowD(accu);
  619.     }
  620.   #else
  621.   inline local uintD shiftright_loop_up(ptr,count,i)
  622.     var reg2 uintD* ptr;
  623.     var reg3 uintC count;
  624.     var reg5 uintC i;
  625.     { var reg6 uintC j = intDsize-i;
  626.       var reg4 uintD carry = 0;
  627.       dotimesC(count,count,
  628.         { var reg1 uintD accu = *ptr;
  629.           *ptr++ = (accu >> i) | carry;
  630.           carry = accu << j;
  631.         });
  632.       return carry;
  633.     }
  634.   #endif
  635.  
  636. # Schiebeschleife um i Bits nach rechts:
  637. # übertrag = shiftrightsigned_loop_up(ptr,count,i);
  638. # schiebt count (uintC>0) Digits aufwärts von ptr um i Bits (0<i<intDsize)
  639. # nach rechts, wobei links das MSBit ver-i-facht wird,
  640. # und liefert den Übertrag (was rechts rauskommt, als Bits intDsize-1..intDsize-i).
  641.   local uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
  642.   #if HAVE_DD
  643.   inline local uintD shiftrightsigned_loop_up(ptr,count,i)
  644.     var reg2 uintD* ptr;
  645.     var reg3 uintC count;
  646.     var reg4 uintC i;
  647.     { var reg1 uintDD accu = # Übertrag mit i Vorzeichenbits initialisieren
  648.                            highlowDD_0(sign_of_sintD((sintD)(*ptr)))>>i;
  649.       dotimespC(count,count,
  650.         { # Die oberen i Bits von (uintD)accu bilden hier den Übertrag.
  651.           accu = highlowDD_0(lowD(accu));
  652.           # Die oberen i Bits von (uintDD)accu bilden hier den Übertrag.
  653.           accu = (highlowDD_0(*ptr)>>i)+accu; *ptr++ = highD(accu);
  654.         });
  655.       return lowD(accu);
  656.     }
  657.   #else
  658.   inline local uintD shiftrightsigned_loop_up(ptr,count,i)
  659.     var reg2 uintD* ptr;
  660.     var reg3 uintC count;
  661.     var reg5 uintC i;
  662.     { var reg6 uintC j = intDsize-i;
  663.       var reg4 uintD carry;
  664.       { var reg1 uintD accu = *ptr;
  665.         *ptr++ = (sintD)accu >> i;
  666.         carry = accu << j;
  667.         count--;
  668.       }
  669.       dotimesC(count,count,
  670.         { var reg1 uintD accu = *ptr;
  671.           *ptr++ = (accu >> i) | carry;
  672.           carry = accu << j;
  673.         });
  674.       return carry;
  675.     }
  676.   #endif
  677.  
  678. # Schiebe- und Kopier-Schleife um i Bits nach rechts:
  679. # übertrag = shiftrightcopy_loop_up(sourceptr,destptr,count,i,carry);
  680. # kopiert count (uintC>=0) Digits aufwärts von sourceptr nach destptr
  681. # und schiebt sie dabei um i Bits (0<i<intDsize) nach rechts, wobei carry
  682. # (sozusagen als sourceptr[-1]) die i Bits ganz links bestimmt,
  683. # und liefert den Übertrag (was rechts rauskommt, als Bits intDsize-1..intDsize-i).
  684.   local uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
  685.   #if HAVE_DD
  686.   inline local uintD shiftrightcopy_loop_up(sourceptr,destptr,count,i,carry)
  687.     var reg2 uintD* sourceptr;
  688.     var reg2 uintD* destptr;
  689.     var reg3 uintC count;
  690.     var reg4 uintC i;
  691.     var reg5 uintD carry;
  692.     { var reg1 uintDD accu = # Übertrag mit carry initialisieren
  693.                            highlowDD_0(carry)>>i;
  694.       dotimesC(count,count,
  695.         { # Die oberen i Bits von (uintD)accu bilden hier den Übertrag.
  696.           accu = highlowDD_0(lowD(accu));
  697.           # Die oberen i Bits von (uintDD)accu bilden hier den Übertrag.
  698.           accu = (highlowDD_0(*sourceptr++)>>i)+accu; *destptr++ = highD(accu);
  699.         });
  700.       return lowD(accu);
  701.     }
  702.   #else
  703.   inline local uintD shiftrightcopy_loop_up(sourceptr,destptr,count,i,carry)
  704.     var reg2 uintD* sourceptr;
  705.     var reg2 uintD* destptr;
  706.     var reg3 uintC count;
  707.     var reg5 uintC i;
  708.     var reg4 uintD carry;
  709.     { var reg6 uintC j = intDsize-i;
  710.       carry = carry << j;
  711.       dotimesC(count,count,
  712.         { var reg1 uintD accu = *sourceptr++;
  713.           *destptr++ = (accu >> i) | carry;
  714.           carry = accu << j;
  715.         });
  716.       return carry;
  717.     }
  718.   #endif
  719.  
  720. #endif
  721.  
  722. #ifndef MUL_LOOPS
  723.  
  724. # Multiplikations-Einfachschleife:
  725. # Multipliziert eine UDS mit einem kleinen Digit und addiert ein kleines Digit.
  726. # mulusmall_loop_down(digit,ptr,len,newdigit)
  727. # multipliziert die UDS  ptr[-len..-1]  mit digit (>=2, <=36),
  728. # addiert dabei newdigit (>=0, <digit) zur letzten Ziffer,
  729. # und liefert den Carry (>=0, <digit).
  730.   local uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
  731.   #if HAVE_DD
  732.   inline local uintD mulusmall_loop_down(digit,ptr,len,newdigit)
  733.     var reg4 uintD digit;
  734.     var reg2 uintD* ptr;
  735.     var reg3 uintC len;
  736.     var reg5 uintD newdigit;
  737.     { var reg1 uintDD carry = newdigit;
  738.       dotimesC(len,len,
  739.         { # Hier ist 0 <= carry < digit.
  740.           carry = carry + muluD(digit,*--ptr);
  741.           # Hier ist 0 <= carry < 2^intDsize*digit.
  742.           *ptr = lowD(carry);
  743.           carry = (uintDD)highD(carry); # carry := floor(carry/2^intDsize) < digit
  744.         });
  745.       return lowD(carry);
  746.     }
  747.   #else
  748.   inline local uintD mulusmall_loop_down(digit,ptr,len,newdigit)
  749.     var reg6 uintD digit;
  750.     var reg1 uintD* ptr;
  751.     var reg5 uintC len;
  752.     var reg7 uintD newdigit;
  753.     { var reg4 uintD carry = newdigit;
  754.       dotimesC(len,len,
  755.         { # Hier ist 0 <= carry < digit.
  756.           var reg3 uintD hi;
  757.           var reg2 uintD lo;
  758.           muluD(digit,*--ptr,hi=,lo=);
  759.           # Hier ist 0 <= 2^intDsize*hi + lo + carry < 2^intDsize*digit.
  760.           lo += carry; if (lo < carry) { hi += 1; }
  761.           *ptr = lo;
  762.           carry = hi;
  763.         });
  764.       return carry;
  765.     }
  766.   #endif
  767.  
  768. # Multiplikations-Einfachschleife:
  769. # Multipliziert eine UDS mit einem Digit und legt das Ergebnis in einer
  770. # zweiten UDS ab.
  771. # mulu_loop_down(digit,sourceptr,destptr,len);
  772. # multipliziert die UDS  sourceptr[-len..-1]  (len>0)
  773. # mit dem einzelnen  digit
  774. # und legt das Ergebnis in der UDS  destptr[-len-1..-1]  ab.
  775.   local void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  776.   #if HAVE_DD
  777.   inline local void mulu_loop_down(digit,sourceptr,destptr,len)
  778.     var reg4 uintD digit;
  779.     var reg2 uintD* sourceptr;
  780.     var reg2 uintD* destptr;
  781.     var reg3 uintC len;
  782.     { var reg1 uintDD carry = 0;
  783.       dotimespC(len,len,
  784.         { # Hier ist carry=digit=0 oder 0 <= carry < digit.
  785.           carry = carry + muluD(digit,*--sourceptr);
  786.           # Hier ist carry=digit=0 oder 0 <= carry < 2^intDsize*digit.
  787.           *--destptr = lowD(carry);
  788.           carry = (uintDD)highD(carry); # carry := floor(carry/2^intDsize) < digit
  789.         });
  790.       *--destptr = lowD(carry);
  791.     }
  792.   #else
  793.   inline local void mulu_loop_down(digit,sourceptr,destptr,len)
  794.     var reg6 uintD digit;
  795.     var reg1 uintD* sourceptr;
  796.     var reg1 uintD* destptr;
  797.     var reg5 uintC len;
  798.     { var reg4 uintD carry = 0;
  799.       dotimespC(len,len,
  800.         { # Hier ist carry=digit=0 oder 0 <= carry < digit.
  801.           var reg3 uintD hi;
  802.           var reg2 uintD lo;
  803.           muluD(digit,*--sourceptr,hi=,lo=);
  804.           # Hier ist 0 <= 2^intDsize*hi + lo + carry < 2^intDsize*digit oder hi=lo=carry=digit=0.
  805.           lo += carry; if (lo < carry) { hi += 1; }
  806.           *--destptr = lo;
  807.           carry = hi;
  808.         });
  809.       *--destptr = carry;
  810.     }
  811.   #endif
  812.  
  813. # Multiplikations-Einfachschleife mit Akkumulation:
  814. # Multipliziert eine UDS mit einem Digit und addiert das Ergebnis zu einer
  815. # zweiten UDS auf.
  816. # muluadd_loop_down(digit,sourceptr,destptr,len);
  817. # multipliziert die UDS  sourceptr[-len..-1]  (len>0)
  818. # mit dem einzelnen digit, legt das Ergebnis in der UDS  destptr[-len..-1]
  819. # ab und liefert den weiteren Übertrag.
  820.   local uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  821.   #if HAVE_DD
  822.   inline local uintD muluadd_loop_down(digit,sourceptr,destptr,len)
  823.     var reg4 uintD digit;
  824.     var reg2 uintD* sourceptr;
  825.     var reg2 uintD* destptr;
  826.     var reg3 uintC len;
  827.     { var reg1 uintDD carry = 0;
  828.       if (!(digit==0))
  829.         { dotimespC(len,len,
  830.             { # Hier ist 0 <= carry <= digit.
  831.               carry = carry + muluD(digit,*--sourceptr) + (uintDD)*--destptr;
  832.               # Hier ist 0 <= carry <= 2^intDsize*digit + 2^intDsize-1.
  833.               *destptr = lowD(carry);
  834.               carry = (uintDD)highD(carry); # carry := floor(carry/2^intDsize) <= digit
  835.             });
  836.         }
  837.       return lowD(carry);
  838.     }
  839.   #else
  840.   inline local uintD muluadd_loop_down(digit,sourceptr,destptr,len)
  841.     var reg6 uintD digit;
  842.     var reg1 uintD* sourceptr;
  843.     var reg1 uintD* destptr;
  844.     var reg5 uintC len;
  845.     { var reg4 uintD carry = 0;
  846.       if (!(digit==0))
  847.         { dotimespC(len,len,
  848.             { # Hier ist 0 <= carry <= digit.
  849.               var reg3 uintD hi;
  850.               var reg2 uintD lo;
  851.               muluD(digit,*--sourceptr,hi=,lo=);
  852.               # Hier ist 0 <= 2^intDsize*hi + lo + carry + *--destptr <= 2^intDsize*digit+2^intDsize-1.
  853.               lo += carry; if (lo < carry) { hi += 1; }
  854.               carry = *--destptr;
  855.               lo += carry; if (lo < carry) { hi += 1; }
  856.               *destptr = lo;
  857.               carry = hi;
  858.             });
  859.         }
  860.       return carry;
  861.     }
  862.   #endif
  863.  
  864. # Multiplikations-Einfachschleife mit Diminution:
  865. # Multipliziert eine UDS mit einem Digit und subtrahiert das Ergebnis von
  866. # einer zweiten UDS.
  867. # mulusub_loop_down(digit,sourceptr,destptr,len);
  868. # multipliziert die UDS  sourceptr[-len..-1]  (len>0)  mit dem einzelnen
  869. # digit, subtrahiert das Ergebnis von der UDS  destptr[-len..-1]  und liefert
  870. # den weiteren Übertrag (>=0, evtl. von destptr[-len-1] zu subtrahieren).
  871.   local uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  872.   #if HAVE_DD
  873.   inline local uintD mulusub_loop_down(digit,sourceptr,destptr,len)
  874.     var reg4 uintD digit;
  875.     var reg2 uintD* sourceptr;
  876.     var reg2 uintD* destptr;
  877.     var reg3 uintC len;
  878.     { var reg1 uintDD carry = 0;
  879.       if (!(digit==0))
  880.         { dotimespC(len,len,
  881.             { # Hier ist 0 <= carry <= digit.
  882.               carry = carry + muluD(digit,*--sourceptr) + (uintD)(~(*--destptr));
  883.               # Hier ist 0 <= carry <= 2^intDsize*digit + 2^intDsize-1.
  884.               *destptr = ~lowD(carry);
  885.               carry = (uintDD)highD(carry); # carry := floor(carry/2^intDsize) <= digit
  886.               # Hier ist 0 <= carry <= digit.
  887.             });
  888.           return lowD(carry);
  889.         }
  890.         else
  891.         return 0; # nichts zu subtrahieren -> kein Übertrag
  892.     }
  893.   #else
  894.   inline local uintD mulusub_loop_down(digit,sourceptr,destptr,len)
  895.     var reg6 uintD digit;
  896.     var reg1 uintD* sourceptr;
  897.     var reg1 uintD* destptr;
  898.     var reg5 uintC len;
  899.     { var reg4 uintD carry = 0;
  900.       if (!(digit==0))
  901.         { dotimespC(len,len,
  902.             { # Hier ist 0 <= carry <= digit.
  903.               var reg3 uintD hi;
  904.               var reg2 uintD lo;
  905.               muluD(digit,*--sourceptr,hi=,lo=);
  906.               # Hier ist 0 <= 2^intDsize*hi + lo + carry + ~(*--destptr) <= 2^intDsize*digit+2^intDsize-1.
  907.               lo += carry; if (lo < carry) { hi += 1; }
  908.               carry = *--destptr;
  909.               *destptr = carry - lo; if (carry < lo) { hi += 1; }
  910.               carry = hi;
  911.             });
  912.           return carry;
  913.         }
  914.         else
  915.         return 0; # nichts zu subtrahieren -> kein Übertrag
  916.     }
  917.   #endif
  918.  
  919. #endif
  920.  
  921. #ifndef DIV_LOOPS
  922.  
  923. # Divisions-Einfachschleife:
  924. # Dividiert eine UDS durch ein Digit.
  925. # divu_loop_up(digit,ptr,len)
  926. # dividiert die UDS  ptr[0..len-1] durch digit,
  927. # legt das Ergebnis in derselben UDS ab, und liefert den Rest (>=0, <digit).
  928.   local uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
  929.   #if HAVE_DD
  930.   inline local uintD divu_loop_up(digit,ptr,len)
  931.     var reg4 uintD digit;
  932.     var reg1 uintD* ptr;
  933.     var reg3 uintC len;
  934.     { var reg2 uintD rest = 0;
  935.       dotimesC(len,len,
  936.         { divuD(highlowDD(rest,*ptr),digit,*ptr =, rest =); ptr++; }
  937.         );
  938.       return rest;
  939.     }
  940.   #else
  941.   inline local uintD divu_loop_up(digit,ptr,len)
  942.     var reg4 uintD digit;
  943.     var reg1 uintD* ptr;
  944.     var reg3 uintC len;
  945.     { var reg2 uintD rest = 0;
  946.       dotimesC(len,len,
  947.         { divuD(rest,*ptr,digit,*ptr =, rest =); ptr++; }
  948.         );
  949.       return rest;
  950.     }
  951.   #endif
  952.  
  953. # Divisions-Einfachschleife:
  954. # Dividiert eine UDS durch ein Digit und legt das Ergebnis in einer
  955. # zweiten UDS ab.
  956. # divucopy_loop_up(digit,sourceptr,destptr,len)
  957. # dividiert die UDS  sourceptr[0..len-1]  durch digit,
  958. # legt das Ergebnis in der UDS  destptr[0..len-1]  ab,
  959. # und liefert den Rest (>=0, <digit).
  960.   local uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  961.   #if HAVE_DD
  962.   inline local uintD divucopy_loop_up(digit,sourceptr,destptr,len)
  963.     var reg5 uintD digit;
  964.     var reg3 uintD* sourceptr;
  965.     var reg2 uintD* destptr;
  966.     var reg4 uintC len;
  967.     { var reg1 uintD rest = 0;
  968.       dotimesC(len,len,
  969.         { divuD(highlowDD(rest,*sourceptr++),digit,*destptr++ =, rest =); }
  970.         );
  971.       return rest;
  972.     }
  973.   #else
  974.   inline local uintD divucopy_loop_up(digit,sourceptr,destptr,len)
  975.     var reg5 uintD digit;
  976.     var reg3 uintD* sourceptr;
  977.     var reg2 uintD* destptr;
  978.     var reg4 uintC len;
  979.     { var reg1 uintD rest = 0;
  980.       dotimesC(len,len,
  981.         { divuD(rest,*sourceptr++,digit,*destptr++ =, rest =); }
  982.         );
  983.       return rest;
  984.     }
  985.   #endif
  986.  
  987. #endif
  988.  
  989.