// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/inter.cpp
// Function: linear_chain_dp_adv(ul_ov_t*, long, ul_ov_t*, ul_idx_t const*, ug_opt_t const*, long, double, long, long, long, long, Chain_Data*, ma_ug_t*, long)
uint64_t linear_chain_dp_adv(ul_ov_t *ch, int64_t ch_n, ul_ov_t *sv, const ul_idx_t *uref, const ug_opt_t *uopt, int64_t bw, 
double diff_ec_ul, int64_t qlen, int64_t max_skip, int64_t max_iter, int64_t max_dis, Chain_Data* dp, ma_ug_t *ug, 
int64_t chain_offset)
{	///all in[].el must be 1
	if(ch_n == 0) return 0;
    int64_t /**mm_ovlp, x,**/ i, j, k, sc, csc, mm_sc, mm_idx, its, ite, max;
    ul_ov_t *li = NULL, *lj = NULL; int64_t *p, *t, st, plus, max_ii, n_skip, end_j; int32_t *f;
	resize_Chain_Data(dp, ch_n, NULL);
	t = dp->tmp; f = dp->score; p = dp->pre;

    radix_sort_ul_ov_srt_qe(ch, ch + ch_n);
	for (i = 1, j = 0; i <= ch_n; i++) {
        if (i == ch_n || ch[i].qe != ch[j].qe) {
            if(i - j > 1) radix_sort_ul_ov_srt_qs(ch+j, ch+i);
            j = i;
        }
    }

	// fprintf(stderr, "[M::%s::] ch_n:%ld\n", __func__, ch_n);
	memset(t, 0, (ch_n*sizeof((*t))));
	for (i = st = plus = 0, max_ii = -1; i < ch_n; ++i) {
		li = &(ch[i]); csc = li->qe - li->qs;
		mm_sc = csc; mm_idx = -1; n_skip = 0; end_j = -1; 
		st = (i<max_iter)?(0):(i-max_iter);
		for (j = i-1; j >= st; --j) {
			lj = &(ch[j]); 
			sc = comput_linear_sc(li, lj, diff_ec_ul, bw); ///should allow contain
			if(sc == INT32_MIN) continue;
			sc += f[j];
			if(sc > mm_sc) {
				mm_sc = sc, mm_idx = j;
				if (n_skip > 0) --n_skip;
			} else if (t[j] == i) {
				if (++n_skip > max_skip)
					break;
			}
			if (p[j] >= 0) t[p[j]] = i;
		}
		end_j = j;
		if (max_ii < 0 || (ch[i].qe>(ch[max_ii].qe+max_dis))) {//too long
			max = INT32_MIN; max_ii = -1;
            for (j = i - 1; (j >= st) && (ch[i].qe<=(max_dis+ch[j].qe)); --j) {
                if (max < f[j]) {
                    max = f[j], max_ii = j;
                }
            }
		}
		
        if (max_ii >= 0 && max_ii < end_j) {///just have a try with a[i]<->a[max_ii]
			lj = &(ch[max_ii]); 
			sc = comput_linear_sc(li, lj, diff_ec_ul, bw); ///should allow contain
			if(sc != INT32_MIN) {
				sc += f[max_ii];
				if(sc > mm_sc) {
					mm_sc = sc; mm_idx = max_ii;
				}
			}
		}

		f[i] = mm_sc; p[i] = mm_idx; 
        if ((max_ii < 0) || ((ch[i].qe<=max_dis+ch[max_ii].qe) && (f[max_ii]<f[i]))) {
            max_ii = i;
        }
		li->sec = (mm_idx<0?0x3FFFFFFF:i-mm_idx); sv[i] = *li;
		// fprintf(stderr, "##(%ld) %u\t%u\t%c\tutg%.6d%c(%u)\t%u\t%u\tmm_idx:%ld\tmm_sc:%ld\n", i, li->qs, li->qe, "+-"[li->rev], 
        // (int32_t)(li->tn)+1, "lc"[uref->ug->u.a[li->tn].circ], uref->ug->u.a[li->tn].len, li->ts, li->te, mm_idx, mm_sc);
		// track[i] = push_sc_pre(mm_sc, mm_idx); 
		// li->sec = (mm_idx<0?0x3FFFFFFF:i-mm_idx); sv[i] = *li;
	}

	for (i = 0; i < ch_n; ++i) t[i] = 0;
	int64_t n_u;
	for (k = ch_n-1, n_u = 0; k >= 0; --k) {
		if(t[k]) continue;
		i = k; ch[n_u]=sv[i]; sc = f[i];
		for (;i>=0;) {
			if(sv[i].qs < ch[n_u].qs) ch[n_u].qs = sv[i].qs;
			if(sv[i].ts < ch[n_u].ts) ch[n_u].ts = sv[i].ts;
			if(sv[i].qe > ch[n_u].qe) ch[n_u].qe = sv[i].qe;
			if(sv[i].te > ch[n_u].te) ch[n_u].te = sv[i].te;
			// ch[n_u].qn = i;//start idx of read alignment in chain
			t[i] = 1; i = p[i];
		}
		adjust_rev_tse(&(ch[n_u]), ug->g->seq[ch[n_u].tn].len, &its, &ite);
		ch[n_u].ts = its; ch[n_u].te = ite; ch[n_u].sec = (sc>0x3FFFFFFF?0x3FFFFFFF:sc);
		// ch[n_u].qn += chain_offset; //start idx of read alignment in chain
		// ch[n_u].tn = k + chain_offset; //end idx of read alignment in chain
		ch[n_u].qn = k + chain_offset; //end idx of read alignment in chain
		n_u++;
	}
	for (i = 0; i < ch_n; ++i) {
		adjust_rev_tse(&(sv[i]), ug->g->seq[sv[i].tn].len, &its, &ite);
		sv[i].ts = its; sv[i].te = ite; 
		k = p[i]; sv[i].tn = k>=0?k+chain_offset:(uint32_t)-1;
	}
	return n_u;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movq %r9, 0x48(%rsp)
testq %rsi, %rsi
je 0x1cf429
movq %rdx, %r14
movq %rsi, %rbx
movq %rdi, %r13
movsd %xmm0, 0x68(%rsp)
movq 0xd0(%rsp), %rbp
movq %rbp, %rdi
xorl %edx, %edx
callq 0x3ecb0
movq 0x28(%rbp), %r15
movq (%rbp), %rax
movq %rax, 0x38(%rsp)
movq 0x8(%rbp), %r12
leaq (%rbx,%rbx,8), %rax
leaq (%rax,%rax,2), %rsi
addq %r13, %rsi
addq %rbx, %rsi
movq %r13, %rdi
callq 0x19e2b4
testq %rbx, %rbx
jle 0x1cf42e
movq %r15, 0x18(%rsp)
movq %rbx, 0x30(%rsp)
negq %rbx
leaq 0x1c(%r13), %rbp
movl $0x1, %r15d
xorl %edi, %edi
movq %rbx, %rax
addq %r15, %rax
je 0x1cee3e
movl 0x8(%rbp), %eax
leaq (%rdi,%rdi,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %rdi, %rcx
cmpl 0x8(%r13,%rcx), %eax
jne 0x1cee3e
movq %rdi, %rax
jmp 0x1cee66
movq %r15, %rcx
subq %rdi, %rcx
movq %r15, %rax
cmpq $0x2, %rcx
jl 0x1cee66
leaq (%rdi,%rdi,8), %rax
leaq (%rax,%rax,2), %rax
addq %r13, %rdi
addq %rax, %rdi
movq %rbp, %rsi
callq 0x19e55c
movq %r15, %rax
leaq (%rbx,%r15), %rcx
incq %rcx
incq %r15
addq $0x1c, %rbp
movq %rax, %rdi
cmpq $0x1, %rcx
jne 0x1cee1c
movq 0x30(%rsp), %rax
leaq (,%rax,8), %rdx
movq 0x18(%rsp), %rdi
xorl %esi, %esi
movq %rdx, 0x60(%rsp)
callq 0x20e0
xorl %esi, %esi
leaq -0x8(%r13), %rax
movq %rax, 0x58(%rsp)
leaq -0x14(%r13), %rax
movq %rax, 0x50(%rsp)
movq $-0x1, %r9
movsd 0x68(%rsp), %xmm1
movq %r13, 0x20(%rsp)
leaq (%rsi,%rsi,8), %rax
leaq (%rax,%rax,2), %rax
addq %rsi, %rax
leaq (%rax,%r13), %rcx
movq %rcx, 0x10(%rsp)
movl 0x8(%r13,%rax), %r11d
movq %rax, 0x70(%rsp)
movl 0x4(%r13,%rax), %eax
movl %r11d, %edx
subl %eax, %edx
movq %rsi, %rax
subq 0xc0(%rsp), %rax
movl $0x0, %ecx
cmovgeq %rax, %rcx
leaq -0x1(%rsi), %r13
movq %rdx, 0x40(%rsp)
movq $-0x1, (%rsp)
movq %r13, %rax
movq %rsi, 0x8(%rsp)
cmpq %rcx, %rsi
jle 0x1cf03d
movq 0x10(%rsp), %rax
movl 0x14(%rax), %r15d
movq $-0x1, (%rsp)
movq 0x58(%rsp), %r8
movq $0x0, 0x28(%rsp)
movq %r13, %r10
movq 0x40(%rsp), %rsi
cmpl %r15d, (%r8)
jbe 0x1cef53
movq %rsi, %rdx
jmp 0x1cf026
movq %r14, %rdi
movq %r12, %r14
movl -0x10(%r8), %eax
movl %r11d, %edx
subl %eax, %edx
movl %r15d, %r12d
subl -0x4(%r8), %r12d
movq %rdx, %rax
subq %r12, %rax
movq %r12, %rbp
cmovaq %rdx, %rbp
movq %rax, %rbx
negq %rbx
cmpl %r12d, %edx
cmovaq %rax, %rbx
xorps %xmm0, %xmm0
cvtsi2sd %rbp, %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rdx
cmpq 0x48(%rsp), %rdx
jg 0x1cefa0
movq 0x48(%rsp), %rdx
cmpq %rdx, %rbx
movq %r14, %r12
jle 0x1cefb0
movq %rsi, %rdx
movq %rdi, %r14
jmp 0x1cf026
movq 0x38(%rsp), %rax
movslq (%rax,%r10,4), %rdx
addq 0x40(%rsp), %rdx
cmpq %rsi, %rdx
movq %rdi, %r14
jle 0x1cefe1
xorl %eax, %eax
movq 0x28(%rsp), %rsi
testq %rsi, %rsi
setg %al
subq %rax, %rsi
movq %rsi, 0x28(%rsp)
movq %r10, (%rsp)
jmp 0x1cf00f
movq 0x18(%rsp), %rax
movq 0x8(%rsp), %rdx
cmpq %rdx, (%rax,%r10,8)
jne 0x1cf00c
movq 0x28(%rsp), %rax
cmpq 0xb8(%rsp), %rax
jge 0x1cf238
incq %rax
movq %rax, 0x28(%rsp)
movq %rsi, %rdx
movq (%r12,%r10,8), %rax
testq %rax, %rax
js 0x1cf026
movq 0x18(%rsp), %rsi
movq 0x8(%rsp), %rdi
movq %rdi, (%rsi,%rax,8)
leaq -0x1(%r10), %rax
addq $-0x1c, %r8
movq %rdx, %rsi
cmpq %rcx, %r10
movq %rax, %r10
jg 0x1cef46
testq %r9, %r9
movq 0x30(%rsp), %rbx
movq 0x38(%rsp), %r10
movq 0xc8(%rsp), %r15
js 0x1cf070
leaq (%r9,%r9,8), %rsi
leaq (%rsi,%rsi,2), %rsi
addq %r9, %rsi
movq 0x20(%rsp), %rdi
movl 0x8(%rdi,%rsi), %esi
addq %r15, %rsi
cmpq %r11, %rsi
jge 0x1cf0b7
movq 0x8(%rsp), %rsi
cmpq %rcx, %rsi
jle 0x1cf0f1
movq $-0x80000000, %rsi      # imm = 0x80000000
movq $-0x1, %r9
movq 0x50(%rsp), %rdi
movl (%rdi), %r8d
addq %r15, %r8
cmpq %r11, %r8
jl 0x1cf0b7
movslq (%r10,%r13,4), %r8
cmpq %r8, %rsi
cmovleq %r8, %rsi
cmovlq %r13, %r9
leaq -0x1(%r13), %r8
addq $-0x1c, %rdi
cmpq %rcx, %r13
movq %r8, %r13
jg 0x1cf08d
testq %r9, %r9
sets %cl
cmpq %rax, %r9
setge %al
orb %cl, %al
leaq (%r9,%r9,8), %rax
jne 0x1cf10f
leaq (%rax,%rax,2), %rsi
addq %r9, %rsi
movq 0x10(%rsp), %r8
movl 0x14(%r8), %ecx
movq 0x20(%rsp), %r13
cmpl %ecx, 0x14(%r13,%rsi)
jbe 0x1cf13b
movq 0x8(%rsp), %rsi
jmp 0x1cf18b
movl %edx, (%r10,%rsi,4)
movq (%rsp), %rdi
movq %rdi, (%r12,%rsi,8)
movq %rsi, %rcx
movq 0x20(%rsp), %r13
movq 0x10(%rsp), %r8
jmp 0x1cf1de
movq 0x8(%rsp), %rsi
movl %edx, (%r10,%rsi,4)
movq (%rsp), %rdi
movq %rdi, (%r12,%rsi,8)
movq %rsi, %rcx
testq %r9, %r9
movq 0x20(%rsp), %r13
movq 0x10(%rsp), %r8
jns 0x1cf1bb
jmp 0x1cf1de
addq %r13, %rsi
subl 0x4(%rsi), %r11d
subl 0x10(%rsi), %ecx
movq %r11, %rsi
subq %rcx, %rsi
movq %rcx, %rdi
cmovaq %r11, %rdi
movq %rsi, %r8
negq %r8
cmpl %ecx, %r11d
cmovaq %rsi, %r8
xorps %xmm0, %xmm0
cvtsi2sd %rdi, %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %rcx
movq 0x48(%rsp), %rsi
cmpq %rsi, %rcx
cmovleq %rsi, %rcx
cmpq %rcx, %r8
jle 0x1cf191
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %r8
movq (%rsp), %rdi
jmp 0x1cf1b3
movslq (%r10,%r9,4), %rcx
addq 0x40(%rsp), %rcx
cmpq %rdx, %rcx
cmovgq %rcx, %rdx
movq (%rsp), %rdi
cmovgq %r9, %rdi
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %r8
movl %edx, (%r10,%rsi,4)
movq %rdi, (%r12,%rsi,8)
movl 0x8(%r8), %ecx
leaq (%rax,%rax,2), %rax
addq %r9, %rax
movl 0x8(%r13,%rax), %eax
addq %r15, %rax
cmpq %rcx, %rax
jl 0x1cf1db
cmpl %edx, (%r10,%r9,4)
cmovlq %rsi, %r9
movq %r9, %rcx
movl %esi, %eax
subl %edi, %eax
movl $0x3fffffff, %edx       # imm = 0x3FFFFFFF
andl %edx, %eax
testq %rdi, %rdi
cmovsl %edx, %eax
movl 0x18(%r8), %edx
movl $0xc0000000, %edi       # imm = 0xC0000000
andl %edi, %edx
orl %eax, %edx
movl %edx, 0x18(%r8)
movups (%r8), %xmm0
movq 0x70(%rsp), %rax
movups %xmm0, (%r14,%rax)
movupd 0xc(%r8), %xmm0
movupd %xmm0, 0xc(%r14,%rax)
incq %rsi
addq $0x1c, 0x58(%rsp)
addq $0x1c, 0x50(%rsp)
movq %rcx, %r9
cmpq %rbx, %rsi
jne 0x1ceec1
jmp 0x1cf243
movq %rsi, %rdx
movq %r10, %rax
jmp 0x1cf03d
xorl %r13d, %r13d
movq 0x18(%rsp), %r15
movq %r15, %rdi
xorl %esi, %esi
movq 0x60(%rsp), %rdx
callq 0x20e0
movl $0x3fffffff, %ecx       # imm = 0x3FFFFFFF
movq %rbx, %rdx
movq 0xe0(%rsp), %r11
leaq -0x1(%rdx), %rsi
cmpq $0x0, -0x8(%r15,%rdx,8)
jne 0x1cf3ae
leaq (%rsi,%rsi,8), %rax
leaq (%rax,%rax,2), %rax
addq %rsi, %rax
leaq (,%r13,8), %rdi
addq %r13, %rdi
leaq (%rdi,%rdi,2), %r9
addq %r13, %r9
movq 0x20(%rsp), %r11
leaq (%r11,%r9), %rdi
movupd (%r14,%rax), %xmm0
movupd 0xc(%r14,%rax), %xmm1
movupd %xmm1, 0xc(%r11,%r9)
movupd %xmm0, (%r11,%r9)
movq 0x38(%rsp), %rax
movl (%rax,%rsi,4), %r8d
movl 0x4(%r11,%r9), %eax
movl 0x8(%r11,%r9), %ebx
movl 0x10(%r11,%r9), %r10d
movl 0x14(%r11,%r9), %r9d
movq %rsi, %r15
leaq (%r15,%r15,8), %r11
leaq (%r11,%r11,2), %rbp
addq %r15, %rbp
movl 0x4(%r14,%rbp), %r11d
cmpl %eax, %r11d
jae 0x1cf2f6
movl %r11d, 0x4(%rdi)
movl %r11d, %eax
addq %r14, %rbp
movl 0x10(%rbp), %r11d
cmpl %r10d, %r11d
jae 0x1cf309
movl %r11d, 0x10(%rdi)
movl %r11d, %r10d
movl 0x8(%rbp), %r11d
cmpl %ebx, %r11d
jbe 0x1cf319
movl %r11d, 0x8(%rdi)
movl %r11d, %ebx
movl 0x14(%rbp), %r11d
cmpl %r9d, %r11d
jbe 0x1cf329
movl %r11d, 0x14(%rdi)
movl %r11d, %r9d
movq 0x18(%rsp), %r11
movq $0x1, (%r11,%r15,8)
movq (%r12,%r15,8), %r15
testq %r15, %r15
jns 0x1cf2da
movq 0xd8(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
movl 0xc(%rdi), %r11d
movl 0x18(%rdi), %ebx
movl (%rax,%r11,8), %eax
movl $0x7fffffff, %r11d      # imm = 0x7FFFFFFF
andl %r11d, %eax
movl %eax, %r11d
subl %r9d, %r11d
subl %r10d, %eax
testl %ebx, %ebx
cmovnsl %r10d, %r11d
cmovnsl %r9d, %eax
movl %r11d, 0x10(%rdi)
cmpl %ecx, %r8d
cmovgel %ecx, %r8d
movl %eax, 0x14(%rdi)
andl %ecx, %r8d
andl $0xc0000000, %ebx       # imm = 0xC0000000
orl %r8d, %ebx
movl %ebx, 0x18(%rdi)
movq 0xe0(%rsp), %r11
leal (%rsi,%r11), %eax
movl %eax, (%rdi)
incq %r13
movq 0x30(%rsp), %rbx
movq 0x18(%rsp), %r15
cmpq $0x1, %rdx
movq %rsi, %rdx
jg 0x1cf26a
movq 0xd8(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
addq $0xc, %r14
xorl %ecx, %ecx
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl (%r14), %edi
movl 0x4(%r14), %r8d
movl (%rax,%rdi,8), %edi
andl %edx, %edi
movl 0x8(%r14), %r9d
movl %edi, %r10d
subl %r9d, %r10d
subl %r8d, %edi
cmpl $0x0, 0xc(%r14)
cmovnsl %r8d, %r10d
cmovnsl %r9d, %edi
movl %r10d, 0x4(%r14)
movl %edi, 0x8(%r14)
movq (%r12,%rcx,8), %rdi
leal (%rdi,%r11), %r8d
testq %rdi, %rdi
cmovsl %esi, %r8d
movl %r8d, (%r14)
incq %rcx
addq $0x1c, %r14
cmpq %rcx, %rbx
jne 0x1cf3db
jmp 0x1cf442
xorl %r13d, %r13d
jmp 0x1cf442
shlq $0x3, %rbx
xorl %r13d, %r13d
movq %r15, %rdi
xorl %esi, %esi
movq %rbx, %rdx
callq 0x20e0
movq %r13, %rax
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq