home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-04 | 77.7 KB | 2,262 lines |
- # Externe Routinen zu ARILEV1.D
- # Prozessor: SPARC
- # Compiler: GNU-C oder SUN-C
- # Parameter-▄bergabe: in Registern %o0-%o5.
- # Einstellungen: intCsize=32, intDsize=32.
-
- #ifdef INCLUDED_FROM_C
-
- #define COPY_LOOPS
- #define FILL_LOOPS
- #define CLEAR_LOOPS
- #define LOG_LOOPS
- #define TEST_LOOPS
- #define ADDSUB_LOOPS
- #define SHIFT_LOOPS
- #define MUL_LOOPS
- #define DIV_LOOPS
-
- #else
-
- #if defined(sparc_v8) || defined(__sparc_v8) || defined(__sparc_v8__)
- #define sparcv8
- #endif
-
- #ifdef UNDERSCORE /* SunOS 4 */
- #ifdef __STDC__
- #define C(entrypoint) _##entrypoint
- #else
- #define C(entrypoint) _/**/entrypoint
- #endif
- #else /* SunOS 5 = Solaris 2 */
- #define C(entrypoint) entrypoint
- #endif
-
- # Indikatoren fⁿr Anweisungen (Instruktionen) in Delay-Slots
- # (diese werden VOR der vorigen Instruktion ausgefⁿhrt):
- #define _ # Instruktion, die stets ausgefⁿhrt wird
- #define __ # Instruktion, die nur im Sprung-Fall ausgefⁿhrt wird
- # Abkⁿrzungen fⁿr Anweisungen:
- #define ret jmp %i7+8 # return from subroutine
- #define retl jmp %o7+8 # return from leaf subroutine (no save/restore)
-
- .seg "text"
-
- .global C(mulu16_),C(mulu32_),C(mulu32_unchecked)
- .global C(divu_6432_3232_),C(divu_3216_1616_)
- .global C(copy_loop_up),C(copy_loop_down),C(fill_loop_up),C(fill_loop_down)
- .global C(clear_loop_up),C(clear_loop_down)
- .global C(or_loop_up),C(xor_loop_up),C(and_loop_up),C(eqv_loop_up)
- .global C(nand_loop_up),C(nor_loop_up),C(andc2_loop_up),C(orc2_loop_up)
- .global C(not_loop_up)
- .global C(and_test_loop_up),C(test_loop_up),C(compare_loop_up)
- .global C(add_loop_down),C(addto_loop_down),C(inc_loop_down)
- .global C(sub_loop_down),C(subx_loop_down),C(subfrom_loop_down),C(dec_loop_down)
- .global C(neg_loop_down)
- .global C(shift1left_loop_down),C(shiftleft_loop_down),C(shiftleftcopy_loop_down)
- .global C(shift1right_loop_up),C(shiftright_loop_up),C(shiftrightsigned_loop_up),C(shiftrightcopy_loop_up)
- .global C(mulusmall_loop_down),C(mulu_loop_down),C(muluadd_loop_down),C(mulusub_loop_down)
- .global C(divu_loop_up),C(divucopy_loop_up)
-
- #define LOOP_TYPE 1 # 1: Standard-Schleifen
- # 2: Schleifen ohne Pointer, nur mit ZΣhler
- # 3: entrollte Schleifen
- #define STANDARD_LOOPS (LOOP_TYPE==1)
- #define COUNTER_LOOPS (LOOP_TYPE==2)
- #define UNROLLED_LOOPS (LOOP_TYPE==3)
- #define MULU32_INLINE 1 # 1: mulu32-Aufrufe inline in die Schleifen
-
- # extern uint32 mulu16_ (uint16 arg1, uint16 arg2);
- # ergebnis := arg1*arg2.
- C(mulu16_:) # Input in %o0,%o1, Output in %o0
- #ifdef sparcv8
- umul %o0,%o1,%o0
- retl
- _ nop
- #else
- mov %o1,%y
- nop # Wartetakt, n÷tig z.B. fⁿr SUN SPARCstation IPC
- andcc %g0,%g0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- # Die 17 unteren Bits von %o2 und die 15 oberen Bits von %y
- # ergeben das Resultat. (Die anderen Bits sind Null.)
- rd %y,%o0
- srl %o0,17,%o0
- sll %o2,15,%o2
- retl
- _ or %o2,%o0,%o0
- #endif
-
- # extern struct { uint32 lo; uint32 hi; } mulu32_ (uint32 arg1, uint32 arg2);
- # 2^32*hi+lo := arg1*arg2.
- C(mulu32_:) # Input in %o0,%o1, Output in %o0,%g1
- #ifdef sparcv8
- umul %o0,%o1,%o0
- retl
- _ rd %y,%g1
- #else
- mov %o1,%y
- sra %o0,31,%o3 # Wartetakt, n÷tig z.B. fⁿr SUN SPARCstation IPC
- andcc %g0,%g0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%g0,%o2
- and %o3,%o1,%o3 # %o3 = (0 falls %o0>=0, %o1 falls %o0<0)
- add %o2,%o3,%g1 # hi
- retl
- _ rd %y,%o0 # lo
- #endif
-
- # extern uint32 mulu32_unchecked (uint32 x, uint32 y);
- # ergebnis := arg1*arg2 < 2^32.
- C(mulu32_unchecked:) # Input in %o0,%o1, Output in %o0
- #ifdef sparcv8
- umul %o0,%o1,%o0
- retl
- _ nop
- #else
- subcc %o0,%o1,%g0
- bcc,a 1f
- __ mov %o1,%y
- # arg1 < arg2, also kann man arg1 < 2^16 annehmen.
- mov %o0,%y
- nop # Wartetakt, n÷tig z.B. fⁿr SUN SPARCstation IPC
- andcc %g0,%g0,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- mulscc %o2,%o1,%o2
- # Die 17 unteren Bits von %o2 und die 15 oberen Bits von %y
- # ergeben das Resultat. (Die anderen Bits sind Null.)
- rd %y,%o0
- srl %o0,17,%o0
- sll %o2,15,%o2
- retl
- _ or %o2,%o0,%o0
- 1: # arg1 >= arg2, also kann man arg2 < 2^16 annehmen.
- nop # Wartetakt, n÷tig z.B. fⁿr SUN SPARCstation IPC
- andcc %g0,%g0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- mulscc %o2,%o0,%o2
- # Die 17 unteren Bits von %o2 und die 15 oberen Bits von %y
- # ergeben das Resultat.
- rd %y,%o0
- srl %o0,17,%o0
- sll %o2,15,%o2
- retl
- _ or %o2,%o0,%o0
- #endif
-
- # extern struct { uint32 q; uint32 r; } divu_6432_3232_ (uint32 xhi, uint32 xlo, uint32 y);
- # x = 2^32*xhi+xlo = q*y+r schreiben. Sei bekannt, da▀ 0 <= x < 2^32*y .
- C(divu_6432_3232_:) # Input in %o0,%o1,%o2, Output in %o0,%g1
- #ifdef sparcv8
- wr %o0,%g0,%y
- udiv %o1,%o2,%o0 # x durch y dividieren, %o0 := q
- umul %o0,%o2,%g1 # %g1 := (q*y) mod 2^32
- retl
- _ sub %o1,%g1,%g1 # %g1 := (xlo-q*y) mod 2^32 = r
- #else
- # %o0 = xhi, %o1 = xlo, %o2 = y
- # Divisions-Einzelschritte:
- # %o0|%o1 wird jeweils um 1 Bit nach links geschoben,
- # dafⁿr wird rechts in %o1 ein Ergebnisbit (negiert!) reingeschoben.
- # Je nachdem wird mit %o3|%o1 statt %o0|%o1 weitergemacht (spart 1 'mov').
- # Deswegen mu▀ man den Code doppelt vorsehen: einmal mit %o0, einmal mit %o3.
- #define SA0(label) # Vergleichsschritt mit %o0 \
- subcc %o0,%o2,%o3; \
- bcc label; \
- _ addxcc %o1,%o1,%o1
- #define SA1(label) # Vergleichsschritt mit %o3 \
- subcc %o3,%o2,%o0; \
- bcc label; \
- _ addxcc %o1,%o1,%o1
- #define SB0() # Additionsschritt mit %o0 \
- addx %o0,%o0,%o0
- #define SB1() # Additionsschritt mit %o3 \
- addx %o3,%o3,%o3
- # Los geht's:
- addcc %o2,%o2,%g0 # y = %o2 < 2^31 ?
- bcc Lsmalldiv # ja -> "kleine" Division
- _ andcc %o2,1,%g0 # y = %o2 gerade ?
- be Levendiv # ja -> Division durch gerade Zahl
- _ srl %o2,1,%o2
- # Division durch ungerade Zahl:
- # floor(x / (2*y'-1)) = floor(floor(x/2) / y') + (0 oder 1 oder 2)
- # da 0 <= x/(2*y'-1) - x/(2*y') = x/(2*y'-1) / (2*y') = x/y / (2*y')
- # < 2^32 / (2*y') < 2^32/y <= 2 .
- add %o2,1,%o2 # %o2 = ceiling(y/2) = y'
- # Man spart im Vergleich zu Lsmalldiv
- # zu Beginn eine Verdoppelung von %o0|%o1 : addcc %o1,%o1,%o1; SB0()
- # dafⁿr am Schlu▀ mehr zu tun...
- SA0(Lb01) # Bit 31 des Quotienten bestimmen
- La01: SB0(); SA0(Lb02) # Bit 30 des Quotienten bestimmen
- La02: SB0(); SA0(Lb03) # Bit 29 des Quotienten bestimmen
- La03: SB0(); SA0(Lb04) # Bit 28 des Quotienten bestimmen
- La04: SB0(); SA0(Lb05) # Bit 27 des Quotienten bestimmen
- La05: SB0(); SA0(Lb06) # Bit 26 des Quotienten bestimmen
- La06: SB0(); SA0(Lb07) # Bit 25 des Quotienten bestimmen
- La07: SB0(); SA0(Lb08) # Bit 24 des Quotienten bestimmen
- La08: SB0(); SA0(Lb09) # Bit 23 des Quotienten bestimmen
- La09: SB0(); SA0(Lb10) # Bit 22 des Quotienten bestimmen
- La10: SB0(); SA0(Lb11) # Bit 21 des Quotienten bestimmen
- La11: SB0(); SA0(Lb12) # Bit 20 des Quotienten bestimmen
- La12: SB0(); SA0(Lb13) # Bit 19 des Quotienten bestimmen
- La13: SB0(); SA0(Lb14) # Bit 18 des Quotienten bestimmen
- La14: SB0(); SA0(Lb15) # Bit 17 des Quotienten bestimmen
- La15: SB0(); SA0(Lb16) # Bit 16 des Quotienten bestimmen
- La16: SB0(); SA0(Lb17) # Bit 15 des Quotienten bestimmen
- La17: SB0(); SA0(Lb18) # Bit 14 des Quotienten bestimmen
- La18: SB0(); SA0(Lb19) # Bit 13 des Quotienten bestimmen
- La19: SB0(); SA0(Lb20) # Bit 12 des Quotienten bestimmen
- La20: SB0(); SA0(Lb21) # Bit 11 des Quotienten bestimmen
- La21: SB0(); SA0(Lb22) # Bit 10 des Quotienten bestimmen
- La22: SB0(); SA0(Lb23) # Bit 9 des Quotienten bestimmen
- La23: SB0(); SA0(Lb24) # Bit 8 des Quotienten bestimmen
- La24: SB0(); SA0(Lb25) # Bit 7 des Quotienten bestimmen
- La25: SB0(); SA0(Lb26) # Bit 6 des Quotienten bestimmen
- La26: SB0(); SA0(Lb27) # Bit 5 des Quotienten bestimmen
- La27: SB0(); SA0(Lb28) # Bit 4 des Quotienten bestimmen
- La28: SB0(); SA0(Lb29) # Bit 3 des Quotienten bestimmen
- La29: SB0(); SA0(Lb30) # Bit 2 des Quotienten bestimmen
- La30: SB0(); SA0(Lb31) # Bit 1 des Quotienten bestimmen
- La31: SB0(); SA0(Lb32) # Bit 0 des Quotienten bestimmen
- La32: SB0() # %o0 = x mod (2*y')
- xor %o1,-1,%o1 # %o1 = floor( floor(x/2) / y') = floor(x/(2*y'))
- add %o2,%o2,%o2
- sub %o2,1,%o2 # wieder %o2 = 2*y'-1 = y
- # Quotient und Rest umrechnen:
- # x = %o1 * 2*y' + %o0 = %o1 * (2*y'-1) + (%o0+%o1)
- # Also Quotient = %o1, Rest = %o0+%o1.
- # Noch maximal 2 mal: Quotient += 1, Rest -= y.
- addcc %o1,%o0,%o0 # Rest mod y bestimmen
- bcc 1f # Additions-▄berlauf -> Quotient erh÷hen
- _ subcc %o0,%o2,%o3
- subcc %o3,%o2,%o0 # mu▀ der Quotient nochmals erh÷ht werden?
- bcs 2f
- _ mov %o3,%g1
- # Quotient 2 mal erh÷hen, Rest %o0
- mov %o0,%g1
- retl
- _ add %o1,2,%o0
- 1: # kein Additions-▄berlauf.
- # Wegen y>=2^31 mu▀ der Quotient noch h÷chstens 1 mal erh÷ht werden:
- bcs 3f # %o0 < %o2 -> Rest %o0 und Quotient %o1 OK
- _ mov %o3,%g1
- 2: # Quotient %o1 erh÷hen, Rest = %o0-%o2 = %o3
- retl
- _ add %o1,1,%o0
- 3: # Quotient %o1 und Rest %o0 OK
- mov %o0,%g1
- retl
- _ mov %o1,%o0
- # Parallelschiene zu La01..La32:
- Lb01: SB1(); SA1(La02)
- Lb02: SB1(); SA1(La03)
- Lb03: SB1(); SA1(La04)
- Lb04: SB1(); SA1(La05)
- Lb05: SB1(); SA1(La06)
- Lb06: SB1(); SA1(La07)
- Lb07: SB1(); SA1(La08)
- Lb08: SB1(); SA1(La09)
- Lb09: SB1(); SA1(La10)
- Lb10: SB1(); SA1(La11)
- Lb11: SB1(); SA1(La12)
- Lb12: SB1(); SA1(La13)
- Lb13: SB1(); SA1(La14)
- Lb14: SB1(); SA1(La15)
- Lb15: SB1(); SA1(La16)
- Lb16: SB1(); SA1(La17)
- Lb17: SB1(); SA1(La18)
- Lb18: SB1(); SA1(La19)
- Lb19: SB1(); SA1(La20)
- Lb20: SB1(); SA1(La21)
- Lb21: SB1(); SA1(La22)
- Lb22: SB1(); SA1(La23)
- Lb23: SB1(); SA1(La24)
- Lb24: SB1(); SA1(La25)
- Lb25: SB1(); SA1(La26)
- Lb26: SB1(); SA1(La27)
- Lb27: SB1(); SA1(La28)
- Lb28: SB1(); SA1(La29)
- Lb29: SB1(); SA1(La30)
- Lb30: SB1(); SA1(La31)
- Lb31: SB1(); SA1(La32)
- Lb32: SB1() # %o3 = x mod (2*y')
- xor %o1,-1,%o1 # %o1 = floor( floor(x/2) / y') = floor(x/(2*y'))
- add %o2,%o2,%o2
- sub %o2,1,%o2 # wieder %o2 = 2*y'-1 = y
- # Quotient und Rest umrechnen:
- # x = %o1 * 2*y' + %o3 = %o1 * (2*y'-1) + (%o3+%o1)
- # Also Quotient = %o1, Rest = %o3+%o1.
- # Noch maximal 2 mal: Quotient += 1, Rest -= y.
- addcc %o1,%o3,%o3 # Rest mod y bestimmen
- bcc 1f # Additions-▄berlauf -> Quotient erh÷hen
- _ subcc %o3,%o2,%o0
- subcc %o0,%o2,%o3 # mu▀ der Quotient nochmals erh÷ht werden?
- bcs 2f
- _ mov %o0,%g1
- # Quotient 2 mal erh÷hen, Rest %o3
- mov %o3,%g1
- retl
- _ add %o1,2,%o0
- 1: # kein Additions-▄berlauf.
- # Wegen y>=2^31 mu▀ der Quotient noch h÷chstens 1 mal erh÷ht werden:
- bcs 3f # %o3 < %o2 -> Rest %o3 und Quotient %o1 OK
- _ mov %o0,%g1
- 2: # Quotient %o1 erh÷hen, Rest = %o3-%o2 = %o0
- retl
- _ add %o1,1,%o0
- 3: # Quotient %o1 und Rest %o3 OK
- mov %o3,%g1
- retl
- _ mov %o1,%o0
- Lsmalldiv: # Division durch y < 2^31
- addcc %o1,%o1,%o1
- Lc00: SB0(); SA0(Ld01) # Bit 31 des Quotienten bestimmen
- Lc01: SB0(); SA0(Ld02) # Bit 30 des Quotienten bestimmen
- Lc02: SB0(); SA0(Ld03) # Bit 29 des Quotienten bestimmen
- Lc03: SB0(); SA0(Ld04) # Bit 28 des Quotienten bestimmen
- Lc04: SB0(); SA0(Ld05) # Bit 27 des Quotienten bestimmen
- Lc05: SB0(); SA0(Ld06) # Bit 26 des Quotienten bestimmen
- Lc06: SB0(); SA0(Ld07) # Bit 25 des Quotienten bestimmen
- Lc07: SB0(); SA0(Ld08) # Bit 24 des Quotienten bestimmen
- Lc08: SB0(); SA0(Ld09) # Bit 23 des Quotienten bestimmen
- Lc09: SB0(); SA0(Ld10) # Bit 22 des Quotienten bestimmen
- Lc10: SB0(); SA0(Ld11) # Bit 21 des Quotienten bestimmen
- Lc11: SB0(); SA0(Ld12) # Bit 20 des Quotienten bestimmen
- Lc12: SB0(); SA0(Ld13) # Bit 19 des Quotienten bestimmen
- Lc13: SB0(); SA0(Ld14) # Bit 18 des Quotienten bestimmen
- Lc14: SB0(); SA0(Ld15) # Bit 17 des Quotienten bestimmen
- Lc15: SB0(); SA0(Ld16) # Bit 16 des Quotienten bestimmen
- Lc16: SB0(); SA0(Ld17) # Bit 15 des Quotienten bestimmen
- Lc17: SB0(); SA0(Ld18) # Bit 14 des Quotienten bestimmen
- Lc18: SB0(); SA0(Ld19) # Bit 13 des Quotienten bestimmen
- Lc19: SB0(); SA0(Ld20) # Bit 12 des Quotienten bestimmen
- Lc20: SB0(); SA0(Ld21) # Bit 11 des Quotienten bestimmen
- Lc21: SB0(); SA0(Ld22) # Bit 10 des Quotienten bestimmen
- Lc22: SB0(); SA0(Ld23) # Bit 9 des Quotienten bestimmen
- Lc23: SB0(); SA0(Ld24) # Bit 8 des Quotienten bestimmen
- Lc24: SB0(); SA0(Ld25) # Bit 7 des Quotienten bestimmen
- Lc25: SB0(); SA0(Ld26) # Bit 6 des Quotienten bestimmen
- Lc26: SB0(); SA0(Ld27) # Bit 5 des Quotienten bestimmen
- Lc27: SB0(); SA0(Ld28) # Bit 4 des Quotienten bestimmen
- Lc28: SB0(); SA0(Ld29) # Bit 3 des Quotienten bestimmen
- Lc29: SB0(); SA0(Ld30) # Bit 2 des Quotienten bestimmen
- Lc30: SB0(); SA0(Ld31) # Bit 1 des Quotienten bestimmen
- Lc31: SB0(); SA0(Ld32) # Bit 0 des Quotienten bestimmen
- Lc32: mov %o0,%g1 # Rest aus %o0 in %g1 abspeichern
- retl
- _ xor %o1,-1,%o0 # Quotient nach %o0
- # Parallelschiene zu Lc01..Lc32:
- Ld01: SB1(); SA1(Lc02)
- Ld02: SB1(); SA1(Lc03)
- Ld03: SB1(); SA1(Lc04)
- Ld04: SB1(); SA1(Lc05)
- Ld05: SB1(); SA1(Lc06)
- Ld06: SB1(); SA1(Lc07)
- Ld07: SB1(); SA1(Lc08)
- Ld08: SB1(); SA1(Lc09)
- Ld09: SB1(); SA1(Lc10)
- Ld10: SB1(); SA1(Lc11)
- Ld11: SB1(); SA1(Lc12)
- Ld12: SB1(); SA1(Lc13)
- Ld13: SB1(); SA1(Lc14)
- Ld14: SB1(); SA1(Lc15)
- Ld15: SB1(); SA1(Lc16)
- Ld16: SB1(); SA1(Lc17)
- Ld17: SB1(); SA1(Lc18)
- Ld18: SB1(); SA1(Lc19)
- Ld19: SB1(); SA1(Lc20)
- Ld20: SB1(); SA1(Lc21)
- Ld21: SB1(); SA1(Lc22)
- Ld22: SB1(); SA1(Lc23)
- Ld23: SB1(); SA1(Lc24)
- Ld24: SB1(); SA1(Lc25)
- Ld25: SB1(); SA1(Lc26)
- Ld26: SB1(); SA1(Lc27)
- Ld27: SB1(); SA1(Lc28)
- Ld28: SB1(); SA1(Lc29)
- Ld29: SB1(); SA1(Lc30)
- Ld30: SB1(); SA1(Lc31)
- Ld31: SB1(); SA1(Lc32)
- Ld32: mov %o3,%g1 # Rest aus %o3 in %g1 abspeichern
- retl
- _ xor %o1,-1,%o0 # Quotient nach %o0
- Levendiv: # Division durch gerades y.
- # x/2 durch y/2 dividieren, Quotient OK, Rest evtl. mit 2 multiplizieren.
- # Es ist schon %o2 = y/2.
- # Man spart im Vergleich zu Lsmalldiv
- # zu Beginn eine Verdoppelung von %o0|%o1 : addcc %o1,%o1,%o1; SB0()
- # dafⁿr am Schlu▀ Bit 0 von x zum Rest dazuschieben.
- SA0(Lf01) # Bit 31 des Quotienten bestimmen
- Le01: SB0(); SA0(Lf02) # Bit 30 des Quotienten bestimmen
- Le02: SB0(); SA0(Lf03) # Bit 29 des Quotienten bestimmen
- Le03: SB0(); SA0(Lf04) # Bit 28 des Quotienten bestimmen
- Le04: SB0(); SA0(Lf05) # Bit 27 des Quotienten bestimmen
- Le05: SB0(); SA0(Lf06) # Bit 26 des Quotienten bestimmen
- Le06: SB0(); SA0(Lf07) # Bit 25 des Quotienten bestimmen
- Le07: SB0(); SA0(Lf08) # Bit 24 des Quotienten bestimmen
- Le08: SB0(); SA0(Lf09) # Bit 23 des Quotienten bestimmen
- Le09: SB0(); SA0(Lf10) # Bit 22 des Quotienten bestimmen
- Le10: SB0(); SA0(Lf11) # Bit 21 des Quotienten bestimmen
- Le11: SB0(); SA0(Lf12) # Bit 20 des Quotienten bestimmen
- Le12: SB0(); SA0(Lf13) # Bit 19 des Quotienten bestimmen
- Le13: SB0(); SA0(Lf14) # Bit 18 des Quotienten bestimmen
- Le14: SB0(); SA0(Lf15) # Bit 17 des Quotienten bestimmen
- Le15: SB0(); SA0(Lf16) # Bit 16 des Quotienten bestimmen
- Le16: SB0(); SA0(Lf17) # Bit 15 des Quotienten bestimmen
- Le17: SB0(); SA0(Lf18) # Bit 14 des Quotienten bestimmen
- Le18: SB0(); SA0(Lf19) # Bit 13 des Quotienten bestimmen
- Le19: SB0(); SA0(Lf20) # Bit 12 des Quotienten bestimmen
- Le20: SB0(); SA0(Lf21) # Bit 11 des Quotienten bestimmen
- Le21: SB0(); SA0(Lf22) # Bit 10 des Quotienten bestimmen
- Le22: SB0(); SA0(Lf23) # Bit 9 des Quotienten bestimmen
- Le23: SB0(); SA0(Lf24) # Bit 8 des Quotienten bestimmen
- Le24: SB0(); SA0(Lf25) # Bit 7 des Quotienten bestimmen
- Le25: SB0(); SA0(Lf26) # Bit 6 des Quotienten bestimmen
- Le26: SB0(); SA0(Lf27) # Bit 5 des Quotienten bestimmen
- Le27: SB0(); SA0(Lf28) # Bit 4 des Quotienten bestimmen
- Le28: SB0(); SA0(Lf29) # Bit 3 des Quotienten bestimmen
- Le29: SB0(); SA0(Lf30) # Bit 2 des Quotienten bestimmen
- Le30: SB0(); SA0(Lf31) # Bit 1 des Quotienten bestimmen
- Le31: SB0(); SA0(Lf32) # Bit 0 des Quotienten bestimmen
- Le32: SB0() # Bit 0 des Restes bestimmen
- mov %o0,%g1 # Rest aus %o0 in %g1 abspeichern
- retl
- _ xor %o1,-1,%o0 # Quotient nach %o0
- # Parallelschiene zu Le01..Le32:
- Lf01: SB1(); SA1(Le02)
- Lf02: SB1(); SA1(Le03)
- Lf03: SB1(); SA1(Le04)
- Lf04: SB1(); SA1(Le05)
- Lf05: SB1(); SA1(Le06)
- Lf06: SB1(); SA1(Le07)
- Lf07: SB1(); SA1(Le08)
- Lf08: SB1(); SA1(Le09)
- Lf09: SB1(); SA1(Le10)
- Lf10: SB1(); SA1(Le11)
- Lf11: SB1(); SA1(Le12)
- Lf12: SB1(); SA1(Le13)
- Lf13: SB1(); SA1(Le14)
- Lf14: SB1(); SA1(Le15)
- Lf15: SB1(); SA1(Le16)
- Lf16: SB1(); SA1(Le17)
- Lf17: SB1(); SA1(Le18)
- Lf18: SB1(); SA1(Le19)
- Lf19: SB1(); SA1(Le20)
- Lf20: SB1(); SA1(Le21)
- Lf21: SB1(); SA1(Le22)
- Lf22: SB1(); SA1(Le23)
- Lf23: SB1(); SA1(Le24)
- Lf24: SB1(); SA1(Le25)
- Lf25: SB1(); SA1(Le26)
- Lf26: SB1(); SA1(Le27)
- Lf27: SB1(); SA1(Le28)
- Lf28: SB1(); SA1(Le29)
- Lf29: SB1(); SA1(Le30)
- Lf30: SB1(); SA1(Le31)
- Lf31: SB1(); SA1(Le32)
- Lf32: SB1()
- mov %o3,%g1 # Rest aus %o0 in %g1 abspeichern
- retl
- _ xor %o1,-1,%o0 # Quotient nach %o0
- #endif
-
- # extern struct { uint16 q; uint16 r; } divu_3216_1616_ (uint32 x, uint16 y);
- # x = q*y+r schreiben. Sei bekannt, da▀ 0 <= x < 2^16*y .
- C(divu_3216_1616_:) # Input in %o0,%o1, Output in %o0 (Rest und Quotient).
- #ifdef sparcv8
- wry %g0,%g0,%y
- udiv %o0,%o1,%o0 # dividieren, Quotient nach %o0
- rd %y,%o1 # Rest aus %y
- sll %o1,16,%o1 # in die oberen 16 Bit schieben
- retl
- _ orl %o0,%o1,%o0
- #else
- # %o0 = x, %o1 = y
- # Divisions-Einzelschritte:
- # %o0 wird jeweils um 1 Bit nach links geschoben,
- # dafⁿr wird rechts in %o1 ein Ergebnisbit (negiert!) reingeschoben.
- # Dann wird auf >= 2^15*y verglichen (nicht auf >= 2^16*y, weil man dann das
- # links herausgeschobene Bit mit vergleichen mⁿ▀te!)
- sll %o1,16,%o1
- srl %o1,1,%o1 # 2^15*y
- sub %g0,%o1,%o2 # zum Addieren statt Subtrahieren: -2^15*y
- # SC0(label) subtrahiert y, schiebt Carry-Bit rechts in %o0 rein
- # (1 falls Subtraktion aufging, 0 sonst).
- # Ging die Subtraktion nicht auf, so mⁿ▀te man noch 2*y addieren.
- # Das fa▀t man mit der nΣchsten Operation zusammen, indem man - statt
- # y zu subtrahieren - y addiert:
- # SC1(label) addiert y, schiebt Carry-Bit rechts in %o0 rein
- # (1 falls Subtraktion aufgegangen wΣre, man also wieder im
- # "positiven Bereich" landet, 0 sonst).
- #define SC0(label) \
- addcc %o0,%o2,%o0; \
- bcc label; \
- _ addx %o0,%o0,%o0
- #define SC1(label) \
- addcc %o0,%o1,%o0; \
- bcs label; \
- _ addx %o0,%o0,%o0
- SC0(Lh01) # Bit 15 des Quotienten bestimmen
- Lg01: SC0(Lh02) # Bit 14 des Quotienten bestimmen
- Lg02: SC0(Lh03) # Bit 13 des Quotienten bestimmen
- Lg03: SC0(Lh04) # Bit 12 des Quotienten bestimmen
- Lg04: SC0(Lh05) # Bit 11 des Quotienten bestimmen
- Lg05: SC0(Lh06) # Bit 10 des Quotienten bestimmen
- Lg06: SC0(Lh07) # Bit 9 des Quotienten bestimmen
- Lg07: SC0(Lh08) # Bit 8 des Quotienten bestimmen
- Lg08: SC0(Lh09) # Bit 7 des Quotienten bestimmen
- Lg09: SC0(Lh10) # Bit 6 des Quotienten bestimmen
- Lg10: SC0(Lh11) # Bit 5 des Quotienten bestimmen
- Lg11: SC0(Lh12) # Bit 4 des Quotienten bestimmen
- Lg12: SC0(Lh13) # Bit 3 des Quotienten bestimmen
- Lg13: SC0(Lh14) # Bit 2 des Quotienten bestimmen
- Lg14: SC0(Lh15) # Bit 1 des Quotienten bestimmen
- Lg15: SC0(Lh16) # Bit 0 des Quotienten bestimmen
- Lg16: # Die oberen 16 Bit von %o0 sind der Rest,
- # die unteren 16 Bit von %o0 sind der Quotient.
- retl
- _ nop
- Lh01: SC1(Lg02) # Bit 14 des Quotienten bestimmen
- Lh02: SC1(Lg03) # Bit 13 des Quotienten bestimmen
- Lh03: SC1(Lg04) # Bit 12 des Quotienten bestimmen
- Lh04: SC1(Lg05) # Bit 11 des Quotienten bestimmen
- Lh05: SC1(Lg06) # Bit 10 des Quotienten bestimmen
- Lh06: SC1(Lg07) # Bit 9 des Quotienten bestimmen
- Lh07: SC1(Lg08) # Bit 8 des Quotienten bestimmen
- Lh08: SC1(Lg09) # Bit 7 des Quotienten bestimmen
- Lh09: SC1(Lg10) # Bit 6 des Quotienten bestimmen
- Lh10: SC1(Lg11) # Bit 5 des Quotienten bestimmen
- Lh11: SC1(Lg12) # Bit 4 des Quotienten bestimmen
- Lh12: SC1(Lg13) # Bit 3 des Quotienten bestimmen
- Lh13: SC1(Lg14) # Bit 2 des Quotienten bestimmen
- Lh14: SC1(Lg15) # Bit 1 des Quotienten bestimmen
- Lh15: SC1(Lg16) # Bit 0 des Quotienten bestimmen
- Lh16: # Noch 2*y addieren:
- add %o0,%o1,%o0
- retl
- _ add %o0,%o1,%o0
- #endif
-
- # extern uintD* copy_loop_up (uintD* sourceptr, uintD* destptr, uintC count);
- C(copy_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- add %o0,4,%o0
- st %o3,[%o1]
- subcc %o2,1,%o2
- bne 1b
- _ add %o1,4,%o1
- 2: retl
- _ mov %o1,%o0
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o1,4,%o1
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &sourceptr[count]
- sub %o1,%o2,%o1 # %o1 = &destptr[count-1]
- 1: ld [%o0+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ add %o1,4,%o0
- #endif
-
- # extern uintD* copy_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
- C(copy_loop_down:) # Input in %o0,%o1,%o2, Output in %o0
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ sub %o0,4,%o0
- 1: ld [%o0],%o3
- sub %o1,4,%o1
- st %o3,[%o1]
- subcc %o2,1,%o2
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %o1,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = 4*count
- sub %o0,%o2,%o0 # %o0 = &sourceptr[-count-1]
- sub %o1,%o2,%o1 # %o1 = &destptr[-count]
- 1: ld [%o0+%o2],%o3 # nΣchstes Digit holen
- subcc %o2,4,%o2 # ZΣhler erniedrigen, Pointer erniedrigen
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ mov %o1,%o0
- #endif
-
- # extern uintD* fill_loop_up (uintD* destptr, uintC count, uintD filler);
- C(fill_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
- #if STANDARD_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ nop
- 1: st %o2,[%o0]
- subcc %o1,1,%o1
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o1,%o1 # %o1 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o1,2,%o1 # %o1 = -4*count
- sub %o0,%o1,%o0 # %o0 = &destptr[count-1]
- 1: addcc %o1,4,%o1 # ZΣhler "erniedrigen", Pointer erh÷hen
- bne 1b
- _ st %o2,[%o0+%o1] # Digit ablegen
- 2: retl
- _ add %o0,4,%o0
- #endif
-
- # extern uintD* fill_loop_down (uintD* destptr, uintC count, uintD filler);
- C(fill_loop_down:) # Input in %o0,%o1,%o2, Output in %o0
- #if STANDARD_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ sub %o0,4,%o0
- 1: st %o2,[%o0]
- subcc %o1,1,%o1
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ add %o0,4,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ sll %o1,2,%o1 # %o1 = 4*count
- sub %o0,%o1,%o0 # %o0 = &destptr[-count]
- 1: subcc %o1,4,%o1 # ZΣhler erniedrigen, Pointer erniedrigen
- bne 1b
- _ st %o2,[%o0+%o1] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern uintD* clear_loop_up (uintD* destptr, uintC count);
- C(clear_loop_up:) # Input in %o0,%o1, Output in %o0
- #if STANDARD_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ nop
- 1: st %g0,[%o0]
- subcc %o1,1,%o1
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o1,%o1 # %o1 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o1,2,%o1 # %o1 = -4*count
- sub %o0,%o1,%o0 # %o0 = &destptr[count-1]
- 1: addcc %o1,4,%o1 # ZΣhler "erniedrigen", Pointer erh÷hen
- bne 1b
- _ st %g0,[%o0+%o1] # Digit 0 ablegen
- 2: retl
- _ add %o0,4,%o0
- #endif
-
- # extern uintD* clear_loop_down (uintD* destptr, uintC count);
- C(clear_loop_down:) # Input in %o0,%o1, Output in %o0
- #if STANDARD_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ sub %o0,4,%o0
- 1: st %g0,[%o0]
- subcc %o1,1,%o1
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ add %o0,4,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ sll %o1,2,%o1 # %o1 = 4*count
- sub %o0,%o1,%o0 # %o0 = &destptr[-count]
- 1: subcc %o1,4,%o1 # ZΣhler erniedrigen, Pointer erniedrigen
- bne 1b
- _ st %g0,[%o0+%o1] # Digit 0 ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void or_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(or_loop_up:) # Input in %o0,%o1,%o2
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o1,4,%o1
- or %o3,%o4,%o3
- st %o3,[%o0]
- subcc %o2,1,%o2
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count-1]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- 1: ld [%o1+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o2],%o4 # noch ein Digit holen
- or %o4,%o3,%o3 # beide verknⁿpfen
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void xor_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(xor_loop_up:) # Input in %o0,%o1,%o2
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o1,4,%o1
- xor %o3,%o4,%o3
- st %o3,[%o0]
- subcc %o2,1,%o2
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count-1]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- 1: ld [%o1+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o2],%o4 # noch ein Digit holen
- xor %o4,%o3,%o3 # beide verknⁿpfen
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void and_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(and_loop_up:) # Input in %o0,%o1,%o2
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o1,4,%o1
- and %o3,%o4,%o3
- st %o3,[%o0]
- subcc %o2,1,%o2
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count-1]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- 1: ld [%o1+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o2],%o4 # noch ein Digit holen
- and %o4,%o3,%o3 # beide verknⁿpfen
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void eqv_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(eqv_loop_up:) # Input in %o0,%o1,%o2
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o1,4,%o1
- xnor %o3,%o4,%o3
- st %o3,[%o0]
- subcc %o2,1,%o2
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count-1]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- 1: ld [%o1+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o2],%o4 # noch ein Digit holen
- xnor %o4,%o3,%o3 # beide verknⁿpfen
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void nand_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(nand_loop_up:) # Input in %o0,%o1,%o2
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o1,4,%o1
- and %o3,%o4,%o3
- xor %o3,-1,%o3
- st %o3,[%o0]
- subcc %o2,1,%o2
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count-1]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- 1: ld [%o1+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o2],%o4 # noch ein Digit holen
- and %o4,%o3,%o3 # beide verknⁿpfen
- xor %o3,-1,%o3
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void nor_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(nor_loop_up:) # Input in %o0,%o1,%o2
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o1,4,%o1
- or %o3,%o4,%o3
- xor %o3,-1,%o3
- st %o3,[%o0]
- subcc %o2,1,%o2
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count-1]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- 1: ld [%o1+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o2],%o4 # noch ein Digit holen
- or %o4,%o3,%o3 # beide verknⁿpfen
- xor %o3,-1,%o3
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void andc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(andc2_loop_up:) # Input in %o0,%o1,%o2
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o1,4,%o1
- andn %o3,%o4,%o3
- st %o3,[%o0]
- subcc %o2,1,%o2
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count-1]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- 1: ld [%o1+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o2],%o4 # noch ein Digit holen
- andn %o4,%o3,%o3 # beide verknⁿpfen
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void orc2_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(orc2_loop_up:) # Input in %o0,%o1,%o2
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o1,4,%o1
- xor %o4,-1,%o4
- or %o3,%o4,%o3
- st %o3,[%o0]
- subcc %o2,1,%o2
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count-1]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- 1: ld [%o1+%o2],%o3 # nΣchstes Digit holen
- addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o2],%o4 # noch ein Digit holen
- xor %o3,-1,%o3
- or %o4,%o3,%o3 # beide verknⁿpfen
- bne 1b
- _ st %o3,[%o1+%o2] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern void not_loop_up (uintD* xptr, uintC count);
- C(not_loop_up:) # Input in %o0,%o1
- #if STANDARD_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o2
- subcc %o1,1,%o1
- xor %o2,-1,%o2
- st %o2,[%o0]
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ nop
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o1,%o1 # %o1 = -count
- be 2f
- _ sub %o0,4,%o0
- sll %o1,2,%o1 # %o1 = -4*count
- sub %o0,%o1,%o0 # %o0 = &destptr[count-1]
- 1: addcc %o1,4,%o1 # ZΣhler "erniedrigen", Pointer erh÷hen
- ld [%o0+%o1],%o2 # nΣchstes Digit holen
- xor %o2,-1,%o2
- bne 1b
- _ st %o2,[%o0+%o1] # Digit ablegen
- 2: retl
- _ nop
- #endif
-
- # extern boolean and_test_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(and_test_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- 1: ld [%o0],%o3
- ld [%o1],%o4
- add %o0,4,%o0
- andcc %o3,%o4,%g0
- bne 3f
- _ subcc %o2,1,%o2
- bne 1b
- _ add %o1,4,%o1
- 2: retl
- _ mov 0,%o0
- 3: retl
- _ mov 1,%o0
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- ld [%o0+%o2],%o3 # nΣchstes Digit holen
- 1: ld [%o1+%o2],%o4 # noch ein Digit holen
- andcc %o3,%o4,%g0 # beide verknⁿpfen
- bne 3f
- _ addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- bne,a 1b
- __ ld [%o0+%o2],%o3 # nΣchstes Digit holen
- 2: retl
- _ mov 0,%o0
- 3: retl
- _ mov 1,%o0
- #endif
-
- # extern boolean test_loop_up (uintD* ptr, uintC count);
- C(test_loop_up:) # Input in %o0,%o1, Output in %o0
- #if STANDARD_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ nop
- ld [%o0],%o2
- 1: add %o0,4,%o0
- andcc %o2,%o2,%g0
- bne 3f
- _ subcc %o1,1,%o1
- bne,a 1b
- __ ld [%o0],%o2
- 2: retl
- _ mov 0,%o0
- 3: retl
- _ mov 1,%o0
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o1,%o1 # %o1 = -count
- be 2f
- _ sll %o1,2,%o1 # %o1 = -4*count
- sub %o0,%o1,%o0 # %o0 = &ptr[count]
- ld [%o0+%o1],%o2 # nΣchstes Digit holen
- 1: andcc %o2,%o2,%g0 # testen
- bne 3f
- _ addcc %o1,4,%o1 # ZΣhler "erniedrigen", Pointer erh÷hen
- bne,a 1b
- __ ld [%o0+%o1],%o2 # nΣchstes Digit holen
- 2: retl
- _ mov 0,%o0
- 3: retl
- _ mov 1,%o0
- #endif
-
- # extern signean compare_loop_up (uintD* xptr, uintD* yptr, uintC count);
- C(compare_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ nop
- ld [%o0],%o3
- 1: ld [%o1],%o4
- add %o0,4,%o0
- subcc %o3,%o4,%g0
- bne 3f
- _ add %o1,4,%o1
- subcc %o2,1,%o2
- bne,a 1b
- __ ld [%o0],%o3
- 2: retl
- _ mov 0,%o0
- 3: blu 4f
- _ nop
- retl
- _ mov 1,%o0
- 4: retl
- _ mov -1,%o0
- #endif
- #if COUNTER_LOOPS
- subcc %g0,%o2,%o2 # %o2 = -count
- be 2f
- _ sll %o2,2,%o2 # %o2 = -4*count
- sub %o0,%o2,%o0 # %o0 = &xptr[count]
- sub %o1,%o2,%o1 # %o1 = &yptr[count]
- ld [%o0+%o2],%o3 # nΣchstes Digit holen
- 1: ld [%o1+%o2],%o4 # noch ein Digit holen
- subcc %o3,%o4,%g0 # vergleichen
- bne 3f
- _ addcc %o2,4,%o2 # ZΣhler "erniedrigen", Pointer erh÷hen
- bne,a 1b
- __ ld [%o0+%o2],%o3 # nΣchstes Digit holen
- 2: retl
- _ mov 0,%o0
- 3: blu 4f
- _ nop
- retl
- _ mov 1,%o0
- 4: retl
- _ mov -1,%o0
- #endif
-
- # extern uintD add_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
- C(add_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1, Output in %o0
- #if STANDARD_LOOPS
- andcc %o3,%o3,%g0
- be 2f
- _ mov %g0,%g1 # Carry := 0
- sub %o0,4,%o0
- 1: ld [%o0],%o4 # source1-digit
- sub %o1,4,%o1
- ld [%o1],%o5 # source2-digit
- subcc %g0,%g1,%g0 # carry
- addxcc %o4,%o5,%o4 # addieren
- addx %g0,%g0,%g1 # neuer Carry
- sub %o2,4,%o2
- st %o4,[%o2] # Digit ablegen
- subcc %o3,1,%o3
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %g1,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o3,%o3,%g0
- be 2f
- _ mov %g0,%g1 # Carry := 0
- sub %o0,4,%o0
- sub %o1,4,%o1
- sll %o3,2,%o3 # %o3 = 4*count
- sub %o0,%o3,%o0 # %o0 = &sourceptr1[-count-1]
- sub %o1,%o3,%o1 # %o1 = &sourceptr2[-count-1]
- sub %o2,%o3,%o2 # %o2 = &destptr[-count]
- 1: ld [%o0+%o3],%o4 # source1-digit
- ld [%o1+%o3],%o5 # source2-digit
- subcc %g0,%g1,%g0 # carry
- addxcc %o4,%o5,%o4 # addieren
- addx %g0,%g0,%g1 # neuer Carry
- subcc %o3,4,%o3
- bne 1b
- _ st %o4,[%o2+%o3] # Digit ablegen
- 2: retl
- _ mov %g1,%o0
- #endif
- #if UNROLLED_LOOPS
- and %o3,7,%o4 # count mod 8
- sll %o4,2,%o5
- sub %o0,%o5,%o0 # %o0 = &sourceptr1[-(count mod 8)]
- sub %o1,%o5,%o1 # %o1 = &sourceptr2[-(count mod 8)]
- sub %o2,%o5,%o2 # %o2 = &destptr[-(count mod 8)]
- sll %o4,4,%o4
- set _add_loop_down+176,%o5
- sub %o4,%o5,%o5
- jmp %o5 # Sprung nach _add_loop_down+4*(12+4*8-4*(count mod 8))
- _ subcc %g0,%g0,%g0 # carry l÷schen
- 1: subcc %g0,%g1,%g0 # carry
- ld [%o0+28],%o4 # source1-digit
- ld [%o1+28],%o5 # source2-digit
- addxcc %o5,%o4,%o5 # addieren
- st %o5,[%o2+28] # Digit ablegen
- ld [%o0+24],%o4 # source1-digit
- ld [%o1+24],%o5 # source2-digit
- addxcc %o5,%o4,%o5 # addieren
- st %o5,[%o2+24] # Digit ablegen
- ld [%o0+20],%o4 # source1-digit
- ld [%o1+20],%o5 # source2-digit
- addxcc %o5,%o4,%o5 # addieren
- st %o5,[%o2+20] # Digit ablegen
- ld [%o0+16],%o4 # source1-digit
- ld [%o1+16],%o5 # source2-digit
- addxcc %o5,%o4,%o5 # addieren
- st %o5,[%o2+16] # Digit ablegen
- ld [%o0+12],%o4 # source1-digit
- ld [%o1+12],%o5 # source2-digit
- addxcc %o5,%o4,%o5 # addieren
- st %o5,[%o2+12] # Digit ablegen
- ld [%o0+8],%o4 # source1-digit
- ld [%o1+8],%o5 # source2-digit
- addxcc %o5,%o4,%o5 # addieren
- st %o5,[%o2+8] # Digit ablegen
- ld [%o0+4],%o4 # source1-digit
- ld [%o1+4],%o5 # source2-digit
- addxcc %o5,%o4,%o5 # addieren
- st %o5,[%o2+4] # Digit ablegen
- ld [%o0],%o4 # source1-digit
- ld [%o1],%o5 # source2-digit
- addxcc %o5,%o4,%o5 # addieren
- st %o5,[%o2] # Digit ablegen
- addx %g0,%g0,%g1 # neuer Carry
- sub %o0,32,%o0
- sub %o1,32,%o1
- subcc %o3,8,%o3 # noch mindestens 8 Digits abzuarbeiten?
- bcc 1b
- _ sub %o2,32,%o2
- retl
- _ mov %g1,%o0
- #endif
-
- # extern uintD addto_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
- C(addto_loop_down:) # Input in %o0,%o1,%o2, Output in %o0
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ mov %g0,%o5 # Carry := 0
- sub %o0,4,%o0
- 1: ld [%o0],%o3 # source-digit
- sub %o1,4,%o1
- ld [%o1],%o4 # dest-digit
- subcc %g0,%o5,%g0 # carry
- addxcc %o4,%o3,%o4 # addieren
- addx %g0,%g0,%o5 # neuer Carry
- st %o4,[%o1] # Digit ablegen
- subcc %o2,1,%o2
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %o5,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ mov %g0,%o5 # Carry := 0
- sub %o0,4,%o0
- sub %o1,4,%o1
- sll %o2,2,%o2 # %o2 = 4*count
- sub %o0,%o2,%o0 # %o0 = &sourceptr[-count-1]
- sub %o1,%o2,%o1 # %o1 = &destptr[-count-1]
- ld [%o0+%o2],%o3 # source-digit
- 1: ld [%o1+%o2],%o4 # dest-digit
- subcc %g0,%o5,%g0 # carry
- addxcc %o4,%o3,%o4 # addieren
- addx %g0,%g0,%o5 # neuer Carry
- st %o4,[%o1+%o2] # Digit ablegen
- subcc %o2,4,%o2
- bne,a 1b
- __ ld [%o0+%o2],%o3 # source-digit
- 2: retl
- _ mov %o5,%o0
- #endif
- #if UNROLLED_LOOPS
- and %o2,7,%o3 # count mod 8
- sll %o3,2,%o4
- sub %o0,%o4,%o0 # %o0 = &sourceptr[-(count mod 8)]
- sub %o1,%o4,%o1 # %o1 = &destptr[-(count mod 8)]
- sll %o3,4,%o3
- set _addto_loop_down+172,%o4
- sub %o3,%o4,%o4
- jmp %o4 # Sprung nach _addto_loop_down+4*(11+4*8-4*(count mod 8))
- _ subcc %g0,%g0,%g0 # carry l÷schen
- 1: subcc %g0,%o5,%g0 # carry
- ld [%o0+28],%o3 # source-digit
- ld [%o1+28],%o4 # dest-digit
- addxcc %o4,%o3,%o4 # addieren
- st %o4,[%o1+28] # Digit ablegen
- ld [%o0+24],%o3 # source-digit
- ld [%o1+24],%o4 # dest-digit
- addxcc %o4,%o3,%o4 # addieren
- st %o4,[%o1+24] # Digit ablegen
- ld [%o0+20],%o3 # source-digit
- ld [%o1+20],%o4 # dest-digit
- addxcc %o4,%o3,%o4 # addieren
- st %o4,[%o1+20] # Digit ablegen
- ld [%o0+16],%o3 # source-digit
- ld [%o1+16],%o4 # dest-digit
- addxcc %o4,%o3,%o4 # addieren
- st %o4,[%o1+16] # Digit ablegen
- ld [%o0+12],%o3 # source-digit
- ld [%o1+12],%o4 # dest-digit
- addxcc %o4,%o3,%o4 # addieren
- st %o4,[%o1+12] # Digit ablegen
- ld [%o0+8],%o3 # source-digit
- ld [%o1+8],%o4 # dest-digit
- addxcc %o4,%o3,%o4 # addieren
- st %o4,[%o1+8] # Digit ablegen
- ld [%o0+4],%o3 # source-digit
- ld [%o1+4],%o4 # dest-digit
- addxcc %o4,%o3,%o4 # addieren
- st %o4,[%o1+4] # Digit ablegen
- ld [%o0],%o3 # source-digit
- ld [%o1],%o4 # dest-digit
- addxcc %o4,%o3,%o4 # addieren
- st %o4,[%o1] # Digit ablegen
- addx %g0,%g0,%o5 # neuer Carry
- sub %o0,32,%o0
- subcc %o2,8,%o2 # noch mindestens 8 Digits abzuarbeiten?
- bcc 1b
- _ sub %o1,32,%o1
- retl
- _ mov %o5,%o0
- #endif
-
- # extern uintD inc_loop_down (uintD* ptr, uintC count);
- C(inc_loop_down:) # Input in %o0,%o1, Output in %o0
- #if STANDARD_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ sub %o0,4,%o0
- 1: ld [%o0],%o2
- addcc %o2,1,%o2
- bne 3f
- _ st %o2,[%o0]
- subcc %o1,1,%o1
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov 1,%o0
- 3: retl
- _ mov 0,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ sub %o0,4,%o0
- sll %o1,2,%o1 # %o1 = 4*count
- sub %o0,%o1,%o0 # %o0 = &ptr[-count-1]
- ld [%o0+%o1],%o2 # digit holen
- 1: addcc %o2,1,%o2 # incrementieren
- bne 3f
- _ st %o2,[%o0+%o1] # ablegen
- subcc %o1,4,%o1 # ZΣhler erniedrigen, Pointer erniedrigen
- bne,a 1b
- __ ld [%o0+%o1],%o2
- 2: retl
- _ mov 1,%o0
- 3: retl
- _ mov 0,%o0
- #endif
-
- # extern uintD sub_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count);
- C(sub_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1, Output in %o0
- #if STANDARD_LOOPS
- andcc %o3,%o3,%g0
- be 2f
- _ mov %g0,%g1 # Carry := 0
- sub %o0,4,%o0
- 1: ld [%o0],%o4 # source1-digit
- sub %o1,4,%o1
- ld [%o1],%o5 # source2-digit
- subcc %g0,%g1,%g0 # carry
- subxcc %o4,%o5,%o4 # subtrahieren
- addx %g0,%g0,%g1 # neuer Carry
- sub %o2,4,%o2
- st %o4,[%o2] # Digit ablegen
- subcc %o3,1,%o3
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %g1,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o3,%o3,%g0
- be 2f
- _ mov %g0,%g1 # Carry := 0
- sub %o0,4,%o0
- sub %o1,4,%o1
- sll %o3,2,%o3 # %o3 = 4*count
- sub %o0,%o3,%o0 # %o0 = &sourceptr1[-count-1]
- sub %o1,%o3,%o1 # %o1 = &sourceptr2[-count-1]
- sub %o2,%o3,%o2 # %o2 = &destptr[-count]
- 1: ld [%o0+%o3],%o4 # source1-digit
- ld [%o1+%o3],%o5 # source2-digit
- subcc %g0,%g1,%g0 # carry
- subxcc %o4,%o5,%o4 # subtrahieren
- addx %g0,%g0,%g1 # neuer Carry
- subcc %o3,4,%o3
- bne 1b
- _ st %o4,[%o2+%o3] # Digit ablegen
- 2: retl
- _ mov %g1,%o0
- #endif
- #if UNROLLED_LOOPS
- and %o3,7,%o4 # count mod 8
- sll %o4,2,%o5
- sub %o0,%o5,%o0 # %o0 = &sourceptr1[-(count mod 8)]
- sub %o1,%o5,%o1 # %o1 = &sourceptr2[-(count mod 8)]
- sub %o2,%o5,%o2 # %o2 = &destptr[-(count mod 8)]
- sll %o4,4,%o4
- set _sub_loop_down+176,%o5
- sub %o4,%o5,%o5
- jmp %o5 # Sprung nach _sub_loop_down+4*(12+4*8-4*(count mod 8))
- _ subcc %g0,%g0,%g0 # carry l÷schen
- 1: subcc %g0,%g1,%g0 # carry
- ld [%o0+28],%o4 # source1-digit
- ld [%o1+28],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+28] # Digit ablegen
- ld [%o0+24],%o4 # source1-digit
- ld [%o1+24],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+24] # Digit ablegen
- ld [%o0+20],%o4 # source1-digit
- ld [%o1+20],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+20] # Digit ablegen
- ld [%o0+16],%o4 # source1-digit
- ld [%o1+16],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+16] # Digit ablegen
- ld [%o0+12],%o4 # source1-digit
- ld [%o1+12],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+12] # Digit ablegen
- ld [%o0+8],%o4 # source1-digit
- ld [%o1+8],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+8] # Digit ablegen
- ld [%o0+4],%o4 # source1-digit
- ld [%o1+4],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+4] # Digit ablegen
- ld [%o0],%o4 # source1-digit
- ld [%o1],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2] # Digit ablegen
- addx %g0,%g0,%g1 # neuer Carry
- sub %o0,32,%o0
- sub %o1,32,%o1
- subcc %o3,8,%o3 # noch mindestens 8 Digits abzuarbeiten?
- bcc 1b
- _ sub %o2,32,%o2
- retl
- _ mov %g1,%o0
- #endif
-
- # extern uintD subx_loop_down (uintD* sourceptr1, uintD* sourceptr2, uintD* destptr, uintC count, uintD carry);
- C(subx_loop_down:) # Input in %o0,%o1,%o2,%o3,%o4, verΣndert %g1, Output in %o0
- #if STANDARD_LOOPS
- andcc %o3,%o3,%g0
- be 2f
- _ mov %o4,%g1 # Carry
- sub %o0,4,%o0
- 1: ld [%o0],%o4 # source1-digit
- sub %o1,4,%o1
- ld [%o1],%o5 # source2-digit
- subcc %g0,%g1,%g0 # carry
- subxcc %o4,%o5,%o4 # subtrahieren
- addx %g0,%g0,%g1 # neuer Carry
- sub %o2,4,%o2
- st %o4,[%o2] # Digit ablegen
- subcc %o3,1,%o3
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %g1,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o3,%o3,%g0
- be 2f
- _ mov %o4,%g1 # Carry
- sub %o0,4,%o0
- sub %o1,4,%o1
- sll %o3,2,%o3 # %o3 = 4*count
- sub %o0,%o3,%o0 # %o0 = &sourceptr1[-count-1]
- sub %o1,%o3,%o1 # %o1 = &sourceptr2[-count-1]
- sub %o2,%o3,%o2 # %o2 = &destptr[-count]
- 1: ld [%o0+%o3],%o4 # source1-digit
- ld [%o1+%o3],%o5 # source2-digit
- subcc %g0,%g1,%g0 # carry
- subxcc %o4,%o5,%o4 # subtrahieren
- addx %g0,%g0,%g1 # neuer Carry
- subcc %o3,4,%o3
- bne 1b
- _ st %o4,[%o2+%o3] # Digit ablegen
- 2: retl
- _ mov %g1,%o0
- #endif
- #if UNROLLED_LOOPS
- and %o3,7,%o5 # count mod 8
- sll %o5,2,%g1
- sub %o0,%g1,%o0 # %o0 = &sourceptr1[-(count mod 8)]
- sub %o1,%g1,%o1 # %o1 = &sourceptr2[-(count mod 8)]
- sub %o2,%g1,%o2 # %o2 = &destptr[-(count mod 8)]
- sll %o5,4,%o5
- set _subx_loop_down+176,%g1
- sub %o5,%g1,%g1
- jmp %g1 # Sprung nach _subx_loop_down+4*(12+4*8-4*(count mod 8))
- _ subcc %g0,%o4,%g0 # carry initialisieren
- 1: subcc %g0,%g1,%g0 # carry
- ld [%o0+28],%o4 # source1-digit
- ld [%o1+28],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+28] # Digit ablegen
- ld [%o0+24],%o4 # source1-digit
- ld [%o1+24],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+24] # Digit ablegen
- ld [%o0+20],%o4 # source1-digit
- ld [%o1+20],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+20] # Digit ablegen
- ld [%o0+16],%o4 # source1-digit
- ld [%o1+16],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+16] # Digit ablegen
- ld [%o0+12],%o4 # source1-digit
- ld [%o1+12],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+12] # Digit ablegen
- ld [%o0+8],%o4 # source1-digit
- ld [%o1+8],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+8] # Digit ablegen
- ld [%o0+4],%o4 # source1-digit
- ld [%o1+4],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2+4] # Digit ablegen
- ld [%o0],%o4 # source1-digit
- ld [%o1],%o5 # source2-digit
- subxcc %o4,%o5,%o4 # subtrahieren
- st %o4,[%o2] # Digit ablegen
- addx %g0,%g0,%g1 # neuer Carry
- sub %o0,32,%o0
- sub %o1,32,%o1
- subcc %o3,8,%o3 # noch mindestens 8 Digits abzuarbeiten?
- bcc 1b
- _ sub %o2,32,%o2
- retl
- _ mov %g1,%o0
- #endif
-
- # extern uintD subfrom_loop_down (uintD* sourceptr, uintD* destptr, uintC count);
- C(subfrom_loop_down:) # Input in %o0,%o1,%o2, Output in %o0
- #if STANDARD_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ mov %g0,%o5 # Carry := 0
- sub %o0,4,%o0
- 1: ld [%o0],%o3 # source-digit
- sub %o1,4,%o1
- ld [%o1],%o4 # dest-digit
- subcc %g0,%o5,%g0 # carry
- subxcc %o4,%o3,%o4 # subtrahieren
- addx %g0,%g0,%o5 # neuer Carry
- st %o4,[%o1] # Digit ablegen
- subcc %o2,1,%o2
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %o5,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o2,%o2,%g0
- be 2f
- _ mov %g0,%o5 # Carry := 0
- sub %o0,4,%o0
- sub %o1,4,%o1
- sll %o2,2,%o2 # %o2 = 4*count
- sub %o0,%o2,%o0 # %o0 = &sourceptr[-count-1]
- sub %o1,%o2,%o1 # %o1 = &destptr[-count-1]
- ld [%o0+%o2],%o3 # source-digit
- 1: ld [%o1+%o2],%o4 # dest-digit
- subcc %g0,%o5,%g0 # carry
- subxcc %o4,%o3,%o4 # subtrahieren
- addx %g0,%g0,%o5 # neuer Carry
- st %o4,[%o1+%o2] # Digit ablegen
- subcc %o2,4,%o2
- bne,a 1b
- __ ld [%o0+%o2],%o3 # source-digit
- 2: retl
- _ mov %o5,%o0
- #endif
- #if UNROLLED_LOOPS
- and %o2,7,%o3 # count mod 8
- sll %o3,2,%o4
- sub %o0,%o4,%o0 # %o0 = &sourceptr[-(count mod 8)]
- sub %o1,%o4,%o1 # %o1 = &destptr[-(count mod 8)]
- sll %o3,4,%o3
- set _subfrom_loop_down+172,%o4
- sub %o3,%o4,%o4
- jmp %o4 # Sprung nach _subfrom_loop_down+4*(11+4*8-4*(count mod 8))
- _ subcc %g0,%g0,%g0 # carry l÷schen
- 1: subcc %g0,%o5,%g0 # carry
- ld [%o0+28],%o3 # source-digit
- ld [%o1+28],%o4 # dest-digit
- subxcc %o4,%o3,%o4 # subtrahieren
- st %o4,[%o1+28] # Digit ablegen
- ld [%o0+24],%o3 # source-digit
- ld [%o1+24],%o4 # dest-digit
- subxcc %o4,%o3,%o4 # subtrahieren
- st %o4,[%o1+24] # Digit ablegen
- ld [%o0+20],%o3 # source-digit
- ld [%o1+20],%o4 # dest-digit
- subxcc %o4,%o3,%o4 # subtrahieren
- st %o4,[%o1+20] # Digit ablegen
- ld [%o0+16],%o3 # source-digit
- ld [%o1+16],%o4 # dest-digit
- subxcc %o4,%o3,%o4 # subtrahieren
- st %o4,[%o1+16] # Digit ablegen
- ld [%o0+12],%o3 # source-digit
- ld [%o1+12],%o4 # dest-digit
- subxcc %o4,%o3,%o4 # subtrahieren
- st %o4,[%o1+12] # Digit ablegen
- ld [%o0+8],%o3 # source-digit
- ld [%o1+8],%o4 # dest-digit
- subxcc %o4,%o3,%o4 # subtrahieren
- st %o4,[%o1+8] # Digit ablegen
- ld [%o0+4],%o3 # source-digit
- ld [%o1+4],%o4 # dest-digit
- subxcc %o4,%o3,%o4 # subtrahieren
- st %o4,[%o1+4] # Digit ablegen
- ld [%o0],%o3 # source-digit
- ld [%o1],%o4 # dest-digit
- subxcc %o4,%o3,%o4 # subtrahieren
- st %o4,[%o1] # Digit ablegen
- addx %g0,%g0,%o5 # neuer Carry
- sub %o0,32,%o0
- subcc %o2,8,%o2 # noch mindestens 8 Digits abzuarbeiten?
- bcc 1b
- _ sub %o1,32,%o1
- retl
- _ mov %o5,%o0
- #endif
-
- # extern uintD dec_loop_down (uintD* ptr, uintC count);
- C(dec_loop_down:) # Input in %o0,%o1, Output in %o0
- #if STANDARD_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ sub %o0,4,%o0
- 1: ld [%o0],%o2
- subcc %o2,1,%o2
- bcc 3f
- _ st %o2,[%o0]
- subcc %o1,1,%o1
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov -1,%o0
- 3: retl
- _ mov 0,%o0
- #endif
- #if COUNTER_LOOPS
- andcc %o1,%o1,%g0
- be 2f
- _ sub %o0,4,%o0
- sll %o1,2,%o1 # %o1 = 4*count
- sub %o0,%o1,%o0 # %o0 = &ptr[-count-1]
- ld [%o0+%o1],%o2 # digit holen
- 1: subcc %o2,1,%o2 # incrementieren
- bcc 3f
- _ st %o2,[%o0+%o1] # ablegen
- subcc %o1,4,%o1 # ZΣhler erniedrigen, Pointer erniedrigen
- bne,a 1b
- __ ld [%o0+%o1],%o2
- 2: retl
- _ mov -1,%o0
- 3: retl
- _ mov 0,%o0
- #endif
-
- # extern uintD neg_loop_down (uintD* ptr, uintC count);
- C(neg_loop_down:) # Input in %o0,%o1, Output in %o0
- #if STANDARD_LOOPS
- # erstes Digit /=0 suchen:
- andcc %o1,%o1,%g0
- be 2f
- _ sub %o0,4,%o0
- 1: ld [%o0],%o2
- subcc %g0,%o2,%o2
- bne 3f
- _ subcc %o1,1,%o1
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov 0,%o0
- 3: # erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
- st %o2,[%o0] # 1 Digit negieren
- # alle anderen Digits invertieren:
- be 5f
- _ sub %o0,4,%o0
- 4: ld [%o0],%o2
- subcc %o1,1,%o1
- xor %o2,-1,%o2
- st %o2,[%o0]
- bne 4b
- _ sub %o0,4,%o0
- 5: retl
- _ mov -1,%o0
- #endif
- #if COUNTER_LOOPS
- # erstes Digit /=0 suchen:
- andcc %o1,%o1,%g0
- be 2f
- _ sub %o0,4,%o0
- sll %o1,2,%o1 # %o1 = 4*count
- sub %o0,%o1,%o0 # %o0 = &ptr[-count-1]
- ld [%o0+%o1],%o2 # digit holen
- 1: subcc %g0,%o2,%o2 # negieren, testen
- bne,a 3f
- __ st %o2,[%o0+%o1] # ablegen
- subcc %o1,4,%o1 # ZΣhler erniedrigen, Pointer erniedrigen
- bne,a 1b
- __ ld [%o0+%o1],%o2
- 2: retl
- _ mov 0,%o0
- 3: # erstes Digit /=0 gefunden, ab jetzt gibt's Carrys
- # alle anderen Digits invertieren:
- subcc %o1,4,%o1
- be 5f
- _ ld [%o0+%o1],%o2
- 4: subcc %o1,4,%o1
- xor %o2,-1,%o2
- st %o2,[%o0+%o1]
- bne,a 4b
- __ ld [%o0+%o1],%o2
- 5: retl
- _ mov -1,%o0
- #endif
-
- # extern uintD shift1left_loop_down (uintD* ptr, uintC count);
- C(shift1left_loop_down:) # Input in %o0,%o1, Output in %o0
- andcc %o1,%o1,%g0
- be 2f
- _ mov 0,%o3 # Carry := 0
- sub %o0,4,%o0
- 1: ld [%o0],%o2 # Digit
- subcc %g0,%o3,%g0 # carry
- addxcc %o2,%o2,%o2 # shiften
- addx %g0,%g0,%o3 # neues Carry
- st %o2,[%o0] # Digit ablegen
- subcc %o1,1,%o1
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %o3,%o0
-
- # extern uintD shiftleft_loop_down (uintD* ptr, uintC count, uintC i, uintD carry);
- C(shiftleft_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1, Output in %o0
- andcc %o1,%o1,%g0
- be 2f
- _ sub %g0,%o2,%g1 # 32-i (mod 32)
- sub %o0,4,%o0
- 1: ld [%o0],%o4 # Digit
- subcc %o1,1,%o1
- sll %o4,%o2,%o5 # dessen niedere (32-i) Bits
- or %o3,%o5,%o5 # mit dem alten Carry kombinieren
- st %o5,[%o0] # Digit ablegen
- srl %o4,%g1,%o3 # dessen h÷chste i Bits liefern den neuen Carry
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %o3,%o0
-
- # extern uintD shiftleftcopy_loop_down (uintD* sourceptr, uintD* destptr, uintC count, uintC i);
- C(shiftleftcopy_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1,%g2, Output in %o0
- andcc %o2,%o2,%g0
- be 2f
- _ mov 0,%o4 # Carry := 0
- sub %g0,%o3,%g1 # 32-i (mod 32)
- sub %o0,4,%o0
- 1: ld [%o0],%o5 # Digit
- subcc %o2,1,%o2
- sll %o5,%o3,%g2 # dessen niedere (32-i) Bits
- or %o4,%g2,%g2 # mit dem alten Carry kombinieren
- sub %o1,4,%o1
- st %g2,[%o1] # Digit ablegen
- srl %o5,%g1,%o4 # dessen h÷chste i Bits liefern den neuen Carry
- bne 1b
- _ sub %o0,4,%o0
- 2: retl
- _ mov %o4,%o0
-
- # extern uintD shift1right_loop_up (uintD* ptr, uintC count, uintD carry);
- C(shift1right_loop_up:) # Input in %o0,%o1,%o2, Output in %o0
- andcc %o1,%o1,%g0
- be 2f
- _ sll %o2,31,%o2 # Carry
- 1: ld [%o0],%o3 # Digit
- subcc %o1,1,%o1
- srl %o3,1,%o4 # shiften
- or %o2,%o4,%o4 # und mit altem Carry kombinieren
- st %o4,[%o0] # und ablegen
- sll %o3,31,%o2 # neuer Carry
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ mov %o2,%o0
-
- # extern uintD shiftright_loop_up (uintD* ptr, uintC count, uintC i);
- C(shiftright_loop_up:) # Input in %o0,%o1,%o2, verΣndert %g1, Output in %o0
- sub %g0,%o2,%g1 # 32-i (mod 32)
- andcc %o1,%o1,%g0
- be 2f
- _ or %g0,%g0,%o3 # Carry := 0
- 1: ld [%o0],%o4 # Digit
- subcc %o1,1,%o1
- srl %o4,%o2,%o5 # shiften
- or %o3,%o5,%o5 # und mit altem Carry kombinieren
- st %o5,[%o0] # und ablegen
- sll %o4,%g1,%o3 # neuer Carry
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ mov %o3,%o0
-
- # extern uintD shiftrightsigned_loop_up (uintD* ptr, uintC count, uintC i);
- C(shiftrightsigned_loop_up:) # Input in %o0,%o1,%o2, verΣndert %g1, Output in %o0
- ld [%o0],%o4 # erstes Digit
- sub %g0,%o2,%g1 # 32-i (mod 32)
- sra %o4,%o2,%o5 # shiften
- st %o5,[%o0] # und ablegen
- sll %o4,%g1,%o3 # neuer Carry
- subcc %o1,1,%o1
- be 2f
- _ add %o0,4,%o0
- 1: ld [%o0],%o4 # Digit
- subcc %o1,1,%o1
- srl %o4,%o2,%o5 # shiften
- or %o3,%o5,%o5 # und mit altem Carry kombinieren
- st %o5,[%o0] # und ablegen
- sll %o4,%g1,%o3 # neuer Carry
- bne 1b
- _ add %o0,4,%o0
- 2: retl
- _ mov %o3,%o0
-
- # extern uintD shiftrightcopy_loop_up (uintD* sourceptr, uintD* destptr, uintC count, uintC i, uintD carry);
- C(shiftrightcopy_loop_up:) # Input in %o0,%o1,%o2,%o3,%o4, verΣndert %g1,%g2, Output in %o0
- sub %g0,%o3,%g1 # 32-i (mod 32)
- andcc %o2,%o2,%g0
- be 2f
- _ sll %o4,%g1,%g2 # erster Carry
- 1: ld [%o0],%o4 # Digit
- add %o0,4,%o0
- srl %o4,%o3,%o5 # shiften
- or %g2,%o5,%o5 # und mit altem Carry kombinieren
- st %o5,[%o1] # und ablegen
- sll %o4,%g1,%g2 # neuer Carry
- subcc %o2,1,%o2
- bne 1b
- _ add %o1,4,%o1
- 2: retl
- _ mov %g2,%o0
-
- # extern uintD mulusmall_loop_down (uintD digit, uintD* ptr, uintC len, uintD newdigit);
- C(mulusmall_loop_down:) # Input in %o0,%o1,%o2,%o3, Output in %o0
- andcc %o2,%o2,%g0
- be 3f
- _ sub %o1,4,%o1
- 1: # nΣchstes Digit [%o1] mit der 6-Bit-Zahl %o0 multiplizieren
- # und kleinen Carry %o3 dazu:
- mov %o0,%y
- ld [%o1],%o4 # Wartetakt!
- addcc %o3,%o3,%o5
- mulscc %o5,%o4,%o5
- mulscc %o5,%o4,%o5
- mulscc %o5,%o4,%o5
- mulscc %o5,%o4,%o5
- mulscc %o5,%o4,%o5
- mulscc %o5,%o4,%o5
- mulscc %o5,%g0,%o5
- # Die 26 unteren Bits von %o5 und die 6 oberen Bits von %y
- # ergeben das Resultat. (Die anderen Bits sind Null.)
- tst %o4 # Korrektur, falls %o4 negativ war
- bge 2f
- _ sra %o5,26,%o3 # 6 obere Bits von %o5 -> neuer Carry
- add %o3,%o0,%o3 # (falls %o4 negativ war, noch + %o0)
- 2: rd %y,%o4
- srl %o4,26,%o4 # 6 obere Bits von %y
- sll %o5,6,%o5 # 26 untere Bits von %o5
- or %o5,%o4,%o4 # neues Digit
- st %o4,[%o1] # ablegen
- subcc %o2,1,%o2
- bne 1b
- _ sub %o1,4,%o1
- 3: retl
- _ mov %o3,%o0
-
- # extern void mulu_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
- #if !MULU32_INLINE
- C(mulu_loop_down:) # Input in %i0,%i1,%i2,%i3
- save %sp,-96,%sp
- mov 0,%l0 # Carry
- 1: sub %i1,4,%i1
- ld [%i1],%o1 # nΣchstes Digit
- call _mulu32_ # mit digit multiplizieren
- _ mov %i0,%o0
- addcc %l0,%o0,%o0 # und bisherigen Carry addieren
- addx %g0,%g1,%l0 # High-Digit gibt neuen Carry
- sub %i2,4,%i2
- subcc %i3,1,%i3
- bne 1b
- _ st %o0,[%i2] # Low-Digit ablegen
- st %l0,[%i2-4] # letzten Carry ablegen
- ret
- _ restore
- #else
- C(mulu_loop_down:) # Input in %o0,%o1,%o2,%o3, verΣndert %g1
- mov 0,%o4 # Carry
- 1: ld [%o1-4],%g1 # nΣchstes Digit
- # mit digit multiplizieren: %o0 * %g1 -> %o5|%g1
- #ifdef sparcv8
- sub %o1,4,%o1
- umul %g1,%o0,%g1
- rd %y,%o5
- #else
- mov %g1,%y
- sub %o1,4,%o1 # Wartetakt!
- andcc %g0,%g0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%o0,%o5
- mulscc %o5,%g0,%o5
- tst %o0
- bl,a 2f
- __ add %o5,%g1,%o5
- 2: rd %y,%g1
- #endif
- addcc %o4,%g1,%g1 # und bisherigen Carry addieren
- addx %g0,%o5,%o4 # High-Digit gibt neuen Carry
- sub %o2,4,%o2
- subcc %o3,1,%o3
- bne 1b
- _ st %g1,[%o2] # Low-Digit ablegen
- retl
- _ st %o4,[%o2-4] # letzten Carry ablegen
- #endif
-
- # extern uintD muluadd_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
- C(muluadd_loop_down:) # Input in %i0,%i1,%i2,%i3, Output in %i0
- #if !MULU32_INLINE
- save %sp,-96,%sp
- mov 0,%l0 # Carry
- 1: sub %i1,4,%i1
- ld [%i1],%o1 # nΣchstes source-Digit
- call _mulu32_ # mit digit multiplizieren
- _ mov %i0,%o0
- sub %i2,4,%i2
- ld [%i2],%o1 # nΣchstes dest-digit
- addcc %l0,%o0,%o0 # und bisherigen Carry addieren
- addx %g0,%g1,%l0 # High-Digit gibt neuen Carry
- addcc %o1,%o0,%o0 # addieren
- addx %g0,%l0,%l0
- subcc %i3,1,%i3
- bne 1b
- _ st %o0,[%i2] # Low-Digit ablegen
- mov %l0,%i0 # letzter Carry
- ret
- _ restore
- #else
- save %sp,-96,%sp
- mov 0,%l0 # Carry
- #ifndef sparcv8
- sra %i0,31,%l1 # 0 falls %i0>=0, -1 falls %i0<0
- #endif
- 1: ld [%i1-4],%o1 # nΣchstes source-Digit
- sub %i1,4,%i1
- # mit digit multiplizieren: %i0 * %o1 -> %o2|%o0
- #ifdef sparcv8
- umul %i0,%o1,%o0
- rd %y,%o2
- #else
- mov %o1,%y
- and %o1,%l1,%o3 # Wartetakt!
- andcc %g0,%g0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%g0,%o2
- add %o2,%o3,%o2 # %o3 = (0 falls %i0>=0, %o1 falls %i0<0)
- rd %y,%o0
- #endif
- sub %i2,4,%i2
- ld [%i2],%o1 # nΣchstes dest-digit
- addcc %l0,%o0,%o0 # und bisherigen Carry addieren
- addx %g0,%o2,%l0 # High-Digit gibt neuen Carry
- addcc %o1,%o0,%o0 # addieren
- addx %g0,%l0,%l0
- subcc %i3,1,%i3
- bne 1b
- _ st %o0,[%i2] # Low-Digit ablegen
- mov %l0,%i0 # letzter Carry
- ret
- _ restore
- #endif
-
- # extern uintD mulusub_loop_down (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
- C(mulusub_loop_down:) # Input in %i0,%i1,%i2,%i3, Output in %i0
- #if !MULU32_INLINE
- save %sp,-96,%sp
- mov 0,%l0 # Carry
- 1: sub %i1,4,%i1
- ld [%i1],%o1 # nΣchstes source-Digit
- call _mulu32_ # mit digit multiplizieren
- _ mov %i0,%o0
- sub %i2,4,%i2
- ld [%i2],%o1 # nΣchstes dest-digit
- addcc %l0,%o0,%o0 # und bisherigen Carry addieren
- addx %g0,%g1,%l0 # High-Digit gibt neuen Carry
- subcc %o1,%o0,%o1 # davon das Low-Digit subtrahieren
- addx %g0,%l0,%l0
- subcc %i3,1,%i3
- bne 1b
- _ st %o1,[%i2] # dest-Digit ablegen
- mov %l0,%i0 # letzter Carry
- ret
- _ restore
- #else
- save %sp,-96,%sp
- mov 0,%l0 # Carry
- #ifndef sparcv8
- sra %i0,31,%l1 # 0 falls %i0>=0, -1 falls %i0<0
- #endif
- 1: ld [%i1-4],%o1 # nΣchstes source-Digit
- sub %i1,4,%i1
- # mit digit multiplizieren: %i0 * %o1 -> %o2|%o0
- #ifdef sparcv8
- umul %i0,%o1,%o0
- rd %y,%o2
- #else
- mov %o1,%y
- and %o1,%l1,%o3 # Wartetakt!
- andcc %g0,%g0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%i0,%o2
- mulscc %o2,%g0,%o2
- add %o2,%o3,%o2 # %o3 = (0 falls %i0>=0, %o1 falls %i0<0)
- rd %y,%o0
- #endif
- sub %i2,4,%i2
- ld [%i2],%o1 # nΣchstes dest-digit
- addcc %l0,%o0,%o0 # und bisherigen Carry addieren
- addx %g0,%o2,%l0 # High-Digit gibt neuen Carry
- subcc %o1,%o0,%o1 # davon das Low-Digit subtrahieren
- addx %g0,%l0,%l0
- subcc %i3,1,%i3
- bne 1b
- _ st %o1,[%i2] # dest-Digit ablegen
- mov %l0,%i0 # letzter Carry
- ret
- _ restore
- #endif
-
- # extern uintD divu_loop_up (uintD digit, uintD* ptr, uintC len);
- C(divu_loop_up:) # Input in %i0,%i1,%i2, Output in %i0
- save %sp,-96,%sp
- andcc %i2,%i2,%g0
- be 2f
- _ mov 0,%g1 # Rest
- 1: mov %g1,%o0 # Rest als High-Digit
- ld [%i1],%o1 # nΣchstes Digit als Low-Digit
- call C(divu_6432_3232_) # zusammen durch digit dividieren
- _ mov %i0,%o2
- st %o0,[%i1] # Quotient ablegen, Rest in %g1
- subcc %i2,1,%i2
- bne 1b
- _ add %i1,4,%i1
- 2: mov %g1,%i0 # Rest als Ergebnis
- ret
- _ restore
-
- # extern uintD divucopy_loop_up (uintD digit, uintD* sourceptr, uintD* destptr, uintC len);
- C(divucopy_loop_up:) # Input in %i0,%i1,%i2,%i3, Output in %i0
- save %sp,-96,%sp
- andcc %i3,%i3,%g0
- be 2f
- _ mov 0,%g1 # Rest
- 1: mov %g1,%o0 # Rest als High-Digit
- ld [%i1],%o1 # nΣchstes Digit als Low-Digit
- call C(divu_6432_3232_) # zusammen durch digit dividieren
- _ mov %i0,%o2
- st %o0,[%i2] # Quotient ablegen, Rest in %g1
- add %i1,4,%i1
- subcc %i3,1,%i3
- bne 1b
- _ add %i2,4,%i2
- 2: mov %g1,%i0 # Rest als Ergebnis
- ret
- _ restore
-
- #endif
-
-