* REGENERATE 3N+C CYCLES *
* 04/19/13 (dkc) *
* *
* This C64 subroutine regenerates a 3n+c cycle given an odd element and finds*
* the minimum element and the number of even and odd elements. The calling *
* sequence of the subroutine is; *
* *
* K[0] (MSW of odd element) => a4 *
* K[1] (LSW of odd element) => b4 *
* address to store output minimum (MIN[0],MIN[1]), (L+2*K,K), etc. => a6 *
* c => b6 *
* *
* If an attachment point is found, a value of 1 is returned. Eleven *
* instruction cycles are required to compute the next odd element in the *
* sequence and compare this odd element to the minimum. *
* *
*******************************************************************************
.global _regen
.text
_regen:zero.l2 b19 ; load 0
mv.d2 b4, b18 ; load K[1]
|| mvk.s1 0, a2 ; clear flag
|| rotl.m1 a4, 0, a21 ; save K[0]
|| mv.l1x b4, a20 ; save K[1]
|| rotl.m2 b4, 0, b30 ; MIN[1]=K[1]
addu.l2 b19:b18, b18, b21:b20 ; K[1]*2
|| rotl.m2x a4, 0, b16 ; load K[0]
|| mvk.s1 0, a17 ; g=0
|| mpy.m1 a19, 0, a19 ; o=0
addu.l2 b21:b20, b18, b21:b20 ; K[1]*3
|| rotl.m2x a4, 0, b31 ; MIN[0]=K[0]
addu.l2 b21:b20, b6, b21:b20 ; K[1]=K[1]*3+c
|| addab.d2 b16, b16, b17 ; K[0]*2
bitr.m2 b20, b0 ; bit-reverse K[1]
|| and.l2 b20, 7, b1 ; check for attachment point
|| addab.d2 b17, b16, b16 ; K[0]*3
[!b1] mvk.s1 1, a2 ; set flag
||[!b1] stw.d1 b20, *+a6[4] ; save K[1]
|| addab.d2 b16, b21, b16 ; K[0]=K[0]*3+carry
lmbd.l2 1, b0, b29 ; count bits
|| mvk.s2 32, b2 ; load 32
||[!b1] stw.d1 b16, *+a6[3] ; save K[0]
subab.d2 b2, b29, b2 ; 32-count
|| shru.s2 b20, b29, b20 ; K[1]>>count
shl.s2 b16, b2, b2 ; K[0]<<(32-count)
|| add.l1x b29, a17, a17 ; increment g
***************
* begin loop *
***************
aloop:
shr.s2 b16, b29, b16 ; K[0]=K[0]>>count
|| or.l2 b20, b2, b20 ; K[1]=K[1]|(K[0]<<(32-count))
|| mpy.m2 b19, 0, b19 ; load 0
|| add.l1 a19, 1, a19 ; o=o+1
subu.l2 b30, b20, b1:b0 ; MIN[1]-K[1]
|| sub.s2 b31, b16, b2 ; MIN[0]-K[0]
|| addab.d2 b20, 0, b18 ; load K[1]
|| add.l1 a19, a17, a18 ; g+o
|| rotl.m2 b20, 0, b22 ; save K[1]
shru.s2 b1, 7, b1 ; isolate carry
|| cmpeq.l1x b20, a20, a1 ; compare to K[1]
|| shl.s1 a18, 16, a18 ; (g+o)<<16
|| rotl.m2 b16, 0, b23 ; save K[0]
sub.s2 b2, b1, b2 ; MIN[0]-K[0]-carry
|| addu.l2 b19:b18, b18, b21:b20 ; K[1]*2
||[a1] cmpeq.l1x b16, a21, a1 ; compare to K[0]
|| or.s1 a18, a19, a18 ; ((g+o)<<16)|o
[!a1] shr.s2 b2, 31, b2 ; isolate sign
||[a1] mvk.d2 1, b2 ; set condition
|| addu.l2 b21:b20, b18, b21:b20 ; K[1]*3
[!a1] b.s1 aloop
|| addu.l2 b21:b20, b6, b21:b20 ; K[1]=K[1]*3+c
||[!b2] addab.d2 b23, 0, b31 ; MIN[0]=K[0]
||[!b2] rotl.m2 b22, 0, b30 ; MIN[1]=K[1]
|| mvk.s2 1, b1 ; load 1
addab.d2 b16, b16, b17 ; K[0]*2
||[!a2] and.l2 b20, 7, b1 ; check for attachment point
|| bitr.m2 b20, b0 ; bit-reverse K[1]
||[a1] b.s2 b3 ; return
||[a1] stw.d1 b31, *a6 ; save MIN[0]
addab.d2 b17, b16, b16 ; K[0]*3
||[!b1] mvk.s1 1, a2 ; set flag
||[!b1] stw.d1 b20, *+a6[4] ; save K[1]
addab.d2 b16, b21, b16 ; K[0]=K[0]*3+carry
|| lmbd.l2 1, b0, b29 ; count bits
|| mvk.s2 32, b2 ; load 32
||[a1] stw.d1 b30, *+a6[1] ; save MIN[1]
subab.d2 b2, b29, b2 ; 32-count
|| shru.s2 b20, b29, b20 ; K[1]>>count
||[a1] stw.d1 a18, *+a6[2] ; store ((g+o)<<16)|o
shl.s2 b16, b2, b2 ; K[0]<<(32-count)
|| add.l1x b29, a17, a17 ; increment g
||[!b1] stw.d1 b16, *+a6[3] ; save K[0]
****************
* end loop *
****************
mv.l1 a2, a4 ; return flag
.end