home *** CD-ROM | disk | FTP | other *** search
/ Il CD di internet / CD.iso / SOURCE / D / CLISP / CLISPSRC.TAR / clisp-1995-01-01 / src / arisparc.d < prev    next >
Encoding:
Text File  |  1993-04-04  |  77.7 KB  |  2,262 lines

  1. # Externe Routinen zu ARILEV1.D
  2. # Prozessor: SPARC
  3. # Compiler: GNU-C oder SUN-C
  4. # Parameter-▄bergabe: in Registern %o0-%o5.
  5. # Einstellungen: intCsize=32, intDsize=32.
  6.  
  7. #ifdef INCLUDED_FROM_C
  8.  
  9.   #define COPY_LOOPS
  10.   #define FILL_LOOPS
  11.   #define CLEAR_LOOPS
  12.   #define LOG_LOOPS
  13.   #define TEST_LOOPS
  14.   #define ADDSUB_LOOPS
  15.   #define SHIFT_LOOPS
  16.   #define MUL_LOOPS
  17.   #define DIV_LOOPS
  18.  
  19. #else
  20.  
  21. #if defined(sparc_v8) || defined(__sparc_v8) || defined(__sparc_v8__)
  22.   #define sparcv8
  23. #endif
  24.  
  25. #ifdef UNDERSCORE /* SunOS 4 */
  26.   #ifdef __STDC__
  27.     #define C(entrypoint) _##entrypoint
  28.   #else
  29.     #define C(entrypoint) _/**/entrypoint
  30.   #endif
  31. #else /* SunOS 5 = Solaris 2 */
  32.   #define C(entrypoint) entrypoint
  33. #endif
  34.  
  35.   # Indikatoren fⁿr Anweisungen (Instruktionen) in Delay-Slots
  36.   # (diese werden VOR der vorigen Instruktion ausgefⁿhrt):
  37.   #define _             # Instruktion, die stets ausgefⁿhrt wird
  38.   #define __            # Instruktion, die nur im Sprung-Fall ausgefⁿhrt wird
  39.   # Abkⁿrzungen fⁿr Anweisungen:
  40.   #define ret   jmp %i7+8    # return from subroutine
  41.   #define retl  jmp %o7+8    # return from leaf subroutine (no save/restore)
  42.  
  43.         .seg "text"
  44.  
  45.         .global C(mulu16_),C(mulu32_),C(mulu32_unchecked)
  46.         .global C(divu_6432_3232_),C(divu_3216_1616_)
  47.         .global C(copy_loop_up),C(copy_loop_down),C(fill_loop_up),C(fill_loop_down)
  48.         .global C(clear_loop_up),C(clear_loop_down)
  49.         .global C(or_loop_up),C(xor_loop_up),C(and_loop_up),C(eqv_loop_up)
  50.         .global C(nand_loop_up),C(nor_loop_up),C(andc2_loop_up),C(orc2_loop_up)
  51.         .global C(not_loop_up)
  52.         .global C(and_test_loop_up),C(test_loop_up),C(compare_loop_up)
  53.         .global C(add_loop_down),C(addto_loop_down),C(inc_loop_down)
  54.         .global C(sub_loop_down),C(subx_loop_down),C(subfrom_loop_down),C(dec_loop_down)
  55.         .global C(neg_loop_down)
  56.         .global C(shift1left_loop_down),C(shiftleft_loop_down),C(shiftleftcopy_loop_down)
  57.         .global C(shift1right_loop_up),C(shiftright_loop_up),C(shiftrightsigned_loop_up),C(shiftrightcopy_loop_up)
  58.         .global C(mulusmall_loop_down),C(mulu_loop_down),C(muluadd_loop_down),C(mulusub_loop_down)
  59.         .global C(divu_loop_up),C(divucopy_loop_up)
  60.  
  61. #define LOOP_TYPE  1    # 1: Standard-Schleifen
  62.                         # 2: Schleifen ohne Pointer, nur mit ZΣhler
  63.                         # 3: entrollte Schleifen
  64. #define STANDARD_LOOPS  (LOOP_TYPE==1)
  65. #define COUNTER_LOOPS  (LOOP_TYPE==2)
  66. #define UNROLLED_LOOPS  (LOOP_TYPE==3)
  67. #define MULU32_INLINE  1  # 1: mulu32-Aufrufe inline in die Schleifen
  68.  
  69. # extern uint32 mulu16_ (uint16 arg1, uint16 arg2);
  70. # ergebnis := arg1*arg2.
  71. C(mulu16_:) # Input in %o0,%o1, Output in %o0
  72. #ifdef sparcv8
  73.         umul    %o0,%o1,%o0
  74.         retl
  75.        _ nop
  76. #else
  77.         mov     %o1,%y
  78.         nop                     # Wartetakt, n÷tig z.B. fⁿr SUN SPARCstation IPC
  79.         andcc   %g0,%g0,%o2
  80.         mulscc  %o2,%o0,%o2
  81.         mulscc  %o2,%o0,%o2
  82.         mulscc  %o2,%o0,%o2
  83.         mulscc  %o2,%o0,%o2
  84.         mulscc  %o2,%o0,%o2
  85.         mulscc  %o2,%o0,%o2
  86.         mulscc  %o2,%o0,%o2
  87.         mulscc  %o2,%o0,%o2
  88.         mulscc  %o2,%o0,%o2
  89.         mulscc  %o2,%o0,%o2
  90.         mulscc  %o2,%o0,%o2
  91.         mulscc  %o2,%o0,%o2
  92.         mulscc  %o2,%o0,%o2
  93.         mulscc  %o2,%o0,%o2
  94.         mulscc  %o2,%o0,%o2
  95.         mulscc  %o2,%o0,%o2
  96.         # Die 17 unteren Bits von %o2 und die 15 oberen Bits von %y
  97.         # ergeben das Resultat. (Die anderen Bits sind Null.)
  98.         rd      %y,%o0
  99.         srl     %o0,17,%o0
  100.         sll     %o2,15,%o2
  101.         retl
  102.        _ or      %o2,%o0,%o0
  103. #endif
  104.  
  105. # extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
  106. # 2^32*hi+lo := arg1*arg2.
  107. C(mulu32_:) # Input in %o0,%o1, Output in %o0,%g1
  108. #ifdef sparcv8
  109.         umul    %o0,%o1,%o0
  110.         retl
  111.        _ rd      %y,%g1
  112. #else
  113.         mov     %o1,%y
  114.         sra     %o0,31,%o3      # Wartetakt, n÷tig z.B. fⁿr SUN SPARCstation IPC
  115.         andcc   %g0,%g0,%o2
  116.         mulscc  %o2,%o0,%o2
  117.         mulscc  %o2,%o0,%o2
  118.         mulscc  %o2,%o0,%o2
  119.         mulscc  %o2,%o0,%o2
  120.         mulscc  %o2,%o0,%o2
  121.         mulscc  %o2,%o0,%o2
  122.         mulscc  %o2,%o0,%o2
  123.         mulscc  %o2,%o0,%o2
  124.         mulscc  %o2,%o0,%o2
  125.         mulscc  %o2,%o0,%o2
  126.         mulscc  %o2,%o0,%o2
  127.         mulscc  %o2,%o0,%o2
  128.         mulscc  %o2,%o0,%o2
  129.         mulscc  %o2,%o0,%o2
  130.         mulscc  %o2,%o0,%o2
  131.         mulscc  %o2,%o0,%o2
  132.         mulscc  %o2,%o0,%o2
  133.         mulscc  %o2,%o0,%o2
  134.         mulscc  %o2,%o0,%o2
  135.         mulscc  %o2,%o0,%o2
  136.         mulscc  %o2,%o0,%o2
  137.         mulscc  %o2,%o0,%o2
  138.         mulscc  %o2,%o0,%o2
  139.         mulscc  %o2,%o0,%o2
  140.         mulscc  %o2,%o0,%o2
  141.         mulscc  %o2,%o0,%o2
  142.         mulscc  %o2,%o0,%o2
  143.         mulscc  %o2,%o0,%o2
  144.         mulscc  %o2,%o0,%o2
  145.         mulscc  %o2,%o0,%o2
  146.         mulscc  %o2,%o0,%o2
  147.         mulscc  %o2,%o0,%o2
  148.         mulscc  %o2,%g0,%o2
  149.         and     %o3,%o1,%o3     # %o3 = (0 falls %o0>=0, %o1 falls %o0<0)
  150.         add     %o2,%o3,%g1     # hi
  151.         retl
  152.        _ rd      %y,%o0         # lo
  153. #endif
  154.  
  155. # extern uint32 mulu32_unchecked (uint32 x, uint32 y);
  156. # ergebnis := arg1*arg2 < 2^32.
  157. C(mulu32_unchecked:) # Input in %o0,%o1, Output in %o0
  158. #ifdef sparcv8
  159.         umul    %o0,%o1,%o0
  160.         retl
  161.        _ nop
  162. #else
  163.         subcc   %o0,%o1,%g0
  164.         bcc,a   1f
  165.        __ mov     %o1,%y
  166.         # arg1 < arg2, also kann man arg1 < 2^16 annehmen.
  167.         mov     %o0,%y
  168.         nop                     # Wartetakt, n÷tig z.B. fⁿr SUN SPARCstation IPC
  169.         andcc   %g0,%g0,%o2
  170.         mulscc  %o2,%o1,%o2
  171.         mulscc  %o2,%o1,%o2
  172.         mulscc  %o2,%o1,%o2
  173.         mulscc  %o2,%o1,%o2
  174.         mulscc  %o2,%o1,%o2
  175.         mulscc  %o2,%o1,%o2
  176.         mulscc  %o2,%o1,%o2
  177.         mulscc  %o2,%o1,%o2
  178.         mulscc  %o2,%o1,%o2
  179.         mulscc  %o2,%o1,%o2
  180.         mulscc  %o2,%o1,%o2
  181.         mulscc  %o2,%o1,%o2
  182.         mulscc  %o2,%o1,%o2
  183.         mulscc  %o2,%o1,%o2
  184.         mulscc  %o2,%o1,%o2
  185.         mulscc  %o2,%o1,%o2
  186.         # Die 17 unteren Bits von %o2 und die 15 oberen Bits von %y
  187.         # ergeben das Resultat. (Die anderen Bits sind Null.)
  188.         rd      %y,%o0
  189.         srl     %o0,17,%o0
  190.         sll     %o2,15,%o2
  191.         retl
  192.        _ or      %o2,%o0,%o0
  193. 1:      # arg1 >= arg2, also kann man arg2 < 2^16 annehmen.
  194.         nop                     # Wartetakt, n÷tig z.B. fⁿr SUN SPARCstation IPC
  195.         andcc   %g0,%g0,%o2
  196.         mulscc  %o2,%o0,%o2
  197.         mulscc  %o2,%o0,%o2
  198.         mulscc  %o2,%o0,%o2
  199.         mulscc  %o2,%o0,%o2
  200.         mulscc  %o2,%o0,%o2
  201.         mulscc  %o2,%o0,%o2
  202.         mulscc  %o2,%o0,%o2
  203.         mulscc  %o2,%o0,%o2
  204.         mulscc  %o2,%o0,%o2
  205.         mulscc  %o2,%o0,%o2
  206.         mulscc  %o2,%o0,%o2
  207.         mulscc  %o2,%o0,%o2
  208.         mulscc  %o2,%o0,%o2
  209.         mulscc  %o2,%o0,%o2
  210.         mulscc  %o2,%o0,%o2
  211.         mulscc  %o2,%o0,%o2
  212.         # Die 17 unteren Bits von %o2 und die 15 oberen Bits von %y
  213.         # ergeben das Resultat.
  214.         rd      %y,%o0
  215.         srl     %o0,17,%o0
  216.         sll     %o2,15,%o2
  217.         retl
  218.        _ or      %o2,%o0,%o0
  219. #endif
  220.  
  221. # extern struct { uint32 q; uint32 r; } divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y);
  222. # x = 2^32*xhi+xlo = q*y+r schreiben. Sei bekannt, da▀ 0 <= x < 2^32*y .
  223. C(divu_6432_3232_:) # Input in %o0,%o1,%o2, Output in %o0,%g1
  224. #ifdef sparcv8
  225.         wr      %o0,%g0,%y
  226.         udiv    %o1,%o2,%o0     # x durch y dividieren, %o0 := q
  227.         umul    %o0,%o2,%g1     # %g1 := (q*y) mod 2^32
  228.         retl
  229.        _ sub     %o1,%g1,%g1    # %g1 := (xlo-q*y) mod 2^32 = r
  230. #else
  231.         # %o0 = xhi, %o1 = xlo, %o2 = y
  232. # Divisions-Einzelschritte:
  233. # %o0|%o1  wird jeweils um 1 Bit nach links geschoben,
  234. # dafⁿr wird rechts in %o1 ein Ergebnisbit (negiert!) reingeschoben.
  235. # Je nachdem wird mit %o3|%o1 statt %o0|%o1 weitergemacht (spart 1 'mov').
  236. # Deswegen mu▀ man den Code doppelt vorsehen: einmal mit %o0, einmal mit %o3.
  237. #define SA0(label) # Vergleichsschritt mit %o0 \
  238.         subcc   %o0,%o2,%o3; \
  239.         bcc     label;       \
  240.        _ addxcc  %o1,%o1,%o1
  241. #define SA1(label) # Vergleichsschritt mit %o3 \
  242.         subcc   %o3,%o2,%o0; \
  243.         bcc     label;       \
  244.        _ addxcc  %o1,%o1,%o1
  245. #define SB0() # Additionsschritt mit %o0 \
  246.         addx    %o0,%o0,%o0
  247. #define SB1() # Additionsschritt mit %o3 \
  248.         addx    %o3,%o3,%o3
  249. # Los geht's:
  250.         addcc   %o2,%o2,%g0     # y = %o2 < 2^31 ?
  251.         bcc     Lsmalldiv       # ja -> "kleine" Division
  252.        _ andcc   %o2,1,%g0      # y = %o2 gerade ?
  253.         be      Levendiv        # ja -> Division durch gerade Zahl
  254.        _ srl     %o2,1,%o2
  255.         # Division durch ungerade Zahl:
  256.         # floor(x / (2*y'-1)) = floor(floor(x/2) / y') + (0 oder 1 oder 2)
  257.         # da  0 <= x/(2*y'-1) - x/(2*y') = x/(2*y'-1) / (2*y') = x/y / (2*y')
  258.         #       < 2^32 / (2*y') < 2^32/y <= 2 .
  259.         add     %o2,1,%o2       # %o2 = ceiling(y/2) = y'
  260.         # Man spart im Vergleich zu Lsmalldiv
  261.         # zu Beginn eine Verdoppelung von %o0|%o1 : addcc %o1,%o1,%o1; SB0()
  262.         # dafⁿr am Schlu▀ mehr zu tun...
  263.         SA0(Lb01)               # Bit 31 des Quotienten bestimmen
  264. La01:   SB0(); SA0(Lb02)        # Bit 30 des Quotienten bestimmen
  265. La02:   SB0(); SA0(Lb03)        # Bit 29 des Quotienten bestimmen
  266. La03:   SB0(); SA0(Lb04)        # Bit 28 des Quotienten bestimmen
  267. La04:   SB0(); SA0(Lb05)        # Bit 27 des Quotienten bestimmen
  268. La05:   SB0(); SA0(Lb06)        # Bit 26 des Quotienten bestimmen
  269. La06:   SB0(); SA0(Lb07)        # Bit 25 des Quotienten bestimmen
  270. La07:   SB0(); SA0(Lb08)        # Bit 24 des Quotienten bestimmen
  271. La08:   SB0(); SA0(Lb09)        # Bit 23 des Quotienten bestimmen
  272. La09:   SB0(); SA0(Lb10)        # Bit 22 des Quotienten bestimmen
  273. La10:   SB0(); SA0(Lb11)        # Bit 21 des Quotienten bestimmen
  274. La11:   SB0(); SA0(Lb12)        # Bit 20 des Quotienten bestimmen
  275. La12:   SB0(); SA0(Lb13)        # Bit 19 des Quotienten bestimmen
  276. La13:   SB0(); SA0(Lb14)        # Bit 18 des Quotienten bestimmen
  277. La14:   SB0(); SA0(Lb15)        # Bit 17 des Quotienten bestimmen
  278. La15:   SB0(); SA0(Lb16)        # Bit 16 des Quotienten bestimmen
  279. La16:   SB0(); SA0(Lb17)        # Bit 15 des Quotienten bestimmen
  280. La17:   SB0(); SA0(Lb18)        # Bit 14 des Quotienten bestimmen
  281. La18:   SB0(); SA0(Lb19)        # Bit 13 des Quotienten bestimmen
  282. La19:   SB0(); SA0(Lb20)        # Bit 12 des Quotienten bestimmen
  283. La20:   SB0(); SA0(Lb21)        # Bit 11 des Quotienten bestimmen
  284. La21:   SB0(); SA0(Lb22)        # Bit 10 des Quotienten bestimmen
  285. La22:   SB0(); SA0(Lb23)        # Bit 9 des Quotienten bestimmen
  286. La23:   SB0(); SA0(Lb24)        # Bit 8 des Quotienten bestimmen
  287. La24:   SB0(); SA0(Lb25)        # Bit 7 des Quotienten bestimmen
  288. La25:   SB0(); SA0(Lb26)        # Bit 6 des Quotienten bestimmen
  289. La26:   SB0(); SA0(Lb27)        # Bit 5 des Quotienten bestimmen
  290. La27:   SB0(); SA0(Lb28)        # Bit 4 des Quotienten bestimmen
  291. La28:   SB0(); SA0(Lb29)        # Bit 3 des Quotienten bestimmen
  292. La29:   SB0(); SA0(Lb30)        # Bit 2 des Quotienten bestimmen
  293. La30:   SB0(); SA0(Lb31)        # Bit 1 des Quotienten bestimmen
  294. La31:   SB0(); SA0(Lb32)        # Bit 0 des Quotienten bestimmen
  295. La32:   SB0()                   # %o0 = x mod (2*y')
  296.         xor     %o1,-1,%o1      # %o1 = floor( floor(x/2) / y') = floor(x/(2*y'))
  297.         add     %o2,%o2,%o2
  298.         sub     %o2,1,%o2       # wieder %o2 = 2*y'-1 = y
  299.         # Quotient und Rest umrechnen:
  300.         # x = %o1 * 2*y' + %o0 = %o1 * (2*y'-1) + (%o0+%o1)
  301.         # Also Quotient = %o1, Rest = %o0+%o1.
  302.         # Noch maximal 2 mal: Quotient += 1, Rest -= y.
  303.         addcc   %o1,%o0,%o0     # Rest mod y bestimmen
  304.         bcc     1f              # Additions-▄berlauf -> Quotient erh÷hen
  305.        _ subcc   %o0,%o2,%o3
  306.         subcc   %o3,%o2,%o0     # mu▀ der Quotient nochmals erh÷ht werden?
  307.         bcs     2f
  308.        _ mov     %o3,%g1
  309.         # Quotient 2 mal erh÷hen, Rest %o0
  310.         mov     %o0,%g1
  311.         retl
  312.        _ add     %o1,2,%o0
  313. 1:      # kein Additions-▄berlauf.
  314.         # Wegen y>=2^31 mu▀ der Quotient noch h÷chstens 1 mal erh÷ht werden:
  315.         bcs     3f              # %o0 < %o2 -> Rest %o0 und Quotient %o1 OK
  316.        _ mov     %o3,%g1
  317. 2:      # Quotient %o1 erh÷hen, Rest = %o0-%o2 = %o3
  318.         retl
  319.        _ add     %o1,1,%o0
  320. 3:      # Quotient %o1 und Rest %o0 OK
  321.         mov     %o0,%g1
  322.         retl
  323.        _ mov     %o1,%o0
  324. # Parallelschiene zu La01..La32:
  325. Lb01:   SB1(); SA1(La02)
  326. Lb02:   SB1(); SA1(La03)
  327. Lb03:   SB1(); SA1(La04)
  328. Lb04:   SB1(); SA1(La05)
  329. Lb05:   SB1(); SA1(La06)
  330. Lb06:   SB1(); SA1(La07)
  331. Lb07:   SB1(); SA1(La08)
  332. Lb08:   SB1(); SA1(La09)
  333. Lb09:   SB1(); SA1(La10)
  334. Lb10:   SB1(); SA1(La11)
  335. Lb11:   SB1(); SA1(La12)
  336. Lb12:   SB1(); SA1(La13)
  337. Lb13:   SB1(); SA1(La14)
  338. Lb14:   SB1(); SA1(La15)
  339. Lb15:   SB1(); SA1(La16)
  340. Lb16:   SB1(); SA1(La17)
  341. Lb17:   SB1(); SA1(La18)
  342. Lb18:   SB1(); SA1(La19)
  343. Lb19:   SB1(); SA1(La20)
  344. Lb20:   SB1(); SA1(La21)
  345. Lb21:   SB1(); SA1(La22)
  346. Lb22:   SB1(); SA1(La23)
  347. Lb23:   SB1(); SA1(La24)
  348. Lb24:   SB1(); SA1(La25)
  349. Lb25:   SB1(); SA1(La26)
  350. Lb26:   SB1(); SA1(La27)
  351. Lb27:   SB1(); SA1(La28)
  352. Lb28:   SB1(); SA1(La29)
  353. Lb29:   SB1(); SA1(La30)
  354. Lb30:   SB1(); SA1(La31)
  355. Lb31:   SB1(); SA1(La32)
  356. Lb32:   SB1()                   # %o3 = x mod (2*y')
  357.         xor     %o1,-1,%o1      # %o1 = floor( floor(x/2) / y') = floor(x/(2*y'))
  358.         add     %o2,%o2,%o2
  359.         sub     %o2,1,%o2       # wieder %o2 = 2*y'-1 = y
  360.         # Quotient und Rest umrechnen:
  361.         # x = %o1 * 2*y' + %o3 = %o1 * (2*y'-1) + (%o3+%o1)
  362.         # Also Quotient = %o1, Rest = %o3+%o1.
  363.         # Noch maximal 2 mal: Quotient += 1, Rest -= y.
  364.         addcc   %o1,%o3,%o3     # Rest mod y bestimmen
  365.         bcc     1f              # Additions-▄berlauf -> Quotient erh÷hen
  366.        _ subcc   %o3,%o2,%o0
  367.         subcc   %o0,%o2,%o3     # mu▀ der Quotient nochmals erh÷ht werden?
  368.         bcs     2f
  369.        _ mov     %o0,%g1
  370.         # Quotient 2 mal erh÷hen, Rest %o3
  371.         mov     %o3,%g1
  372.         retl
  373.        _ add     %o1,2,%o0
  374. 1:      # kein Additions-▄berlauf.
  375.         # Wegen y>=2^31 mu▀ der Quotient noch h÷chstens 1 mal erh÷ht werden:
  376.         bcs     3f              # %o3 < %o2 -> Rest %o3 und Quotient %o1 OK
  377.        _ mov     %o0,%g1
  378. 2:      # Quotient %o1 erh÷hen, Rest = %o3-%o2 = %o0
  379.         retl
  380.        _ add     %o1,1,%o0
  381. 3:      # Quotient %o1 und Rest %o3 OK
  382.         mov     %o3,%g1
  383.         retl
  384.        _ mov     %o1,%o0
  385. Lsmalldiv: # Division durch y < 2^31
  386.         addcc   %o1,%o1,%o1
  387. Lc00:   SB0(); SA0(Ld01)        # Bit 31 des Quotienten bestimmen
  388. Lc01:   SB0(); SA0(Ld02)        # Bit 30 des Quotienten bestimmen
  389. Lc02:   SB0(); SA0(Ld03)        # Bit 29 des Quotienten bestimmen
  390. Lc03:   SB0(); SA0(Ld04)        # Bit 28 des Quotienten bestimmen
  391. Lc04:   SB0(); SA0(Ld05)        # Bit 27 des Quotienten bestimmen
  392. Lc05:   SB0(); SA0(Ld06)        # Bit 26 des Quotienten bestimmen
  393. Lc06:   SB0(); SA0(Ld07)        # Bit 25 des Quotienten bestimmen
  394. Lc07:   SB0(); SA0(Ld08)        # Bit 24 des Quotienten bestimmen
  395. Lc08:   SB0(); SA0(Ld09)        # Bit 23 des Quotienten bestimmen
  396. Lc09:   SB0(); SA0(Ld10)        # Bit 22 des Quotienten bestimmen
  397. Lc10:   SB0(); SA0(Ld11)        # Bit 21 des Quotienten bestimmen
  398. Lc11:   SB0(); SA0(Ld12)        # Bit 20 des Quotienten bestimmen
  399. Lc12:   SB0(); SA0(Ld13)        # Bit 19 des Quotienten bestimmen
  400. Lc13:   SB0(); SA0(Ld14)        # Bit 18 des Quotienten bestimmen
  401. Lc14:   SB0(); SA0(Ld15)        # Bit 17 des Quotienten bestimmen
  402. Lc15:   SB0(); SA0(Ld16)        # Bit 16 des Quotienten bestimmen
  403. Lc16:   SB0(); SA0(Ld17)        # Bit 15 des Quotienten bestimmen
  404. Lc17:   SB0(); SA0(Ld18)        # Bit 14 des Quotienten bestimmen
  405. Lc18:   SB0(); SA0(Ld19)        # Bit 13 des Quotienten bestimmen
  406. Lc19:   SB0(); SA0(Ld20)        # Bit 12 des Quotienten bestimmen
  407. Lc20:   SB0(); SA0(Ld21)        # Bit 11 des Quotienten bestimmen
  408. Lc21:   SB0(); SA0(Ld22)        # Bit 10 des Quotienten bestimmen
  409. Lc22:   SB0(); SA0(Ld23)        # Bit 9 des Quotienten bestimmen
  410. Lc23:   SB0(); SA0(Ld24)        # Bit 8 des Quotienten bestimmen
  411. Lc24:   SB0(); SA0(Ld25)        # Bit 7 des Quotienten bestimmen
  412. Lc25:   SB0(); SA0(Ld26)        # Bit 6 des Quotienten bestimmen
  413. Lc26:   SB0(); SA0(Ld27)        # Bit 5 des Quotienten bestimmen
  414. Lc27:   SB0(); SA0(Ld28)        # Bit 4 des Quotienten bestimmen
  415. Lc28:   SB0(); SA0(Ld29)        # Bit 3 des Quotienten bestimmen
  416. Lc29:   SB0(); SA0(Ld30)        # Bit 2 des Quotienten bestimmen
  417. Lc30:   SB0(); SA0(Ld31)        # Bit 1 des Quotienten bestimmen
  418. Lc31:   SB0(); SA0(Ld32)        # Bit 0 des Quotienten bestimmen
  419. Lc32:   mov     %o0,%g1         # Rest aus %o0 in %g1 abspeichern
  420.         retl
  421.        _ xor     %o1,-1,%o0     # Quotient nach %o0
  422. # Parallelschiene zu Lc01..Lc32:
  423. Ld01:   SB1(); SA1(Lc02)
  424. Ld02:   SB1(); SA1(Lc03)
  425. Ld03:   SB1(); SA1(Lc04)
  426. Ld04:   SB1(); SA1(Lc05)
  427. Ld05:   SB1(); SA1(Lc06)
  428. Ld06:   SB1(); SA1(Lc07)
  429. Ld07:   SB1(); SA1(Lc08)
  430. Ld08:   SB1(); SA1(Lc09)
  431. Ld09:   SB1(); SA1(Lc10)
  432. Ld10:   SB1(); SA1(Lc11)
  433. Ld11:   SB1(); SA1(Lc12)
  434. Ld12:   SB1(); SA1(Lc13)
  435. Ld13:   SB1(); SA1(Lc14)
  436. Ld14:   SB1(); SA1(Lc15)
  437. Ld15:   SB1(); SA1(Lc16)
  438. Ld16:   SB1(); SA1(Lc17)
  439. Ld17:   SB1(); SA1(Lc18)
  440. Ld18:   SB1(); SA1(Lc19)
  441. Ld19:   SB1(); SA1(Lc20)
  442. Ld20:   SB1(); SA1(Lc21)
  443. Ld21:   SB1(); SA1(Lc22)
  444. Ld22:   SB1(); SA1(Lc23)
  445. Ld23:   SB1(); SA1(Lc24)
  446. Ld24:   SB1(); SA1(Lc25)
  447. Ld25:   SB1(); SA1(Lc26)
  448. Ld26:   SB1(); SA1(Lc27)
  449. Ld27:   SB1(); SA1(Lc28)
  450. Ld28:   SB1(); SA1(Lc29)
  451. Ld29:   SB1(); SA1(Lc30)
  452. Ld30:   SB1(); SA1(Lc31)
  453. Ld31:   SB1(); SA1(Lc32)
  454. Ld32:   mov     %o3,%g1         # Rest aus %o3 in %g1 abspeichern
  455.         retl
  456.        _ xor     %o1,-1,%o0     # Quotient nach %o0
  457. Levendiv: # Division durch gerades y.
  458.         # x/2 durch y/2 dividieren, Quotient OK, Rest evtl. mit 2 multiplizieren.
  459.         # Es ist schon %o2 = y/2.
  460.         # Man spart im Vergleich zu Lsmalldiv
  461.         # zu Beginn eine Verdoppelung von %o0|%o1 : addcc %o1,%o1,%o1; SB0()
  462.         # dafⁿr am Schlu▀ Bit 0 von x zum Rest dazuschieben.
  463.         SA0(Lf01)               # Bit 31 des Quotienten bestimmen
  464. Le01:   SB0(); SA0(Lf02)        # Bit 30 des Quotienten bestimmen
  465. Le02:   SB0(); SA0(Lf03)        # Bit 29 des Quotienten bestimmen
  466. Le03:   SB0(); SA0(Lf04)        # Bit 28 des Quotienten bestimmen
  467. Le04:   SB0(); SA0(Lf05)        # Bit 27 des Quotienten bestimmen
  468. Le05:   SB0(); SA0(Lf06)        # Bit 26 des Quotienten bestimmen
  469. Le06:   SB0(); SA0(Lf07)        # Bit 25 des Quotienten bestimmen
  470. Le07:   SB0(); SA0(Lf08)        # Bit 24 des Quotienten bestimmen
  471. Le08:   SB0(); SA0(Lf09)        # Bit 23 des Quotienten bestimmen
  472. Le09:   SB0(); SA0(Lf10)        # Bit 22 des Quotienten bestimmen
  473. Le10:   SB0(); SA0(Lf11)        # Bit 21 des Quotienten bestimmen
  474. Le11:   SB0(); SA0(Lf12)        # Bit 20 des Quotienten bestimmen
  475. Le12:   SB0(); SA0(Lf13)        # Bit 19 des Quotienten bestimmen
  476. Le13:   SB0(); SA0(Lf14)        # Bit 18 des Quotienten bestimmen
  477. Le14:   SB0(); SA0(Lf15)        # Bit 17 des Quotienten bestimmen
  478. Le15:   SB0(); SA0(Lf16)        # Bit 16 des Quotienten bestimmen
  479. Le16:   SB0(); SA0(Lf17)        # Bit 15 des Quotienten bestimmen
  480. Le17:   SB0(); SA0(Lf18)        # Bit 14 des Quotienten bestimmen
  481. Le18:   SB0(); SA0(Lf19)        # Bit 13 des Quotienten bestimmen
  482. Le19:   SB0(); SA0(Lf20)        # Bit 12 des Quotienten bestimmen
  483. Le20:   SB0(); SA0(Lf21)        # Bit 11 des Quotienten bestimmen
  484. Le21:   SB0(); SA0(Lf22)        # Bit 10 des Quotienten bestimmen
  485. Le22:   SB0(); SA0(Lf23)        # Bit 9 des Quotienten bestimmen
  486. Le23:   SB0(); SA0(Lf24)        # Bit 8 des Quotienten bestimmen
  487. Le24:   SB0(); SA0(Lf25)        # Bit 7 des Quotienten bestimmen
  488. Le25:   SB0(); SA0(Lf26)        # Bit 6 des Quotienten bestimmen
  489. Le26:   SB0(); SA0(Lf27)        # Bit 5 des Quotienten bestimmen
  490. Le27:   SB0(); SA0(Lf28)        # Bit 4 des Quotienten bestimmen
  491. Le28:   SB0(); SA0(Lf29)        # Bit 3 des Quotienten bestimmen
  492. Le29:   SB0(); SA0(Lf30)        # Bit 2 des Quotienten bestimmen
  493. Le30:   SB0(); SA0(Lf31)        # Bit 1 des Quotienten bestimmen
  494. Le31:   SB0(); SA0(Lf32)        # Bit 0 des Quotienten bestimmen
  495. Le32:   SB0()                   # Bit 0 des Restes bestimmen
  496.         mov     %o0,%g1         # Rest aus %o0 in %g1 abspeichern
  497.         retl
  498.        _ xor     %o1,-1,%o0     # Quotient nach %o0
  499. # Parallelschiene zu Le01..Le32:
  500. Lf01:   SB1(); SA1(Le02)
  501. Lf02:   SB1(); SA1(Le03)
  502. Lf03:   SB1(); SA1(Le04)
  503. Lf04:   SB1(); SA1(Le05)
  504. Lf05:   SB1(); SA1(Le06)
  505. Lf06:   SB1(); SA1(Le07)
  506. Lf07:   SB1(); SA1(Le08)
  507. Lf08:   SB1(); SA1(Le09)
  508. Lf09:   SB1(); SA1(Le10)
  509. Lf10:   SB1(); SA1(Le11)
  510. Lf11:   SB1(); SA1(Le12)
  511. Lf12:   SB1(); SA1(Le13)
  512. Lf13:   SB1(); SA1(Le14)
  513. Lf14:   SB1(); SA1(Le15)
  514. Lf15:   SB1(); SA1(Le16)
  515. Lf16:   SB1(); SA1(Le17)
  516. Lf17:   SB1(); SA1(Le18)
  517. Lf18:   SB1(); SA1(Le19)
  518. Lf19:   SB1(); SA1(Le20)
  519. Lf20:   SB1(); SA1(Le21)
  520. Lf21:   SB1(); SA1(Le22)
  521. Lf22:   SB1(); SA1(Le23)
  522. Lf23:   SB1(); SA1(Le24)
  523. Lf24:   SB1(); SA1(Le25)
  524. Lf25:   SB1(); SA1(Le26)
  525. Lf26:   SB1(); SA1(Le27)
  526. Lf27:   SB1(); SA1(Le28)
  527. Lf28:   SB1(); SA1(Le29)
  528. Lf29:   SB1(); SA1(Le30)
  529. Lf30:   SB1(); SA1(Le31)
  530. Lf31:   SB1(); SA1(Le32)
  531. Lf32:   SB1()
  532.         mov     %o3,%g1         # Rest aus %o0 in %g1 abspeichern
  533.         retl
  534.        _ xor     %o1,-1,%o0     # Quotient nach %o0
  535. #endif
  536.  
  537. # extern struct { uint16 q; uint16 r; } divu_3216_1616_ (uint32 x, uint16 y);
  538. # x = q*y+r schreiben. Sei bekannt, da▀ 0 <= x < 2^16*y .
  539. C(divu_3216_1616_:) # Input in %o0,%o1, Output in %o0 (Rest und Quotient).
  540. #ifdef sparcv8
  541.         wry     %g0,%g0,%y
  542.         udiv    %o0,%o1,%o0     # dividieren, Quotient nach %o0
  543.         rd      %y,%o1          # Rest aus %y
  544.         sll     %o1,16,%o1      # in die oberen 16 Bit schieben
  545.         retl
  546.        _ orl     %o0,%o1,%o0
  547. #else
  548.         # %o0 = x, %o1 = y
  549. # Divisions-Einzelschritte:
  550. # %o0  wird jeweils um 1 Bit nach links geschoben,
  551. # dafⁿr wird rechts in %o1 ein Ergebnisbit (negiert!) reingeschoben.
  552. # Dann wird auf >= 2^15*y verglichen (nicht auf >= 2^16*y, weil man dann das
  553. # links herausgeschobene Bit mit vergleichen mⁿ▀te!)
  554.         sll %o1,16,%o1
  555.         srl %o1,1,%o1           # 2^15*y
  556.         sub %g0,%o1,%o2         # zum Addieren statt Subtrahieren: -2^15*y
  557.         # SC0(label) subtrahiert y, schiebt Carry-Bit rechts in %o0 rein
  558.         # (1 falls Subtraktion aufging, 0 sonst).
  559.         # Ging die Subtraktion nicht auf, so mⁿ▀te man noch 2*y addieren.
  560.         # Das fa▀t man mit der nΣchsten Operation zusammen, indem man - statt
  561.         # y zu subtrahieren - y addiert:
  562.         # SC1(label) addiert y, schiebt Carry-Bit rechts in %o0 rein
  563.         # (1 falls Subtraktion aufgegangen wΣre, man also wieder im
  564.         # "positiven Bereich" landet, 0 sonst).
  565. #define SC0(label) \
  566.         addcc   %o0,%o2,%o0; \
  567.         bcc     label;       \
  568.        _ addx    %o0,%o0,%o0
  569. #define SC1(label) \
  570.         addcc   %o0,%o1,%o0; \
  571.         bcs     label;       \
  572.        _ addx    %o0,%o0,%o0
  573.         SC0(Lh01)               # Bit 15 des Quotienten bestimmen
  574. Lg01:   SC0(Lh02)               # Bit 14 des Quotienten bestimmen
  575. Lg02:   SC0(Lh03)               # Bit 13 des Quotienten bestimmen
  576. Lg03:   SC0(Lh04)               # Bit 12 des Quotienten bestimmen
  577. Lg04:   SC0(Lh05)               # Bit 11 des Quotienten bestimmen
  578. Lg05:   SC0(Lh06)               # Bit 10 des Quotienten bestimmen
  579. Lg06:   SC0(Lh07)               # Bit 9 des Quotienten bestimmen
  580. Lg07:   SC0(Lh08)               # Bit 8 des Quotienten bestimmen
  581. Lg08:   SC0(Lh09)               # Bit 7 des Quotienten bestimmen
  582. Lg09:   SC0(Lh10)               # Bit 6 des Quotienten bestimmen
  583. Lg10:   SC0(Lh11)               # Bit 5 des Quotienten bestimmen
  584. Lg11:   SC0(Lh12)               # Bit 4 des Quotienten bestimmen
  585. Lg12:   SC0(Lh13)               # Bit 3 des Quotienten bestimmen
  586. Lg13:   SC0(Lh14)               # Bit 2 des Quotienten bestimmen
  587. Lg14:   SC0(Lh15)               # Bit 1 des Quotienten bestimmen
  588. Lg15:   SC0(Lh16)               # Bit 0 des Quotienten bestimmen
  589. Lg16:   # Die oberen 16 Bit von %o0 sind der Rest,
  590.         # die unteren 16 Bit von %o0 sind der Quotient.
  591.         retl
  592.        _ nop
  593. Lh01:   SC1(Lg02)               # Bit 14 des Quotienten bestimmen
  594. Lh02:   SC1(Lg03)               # Bit 13 des Quotienten bestimmen
  595. Lh03:   SC1(Lg04)               # Bit 12 des Quotienten bestimmen
  596. Lh04:   SC1(Lg05)               # Bit 11 des Quotienten bestimmen
  597. Lh05:   SC1(Lg06)               # Bit 10 des Quotienten bestimmen
  598. Lh06:   SC1(Lg07)               # Bit 9 des Quotienten bestimmen
  599. Lh07:   SC1(Lg08)               # Bit 8 des Quotienten bestimmen
  600. Lh08:   SC1(Lg09)               # Bit 7 des Quotienten bestimmen
  601. Lh09:   SC1(Lg10)               # Bit 6 des Quotienten bestimmen
  602. Lh10:   SC1(Lg11)               # Bit 5 des Quotienten bestimmen
  603. Lh11:   SC1(Lg12)               # Bit 4 des Quotienten bestimmen
  604. Lh12:   SC1(Lg13)               # Bit 3 des Quotienten bestimmen
  605. Lh13:   SC1(Lg14)               # Bit 2 des Quotienten bestimmen
  606. Lh14:   SC1(Lg15)               # Bit 1 des Quotienten bestimmen
  607. Lh15:   SC1(Lg16)               # Bit 0 des Quotienten bestimmen
  608. Lh16:   # Noch 2*y addieren:
  609.         add %o0,%o1,%o0
  610.         retl
  611.        _ add %o0,%o1,%o0
  612. #endif
  613.  
  614. # extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
  615. C(copy_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
  616. #if STANDARD_LOOPS
  617.         andcc %o2,%o2,%g0
  618.         be 2f
  619.        _ nop
  620. 1:        ld [%o0],%o3
  621.           add %o0,4,%o0
  622.           st %o3,[%o1]
  623.           subcc %o2,1,%o2
  624.           bne 1b
  625.          _ add %o1,4,%o1
  626. 2:      retl
  627.        _ mov %o1,%o0
  628. #endif
  629. #if COUNTER_LOOPS
  630.         subcc %g0,%o2,%o2       # %o2 = -count
  631.         be 2f
  632.        _ sub %o1,4,%o1
  633.         sll %o2,2,%o2           # %o2 = -4*count
  634.         sub %o0,%o2,%o0         # %o0 = &sourceptr[count]
  635.         sub %o1,%o2,%o1         # %o1 = &destptr[count-1]
  636. 1:        ld [%o0+%o2],%o3      # nΣchstes Digit holen
  637.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  638.           bne 1b
  639.          _ st %o3,[%o1+%o2]     # Digit ablegen
  640. 2:      retl
  641.        _ add %o1,4,%o0
  642. #endif
  643.  
  644. # extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  645. C(copy_loop_down:) # Input in %o0,%o1,%o2, Output in %o0
  646. #if STANDARD_LOOPS
  647.         andcc %o2,%o2,%g0
  648.         be 2f
  649.        _ sub %o0,4,%o0
  650. 1:        ld [%o0],%o3
  651.           sub %o1,4,%o1
  652.           st %o3,[%o1]
  653.           subcc %o2,1,%o2
  654.           bne 1b
  655.          _ sub %o0,4,%o0
  656. 2:      retl
  657.        _ mov %o1,%o0
  658. #endif
  659. #if COUNTER_LOOPS
  660.         andcc %o2,%o2,%g0
  661.         be 2f
  662.        _ sub %o0,4,%o0
  663.         sll %o2,2,%o2           # %o2 = 4*count
  664.         sub %o0,%o2,%o0         # %o0 = &sourceptr[-count-1]
  665.         sub %o1,%o2,%o1         # %o1 = &destptr[-count]
  666. 1:        ld [%o0+%o2],%o3      # nΣchstes Digit holen
  667.           subcc %o2,4,%o2       # ZΣhler erniedrigen, Pointer erniedrigen
  668.           bne 1b
  669.          _ st %o3,[%o1+%o2]     # Digit ablegen
  670. 2:      retl
  671.        _ mov %o1,%o0
  672. #endif
  673.  
  674. # extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
  675. C(fill_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
  676. #if STANDARD_LOOPS
  677.         andcc %o1,%o1,%g0
  678.         be 2f
  679.        _ nop
  680. 1:        st %o2,[%o0]
  681.           subcc %o1,1,%o1
  682.           bne 1b
  683.          _ add %o0,4,%o0
  684. 2:      retl
  685.        _ nop
  686. #endif
  687. #if COUNTER_LOOPS
  688.         subcc %g0,%o1,%o1       # %o1 = -count
  689.         be 2f
  690.        _ sub %o0,4,%o0
  691.         sll %o1,2,%o1           # %o1 = -4*count
  692.         sub %o0,%o1,%o0         # %o0 = &destptr[count-1]
  693. 1:        addcc %o1,4,%o1       # ZΣhler "erniedrigen", Pointer erh÷hen
  694.           bne 1b
  695.          _ st %o2,[%o0+%o1]     # Digit ablegen
  696. 2:      retl
  697.        _ add %o0,4,%o0
  698. #endif
  699.  
  700. # extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
  701. C(fill_loop_down:) # Input in %o0,%o1,%o2, Output in %o0
  702. #if STANDARD_LOOPS
  703.         andcc %o1,%o1,%g0
  704.         be 2f
  705.        _ sub %o0,4,%o0
  706. 1:        st %o2,[%o0]
  707.           subcc %o1,1,%o1
  708.           bne 1b
  709.          _ sub %o0,4,%o0
  710. 2:      retl
  711.        _ add %o0,4,%o0
  712. #endif
  713. #if COUNTER_LOOPS
  714.         andcc %o1,%o1,%g0
  715.         be 2f
  716.        _ sll %o1,2,%o1          # %o1 = 4*count
  717.         sub %o0,%o1,%o0         # %o0 = &destptr[-count]
  718. 1:        subcc %o1,4,%o1       # ZΣhler erniedrigen, Pointer erniedrigen
  719.           bne 1b
  720.          _ st %o2,[%o0+%o1]     # Digit ablegen
  721. 2:      retl
  722.        _ nop
  723. #endif
  724.  
  725. # extern uintD* clear_loop_up (uintD* destptr, uintC count);
  726. C(clear_loop_up:) # Input in %o0,%o1, Output in %o0
  727. #if STANDARD_LOOPS
  728.         andcc %o1,%o1,%g0
  729.         be 2f
  730.        _ nop
  731. 1:        st %g0,[%o0]
  732.           subcc %o1,1,%o1
  733.           bne 1b
  734.          _ add %o0,4,%o0
  735. 2:      retl
  736.        _ nop
  737. #endif
  738. #if COUNTER_LOOPS
  739.         subcc %g0,%o1,%o1       # %o1 = -count
  740.         be 2f
  741.        _ sub %o0,4,%o0
  742.         sll %o1,2,%o1           # %o1 = -4*count
  743.         sub %o0,%o1,%o0         # %o0 = &destptr[count-1]
  744. 1:        addcc %o1,4,%o1       # ZΣhler "erniedrigen", Pointer erh÷hen
  745.           bne 1b
  746.          _ st %g0,[%o0+%o1]     # Digit 0 ablegen
  747. 2:      retl
  748.        _ add %o0,4,%o0
  749. #endif
  750.  
  751. # extern uintD* clear_loop_down (uintD* destptr, uintC count);
  752. C(clear_loop_down:) # Input in %o0,%o1, Output in %o0
  753. #if STANDARD_LOOPS
  754.         andcc %o1,%o1,%g0
  755.         be 2f
  756.        _ sub %o0,4,%o0
  757. 1:        st %g0,[%o0]
  758.           subcc %o1,1,%o1
  759.           bne 1b
  760.          _ sub %o0,4,%o0
  761. 2:      retl
  762.        _ add %o0,4,%o0
  763. #endif
  764. #if COUNTER_LOOPS
  765.         andcc %o1,%o1,%g0
  766.         be 2f
  767.        _ sll %o1,2,%o1          # %o1 = 4*count
  768.         sub %o0,%o1,%o0         # %o0 = &destptr[-count]
  769. 1:        subcc %o1,4,%o1       # ZΣhler erniedrigen, Pointer erniedrigen
  770.           bne 1b
  771.          _ st %g0,[%o0+%o1]     # Digit 0 ablegen
  772. 2:      retl
  773.        _ nop
  774. #endif
  775.  
  776. # extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
  777. C(or_loop_up:) # Input in %o0,%o1,%o2
  778. #if STANDARD_LOOPS
  779.         andcc %o2,%o2,%g0
  780.         be 2f
  781.        _ nop
  782. 1:        ld [%o0],%o3
  783.           ld [%o1],%o4
  784.           add %o1,4,%o1
  785.           or %o3,%o4,%o3
  786.           st %o3,[%o0]
  787.           subcc %o2,1,%o2
  788.           bne 1b
  789.          _ add %o0,4,%o0
  790. 2:      retl
  791.        _ nop
  792. #endif
  793. #if COUNTER_LOOPS
  794.         subcc %g0,%o2,%o2       # %o2 = -count
  795.         be 2f
  796.        _ sub %o0,4,%o0
  797.         sll %o2,2,%o2           # %o2 = -4*count
  798.         sub %o0,%o2,%o0         # %o0 = &xptr[count-1]
  799.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  800. 1:        ld [%o1+%o2],%o3      # nΣchstes Digit holen
  801.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  802.           ld [%o0+%o2],%o4      # noch ein Digit holen
  803.           or %o4,%o3,%o3        # beide verknⁿpfen
  804.           bne 1b
  805.          _ st %o3,[%o1+%o2]     # Digit ablegen
  806. 2:      retl
  807.        _ nop
  808. #endif
  809.  
  810. # extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  811. C(xor_loop_up:) # Input in %o0,%o1,%o2
  812. #if STANDARD_LOOPS
  813.         andcc %o2,%o2,%g0
  814.         be 2f
  815.        _ nop
  816. 1:        ld [%o0],%o3
  817.           ld [%o1],%o4
  818.           add %o1,4,%o1
  819.           xor %o3,%o4,%o3
  820.           st %o3,[%o0]
  821.           subcc %o2,1,%o2
  822.           bne 1b
  823.          _ add %o0,4,%o0
  824. 2:      retl
  825.        _ nop
  826. #endif
  827. #if COUNTER_LOOPS
  828.         subcc %g0,%o2,%o2       # %o2 = -count
  829.         be 2f
  830.        _ sub %o0,4,%o0
  831.         sll %o2,2,%o2           # %o2 = -4*count
  832.         sub %o0,%o2,%o0         # %o0 = &xptr[count-1]
  833.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  834. 1:        ld [%o1+%o2],%o3      # nΣchstes Digit holen
  835.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  836.           ld [%o0+%o2],%o4      # noch ein Digit holen
  837.           xor %o4,%o3,%o3       # beide verknⁿpfen
  838.           bne 1b
  839.          _ st %o3,[%o1+%o2]     # Digit ablegen
  840. 2:      retl
  841.        _ nop
  842. #endif
  843.  
  844. # extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
  845. C(and_loop_up:) # Input in %o0,%o1,%o2
  846. #if STANDARD_LOOPS
  847.         andcc %o2,%o2,%g0
  848.         be 2f
  849.        _ nop
  850. 1:        ld [%o0],%o3
  851.           ld [%o1],%o4
  852.           add %o1,4,%o1
  853.           and %o3,%o4,%o3
  854.           st %o3,[%o0]
  855.           subcc %o2,1,%o2
  856.           bne 1b
  857.          _ add %o0,4,%o0
  858. 2:      retl
  859.        _ nop
  860. #endif
  861. #if COUNTER_LOOPS
  862.         subcc %g0,%o2,%o2       # %o2 = -count
  863.         be 2f
  864.        _ sub %o0,4,%o0
  865.         sll %o2,2,%o2           # %o2 = -4*count
  866.         sub %o0,%o2,%o0         # %o0 = &xptr[count-1]
  867.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  868. 1:        ld [%o1+%o2],%o3      # nΣchstes Digit holen
  869.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  870.           ld [%o0+%o2],%o4      # noch ein Digit holen
  871.           and %o4,%o3,%o3       # beide verknⁿpfen
  872.           bne 1b
  873.          _ st %o3,[%o1+%o2]     # Digit ablegen
  874. 2:      retl
  875.        _ nop
  876. #endif
  877.  
  878. # extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
  879. C(eqv_loop_up:) # Input in %o0,%o1,%o2
  880. #if STANDARD_LOOPS
  881.         andcc %o2,%o2,%g0
  882.         be 2f
  883.        _ nop
  884. 1:        ld [%o0],%o3
  885.           ld [%o1],%o4
  886.           add %o1,4,%o1
  887.           xnor %o3,%o4,%o3
  888.           st %o3,[%o0]
  889.           subcc %o2,1,%o2
  890.           bne 1b
  891.          _ add %o0,4,%o0
  892. 2:      retl
  893.        _ nop
  894. #endif
  895. #if COUNTER_LOOPS
  896.         subcc %g0,%o2,%o2       # %o2 = -count
  897.         be 2f
  898.        _ sub %o0,4,%o0
  899.         sll %o2,2,%o2           # %o2 = -4*count
  900.         sub %o0,%o2,%o0         # %o0 = &xptr[count-1]
  901.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  902. 1:        ld [%o1+%o2],%o3      # nΣchstes Digit holen
  903.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  904.           ld [%o0+%o2],%o4      # noch ein Digit holen
  905.           xnor %o4,%o3,%o3      # beide verknⁿpfen
  906.           bne 1b
  907.          _ st %o3,[%o1+%o2]     # Digit ablegen
  908. 2:      retl
  909.        _ nop
  910. #endif
  911.  
  912. # extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
  913. C(nand_loop_up:) # Input in %o0,%o1,%o2
  914. #if STANDARD_LOOPS
  915.         andcc %o2,%o2,%g0
  916.         be 2f
  917.        _ nop
  918. 1:        ld [%o0],%o3
  919.           ld [%o1],%o4
  920.           add %o1,4,%o1
  921.           and %o3,%o4,%o3
  922.           xor %o3,-1,%o3
  923.           st %o3,[%o0]
  924.           subcc %o2,1,%o2
  925.           bne 1b
  926.          _ add %o0,4,%o0
  927. 2:      retl
  928.        _ nop
  929. #endif
  930. #if COUNTER_LOOPS
  931.         subcc %g0,%o2,%o2       # %o2 = -count
  932.         be 2f
  933.        _ sub %o0,4,%o0
  934.         sll %o2,2,%o2           # %o2 = -4*count
  935.         sub %o0,%o2,%o0         # %o0 = &xptr[count-1]
  936.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  937. 1:        ld [%o1+%o2],%o3      # nΣchstes Digit holen
  938.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  939.           ld [%o0+%o2],%o4      # noch ein Digit holen
  940.           and %o4,%o3,%o3       # beide verknⁿpfen
  941.           xor %o3,-1,%o3
  942.           bne 1b
  943.          _ st %o3,[%o1+%o2]     # Digit ablegen
  944. 2:      retl
  945.        _ nop
  946. #endif
  947.  
  948. # extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
  949. C(nor_loop_up:) # Input in %o0,%o1,%o2
  950. #if STANDARD_LOOPS
  951.         andcc %o2,%o2,%g0
  952.         be 2f
  953.        _ nop
  954. 1:        ld [%o0],%o3
  955.           ld [%o1],%o4
  956.           add %o1,4,%o1
  957.           or %o3,%o4,%o3
  958.           xor %o3,-1,%o3
  959.           st %o3,[%o0]
  960.           subcc %o2,1,%o2
  961.           bne 1b
  962.          _ add %o0,4,%o0
  963. 2:      retl
  964.        _ nop
  965. #endif
  966. #if COUNTER_LOOPS
  967.         subcc %g0,%o2,%o2       # %o2 = -count
  968.         be 2f
  969.        _ sub %o0,4,%o0
  970.         sll %o2,2,%o2           # %o2 = -4*count
  971.         sub %o0,%o2,%o0         # %o0 = &xptr[count-1]
  972.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  973. 1:        ld [%o1+%o2],%o3      # nΣchstes Digit holen
  974.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  975.           ld [%o0+%o2],%o4      # noch ein Digit holen
  976.           or %o4,%o3,%o3        # beide verknⁿpfen
  977.           xor %o3,-1,%o3
  978.           bne 1b
  979.          _ st %o3,[%o1+%o2]     # Digit ablegen
  980. 2:      retl
  981.        _ nop
  982. #endif
  983.  
  984. # extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  985. C(andc2_loop_up:) # Input in %o0,%o1,%o2
  986. #if STANDARD_LOOPS
  987.         andcc %o2,%o2,%g0
  988.         be 2f
  989.        _ nop
  990. 1:        ld [%o0],%o3
  991.           ld [%o1],%o4
  992.           add %o1,4,%o1
  993.           andn %o3,%o4,%o3
  994.           st %o3,[%o0]
  995.           subcc %o2,1,%o2
  996.           bne 1b
  997.          _ add %o0,4,%o0
  998. 2:      retl
  999.        _ nop
  1000. #endif
  1001. #if COUNTER_LOOPS
  1002.         subcc %g0,%o2,%o2       # %o2 = -count
  1003.         be 2f
  1004.        _ sub %o0,4,%o0
  1005.         sll %o2,2,%o2           # %o2 = -4*count
  1006.         sub %o0,%o2,%o0         # %o0 = &xptr[count-1]
  1007.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  1008. 1:        ld [%o1+%o2],%o3      # nΣchstes Digit holen
  1009.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  1010.           ld [%o0+%o2],%o4      # noch ein Digit holen
  1011.           andn %o4,%o3,%o3      # beide verknⁿpfen
  1012.           bne 1b
  1013.          _ st %o3,[%o1+%o2]     # Digit ablegen
  1014. 2:      retl
  1015.        _ nop
  1016. #endif
  1017.  
  1018. # extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
  1019. C(orc2_loop_up:) # Input in %o0,%o1,%o2
  1020. #if STANDARD_LOOPS
  1021.         andcc %o2,%o2,%g0
  1022.         be 2f
  1023.        _ nop
  1024. 1:        ld [%o0],%o3
  1025.           ld [%o1],%o4
  1026.           add %o1,4,%o1
  1027.           xor %o4,-1,%o4
  1028.           or %o3,%o4,%o3
  1029.           st %o3,[%o0]
  1030.           subcc %o2,1,%o2
  1031.           bne 1b
  1032.          _ add %o0,4,%o0
  1033. 2:      retl
  1034.        _ nop
  1035. #endif
  1036. #if COUNTER_LOOPS
  1037.         subcc %g0,%o2,%o2       # %o2 = -count
  1038.         be 2f
  1039.        _ sub %o0,4,%o0
  1040.         sll %o2,2,%o2           # %o2 = -4*count
  1041.         sub %o0,%o2,%o0         # %o0 = &xptr[count-1]
  1042.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  1043. 1:        ld [%o1+%o2],%o3      # nΣchstes Digit holen
  1044.           addcc %o2,4,%o2       # ZΣhler "erniedrigen", Pointer erh÷hen
  1045.           ld [%o0+%o2],%o4      # noch ein Digit holen
  1046.           xor %o3,-1,%o3
  1047.           or %o4,%o3,%o3        # beide verknⁿpfen
  1048.           bne 1b
  1049.          _ st %o3,[%o1+%o2]     # Digit ablegen
  1050. 2:      retl
  1051.        _ nop
  1052. #endif
  1053.  
  1054. # extern void not_loop_up (uintD* xptr, uintC count);
  1055. C(not_loop_up:) # Input in %o0,%o1
  1056. #if STANDARD_LOOPS
  1057.         andcc %o1,%o1,%g0
  1058.         be 2f
  1059.        _ nop
  1060. 1:        ld [%o0],%o2
  1061.           subcc %o1,1,%o1
  1062.           xor %o2,-1,%o2
  1063.           st %o2,[%o0]
  1064.           bne 1b
  1065.          _ add %o0,4,%o0
  1066. 2:      retl
  1067.        _ nop
  1068. #endif
  1069. #if COUNTER_LOOPS
  1070.         subcc %g0,%o1,%o1       # %o1 = -count
  1071.         be 2f
  1072.        _ sub %o0,4,%o0
  1073.         sll %o1,2,%o1           # %o1 = -4*count
  1074.         sub %o0,%o1,%o0         # %o0 = &destptr[count-1]
  1075. 1:        addcc %o1,4,%o1       # ZΣhler "erniedrigen", Pointer erh÷hen
  1076.           ld [%o0+%o1],%o2      # nΣchstes Digit holen
  1077.           xor %o2,-1,%o2
  1078.           bne 1b
  1079.          _ st %o2,[%o0+%o1]     # Digit ablegen
  1080. 2:      retl
  1081.        _ nop
  1082. #endif
  1083.  
  1084. # extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
  1085. C(and_test_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
  1086. #if STANDARD_LOOPS
  1087.         andcc %o2,%o2,%g0
  1088.         be 2f
  1089.        _ nop
  1090. 1:        ld [%o0],%o3
  1091.           ld [%o1],%o4
  1092.           add %o0,4,%o0
  1093.           andcc %o3,%o4,%g0
  1094.           bne 3f
  1095.          _ subcc %o2,1,%o2
  1096.           bne 1b
  1097.          _ add %o1,4,%o1
  1098. 2:      retl
  1099.        _ mov 0,%o0
  1100. 3:      retl
  1101.        _ mov 1,%o0
  1102. #endif
  1103. #if COUNTER_LOOPS
  1104.         subcc %g0,%o2,%o2       # %o2 = -count
  1105.         be 2f
  1106.        _ sll %o2,2,%o2          # %o2 = -4*count
  1107.         sub %o0,%o2,%o0         # %o0 = &xptr[count]
  1108.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  1109.           ld [%o0+%o2],%o3      # nΣchstes Digit holen
  1110. 1:        ld [%o1+%o2],%o4      # noch ein Digit holen
  1111.           andcc %o3,%o4,%g0     # beide verknⁿpfen
  1112.           bne 3f
  1113.          _ addcc %o2,4,%o2      # ZΣhler "erniedrigen", Pointer erh÷hen
  1114.           bne,a 1b
  1115.          __ ld [%o0+%o2],%o3    # nΣchstes Digit holen
  1116. 2:      retl
  1117.        _ mov 0,%o0
  1118. 3:      retl
  1119.        _ mov 1,%o0
  1120. #endif
  1121.  
  1122. # extern boolean test_loop_up (uintD* ptr, uintC count);
  1123. C(test_loop_up:) # Input in %o0,%o1, Output in %o0
  1124. #if STANDARD_LOOPS
  1125.         andcc %o1,%o1,%g0
  1126.         be 2f
  1127.        _ nop
  1128.           ld [%o0],%o2
  1129. 1:        add %o0,4,%o0
  1130.           andcc %o2,%o2,%g0
  1131.           bne 3f
  1132.          _ subcc %o1,1,%o1
  1133.           bne,a 1b
  1134.          __ ld [%o0],%o2
  1135. 2:      retl
  1136.        _ mov 0,%o0
  1137. 3:      retl
  1138.        _ mov 1,%o0
  1139. #endif
  1140. #if COUNTER_LOOPS
  1141.         subcc %g0,%o1,%o1       # %o1 = -count
  1142.         be 2f
  1143.        _ sll %o1,2,%o1          # %o1 = -4*count
  1144.         sub %o0,%o1,%o0         # %o0 = &ptr[count]
  1145.           ld [%o0+%o1],%o2      # nΣchstes Digit holen
  1146. 1:        andcc %o2,%o2,%g0     # testen
  1147.           bne 3f
  1148.          _ addcc %o1,4,%o1      # ZΣhler "erniedrigen", Pointer erh÷hen
  1149.           bne,a 1b
  1150.          __ ld [%o0+%o1],%o2    # nΣchstes Digit holen
  1151. 2:      retl
  1152.        _ mov 0,%o0
  1153. 3:      retl
  1154.        _ mov 1,%o0
  1155. #endif
  1156.  
  1157. # extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
  1158. C(compare_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
  1159. #if STANDARD_LOOPS
  1160.         andcc %o2,%o2,%g0
  1161.         be 2f
  1162.        _ nop
  1163.           ld [%o0],%o3
  1164. 1:        ld [%o1],%o4
  1165.           add %o0,4,%o0
  1166.           subcc %o3,%o4,%g0
  1167.           bne 3f
  1168.          _ add %o1,4,%o1
  1169.           subcc %o2,1,%o2
  1170.           bne,a 1b
  1171.          __ ld [%o0],%o3
  1172. 2:      retl
  1173.        _ mov 0,%o0
  1174. 3:      blu 4f
  1175.        _ nop
  1176.         retl
  1177.        _ mov 1,%o0
  1178. 4:      retl
  1179.        _ mov -1,%o0
  1180. #endif
  1181. #if COUNTER_LOOPS
  1182.         subcc %g0,%o2,%o2       # %o2 = -count
  1183.         be 2f
  1184.        _ sll %o2,2,%o2          # %o2 = -4*count
  1185.         sub %o0,%o2,%o0         # %o0 = &xptr[count]
  1186.         sub %o1,%o2,%o1         # %o1 = &yptr[count]
  1187.           ld [%o0+%o2],%o3      # nΣchstes Digit holen
  1188. 1:        ld [%o1+%o2],%o4      # noch ein Digit holen
  1189.           subcc %o3,%o4,%g0     # vergleichen
  1190.           bne 3f
  1191.          _ addcc %o2,4,%o2      # ZΣhler "erniedrigen", Pointer erh÷hen
  1192.           bne,a 1b
  1193.          __ ld [%o0+%o2],%o3    # nΣchstes Digit holen
  1194. 2:      retl
  1195.        _ mov 0,%o0
  1196. 3:      blu 4f
  1197.        _ nop
  1198.         retl
  1199.        _ mov 1,%o0
  1200. 4:      retl
  1201.        _ mov -1,%o0
  1202. #endif
  1203.  
  1204. # extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  1205. C(add_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1, Output in %o0
  1206. #if STANDARD_LOOPS
  1207.         andcc %o3,%o3,%g0
  1208.         be 2f
  1209.        _ mov %g0,%g1            # Carry := 0
  1210.         sub %o0,4,%o0
  1211. 1:        ld [%o0],%o4          # source1-digit
  1212.           sub %o1,4,%o1
  1213.           ld [%o1],%o5          # source2-digit
  1214.           subcc %g0,%g1,%g0     # carry
  1215.           addxcc %o4,%o5,%o4    # addieren
  1216.           addx %g0,%g0,%g1      # neuer Carry
  1217.           sub %o2,4,%o2
  1218.           st %o4,[%o2]          # Digit ablegen
  1219.           subcc %o3,1,%o3
  1220.           bne 1b
  1221.          _ sub %o0,4,%o0
  1222. 2:      retl
  1223.        _ mov %g1,%o0
  1224. #endif
  1225. #if COUNTER_LOOPS
  1226.         andcc %o3,%o3,%g0
  1227.         be 2f
  1228.        _ mov %g0,%g1            # Carry := 0
  1229.         sub %o0,4,%o0
  1230.         sub %o1,4,%o1
  1231.         sll %o3,2,%o3           # %o3 = 4*count
  1232.         sub %o0,%o3,%o0         # %o0 = &sourceptr1[-count-1]
  1233.         sub %o1,%o3,%o1         # %o1 = &sourceptr2[-count-1]
  1234.         sub %o2,%o3,%o2         # %o2 = &destptr[-count]
  1235. 1:        ld [%o0+%o3],%o4      # source1-digit
  1236.           ld [%o1+%o3],%o5      # source2-digit
  1237.           subcc %g0,%g1,%g0     # carry
  1238.           addxcc %o4,%o5,%o4    # addieren
  1239.           addx %g0,%g0,%g1      # neuer Carry
  1240.           subcc %o3,4,%o3
  1241.           bne 1b
  1242.          _ st %o4,[%o2+%o3]     # Digit ablegen
  1243. 2:      retl
  1244.        _ mov %g1,%o0
  1245. #endif
  1246. #if UNROLLED_LOOPS
  1247.         and %o3,7,%o4           # count mod 8
  1248.         sll %o4,2,%o5
  1249.         sub %o0,%o5,%o0         # %o0 = &sourceptr1[-(count mod 8)]
  1250.         sub %o1,%o5,%o1         # %o1 = &sourceptr2[-(count mod 8)]
  1251.         sub %o2,%o5,%o2         # %o2 = &destptr[-(count mod 8)]
  1252.         sll %o4,4,%o4
  1253.         set _add_loop_down+176,%o5
  1254.         sub %o4,%o5,%o5
  1255.         jmp %o5                 # Sprung nach _add_loop_down+4*(12+4*8-4*(count mod 8))
  1256.        _ subcc %g0,%g0,%g0      # carry l÷schen
  1257. 1:        subcc %g0,%g1,%g0     # carry
  1258.           ld [%o0+28],%o4       # source1-digit
  1259.           ld [%o1+28],%o5       # source2-digit
  1260.           addxcc %o5,%o4,%o5    # addieren
  1261.           st %o5,[%o2+28]       # Digit ablegen
  1262.           ld [%o0+24],%o4       # source1-digit
  1263.           ld [%o1+24],%o5       # source2-digit
  1264.           addxcc %o5,%o4,%o5    # addieren
  1265.           st %o5,[%o2+24]       # Digit ablegen
  1266.           ld [%o0+20],%o4       # source1-digit
  1267.           ld [%o1+20],%o5       # source2-digit
  1268.           addxcc %o5,%o4,%o5    # addieren
  1269.           st %o5,[%o2+20]       # Digit ablegen
  1270.           ld [%o0+16],%o4       # source1-digit
  1271.           ld [%o1+16],%o5       # source2-digit
  1272.           addxcc %o5,%o4,%o5    # addieren
  1273.           st %o5,[%o2+16]       # Digit ablegen
  1274.           ld [%o0+12],%o4       # source1-digit
  1275.           ld [%o1+12],%o5       # source2-digit
  1276.           addxcc %o5,%o4,%o5    # addieren
  1277.           st %o5,[%o2+12]       # Digit ablegen
  1278.           ld [%o0+8],%o4        # source1-digit
  1279.           ld [%o1+8],%o5        # source2-digit
  1280.           addxcc %o5,%o4,%o5    # addieren
  1281.           st %o5,[%o2+8]        # Digit ablegen
  1282.           ld [%o0+4],%o4        # source1-digit
  1283.           ld [%o1+4],%o5        # source2-digit
  1284.           addxcc %o5,%o4,%o5    # addieren
  1285.           st %o5,[%o2+4]        # Digit ablegen
  1286.           ld [%o0],%o4          # source1-digit
  1287.           ld [%o1],%o5          # source2-digit
  1288.           addxcc %o5,%o4,%o5    # addieren
  1289.           st %o5,[%o2]          # Digit ablegen
  1290.           addx %g0,%g0,%g1      # neuer Carry
  1291.           sub %o0,32,%o0
  1292.           sub %o1,32,%o1
  1293.           subcc %o3,8,%o3       # noch mindestens 8 Digits abzuarbeiten?
  1294.           bcc 1b
  1295.          _ sub %o2,32,%o2
  1296.         retl
  1297.        _ mov %g1,%o0
  1298. #endif
  1299.  
  1300. # extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  1301. C(addto_loop_down:) # Input in %o0,%o1,%o2, Output in %o0
  1302. #if STANDARD_LOOPS
  1303.         andcc %o2,%o2,%g0
  1304.         be 2f
  1305.        _ mov %g0,%o5            # Carry := 0
  1306.         sub %o0,4,%o0
  1307. 1:        ld [%o0],%o3          # source-digit
  1308.           sub %o1,4,%o1
  1309.           ld [%o1],%o4          # dest-digit
  1310.           subcc %g0,%o5,%g0     # carry
  1311.           addxcc %o4,%o3,%o4    # addieren
  1312.           addx %g0,%g0,%o5      # neuer Carry
  1313.           st %o4,[%o1]          # Digit ablegen
  1314.           subcc %o2,1,%o2
  1315.           bne 1b
  1316.          _ sub %o0,4,%o0
  1317. 2:      retl
  1318.        _ mov %o5,%o0
  1319. #endif
  1320. #if COUNTER_LOOPS
  1321.         andcc %o2,%o2,%g0
  1322.         be 2f
  1323.        _ mov %g0,%o5            # Carry := 0
  1324.         sub %o0,4,%o0
  1325.         sub %o1,4,%o1
  1326.         sll %o2,2,%o2           # %o2 = 4*count
  1327.         sub %o0,%o2,%o0         # %o0 = &sourceptr[-count-1]
  1328.         sub %o1,%o2,%o1         # %o1 = &destptr[-count-1]
  1329.           ld [%o0+%o2],%o3      # source-digit
  1330. 1:        ld [%o1+%o2],%o4      # dest-digit
  1331.           subcc %g0,%o5,%g0     # carry
  1332.           addxcc %o4,%o3,%o4    # addieren
  1333.           addx %g0,%g0,%o5      # neuer Carry
  1334.           st %o4,[%o1+%o2]      # Digit ablegen
  1335.           subcc %o2,4,%o2
  1336.           bne,a 1b
  1337.          __ ld [%o0+%o2],%o3    # source-digit
  1338. 2:      retl
  1339.        _ mov %o5,%o0
  1340. #endif
  1341. #if UNROLLED_LOOPS
  1342.         and %o2,7,%o3           # count mod 8
  1343.         sll %o3,2,%o4
  1344.         sub %o0,%o4,%o0         # %o0 = &sourceptr[-(count mod 8)]
  1345.         sub %o1,%o4,%o1         # %o1 = &destptr[-(count mod 8)]
  1346.         sll %o3,4,%o3
  1347.         set _addto_loop_down+172,%o4
  1348.         sub %o3,%o4,%o4
  1349.         jmp %o4                 # Sprung nach _addto_loop_down+4*(11+4*8-4*(count mod 8))
  1350.        _ subcc %g0,%g0,%g0      # carry l÷schen
  1351. 1:        subcc %g0,%o5,%g0     # carry
  1352.           ld [%o0+28],%o3       # source-digit
  1353.           ld [%o1+28],%o4       # dest-digit
  1354.           addxcc %o4,%o3,%o4    # addieren
  1355.           st %o4,[%o1+28]       # Digit ablegen
  1356.           ld [%o0+24],%o3       # source-digit
  1357.           ld [%o1+24],%o4       # dest-digit
  1358.           addxcc %o4,%o3,%o4    # addieren
  1359.           st %o4,[%o1+24]       # Digit ablegen
  1360.           ld [%o0+20],%o3       # source-digit
  1361.           ld [%o1+20],%o4       # dest-digit
  1362.           addxcc %o4,%o3,%o4    # addieren
  1363.           st %o4,[%o1+20]       # Digit ablegen
  1364.           ld [%o0+16],%o3       # source-digit
  1365.           ld [%o1+16],%o4       # dest-digit
  1366.           addxcc %o4,%o3,%o4    # addieren
  1367.           st %o4,[%o1+16]       # Digit ablegen
  1368.           ld [%o0+12],%o3       # source-digit
  1369.           ld [%o1+12],%o4       # dest-digit
  1370.           addxcc %o4,%o3,%o4    # addieren
  1371.           st %o4,[%o1+12]       # Digit ablegen
  1372.           ld [%o0+8],%o3        # source-digit
  1373.           ld [%o1+8],%o4        # dest-digit
  1374.           addxcc %o4,%o3,%o4    # addieren
  1375.           st %o4,[%o1+8]        # Digit ablegen
  1376.           ld [%o0+4],%o3        # source-digit
  1377.           ld [%o1+4],%o4        # dest-digit
  1378.           addxcc %o4,%o3,%o4    # addieren
  1379.           st %o4,[%o1+4]        # Digit ablegen
  1380.           ld [%o0],%o3          # source-digit
  1381.           ld [%o1],%o4          # dest-digit
  1382.           addxcc %o4,%o3,%o4    # addieren
  1383.           st %o4,[%o1]          # Digit ablegen
  1384.           addx %g0,%g0,%o5      # neuer Carry
  1385.           sub %o0,32,%o0
  1386.           subcc %o2,8,%o2       # noch mindestens 8 Digits abzuarbeiten?
  1387.           bcc 1b
  1388.          _ sub %o1,32,%o1
  1389.         retl
  1390.        _ mov %o5,%o0
  1391. #endif
  1392.  
  1393. # extern uintD inc_loop_down (uintD* ptr, uintC count);
  1394. C(inc_loop_down:) # Input in %o0,%o1, Output in %o0
  1395. #if STANDARD_LOOPS
  1396.         andcc %o1,%o1,%g0
  1397.         be 2f
  1398.        _ sub %o0,4,%o0
  1399. 1:        ld [%o0],%o2
  1400.           addcc %o2,1,%o2
  1401.           bne 3f
  1402.          _ st %o2,[%o0]
  1403.           subcc %o1,1,%o1
  1404.           bne 1b
  1405.          _ sub %o0,4,%o0
  1406. 2:      retl
  1407.        _ mov 1,%o0
  1408. 3:      retl
  1409.        _ mov 0,%o0
  1410. #endif
  1411. #if COUNTER_LOOPS
  1412.         andcc %o1,%o1,%g0
  1413.         be 2f
  1414.        _ sub %o0,4,%o0
  1415.         sll %o1,2,%o1           # %o1 = 4*count
  1416.         sub %o0,%o1,%o0         # %o0 = &ptr[-count-1]
  1417.           ld [%o0+%o1],%o2      # digit holen
  1418. 1:        addcc %o2,1,%o2       # incrementieren
  1419.           bne 3f
  1420.          _ st %o2,[%o0+%o1]     # ablegen
  1421.           subcc %o1,4,%o1       # ZΣhler erniedrigen, Pointer erniedrigen
  1422.           bne,a 1b
  1423.          __ ld [%o0+%o1],%o2
  1424. 2:      retl
  1425.        _ mov 1,%o0
  1426. 3:      retl
  1427.        _ mov 0,%o0
  1428. #endif
  1429.  
  1430. # extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
  1431. C(sub_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1, Output in %o0
  1432. #if STANDARD_LOOPS
  1433.         andcc %o3,%o3,%g0
  1434.         be 2f
  1435.        _ mov %g0,%g1            # Carry := 0
  1436.         sub %o0,4,%o0
  1437. 1:        ld [%o0],%o4          # source1-digit
  1438.           sub %o1,4,%o1
  1439.           ld [%o1],%o5          # source2-digit
  1440.           subcc %g0,%g1,%g0     # carry
  1441.           subxcc %o4,%o5,%o4    # subtrahieren
  1442.           addx %g0,%g0,%g1      # neuer Carry
  1443.           sub %o2,4,%o2
  1444.           st %o4,[%o2]          # Digit ablegen
  1445.           subcc %o3,1,%o3
  1446.           bne 1b
  1447.          _ sub %o0,4,%o0
  1448. 2:      retl
  1449.        _ mov %g1,%o0
  1450. #endif
  1451. #if COUNTER_LOOPS
  1452.         andcc %o3,%o3,%g0
  1453.         be 2f
  1454.        _ mov %g0,%g1            # Carry := 0
  1455.         sub %o0,4,%o0
  1456.         sub %o1,4,%o1
  1457.         sll %o3,2,%o3           # %o3 = 4*count
  1458.         sub %o0,%o3,%o0         # %o0 = &sourceptr1[-count-1]
  1459.         sub %o1,%o3,%o1         # %o1 = &sourceptr2[-count-1]
  1460.         sub %o2,%o3,%o2         # %o2 = &destptr[-count]
  1461. 1:        ld [%o0+%o3],%o4      # source1-digit
  1462.           ld [%o1+%o3],%o5      # source2-digit
  1463.           subcc %g0,%g1,%g0     # carry
  1464.           subxcc %o4,%o5,%o4    # subtrahieren
  1465.           addx %g0,%g0,%g1      # neuer Carry
  1466.           subcc %o3,4,%o3
  1467.           bne 1b
  1468.          _ st %o4,[%o2+%o3]     # Digit ablegen
  1469. 2:      retl
  1470.        _ mov %g1,%o0
  1471. #endif
  1472. #if UNROLLED_LOOPS
  1473.         and %o3,7,%o4           # count mod 8
  1474.         sll %o4,2,%o5
  1475.         sub %o0,%o5,%o0         # %o0 = &sourceptr1[-(count mod 8)]
  1476.         sub %o1,%o5,%o1         # %o1 = &sourceptr2[-(count mod 8)]
  1477.         sub %o2,%o5,%o2         # %o2 = &destptr[-(count mod 8)]
  1478.         sll %o4,4,%o4
  1479.         set _sub_loop_down+176,%o5
  1480.         sub %o4,%o5,%o5
  1481.         jmp %o5                 # Sprung nach _sub_loop_down+4*(12+4*8-4*(count mod 8))
  1482.        _ subcc %g0,%g0,%g0      # carry l÷schen
  1483. 1:        subcc %g0,%g1,%g0     # carry
  1484.           ld [%o0+28],%o4       # source1-digit
  1485.           ld [%o1+28],%o5       # source2-digit
  1486.           subxcc %o4,%o5,%o4    # subtrahieren
  1487.           st %o4,[%o2+28]       # Digit ablegen
  1488.           ld [%o0+24],%o4       # source1-digit
  1489.           ld [%o1+24],%o5       # source2-digit
  1490.           subxcc %o4,%o5,%o4    # subtrahieren
  1491.           st %o4,[%o2+24]       # Digit ablegen
  1492.           ld [%o0+20],%o4       # source1-digit
  1493.           ld [%o1+20],%o5       # source2-digit
  1494.           subxcc %o4,%o5,%o4    # subtrahieren
  1495.           st %o4,[%o2+20]       # Digit ablegen
  1496.           ld [%o0+16],%o4       # source1-digit
  1497.           ld [%o1+16],%o5       # source2-digit
  1498.           subxcc %o4,%o5,%o4    # subtrahieren
  1499.           st %o4,[%o2+16]       # Digit ablegen
  1500.           ld [%o0+12],%o4       # source1-digit
  1501.           ld [%o1+12],%o5       # source2-digit
  1502.           subxcc %o4,%o5,%o4    # subtrahieren
  1503.           st %o4,[%o2+12]       # Digit ablegen
  1504.           ld [%o0+8],%o4        # source1-digit
  1505.           ld [%o1+8],%o5        # source2-digit
  1506.           subxcc %o4,%o5,%o4    # subtrahieren
  1507.           st %o4,[%o2+8]        # Digit ablegen
  1508.           ld [%o0+4],%o4        # source1-digit
  1509.           ld [%o1+4],%o5        # source2-digit
  1510.           subxcc %o4,%o5,%o4    # subtrahieren
  1511.           st %o4,[%o2+4]        # Digit ablegen
  1512.           ld [%o0],%o4          # source1-digit
  1513.           ld [%o1],%o5          # source2-digit
  1514.           subxcc %o4,%o5,%o4    # subtrahieren
  1515.           st %o4,[%o2]          # Digit ablegen
  1516.           addx %g0,%g0,%g1      # neuer Carry
  1517.           sub %o0,32,%o0
  1518.           sub %o1,32,%o1
  1519.           subcc %o3,8,%o3       # noch mindestens 8 Digits abzuarbeiten?
  1520.           bcc 1b
  1521.          _ sub %o2,32,%o2
  1522.         retl
  1523.        _ mov %g1,%o0
  1524. #endif
  1525.  
  1526. # extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
  1527. C(subx_loop_down:) # Input in %o0,%o1,%o2,%o3,%o4, verΣndert %g1, Output in %o0
  1528. #if STANDARD_LOOPS
  1529.         andcc %o3,%o3,%g0
  1530.         be 2f
  1531.        _ mov %o4,%g1            # Carry
  1532.         sub %o0,4,%o0
  1533. 1:        ld [%o0],%o4          # source1-digit
  1534.           sub %o1,4,%o1
  1535.           ld [%o1],%o5          # source2-digit
  1536.           subcc %g0,%g1,%g0     # carry
  1537.           subxcc %o4,%o5,%o4    # subtrahieren
  1538.           addx %g0,%g0,%g1      # neuer Carry
  1539.           sub %o2,4,%o2
  1540.           st %o4,[%o2]          # Digit ablegen
  1541.           subcc %o3,1,%o3
  1542.           bne 1b
  1543.          _ sub %o0,4,%o0
  1544. 2:      retl
  1545.        _ mov %g1,%o0
  1546. #endif
  1547. #if COUNTER_LOOPS
  1548.         andcc %o3,%o3,%g0
  1549.         be 2f
  1550.        _ mov %o4,%g1            # Carry
  1551.         sub %o0,4,%o0
  1552.         sub %o1,4,%o1
  1553.         sll %o3,2,%o3           # %o3 = 4*count
  1554.         sub %o0,%o3,%o0         # %o0 = &sourceptr1[-count-1]
  1555.         sub %o1,%o3,%o1         # %o1 = &sourceptr2[-count-1]
  1556.         sub %o2,%o3,%o2         # %o2 = &destptr[-count]
  1557. 1:        ld [%o0+%o3],%o4      # source1-digit
  1558.           ld [%o1+%o3],%o5      # source2-digit
  1559.           subcc %g0,%g1,%g0     # carry
  1560.           subxcc %o4,%o5,%o4    # subtrahieren
  1561.           addx %g0,%g0,%g1      # neuer Carry
  1562.           subcc %o3,4,%o3
  1563.           bne 1b
  1564.          _ st %o4,[%o2+%o3]     # Digit ablegen
  1565. 2:      retl
  1566.        _ mov %g1,%o0
  1567. #endif
  1568. #if UNROLLED_LOOPS
  1569.         and %o3,7,%o5           # count mod 8
  1570.         sll %o5,2,%g1
  1571.         sub %o0,%g1,%o0         # %o0 = &sourceptr1[-(count mod 8)]
  1572.         sub %o1,%g1,%o1         # %o1 = &sourceptr2[-(count mod 8)]
  1573.         sub %o2,%g1,%o2         # %o2 = &destptr[-(count mod 8)]
  1574.         sll %o5,4,%o5
  1575.         set _subx_loop_down+176,%g1
  1576.         sub %o5,%g1,%g1
  1577.         jmp %g1                 # Sprung nach _subx_loop_down+4*(12+4*8-4*(count mod 8))
  1578.        _ subcc %g0,%o4,%g0      # carry initialisieren
  1579. 1:        subcc %g0,%g1,%g0     # carry
  1580.           ld [%o0+28],%o4       # source1-digit
  1581.           ld [%o1+28],%o5       # source2-digit
  1582.           subxcc %o4,%o5,%o4    # subtrahieren
  1583.           st %o4,[%o2+28]       # Digit ablegen
  1584.           ld [%o0+24],%o4       # source1-digit
  1585.           ld [%o1+24],%o5       # source2-digit
  1586.           subxcc %o4,%o5,%o4    # subtrahieren
  1587.           st %o4,[%o2+24]       # Digit ablegen
  1588.           ld [%o0+20],%o4       # source1-digit
  1589.           ld [%o1+20],%o5       # source2-digit
  1590.           subxcc %o4,%o5,%o4    # subtrahieren
  1591.           st %o4,[%o2+20]       # Digit ablegen
  1592.           ld [%o0+16],%o4       # source1-digit
  1593.           ld [%o1+16],%o5       # source2-digit
  1594.           subxcc %o4,%o5,%o4    # subtrahieren
  1595.           st %o4,[%o2+16]       # Digit ablegen
  1596.           ld [%o0+12],%o4       # source1-digit
  1597.           ld [%o1+12],%o5       # source2-digit
  1598.           subxcc %o4,%o5,%o4    # subtrahieren
  1599.           st %o4,[%o2+12]       # Digit ablegen
  1600.           ld [%o0+8],%o4        # source1-digit
  1601.           ld [%o1+8],%o5        # source2-digit
  1602.           subxcc %o4,%o5,%o4    # subtrahieren
  1603.           st %o4,[%o2+8]        # Digit ablegen
  1604.           ld [%o0+4],%o4        # source1-digit
  1605.           ld [%o1+4],%o5        # source2-digit
  1606.           subxcc %o4,%o5,%o4    # subtrahieren
  1607.           st %o4,[%o2+4]        # Digit ablegen
  1608.           ld [%o0],%o4          # source1-digit
  1609.           ld [%o1],%o5          # source2-digit
  1610.           subxcc %o4,%o5,%o4    # subtrahieren
  1611.           st %o4,[%o2]          # Digit ablegen
  1612.           addx %g0,%g0,%g1      # neuer Carry
  1613.           sub %o0,32,%o0
  1614.           sub %o1,32,%o1
  1615.           subcc %o3,8,%o3       # noch mindestens 8 Digits abzuarbeiten?
  1616.           bcc 1b
  1617.          _ sub %o2,32,%o2
  1618.         retl
  1619.        _ mov %g1,%o0
  1620. #endif
  1621.  
  1622. # extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
  1623. C(subfrom_loop_down:) # Input in %o0,%o1,%o2, Output in %o0
  1624. #if STANDARD_LOOPS
  1625.         andcc %o2,%o2,%g0
  1626.         be 2f
  1627.        _ mov %g0,%o5            # Carry := 0
  1628.         sub %o0,4,%o0
  1629. 1:        ld [%o0],%o3          # source-digit
  1630.           sub %o1,4,%o1
  1631.           ld [%o1],%o4          # dest-digit
  1632.           subcc %g0,%o5,%g0     # carry
  1633.           subxcc %o4,%o3,%o4    # subtrahieren
  1634.           addx %g0,%g0,%o5      # neuer Carry
  1635.           st %o4,[%o1]          # Digit ablegen
  1636.           subcc %o2,1,%o2
  1637.           bne 1b
  1638.          _ sub %o0,4,%o0
  1639. 2:      retl
  1640.        _ mov %o5,%o0
  1641. #endif
  1642. #if COUNTER_LOOPS
  1643.         andcc %o2,%o2,%g0
  1644.         be 2f
  1645.        _ mov %g0,%o5            # Carry := 0
  1646.         sub %o0,4,%o0
  1647.         sub %o1,4,%o1
  1648.         sll %o2,2,%o2           # %o2 = 4*count
  1649.         sub %o0,%o2,%o0         # %o0 = &sourceptr[-count-1]
  1650.         sub %o1,%o2,%o1         # %o1 = &destptr[-count-1]
  1651.           ld [%o0+%o2],%o3      # source-digit
  1652. 1:        ld [%o1+%o2],%o4      # dest-digit
  1653.           subcc %g0,%o5,%g0     # carry
  1654.           subxcc %o4,%o3,%o4    # subtrahieren
  1655.           addx %g0,%g0,%o5      # neuer Carry
  1656.           st %o4,[%o1+%o2]      # Digit ablegen
  1657.           subcc %o2,4,%o2
  1658.           bne,a 1b
  1659.          __ ld [%o0+%o2],%o3    # source-digit
  1660. 2:      retl
  1661.        _ mov %o5,%o0
  1662. #endif
  1663. #if UNROLLED_LOOPS
  1664.         and %o2,7,%o3           # count mod 8
  1665.         sll %o3,2,%o4
  1666.         sub %o0,%o4,%o0         # %o0 = &sourceptr[-(count mod 8)]
  1667.         sub %o1,%o4,%o1         # %o1 = &destptr[-(count mod 8)]
  1668.         sll %o3,4,%o3
  1669.         set _subfrom_loop_down+172,%o4
  1670.         sub %o3,%o4,%o4
  1671.         jmp %o4                 # Sprung nach _subfrom_loop_down+4*(11+4*8-4*(count mod 8))
  1672.        _ subcc %g0,%g0,%g0      # carry l÷schen
  1673. 1:        subcc %g0,%o5,%g0     # carry
  1674.           ld [%o0+28],%o3       # source-digit
  1675.           ld [%o1+28],%o4       # dest-digit
  1676.           subxcc %o4,%o3,%o4    # subtrahieren
  1677.           st %o4,[%o1+28]       # Digit ablegen
  1678.           ld [%o0+24],%o3       # source-digit
  1679.           ld [%o1+24],%o4       # dest-digit
  1680.           subxcc %o4,%o3,%o4    # subtrahieren
  1681.           st %o4,[%o1+24]       # Digit ablegen
  1682.           ld [%o0+20],%o3       # source-digit
  1683.           ld [%o1+20],%o4       # dest-digit
  1684.           subxcc %o4,%o3,%o4    # subtrahieren
  1685.           st %o4,[%o1+20]       # Digit ablegen
  1686.           ld [%o0+16],%o3       # source-digit
  1687.           ld [%o1+16],%o4       # dest-digit
  1688.           subxcc %o4,%o3,%o4    # subtrahieren
  1689.           st %o4,[%o1+16]       # Digit ablegen
  1690.           ld [%o0+12],%o3       # source-digit
  1691.           ld [%o1+12],%o4       # dest-digit
  1692.           subxcc %o4,%o3,%o4    # subtrahieren
  1693.           st %o4,[%o1+12]       # Digit ablegen
  1694.           ld [%o0+8],%o3        # source-digit
  1695.           ld [%o1+8],%o4        # dest-digit
  1696.           subxcc %o4,%o3,%o4    # subtrahieren
  1697.           st %o4,[%o1+8]        # Digit ablegen
  1698.           ld [%o0+4],%o3        # source-digit
  1699.           ld [%o1+4],%o4        # dest-digit
  1700.           subxcc %o4,%o3,%o4    # subtrahieren
  1701.           st %o4,[%o1+4]        # Digit ablegen
  1702.           ld [%o0],%o3          # source-digit
  1703.           ld [%o1],%o4          # dest-digit
  1704.           subxcc %o4,%o3,%o4    # subtrahieren
  1705.           st %o4,[%o1]          # Digit ablegen
  1706.           addx %g0,%g0,%o5      # neuer Carry
  1707.           sub %o0,32,%o0
  1708.           subcc %o2,8,%o2       # noch mindestens 8 Digits abzuarbeiten?
  1709.           bcc 1b
  1710.          _ sub %o1,32,%o1
  1711.         retl
  1712.        _ mov %o5,%o0
  1713. #endif
  1714.  
  1715. # extern uintD dec_loop_down (uintD* ptr, uintC count);
  1716. C(dec_loop_down:) # Input in %o0,%o1, Output in %o0
  1717. #if STANDARD_LOOPS
  1718.         andcc %o1,%o1,%g0
  1719.         be 2f
  1720.        _ sub %o0,4,%o0
  1721. 1:        ld [%o0],%o2
  1722.           subcc %o2,1,%o2
  1723.           bcc 3f
  1724.          _ st %o2,[%o0]
  1725.           subcc %o1,1,%o1
  1726.           bne 1b
  1727.          _ sub %o0,4,%o0
  1728. 2:      retl
  1729.        _ mov -1,%o0
  1730. 3:      retl
  1731.        _ mov 0,%o0
  1732. #endif
  1733. #if COUNTER_LOOPS
  1734.         andcc %o1,%o1,%g0
  1735.         be 2f
  1736.        _ sub %o0,4,%o0
  1737.         sll %o1,2,%o1           # %o1 = 4*count
  1738.         sub %o0,%o1,%o0         # %o0 = &ptr[-count-1]
  1739.           ld [%o0+%o1],%o2      # digit holen
  1740. 1:        subcc %o2,1,%o2       # incrementieren
  1741.           bcc 3f
  1742.          _ st %o2,[%o0+%o1]     # ablegen
  1743.           subcc %o1,4,%o1       # ZΣhler erniedrigen, Pointer erniedrigen
  1744.           bne,a 1b
  1745.          __ ld [%o0+%o1],%o2
  1746. 2:      retl
  1747.        _ mov -1,%o0
  1748. 3:      retl
  1749.        _ mov 0,%o0
  1750. #endif
  1751.  
  1752. # extern uintD neg_loop_down (uintD* ptr, uintC count);
  1753. C(neg_loop_down:) # Input in %o0,%o1, Output in %o0
  1754. #if STANDARD_LOOPS
  1755.         # erstes Digit /=0 suchen:
  1756.         andcc %o1,%o1,%g0
  1757.         be 2f
  1758.        _ sub %o0,4,%o0
  1759. 1:        ld [%o0],%o2
  1760.           subcc %g0,%o2,%o2
  1761.           bne 3f
  1762.          _ subcc %o1,1,%o1
  1763.           bne 1b
  1764.          _ sub %o0,4,%o0
  1765. 2:      retl
  1766.        _ mov 0,%o0
  1767. 3:      # erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
  1768.         st %o2,[%o0]            # 1 Digit negieren
  1769.         # alle anderen Digits invertieren:
  1770.         be 5f
  1771.        _ sub %o0,4,%o0
  1772. 4:        ld [%o0],%o2
  1773.           subcc %o1,1,%o1
  1774.           xor %o2,-1,%o2
  1775.           st %o2,[%o0]
  1776.           bne 4b
  1777.          _ sub %o0,4,%o0
  1778. 5:      retl
  1779.        _ mov -1,%o0
  1780. #endif
  1781. #if COUNTER_LOOPS
  1782.         # erstes Digit /=0 suchen:
  1783.         andcc %o1,%o1,%g0
  1784.         be 2f
  1785.        _ sub %o0,4,%o0
  1786.         sll %o1,2,%o1           # %o1 = 4*count
  1787.         sub %o0,%o1,%o0         # %o0 = &ptr[-count-1]
  1788.           ld [%o0+%o1],%o2      # digit holen
  1789. 1:        subcc %g0,%o2,%o2     # negieren, testen
  1790.           bne,a 3f
  1791.          __ st %o2,[%o0+%o1]    # ablegen
  1792.           subcc %o1,4,%o1       # ZΣhler erniedrigen, Pointer erniedrigen
  1793.           bne,a 1b
  1794.          __ ld [%o0+%o1],%o2
  1795. 2:      retl
  1796.        _ mov 0,%o0
  1797. 3:      # erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
  1798.         # alle anderen Digits invertieren:
  1799.         subcc %o1,4,%o1
  1800.         be 5f
  1801.        _ ld [%o0+%o1],%o2
  1802. 4:        subcc %o1,4,%o1
  1803.           xor %o2,-1,%o2
  1804.           st %o2,[%o0+%o1]
  1805.           bne,a 4b
  1806.          __ ld [%o0+%o1],%o2
  1807. 5:      retl
  1808.        _ mov -1,%o0
  1809. #endif
  1810.  
  1811. # extern uintD shift1left_loop_down (uintD* ptr, uintC count);
  1812. C(shift1left_loop_down:) # Input in %o0,%o1, Output in %o0
  1813.         andcc %o1,%o1,%g0
  1814.         be 2f
  1815.        _ mov 0,%o3              # Carry := 0
  1816.         sub %o0,4,%o0
  1817. 1:        ld [%o0],%o2          # Digit
  1818.           subcc %g0,%o3,%g0     # carry
  1819.           addxcc %o2,%o2,%o2    # shiften
  1820.           addx %g0,%g0,%o3      # neues Carry
  1821.           st %o2,[%o0]          # Digit ablegen
  1822.           subcc %o1,1,%o1
  1823.           bne 1b
  1824.          _ sub %o0,4,%o0
  1825. 2:      retl
  1826.        _ mov %o3,%o0
  1827.  
  1828. # extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
  1829. C(shiftleft_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1, Output in %o0
  1830.         andcc %o1,%o1,%g0
  1831.         be 2f
  1832.        _ sub %g0,%o2,%g1        # 32-i (mod 32)
  1833.         sub %o0,4,%o0
  1834. 1:        ld [%o0],%o4          # Digit
  1835.           subcc %o1,1,%o1
  1836.           sll %o4,%o2,%o5       # dessen niedere (32-i) Bits
  1837.           or %o3,%o5,%o5        # mit dem alten Carry kombinieren
  1838.           st %o5,[%o0]          # Digit ablegen
  1839.           srl %o4,%g1,%o3       # dessen h÷chste i Bits liefern den neuen Carry
  1840.           bne 1b
  1841.          _ sub %o0,4,%o0
  1842. 2:      retl
  1843.        _ mov %o3,%o0
  1844.  
  1845. # extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
  1846. C(shiftleftcopy_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1,%g2, Output in %o0
  1847.         andcc %o2,%o2,%g0
  1848.         be 2f
  1849.        _ mov 0,%o4              # Carry := 0
  1850.         sub %g0,%o3,%g1         # 32-i (mod 32)
  1851.         sub %o0,4,%o0
  1852. 1:        ld [%o0],%o5          # Digit
  1853.           subcc %o2,1,%o2
  1854.           sll %o5,%o3,%g2       # dessen niedere (32-i) Bits
  1855.           or %o4,%g2,%g2        # mit dem alten Carry kombinieren
  1856.           sub %o1,4,%o1
  1857.           st %g2,[%o1]          # Digit ablegen
  1858.           srl %o5,%g1,%o4       # dessen h÷chste i Bits liefern den neuen Carry
  1859.           bne 1b
  1860.          _ sub %o0,4,%o0
  1861. 2:      retl
  1862.        _ mov %o4,%o0
  1863.  
  1864. # extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
  1865. C(shift1right_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
  1866.         andcc %o1,%o1,%g0
  1867.         be 2f
  1868.        _ sll %o2,31,%o2         # Carry
  1869. 1:        ld [%o0],%o3          # Digit
  1870.           subcc %o1,1,%o1
  1871.           srl %o3,1,%o4         # shiften
  1872.           or %o2,%o4,%o4        # und mit altem Carry kombinieren
  1873.           st %o4,[%o0]          # und ablegen
  1874.           sll %o3,31,%o2        # neuer Carry
  1875.           bne 1b
  1876.          _ add %o0,4,%o0
  1877. 2:      retl
  1878.        _ mov %o2,%o0
  1879.  
  1880. # extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
  1881. C(shiftright_loop_up:) # Input in %o0,%o1,%o2, verΣndert %g1, Output in %o0
  1882.         sub %g0,%o2,%g1         # 32-i (mod 32)
  1883.         andcc %o1,%o1,%g0
  1884.         be 2f
  1885.        _ or %g0,%g0,%o3         # Carry := 0
  1886. 1:        ld [%o0],%o4          # Digit
  1887.           subcc %o1,1,%o1
  1888.           srl %o4,%o2,%o5       # shiften
  1889.           or %o3,%o5,%o5        # und mit altem Carry kombinieren
  1890.           st %o5,[%o0]          # und ablegen
  1891.           sll %o4,%g1,%o3       # neuer Carry
  1892.           bne 1b
  1893.          _ add %o0,4,%o0
  1894. 2:      retl
  1895.        _ mov %o3,%o0
  1896.  
  1897. # extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
  1898. C(shiftrightsigned_loop_up:) # Input in %o0,%o1,%o2, verΣndert %g1, Output in %o0
  1899.         ld [%o0],%o4            # erstes Digit
  1900.         sub %g0,%o2,%g1         # 32-i (mod 32)
  1901.         sra %o4,%o2,%o5         # shiften
  1902.         st %o5,[%o0]            # und ablegen
  1903.         sll %o4,%g1,%o3         # neuer Carry
  1904.         subcc %o1,1,%o1
  1905.         be 2f
  1906.        _ add %o0,4,%o0
  1907. 1:        ld [%o0],%o4          # Digit
  1908.           subcc %o1,1,%o1
  1909.           srl %o4,%o2,%o5       # shiften
  1910.           or %o3,%o5,%o5        # und mit altem Carry kombinieren
  1911.           st %o5,[%o0]          # und ablegen
  1912.           sll %o4,%g1,%o3       # neuer Carry
  1913.           bne 1b
  1914.          _ add %o0,4,%o0
  1915. 2:      retl
  1916.        _ mov %o3,%o0
  1917.  
  1918. # extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
  1919. C(shiftrightcopy_loop_up:) # Input in %o0,%o1,%o2,%o3,%o4, verΣndert %g1,%g2, Output in %o0
  1920.         sub %g0,%o3,%g1         # 32-i (mod 32)
  1921.         andcc %o2,%o2,%g0
  1922.         be 2f
  1923.        _ sll %o4,%g1,%g2        # erster Carry
  1924. 1:        ld [%o0],%o4          # Digit
  1925.           add %o0,4,%o0
  1926.           srl %o4,%o3,%o5       # shiften
  1927.           or %g2,%o5,%o5        # und mit altem Carry kombinieren
  1928.           st %o5,[%o1]          # und ablegen
  1929.           sll %o4,%g1,%g2       # neuer Carry
  1930.           subcc %o2,1,%o2
  1931.           bne 1b
  1932.          _ add %o1,4,%o1
  1933. 2:      retl
  1934.        _ mov %g2,%o0
  1935.  
  1936. # extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
  1937. C(mulusmall_loop_down:) # Input in %o0,%o1,%o2,%o3, Output in %o0
  1938.         andcc %o2,%o2,%g0
  1939.         be 3f
  1940.        _ sub %o1,4,%o1
  1941. 1:        # nΣchstes Digit [%o1] mit der 6-Bit-Zahl %o0 multiplizieren
  1942.           # und kleinen Carry %o3 dazu:
  1943.           mov %o0,%y
  1944.           ld [%o1],%o4          # Wartetakt!
  1945.           addcc %o3,%o3,%o5
  1946.           mulscc %o5,%o4,%o5
  1947.           mulscc %o5,%o4,%o5
  1948.           mulscc %o5,%o4,%o5
  1949.           mulscc %o5,%o4,%o5
  1950.           mulscc %o5,%o4,%o5
  1951.           mulscc %o5,%o4,%o5
  1952.           mulscc %o5,%g0,%o5
  1953.           # Die 26 unteren Bits von %o5 und die 6 oberen Bits von %y
  1954.           # ergeben das Resultat. (Die anderen Bits sind Null.)
  1955.           tst %o4               # Korrektur, falls %o4 negativ war
  1956.           bge 2f
  1957.          _ sra %o5,26,%o3       # 6 obere Bits von %o5 -> neuer Carry
  1958.           add %o3,%o0,%o3       # (falls %o4 negativ war, noch + %o0)
  1959. 2:        rd %y,%o4
  1960.           srl %o4,26,%o4        # 6 obere Bits von %y
  1961.           sll %o5,6,%o5         # 26 untere Bits von %o5
  1962.           or %o5,%o4,%o4        # neues Digit
  1963.           st %o4,[%o1]          # ablegen
  1964.           subcc %o2,1,%o2
  1965.           bne 1b
  1966.          _ sub %o1,4,%o1
  1967. 3:      retl
  1968.        _ mov %o3,%o0
  1969.  
  1970. # extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  1971. #if !MULU32_INLINE
  1972. C(mulu_loop_down:) # Input in %i0,%i1,%i2,%i3
  1973.         save %sp,-96,%sp
  1974.         mov 0,%l0               # Carry
  1975. 1:        sub %i1,4,%i1
  1976.           ld [%i1],%o1          # nΣchstes Digit
  1977.           call _mulu32_         # mit digit multiplizieren
  1978.          _ mov %i0,%o0
  1979.           addcc %l0,%o0,%o0     # und bisherigen Carry addieren
  1980.           addx %g0,%g1,%l0      # High-Digit gibt neuen Carry
  1981.           sub %i2,4,%i2
  1982.           subcc %i3,1,%i3
  1983.           bne 1b
  1984.          _ st %o0,[%i2]         # Low-Digit ablegen
  1985.         st %l0,[%i2-4]          # letzten Carry ablegen
  1986.         ret
  1987.        _ restore
  1988. #else
  1989. C(mulu_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1
  1990.         mov 0,%o4               # Carry
  1991. 1:        ld [%o1-4],%g1        # nΣchstes Digit
  1992.           # mit digit multiplizieren: %o0 * %g1 -> %o5|%g1
  1993. #ifdef sparcv8
  1994.           sub     %o1,4,%o1
  1995.           umul    %g1,%o0,%g1
  1996.           rd      %y,%o5
  1997. #else
  1998.           mov     %g1,%y
  1999.           sub     %o1,4,%o1     # Wartetakt!
  2000.           andcc   %g0,%g0,%o5
  2001.           mulscc  %o5,%o0,%o5
  2002.           mulscc  %o5,%o0,%o5
  2003.           mulscc  %o5,%o0,%o5
  2004.           mulscc  %o5,%o0,%o5
  2005.           mulscc  %o5,%o0,%o5
  2006.           mulscc  %o5,%o0,%o5
  2007.           mulscc  %o5,%o0,%o5
  2008.           mulscc  %o5,%o0,%o5
  2009.           mulscc  %o5,%o0,%o5
  2010.           mulscc  %o5,%o0,%o5
  2011.           mulscc  %o5,%o0,%o5
  2012.           mulscc  %o5,%o0,%o5
  2013.           mulscc  %o5,%o0,%o5
  2014.           mulscc  %o5,%o0,%o5
  2015.           mulscc  %o5,%o0,%o5
  2016.           mulscc  %o5,%o0,%o5
  2017.           mulscc  %o5,%o0,%o5
  2018.           mulscc  %o5,%o0,%o5
  2019.           mulscc  %o5,%o0,%o5
  2020.           mulscc  %o5,%o0,%o5
  2021.           mulscc  %o5,%o0,%o5
  2022.           mulscc  %o5,%o0,%o5
  2023.           mulscc  %o5,%o0,%o5
  2024.           mulscc  %o5,%o0,%o5
  2025.           mulscc  %o5,%o0,%o5
  2026.           mulscc  %o5,%o0,%o5
  2027.           mulscc  %o5,%o0,%o5
  2028.           mulscc  %o5,%o0,%o5
  2029.           mulscc  %o5,%o0,%o5
  2030.           mulscc  %o5,%o0,%o5
  2031.           mulscc  %o5,%o0,%o5
  2032.           mulscc  %o5,%o0,%o5
  2033.           mulscc  %o5,%g0,%o5
  2034.           tst     %o0
  2035.           bl,a    2f
  2036.          __ add     %o5,%g1,%o5
  2037. 2:        rd      %y,%g1
  2038. #endif
  2039.           addcc %o4,%g1,%g1     # und bisherigen Carry addieren
  2040.           addx %g0,%o5,%o4      # High-Digit gibt neuen Carry
  2041.           sub %o2,4,%o2
  2042.           subcc %o3,1,%o3
  2043.           bne 1b
  2044.          _ st %g1,[%o2]         # Low-Digit ablegen
  2045.         retl
  2046.        _ st %o4,[%o2-4]         # letzten Carry ablegen
  2047. #endif
  2048.  
  2049. # extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  2050. C(muluadd_loop_down:) # Input in %i0,%i1,%i2,%i3, Output in %i0
  2051. #if !MULU32_INLINE
  2052.         save %sp,-96,%sp
  2053.         mov 0,%l0               # Carry
  2054. 1:        sub %i1,4,%i1
  2055.           ld [%i1],%o1          # nΣchstes source-Digit
  2056.           call _mulu32_         # mit digit multiplizieren
  2057.          _ mov %i0,%o0
  2058.           sub %i2,4,%i2
  2059.           ld [%i2],%o1          # nΣchstes dest-digit
  2060.           addcc %l0,%o0,%o0     # und bisherigen Carry addieren
  2061.           addx %g0,%g1,%l0      # High-Digit gibt neuen Carry
  2062.           addcc %o1,%o0,%o0     # addieren
  2063.           addx %g0,%l0,%l0
  2064.           subcc %i3,1,%i3
  2065.           bne 1b
  2066.          _ st %o0,[%i2]         # Low-Digit ablegen
  2067.         mov %l0,%i0             # letzter Carry
  2068.         ret
  2069.        _ restore
  2070. #else
  2071.         save %sp,-96,%sp
  2072.         mov 0,%l0               # Carry
  2073. #ifndef sparcv8
  2074.         sra %i0,31,%l1          # 0 falls %i0>=0, -1 falls %i0<0
  2075. #endif
  2076. 1:        ld [%i1-4],%o1        # nΣchstes source-Digit
  2077.           sub %i1,4,%i1
  2078.           # mit digit multiplizieren: %i0 * %o1 -> %o2|%o0
  2079. #ifdef sparcv8
  2080.           umul    %i0,%o1,%o0
  2081.           rd      %y,%o2
  2082. #else
  2083.           mov     %o1,%y
  2084.           and     %o1,%l1,%o3   # Wartetakt!
  2085.           andcc   %g0,%g0,%o2
  2086.           mulscc  %o2,%i0,%o2
  2087.           mulscc  %o2,%i0,%o2
  2088.           mulscc  %o2,%i0,%o2
  2089.           mulscc  %o2,%i0,%o2
  2090.           mulscc  %o2,%i0,%o2
  2091.           mulscc  %o2,%i0,%o2
  2092.           mulscc  %o2,%i0,%o2
  2093.           mulscc  %o2,%i0,%o2
  2094.           mulscc  %o2,%i0,%o2
  2095.           mulscc  %o2,%i0,%o2
  2096.           mulscc  %o2,%i0,%o2
  2097.           mulscc  %o2,%i0,%o2
  2098.           mulscc  %o2,%i0,%o2
  2099.           mulscc  %o2,%i0,%o2
  2100.           mulscc  %o2,%i0,%o2
  2101.           mulscc  %o2,%i0,%o2
  2102.           mulscc  %o2,%i0,%o2
  2103.           mulscc  %o2,%i0,%o2
  2104.           mulscc  %o2,%i0,%o2
  2105.           mulscc  %o2,%i0,%o2
  2106.           mulscc  %o2,%i0,%o2
  2107.           mulscc  %o2,%i0,%o2
  2108.           mulscc  %o2,%i0,%o2
  2109.           mulscc  %o2,%i0,%o2
  2110.           mulscc  %o2,%i0,%o2
  2111.           mulscc  %o2,%i0,%o2
  2112.           mulscc  %o2,%i0,%o2
  2113.           mulscc  %o2,%i0,%o2
  2114.           mulscc  %o2,%i0,%o2
  2115.           mulscc  %o2,%i0,%o2
  2116.           mulscc  %o2,%i0,%o2
  2117.           mulscc  %o2,%i0,%o2
  2118.           mulscc  %o2,%g0,%o2
  2119.           add     %o2,%o3,%o2   # %o3 = (0 falls %i0>=0, %o1 falls %i0<0)
  2120.           rd      %y,%o0
  2121. #endif
  2122.           sub %i2,4,%i2
  2123.           ld [%i2],%o1          # nΣchstes dest-digit
  2124.           addcc %l0,%o0,%o0     # und bisherigen Carry addieren
  2125.           addx %g0,%o2,%l0      # High-Digit gibt neuen Carry
  2126.           addcc %o1,%o0,%o0     # addieren
  2127.           addx %g0,%l0,%l0
  2128.           subcc %i3,1,%i3
  2129.           bne 1b
  2130.          _ st %o0,[%i2]         # Low-Digit ablegen
  2131.         mov %l0,%i0             # letzter Carry
  2132.         ret
  2133.        _ restore
  2134. #endif
  2135.  
  2136. # extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  2137. C(mulusub_loop_down:) # Input in %i0,%i1,%i2,%i3, Output in %i0
  2138. #if !MULU32_INLINE
  2139.         save %sp,-96,%sp
  2140.         mov 0,%l0               # Carry
  2141. 1:        sub %i1,4,%i1
  2142.           ld [%i1],%o1          # nΣchstes source-Digit
  2143.           call _mulu32_         # mit digit multiplizieren
  2144.          _ mov %i0,%o0
  2145.           sub %i2,4,%i2
  2146.           ld [%i2],%o1          # nΣchstes dest-digit
  2147.           addcc %l0,%o0,%o0     # und bisherigen Carry addieren
  2148.           addx %g0,%g1,%l0      # High-Digit gibt neuen Carry
  2149.           subcc %o1,%o0,%o1     # davon das Low-Digit subtrahieren
  2150.           addx %g0,%l0,%l0
  2151.           subcc %i3,1,%i3
  2152.           bne 1b
  2153.          _ st %o1,[%i2]         # dest-Digit ablegen
  2154.         mov %l0,%i0             # letzter Carry
  2155.         ret
  2156.        _ restore
  2157. #else
  2158.         save %sp,-96,%sp
  2159.         mov 0,%l0               # Carry
  2160. #ifndef sparcv8
  2161.         sra %i0,31,%l1          # 0 falls %i0>=0, -1 falls %i0<0
  2162. #endif
  2163. 1:        ld [%i1-4],%o1        # nΣchstes source-Digit
  2164.           sub %i1,4,%i1
  2165.           # mit digit multiplizieren: %i0 * %o1 -> %o2|%o0
  2166. #ifdef sparcv8
  2167.           umul    %i0,%o1,%o0
  2168.           rd      %y,%o2
  2169. #else
  2170.           mov     %o1,%y
  2171.           and     %o1,%l1,%o3   # Wartetakt!
  2172.           andcc   %g0,%g0,%o2
  2173.           mulscc  %o2,%i0,%o2
  2174.           mulscc  %o2,%i0,%o2
  2175.           mulscc  %o2,%i0,%o2
  2176.           mulscc  %o2,%i0,%o2
  2177.           mulscc  %o2,%i0,%o2
  2178.           mulscc  %o2,%i0,%o2
  2179.           mulscc  %o2,%i0,%o2
  2180.           mulscc  %o2,%i0,%o2
  2181.           mulscc  %o2,%i0,%o2
  2182.           mulscc  %o2,%i0,%o2
  2183.           mulscc  %o2,%i0,%o2
  2184.           mulscc  %o2,%i0,%o2
  2185.           mulscc  %o2,%i0,%o2
  2186.           mulscc  %o2,%i0,%o2
  2187.           mulscc  %o2,%i0,%o2
  2188.           mulscc  %o2,%i0,%o2
  2189.           mulscc  %o2,%i0,%o2
  2190.           mulscc  %o2,%i0,%o2
  2191.           mulscc  %o2,%i0,%o2
  2192.           mulscc  %o2,%i0,%o2
  2193.           mulscc  %o2,%i0,%o2
  2194.           mulscc  %o2,%i0,%o2
  2195.           mulscc  %o2,%i0,%o2
  2196.           mulscc  %o2,%i0,%o2
  2197.           mulscc  %o2,%i0,%o2
  2198.           mulscc  %o2,%i0,%o2
  2199.           mulscc  %o2,%i0,%o2
  2200.           mulscc  %o2,%i0,%o2
  2201.           mulscc  %o2,%i0,%o2
  2202.           mulscc  %o2,%i0,%o2
  2203.           mulscc  %o2,%i0,%o2
  2204.           mulscc  %o2,%i0,%o2
  2205.           mulscc  %o2,%g0,%o2
  2206.           add     %o2,%o3,%o2   # %o3 = (0 falls %i0>=0, %o1 falls %i0<0)
  2207.           rd      %y,%o0
  2208. #endif
  2209.           sub %i2,4,%i2
  2210.           ld [%i2],%o1          # nΣchstes dest-digit
  2211.           addcc %l0,%o0,%o0     # und bisherigen Carry addieren
  2212.           addx %g0,%o2,%l0      # High-Digit gibt neuen Carry
  2213.           subcc %o1,%o0,%o1     # davon das Low-Digit subtrahieren
  2214.           addx %g0,%l0,%l0
  2215.           subcc %i3,1,%i3
  2216.           bne 1b
  2217.          _ st %o1,[%i2]         # dest-Digit ablegen
  2218.         mov %l0,%i0             # letzter Carry
  2219.         ret
  2220.        _ restore
  2221. #endif
  2222.  
  2223. # extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
  2224. C(divu_loop_up:) # Input in %i0,%i1,%i2, Output in %i0
  2225.         save %sp,-96,%sp
  2226.         andcc %i2,%i2,%g0
  2227.         be 2f
  2228.        _ mov 0,%g1                 # Rest
  2229. 1:        mov %g1,%o0              # Rest als High-Digit
  2230.           ld [%i1],%o1             # nΣchstes Digit als Low-Digit
  2231.           call C(divu_6432_3232_)  # zusammen durch digit dividieren
  2232.          _ mov %i0,%o2
  2233.           st %o0,[%i1]             # Quotient ablegen, Rest in %g1
  2234.           subcc %i2,1,%i2
  2235.           bne 1b
  2236.          _ add %i1,4,%i1
  2237. 2:      mov %g1,%i0                # Rest als Ergebnis
  2238.         ret
  2239.        _ restore
  2240.  
  2241. # extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
  2242. C(divucopy_loop_up:) # Input in %i0,%i1,%i2,%i3, Output in %i0
  2243.         save %sp,-96,%sp
  2244.         andcc %i3,%i3,%g0
  2245.         be 2f
  2246.        _ mov 0,%g1                 # Rest
  2247. 1:        mov %g1,%o0              # Rest als High-Digit
  2248.           ld [%i1],%o1             # nΣchstes Digit als Low-Digit
  2249.           call C(divu_6432_3232_)  # zusammen durch digit dividieren
  2250.          _ mov %i0,%o2
  2251.           st %o0,[%i2]             # Quotient ablegen, Rest in %g1
  2252.           add %i1,4,%i1
  2253.           subcc %i3,1,%i3
  2254.           bne 1b
  2255.          _ add %i2,4,%i2
  2256. 2:      mov %g1,%i0                # Rest als Ergebnis
  2257.         ret
  2258.        _ restore
  2259.  
  2260. #endif
  2261.  
  2262.