// File: /workspace/github_cpp_makefile_star2_O1/chhylp123[P]hifiasm/inter.cpp
// Function: linear_chain_dp(ul_ov_t*, long, ul_ov_t*, ul_idx_t const*, ug_opt_t const*, long, double, long, long, unsigned long*, unsigned long*, ma_ug_t*, long)
uint64_t linear_chain_dp(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, uint64_t *idx, uint64_t *track, 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, jts, jte, cov_i, dq, dt, dd, mm;
    ul_ov_t *li = NULL, *lj = NULL;
    radix_sort_ul_ov_srt_qe(ch, ch + ch_n);
	for (i = 1, j = 0; i <= ch_n; i++) {
		// if(i < ch_n) {
		// 	li = &(ch[i]); 
		// 	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);
		// }
        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);
	for (i = 0; i < ch_n; ++i) {
		li = &(ch[i]); 
		// mm_ovlp = max_ovlp_src(uopt, ((li->tn<<1)|li->rev)^1);  
		// x = (li->qs + mm_ovlp)*diff_ec_ul; 
        // if(x < bw) x = bw; 
        // x += li->qs + mm_ovlp;
        // if (x > qlen+1) x = qlen+1;
        // x = find_ul_ov_max(i, ch, x+G_CHAIN_INDEL); 
		adjust_rev_tse(li, ug->g->seq[li->tn].len, &its, &ite);
		cov_i = 0;
		csc = retrieve_u_cov_region(uref, li->tn, 0, its, ite, &cov_i);
		mm_sc = csc; mm_idx = -1; 
		for (j = i-1/**x**/; j >= 0; --j) {
			lj = &(ch[j]); 
			// fprintf(stderr, "<0>\n");
			if(lj->qs <= li->qs && lj->qe <= li->qe && lj->ts <= li->ts && lj->te <= li->te) {///co-linear
				assert(li->tn == lj->tn && li->rev == lj->rev);
				// fprintf(stderr, "<1>\n");
				if(lj->qs == li->qs && lj->qe == li->qe && lj->ts == li->ts && lj->te == li->te) continue;
				dq = li->qe - lj->qs; dt = li->te - lj->ts;
				dd = (dq>dt? dq-dt:dt-dq);
				mm = MAX(dq, dt); mm *= diff_ec_ul; if(mm < bw) mm = bw;
				// fprintf(stderr, "+++i->%ld, j->%ld, dd->%ld, mm->%ld\n", i, j, dd, mm);
				if(dd <= mm) {///pass distance checking
					adjust_rev_tse(lj, ug->g->seq[lj->tn].len, &jts, &jte);
					sc = get_add_cov_score(uref, jts, jte, its, ite, li->tn, &cov_i) + pop_sc(track[j]);
					
					if((sc > mm_sc) || (sc == mm_sc && mm_idx == -1)) { ///must be >= instead of >
						mm_sc = sc, mm_idx = j;
					}
					// fprintf(stderr, "<i->%ld, its:%ld, ite:%ld>, <j->%ld, jts:%ld, jte:%ld> sc:%ld, pop_sc(track[j]):%ld, csc:%ld\n", 
					// i, its, ite, j, jts, jte, sc, pop_sc(track[j]), csc);
				}
			}
		}

		// 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;
	}

	int64_t n_u;
	for (k = ch_n-1, n_u = 0; k >= 0; --k) {
		if(track[k]&((uint64_t)0x80000000)) continue;
		i = k; ch[n_u]=sv[i]; sc = pop_sc(track[i]);
		for (;i>=0;) {
			track[i] |= ((uint64_t)0x80000000);
			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
			i = pop_pre(track[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 = pop_pre(track[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 $0x88, %rsp
movsd %xmm0, 0x58(%rsp)
movq %r9, 0x38(%rsp)
movq %rcx, 0x40(%rsp)
testq %rsi, %rsi
je 0x1c4dda
movq %rdx, %rbx
movq %rsi, %r14
leaq (%rsi,%rsi,8), %rax
leaq (%rax,%rax,2), %rsi
addq %rdi, %rsi
addq %r14, %rsi
movq %rdi, 0x10(%rsp)
callq 0x195511
movq %r14, 0x28(%rsp)
testq %r14, %r14
jle 0x1c4891
movq 0x28(%rsp), %r14
negq %r14
movq 0x10(%rsp), %rax
leaq 0x1c(%rax), %r12
movl $0x1, %r15d
xorl %edi, %edi
movq %r14, %rax
addq %r15, %rax
je 0x1c4850
movl 0x8(%r12), %eax
leaq (%rdi,%rdi,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %rdi, %rcx
movq 0x10(%rsp), %rdx
cmpl 0x8(%rdx,%rcx), %eax
jne 0x1c4850
movq %rdi, %rax
jmp 0x1c487a
movq %r15, %rcx
subq %rdi, %rcx
movq %r15, %rax
cmpq $0x2, %rcx
jl 0x1c487a
leaq (%rdi,%rdi,8), %rax
leaq (%rax,%rax,2), %rax
addq 0x10(%rsp), %rdi
addq %rax, %rdi
movq %r12, %rsi
callq 0x1957bd
movq %r15, %rax
leaq (%r14,%r15), %rcx
incq %rcx
incq %r15
addq $0x1c, %r12
movq %rax, %rdi
cmpq $0x1, %rcx
jne 0x1c4828
movq 0xd8(%rsp), %r15
movq 0x28(%rsp), %r14
testq %r14, %r14
jle 0x1c4b93
movq 0x10(%rsp), %rax
leaq -0x4(%rax), %r12
movq $-0x1, 0x48(%rsp)
xorl %esi, %esi
movq %rsi, 0x18(%rsp)
leaq (%rsi,%rsi,8), %rax
leaq (%rax,%rax,2), %rdi
addq %rsi, %rdi
movq 0xe0(%rsp), %rax
movq 0x18(%rax), %rax
movq 0x20(%rax), %rax
movq 0x10(%rsp), %rdx
movl 0xc(%rdx,%rdi), %esi
movl 0x10(%rdx,%rdi), %r8d
movl (%rax,%rsi,8), %r15d
andl $0x7fffffff, %r15d      # imm = 0x7FFFFFFF
movl 0x14(%rdx,%rdi), %eax
movq %r15, %rcx
subq %rax, %rcx
subq %r8, %r15
cmpl $0x0, 0x18(%rdx,%rdi)
cmovnsq %r8, %rcx
movq %rdi, 0x78(%rsp)
leaq (%rdx,%rdi), %r14
cmovnsq %rax, %r15
movq $0x0, 0x50(%rsp)
movq 0x40(%rsp), %rdi
xorl %edx, %edx
movq %rcx, 0x68(%rsp)
movq %r15, %r8
leaq 0x50(%rsp), %r9
callq 0x36ec9
movq 0x18(%rsp), %rsi
testq %rsi, %rsi
movq %r12, 0x80(%rsp)
je 0x1c4af7
movq %r15, 0x60(%rsp)
movq $-0x1, 0x30(%rsp)
movq 0x48(%rsp), %r15
movl -0x14(%r12), %r8d
movl 0x4(%r14), %r11d
cmpl %r11d, %r8d
ja 0x1c4a37
movl -0x10(%r12), %r13d
movl 0x8(%r14), %edx
cmpl %edx, %r13d
ja 0x1c4a37
movl -0x8(%r12), %r9d
movl 0x10(%r14), %ebp
cmpl %ebp, %r9d
ja 0x1c4a37
movl -0x4(%r12), %ecx
movl 0x14(%r14), %r10d
cmpl %r10d, %ecx
ja 0x1c4a37
movq %rax, 0x20(%rsp)
movl 0xc(%r14), %eax
movl -0xc(%r12), %esi
movq %rax, 0x70(%rsp)
cmpl %esi, %eax
jne 0x1c4dee
movl (%r12), %eax
movl 0x18(%r14), %edi
xorl %eax, %edi
js 0x1c4dee
cmpl %r11d, %r8d
jne 0x1c49e9
cmpl %edx, %r13d
jne 0x1c49e9
cmpl %ebp, %r9d
jne 0x1c49e9
cmpl %r10d, %ecx
je 0x1c4a2d
subl %r8d, %edx
subl %r9d, %r10d
movq %rdx, %rdi
subq %r10, %rdi
movq %r10, %r11
cmovaq %rdx, %r11
movq %rdi, %r8
negq %r8
cmpl %r10d, %edx
cmovaq %rdi, %r8
xorps %xmm0, %xmm0
cvtsi2sd %r11, %xmm0
mulsd 0x58(%rsp), %xmm0
cvttsd2si %xmm0, %rdx
cmpq 0x38(%rsp), %rdx
jg 0x1c4a28
movq 0x38(%rsp), %rdx
cmpq %rdx, %r8
jle 0x1c4a54
movq 0x18(%rsp), %rsi
movq 0x20(%rsp), %rax
leaq -0x1(%r15), %rcx
incq %r15
addq $-0x1c, %r12
cmpq $0x1, %r15
movq %rcx, %r15
jg 0x1c4962
jmp 0x1c4b00
movq 0xe0(%rsp), %rdx
movq 0x18(%rdx), %rdx
movq 0x20(%rdx), %rdx
movl (%rdx,%rsi,8), %edx
andl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movq %rdx, %rsi
subq %rcx, %rsi
subq %r9, %rdx
testl %eax, %eax
cmovnsq %r9, %rsi
cmovnsq %rcx, %rdx
leaq 0x50(%rsp), %rax
movq %rax, (%rsp)
movq 0x40(%rsp), %rdi
movq 0x68(%rsp), %rcx
movq 0x60(%rsp), %r8
movq 0x70(%rsp), %r9
callq 0x1c4710
movq 0xd8(%rsp), %rcx
movq (%rcx,%r15,8), %rdx
movq %rdx, %rcx
shrq $0x20, %rcx
leaq -0x80000000(%rcx), %rsi
negq %rcx
testq %rdx, %rdx
cmovsq %rsi, %rcx
addq %rax, %rcx
movq 0x20(%rsp), %rax
cmpq %rax, %rcx
movq 0x18(%rsp), %rsi
jg 0x1c4aea
jne 0x1c4a37
cmpq $-0x1, 0x30(%rsp)
jne 0x1c4a37
movq %rcx, %rax
movq %r15, 0x30(%rsp)
jmp 0x1c4a37
movq $-0x1, 0x30(%rsp)
movl %eax, %edx
movl $0x80000000, %ecx       # imm = 0x80000000
orl %ecx, %edx
movl %eax, %ecx
negl %ecx
testq %rax, %rax
cmovnsq %rdx, %rcx
shlq $0x20, %rcx
movl %esi, %eax
movq 0x30(%rsp), %r8
subl %r8d, %eax
movl $0x3fffffff, %edx       # imm = 0x3FFFFFFF
andl %edx, %eax
testq %r8, %r8
movl $0x7fffffff, %edi       # imm = 0x7FFFFFFF
cmovsq %rdi, %r8
cmovsl %edx, %eax
orq %rcx, %r8
movq 0xd8(%rsp), %r15
movq %r8, (%r15,%rsi,8)
movl 0x18(%r14), %ecx
movl $0xc0000000, %edx       # imm = 0xC0000000
andl %edx, %ecx
orl %eax, %ecx
movl %ecx, 0x18(%r14)
movups (%r14), %xmm0
movq 0x78(%rsp), %rax
movups %xmm0, (%rbx,%rax)
movupd 0xc(%r14), %xmm0
movupd %xmm0, 0xc(%rbx,%rax)
incq %rsi
incq 0x48(%rsp)
movq 0x80(%rsp), %r12
addq $0x1c, %r12
movq 0x28(%rsp), %r14
cmpq %r14, %rsi
jne 0x1c48bb
movq 0xe8(%rsp), %r13
xorl %eax, %eax
testq %r14, %r14
jle 0x1c4d4c
movl $0x7fffffff, %edx       # imm = 0x7FFFFFFF
movq $-0x1, %rsi
movq %r14, %r9
leaq -0x1(%r9), %rdi
testb $-0x80, -0x5(%r15,%r9,8)
jne 0x1c4d3f
leaq (%rdi,%rdi,8), %rcx
leaq (%rcx,%rcx,2), %rcx
addq %rdi, %rcx
movq %rdi, %r10
leaq (%rax,%rax,8), %rdi
leaq (%rdi,%rdi,2), %rdi
movq %rax, 0x18(%rsp)
addq %rax, %rdi
movq 0x10(%rsp), %r13
leaq (%rdi,%r13), %r11
movupd (%rbx,%rcx), %xmm0
movups 0xc(%rbx,%rcx), %xmm1
movups %xmm1, 0xc(%r13,%rdi)
movupd %xmm0, (%r13,%rdi)
movq (%r15,%r10,8), %rcx
movq %rcx, %r14
shrq $0x20, %r14
leaq -0x80000000(%r14), %r8
negq %r14
testq %rcx, %rcx
cmovsq %r8, %r14
movl 0x4(%r13,%rdi), %ebp
movl 0x8(%r13,%rdi), %r15d
movl 0x10(%r13,%rdi), %r12d
movl 0x14(%r13,%rdi), %r13d
movq %r10, 0x20(%rsp)
movq %r10, %rdi
movq 0xd8(%rsp), %r10
movq (%r10,%rdi,8), %rcx
movq %rcx, %r8
movl $0x80000000, %eax       # imm = 0x80000000
orq %rax, %r8
movq %r8, (%r10,%rdi,8)
leaq (%rdi,%rdi,8), %r8
leaq (%r8,%r8,2), %r8
addq %rdi, %r8
movl 0x4(%rbx,%r8), %edi
cmpl %ebp, %edi
jae 0x1c4c70
movl %edi, 0x4(%r11)
movl %edi, %ebp
addq %rbx, %r8
movl 0x10(%r8), %edi
cmpl %r12d, %edi
jae 0x1c4c83
movl %edi, 0x10(%r11)
movl %edi, %r12d
movl 0x8(%r8), %edi
cmpl %r15d, %edi
jbe 0x1c4c93
movl %edi, 0x8(%r11)
movl %edi, %r15d
movl 0x14(%r8), %edi
cmpl %r13d, %edi
jbe 0x1c4ca3
movl %edi, 0x14(%r11)
movl %edi, %r13d
andq %rdx, %rcx
cmpq %rdx, %rcx
cmoveq %rsi, %rcx
movq %rcx, %rdi
jne 0x1c4c3b
movq 0xe0(%rsp), %rax
movq 0x18(%rax), %rcx
movq 0x20(%rcx), %rcx
movl 0xc(%r11), %edi
movl 0x10(%r11), %r8d
movl (%rcx,%rdi,8), %ecx
movl $0x7fffffff, %eax       # imm = 0x7FFFFFFF
andl %eax, %ecx
movl 0x14(%r11), %edi
movl 0x18(%r11), %ebp
movl %ecx, %r15d
subl %edi, %r15d
subl %r8d, %ecx
testl %ebp, %ebp
cmovnsl %r8d, %r15d
cmovnsl %edi, %ecx
movl %r15d, 0x10(%r11)
movl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
cmpq %rax, %r14
cmovgeq %rax, %r14
movl %ecx, 0x14(%r11)
andl $0x3fffffff, %r14d      # imm = 0x3FFFFFFF
andl $0xc0000000, %ebp       # imm = 0xC0000000
orl %r14d, %ebp
movl %ebp, 0x18(%r11)
movq 0xe8(%rsp), %r13
movq 0x20(%rsp), %rdi
leal (%rdi,%r13), %ecx
movl %ecx, (%r11)
movq 0x18(%rsp), %rax
incq %rax
movq 0x28(%rsp), %r14
movq 0xd8(%rsp), %r15
cmpq $0x1, %r9
movq %rdi, %r9
jg 0x1c4bb5
testq %r14, %r14
movl $0x80000000, %r12d      # imm = 0x80000000
jle 0x1c4ddc
movq 0xe0(%rsp), %rcx
movq 0x18(%rcx), %rcx
movq 0x20(%rcx), %rdx
addq $0xc, %rbx
xorl %esi, %esi
movl $0x7fffffff, %edi       # imm = 0x7FFFFFFF
movl $0x7fffffff, %r8d       # imm = 0x7FFFFFFF
addl %edi, %r12d
movl $0xffffffff, %r9d       # imm = 0xFFFFFFFF
movl (%rbx), %ecx
movl 0x4(%rbx), %r10d
movl (%rdx,%rcx,8), %ecx
andl %edi, %ecx
movl 0x8(%rbx), %r11d
movl %ecx, %ebp
subl %r11d, %ebp
subl %r10d, %ecx
cmpl $0x0, 0xc(%rbx)
cmovnsl %r10d, %ebp
cmovnsl %r11d, %ecx
movl %ebp, 0x4(%rbx)
movl %ecx, 0x8(%rbx)
movq (%r15,%rsi,8), %rcx
andq %r8, %rcx
cmpq %r8, %rcx
movl %ecx, %r10d
cmovel %r12d, %r10d
addl %r13d, %r10d
cmpq %r8, %rcx
cmovel %r9d, %r10d
movl %r10d, (%rbx)
incq %rsi
addq $0x1c, %rbx
cmpq %rsi, %r14
jne 0x1c4d85
jmp 0x1c4ddc
xorl %eax, %eax
addq $0x88, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x711bf(%rip), %rdi     # 0x235fb4
leaq 0x6eb8f(%rip), %rsi     # 0x23398b
leaq 0x711d8(%rip), %rcx     # 0x235fdb
movl $0x3460, %edx           # imm = 0x3460
callq 0x2110