// File: chhylp123[P]hifiasm/rcut.cpp
// Function: mc_init_spin_all(mc_opt_t const*, mc_g_t*, mb_g_t*, mc_svaux_t*)
void mc_init_spin_all(const mc_opt_t *opt, mc_g_t *mg, mb_g_t *mbg, mc_svaux_t *b)
{
	uint32_t st, i, k, m, a_n[2], *a[2], qn;
	for (st = 0, i = 1; i <= mg->e->n_seq; ++i) {
		if (i == mg->e->n_seq || mg->e->cc[st]>>32 != mg->e->cc[i]>>32) {
			b->cc_off = st, b->cc_size = i - st;
			if (b->cc_size >= 2)
			{
				mc_init_spin(mg->e, b);
			}
			st = i;
		}
	}

	if(!mbg) return;
	// memcpy(b->s_opt, b->s, sizeof(int8_t)*mg->e->n_seq);

	///adjust by block
	kvec_t(uint32_t) s; kv_init(s);
	uint32_t ws, we, n_flip;
	uint8_t *vis = NULL; CALLOC(vis, mg->e->n_seq);
	t_w_t w = 0, max_w = 0;
	for (i = 0; i < mbg->u->u.n; i++)///each block
	{
		decode_mb_node(mbg, i, &(a[0]), &(a_n[0]), NULL, &(a[1]), &(a_n[1]), NULL);
		///if(a_n[0] == 0 || a_n[1] == 0) continue;
		if(a_n[0] + a_n[1] <= 1) continue;
		s.n = 0;
		for (k = 0; k < a_n[0]; k++)
        {
            qn = a[0][k];
			if(b->s[qn] == 0) continue;
			// qn <<= 1;
			if(b->s[qn] < 0) qn += ((uint32_t)1<<31);			
			kv_push(uint32_t, s, qn);
		}

		for (k = 0; k < a_n[1]; k++)
        {
            qn = a[1][k];
			if(b->s[qn] == 0) continue;
			// qn <<= 1; qn++;
			if(b->s[qn] > 0) qn += ((uint32_t)1<<31);
			kv_push(uint32_t, s, qn);
		}

		if(s.n == 0) continue;
		radix_sort_mc32(s.a, s.a + s.n);

		ws = we = (uint32_t)-1; n_flip = 0;
		for (st = 0, k = 1; k <= s.n; k++)
		{
			if(k == s.n || (s.a[k]>>31) != (s.a[st]>>31))
			{
				w = 0;
				for (m = st; m < k; m++) vis[(s.a[m]<<1)>>1] = 1;
				for (m = st; m < k; m++) w += incre_weight(b, mg->e, vis, (s.a[m]<<1)>>1);
				for (m = st; m < k; m++) vis[(s.a[m]<<1)>>1] = 0;
				if(ws == (uint32_t)-1 || max_w < w) max_w = w, ws = st, we = k;
				st = k;
				n_flip++;
			}
		}

		if(n_flip <= 1) continue;

		/*******************************for debug************************************/
		// t_w_t sc_opt = mc_score_all(mg->e, b);
		/*******************************for debug************************************/
		for (m = ws; m < we; m++) mc_set_spin(mg->e, b, (s.a[m]<<1)>>1, -b->s[(s.a[m]<<1)>>1]);
		/*******************************for debug************************************/
		// t_w_t sc_cur = mc_score_all(mg->e, b);
		// if(sc_cur - sc_opt != max_w*2)
		// {
		// 	fprintf(stderr, "ERROR-0-::%s\n", __func__);
		// 	// fprintf(stderr, "sc_opt: %ld, sc_cur: %ld, max_w: %ld\n", sc_opt, sc_cur, max_w);
		// 	fprintf(stderr, "sc_opt: %f, sc_cur: %f, max_w: %f\n", sc_opt, sc_cur, max_w);
		// }
		/*******************************for debug************************************/
	}
	kv_destroy(s); free(vis);

	for (i = 0; i < mbg->u->u.n; i++)///each block
	{
		decode_mb_node(mbg, i, &(a[0]), &(a_n[0]), NULL, &(a[1]), &(a_n[1]), NULL);
		mbg->u->u.a[i].s[0] = mbg->u->u.a[i].s[1] = 0;
		mbg->u->u.a[i].z[0] = mbg->u->u.a[i].z[1] = 0;
		mbg->u->u.a[i].z[2] = mbg->u->u.a[i].z[3] = 0;
		for (k = 0; k < a_n[0]; k++)
        {
            qn = a[0][k];
			if(b->s[qn] == 0) continue;
			mbg->u->u.a[i].s[0] = b->s[qn];
			break;
		}

		for (k = 0; k < a_n[1]; k++)
        {
            qn = a[1][k];
			if(b->s[qn] == 0) continue;
			mbg->u->u.a[i].s[1] = b->s[qn];
			break;
		}
	}

	reset_mb_g_t_z(mbg);

	/*******************************for debug************************************/
	// debug_mbg(mbg, mg, b);
	/*******************************for debug************************************/
	// memcpy(b->s, b->s_opt, sizeof(int8_t)*mg->e->n_seq);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movl $0x1, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x10(%rbp), %rcx
movq 0x28(%rcx), %rcx
cmpl 0x38(%rcx), %eax
ja 0x2246f8
movl -0x28(%rbp), %eax
movq -0x10(%rbp), %rcx
movq 0x28(%rcx), %rcx
cmpl 0x38(%rcx), %eax
je 0x2246b0
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq 0x30(%rax), %rax
movl -0x24(%rbp), %ecx
movq (%rax,%rcx,8), %rax
shrq $0x20, %rax
movq -0x10(%rbp), %rcx
movq 0x28(%rcx), %rcx
movq 0x30(%rcx), %rcx
movl -0x28(%rbp), %edx
movq (%rcx,%rdx,8), %rcx
shrq $0x20, %rcx
cmpq %rcx, %rax
je 0x2246e8
movl -0x24(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0x8(%rax)
movl -0x28(%rbp), %ecx
subl -0x24(%rbp), %ecx
movq -0x20(%rbp), %rax
movl %ecx, 0xc(%rax)
movq -0x20(%rbp), %rax
cmpl $0x2, 0xc(%rax)
jb 0x2246e2
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x20(%rbp), %rsi
callq 0x21ca90
movl -0x28(%rbp), %eax
movl %eax, -0x24(%rbp)
jmp 0x2246ea
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x224659
cmpq $0x0, -0x18(%rbp)
jne 0x224704
jmp 0x224d60
movq $0x0, -0x68(%rbp)
movq $0x0, -0x70(%rbp)
movq $0x0, -0x60(%rbp)
movq $0x0, -0x88(%rbp)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movl 0x38(%rax), %eax
movl %eax, %edi
movl $0x1, %esi
callq 0x2140
movq %rax, -0x88(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x90(%rbp)
xorps %xmm0, %xmm0
movsd %xmm0, -0x98(%rbp)
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x18(%rbp), %rcx
movq (%rcx), %rcx
cmpq 0x30(%rcx), %rax
jae 0x224b73
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
leaq -0x50(%rbp), %rdx
leaq -0x38(%rbp), %rcx
leaq -0x50(%rbp), %r9
addq $0x8, %r9
leaq -0x38(%rbp), %rax
addq $0x4, %rax
xorl %r8d, %r8d
movq %rax, (%rsp)
movq $0x0, 0x8(%rsp)
callq 0x22d100
movl -0x38(%rbp), %eax
addl -0x34(%rbp), %eax
cmpl $0x1, %eax
ja 0x2247ba
jmp 0x224b65
movq $0x0, -0x70(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x38(%rbp), %eax
jae 0x224894
movq -0x50(%rbp), %rax
movl -0x2c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x54(%rbp)
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x54(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x2247fb
jmp 0x224886
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x54(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jge 0x22481a
movl -0x54(%rbp), %eax
addl $0x80000000, %eax       # imm = 0x80000000
movl %eax, -0x54(%rbp)
jmp 0x22481c
movq -0x70(%rbp), %rax
cmpq -0x68(%rbp), %rax
jne 0x22486b
cmpq $0x0, -0x68(%rbp)
je 0x22483d
movq -0x68(%rbp), %rax
shlq %rax
movq %rax, -0xa0(%rbp)
jmp 0x22484b
movl $0x2, %eax
movq %rax, -0xa0(%rbp)
jmp 0x22484b
movq -0xa0(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rdi
movq -0x68(%rbp), %rsi
shlq $0x2, %rsi
callq 0x2360
movq %rax, -0x60(%rbp)
movl -0x54(%rbp), %edx
movq -0x60(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0x70(%rbp)
movl %edx, (%rax,%rcx,4)
jmp 0x224886
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x2247c9
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jae 0x224966
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x54(%rbp)
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x54(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x2248cd
jmp 0x224958
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x54(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jle 0x2248ec
movl -0x54(%rbp), %eax
addl $0x80000000, %eax       # imm = 0x80000000
movl %eax, -0x54(%rbp)
jmp 0x2248ee
movq -0x70(%rbp), %rax
cmpq -0x68(%rbp), %rax
jne 0x22493d
cmpq $0x0, -0x68(%rbp)
je 0x22490f
movq -0x68(%rbp), %rax
shlq %rax
movq %rax, -0xa8(%rbp)
jmp 0x22491d
movl $0x2, %eax
movq %rax, -0xa8(%rbp)
jmp 0x22491d
movq -0xa8(%rbp), %rax
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rdi
movq -0x68(%rbp), %rsi
shlq $0x2, %rsi
callq 0x2360
movq %rax, -0x60(%rbp)
movl -0x54(%rbp), %edx
movq -0x60(%rbp), %rax
movq -0x70(%rbp), %rcx
movq %rcx, %rsi
addq $0x1, %rsi
movq %rsi, -0x70(%rbp)
movl %edx, (%rax,%rcx,4)
jmp 0x224958
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x22489b
cmpq $0x0, -0x70(%rbp)
jne 0x224972
jmp 0x224b65
movq -0x60(%rbp), %rdi
movq -0x60(%rbp), %rsi
movq -0x70(%rbp), %rax
shlq $0x2, %rax
addq %rax, %rsi
callq 0x2166b0
movl $0xffffffff, -0x78(%rbp) # imm = 0xFFFFFFFF
movl $0xffffffff, -0x74(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x7c(%rbp)
movl $0x0, -0x24(%rbp)
movl $0x1, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpq -0x70(%rbp), %rax
ja 0x224afe
movl -0x2c(%rbp), %eax
cmpq -0x70(%rbp), %rax
je 0x2249e5
movq -0x60(%rbp), %rax
movl -0x2c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
shrl $0x1f, %eax
movq -0x60(%rbp), %rcx
movl -0x24(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
shrl $0x1f, %ecx
cmpl %ecx, %eax
je 0x224aee
xorps %xmm0, %xmm0
movsd %xmm0, -0x90(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jae 0x224a24
movq -0x88(%rbp), %rax
movq -0x60(%rbp), %rcx
movl -0x30(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
shll %ecx
shrl %ecx
movl %ecx, %ecx
movb $0x1, (%rax,%rcx)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x2249f6
movl -0x24(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jae 0x224a73
movq -0x20(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rsi
movq -0x88(%rbp), %rdx
movq -0x60(%rbp), %rax
movl -0x30(%rbp), %ecx
movl (%rax,%rcx,4), %ecx
shll %ecx
shrl %ecx
callq 0x21d770
addsd -0x90(%rbp), %xmm0
movsd %xmm0, -0x90(%rbp)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x224a2a
movl -0x24(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x2c(%rbp), %eax
jae 0x224aa7
movq -0x88(%rbp), %rax
movq -0x60(%rbp), %rcx
movl -0x30(%rbp), %edx
movl (%rcx,%rdx,4), %ecx
shll %ecx
shrl %ecx
movl %ecx, %ecx
movb $0x0, (%rax,%rcx)
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x224a79
cmpl $-0x1, -0x74(%rbp)
je 0x224ac3
movsd -0x98(%rbp), %xmm1
movsd -0x90(%rbp), %xmm0
ucomisd %xmm1, %xmm0
jbe 0x224adf
movsd -0x90(%rbp), %xmm0
movsd %xmm0, -0x98(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x74(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0x78(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x224af0
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x2249ad
cmpl $0x1, -0x7c(%rbp)
ja 0x224b06
jmp 0x224b65
movl -0x74(%rbp), %eax
movl %eax, -0x30(%rbp)
movl -0x30(%rbp), %eax
cmpl -0x78(%rbp), %eax
jae 0x224b63
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x20(%rbp), %rsi
movq -0x60(%rbp), %rax
movl -0x30(%rbp), %ecx
movl (%rax,%rcx,4), %edx
shll %edx
shrl %edx
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movq -0x60(%rbp), %rcx
movl -0x30(%rbp), %r8d
movl (%rcx,%r8,4), %ecx
shll %ecx
shrl %ecx
movl %ecx, %ecx
movsbl (%rax,%rcx), %ecx
xorl %eax, %eax
subl %ecx, %eax
movsbl %al, %ecx
callq 0x21d470
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
jmp 0x224b0c
jmp 0x224b65
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x224762
movq -0x60(%rbp), %rdi
callq 0x2210
movq -0x88(%rbp), %rdi
callq 0x2210
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movq -0x18(%rbp), %rcx
movq (%rcx), %rcx
cmpq 0x30(%rcx), %rax
jae 0x224d57
movq -0x18(%rbp), %rdi
movl -0x28(%rbp), %esi
leaq -0x50(%rbp), %rdx
leaq -0x38(%rbp), %rcx
leaq -0x50(%rbp), %r9
addq $0x8, %r9
leaq -0x38(%rbp), %rax
addq $0x4, %rax
xorl %r8d, %r8d
movq %rax, (%rsp)
movq $0x0, 0x8(%rsp)
callq 0x22d100
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x40(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movb $0x0, 0x11(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x40(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
movb $0x0, 0x10(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x40(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x20(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x40(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x18(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x40(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x30(%rax)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x40(%rax), %rax
movl -0x28(%rbp), %ecx
imulq $0x38, %rcx, %rcx
addq %rcx, %rax
xorps %xmm0, %xmm0
movsd %xmm0, 0x28(%rax)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x38(%rbp), %eax
jae 0x224ce2
movq -0x50(%rbp), %rax
movl -0x2c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x54(%rbp)
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x54(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x224caf
jmp 0x224cd7
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x54(%rbp), %ecx
movb (%rax,%rcx), %cl
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x40(%rax), %rax
movl -0x28(%rbp), %edx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movb %cl, 0x10(%rax)
jmp 0x224ce2
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x224c84
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jae 0x224d47
movq -0x48(%rbp), %rax
movl -0x2c(%rbp), %ecx
movl (%rax,%rcx,4), %eax
movl %eax, -0x54(%rbp)
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x54(%rbp), %ecx
movsbl (%rax,%rcx), %eax
cmpl $0x0, %eax
jne 0x224d14
jmp 0x224d3c
movq -0x20(%rbp), %rax
movq 0x50(%rax), %rax
movl -0x54(%rbp), %ecx
movb (%rax,%rcx), %cl
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq 0x40(%rax), %rax
movl -0x28(%rbp), %edx
imulq $0x38, %rdx, %rdx
addq %rdx, %rax
movb %cl, 0x11(%rax)
jmp 0x224d47
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x224ce9
jmp 0x224d49
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x224b8f
movq -0x18(%rbp), %rdi
callq 0x224080
addq $0xc0, %rsp
popq %rbp
retq
nopl (%rax)