// File: /workspace/github_cpp_makefile_star2_O2/chhylp123[P]hifiasm/inter.cpp
// Function: cal_gchain_sc_adv(ma_ug_t const*, ul_idx_t const*, ug_opt_t const*, overlap_region*, mg_path_dst_t const*, mg_lchain_t const*, ul_ov_t*, mg_lchain_t*, long*, long, float, float, rtrace_iter*, long, long)
inline int32_t cal_gchain_sc_adv(const ma_ug_t *ug, const ul_idx_t *uref, const ug_opt_t *uopt, 
overlap_region *ol, const mg_path_dst_t *dj, const mg_lchain_t *li, ul_ov_t *ui, mg_lchain_t *lc, int64_t *f, 
int64_t b_w, float diff_thre, float chn_pen_gap, rtrace_iter *tc, int64_t trans_sc, int64_t sec_sec)
{
	// const mg_lchain_t *lj;
	int32_t gap; 
	float lin_pen, log_pen;
	if (dj->n_path == 0) return INT32_MIN;
	gap = dj->dist - dj->target_dist;
	// lj = &lc[dj->meta];
	if (gap < 0) gap = -gap;
	if ((gap > ((dj->target_dist)*diff_thre)) && (gap > b_w)) return INT32_MIN;
	// if (lj->qe <= li->qs) sc = li->score;
	// else sc = (int32_t)((double)(li->qe - lj->qe) / (li->qe - li->qs) * li->score + .499); // dealing with overlap on query
	int64_t trans_l = 0, sec_err = 0, qo, el = 0, sc, sc0; 
	mg_lchain_t *lj = &(lc[dj->meta]); ul_ov_t uj;
	
	trans_l = get_overlap_region_sub_err(&(ol[li->off]), tc, lj->qe, &sec_err);
	sc = (li->qe - lj->qe) - (trans_l*trans_sc) - (sec_err*sec_sec); sc += f[dj->meta];
	if(((trans_l > 0) || (sec_err > 0)) && (lj->qe > li->qs)) {
		set_ul_ov_t_by_mg_lchain_t(&uj, lj);
		qo = infer_rovlp(ui, &uj, NULL, NULL, NULL, (ma_ug_t *)ug);
		if((!get_ecov_el(uref, uopt, li->v^1, lj->v^1, b_w, N_GCHAIN_RATE, qo, 0, &el)) || (el == 0)) {
			rtrace_iter tr; tr.k = INT32_MAX; sc0 = sc;
			sc = f[dj->meta] + li->score;
			trans_l = get_overlap_region_sub_err(&(ol[lj->off]), &tr, li->qs, &sec_err);
            sc -= (((int64_t)(lj->qe - li->qs)) - (trans_l*trans_sc) - (sec_err*sec_sec));
            if(sc < sc0) sc = sc0;
		}
	}
	

	// int64_t trans_l_debug, sec_err_debug;
	// trans_l_debug = get_overlap_region_sub_err_debug(&(ol[li->off]), lc[dj->meta].qe, &sec_err_debug);
	// if(!(trans_l_debug == trans_l && sec_err_debug == sec_err)) {
	// 	fprintf(stderr, "[M::%s::] trans_l::%ld, trans_l_debug::%ld, sec_err::%ld, sec_err_debug::%ld\n", 
	// 	__func__, trans_l, trans_l_debug, sec_err, sec_err_debug);
	// }
	// assert(trans_l_debug == trans_l && sec_err_debug == sec_err);

	
	// sc = li->score;
	//sc += dj->mlen; // TODO: is this line the right thing to do?
	// if (dj->is_0) sc += ref_bonus;
	lin_pen = chn_pen_gap * (float)gap;
	log_pen = gap >= 2? mg_log2(gap) : 0.0f;
	sc -= (int32_t)(lin_pen + log_pen);
	return sc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xf8, %rsp
movl $0x80000000, %ebx       # imm = 0x80000000
testl $0x7fffffff, 0x14(%r8)  # imm = 0x7FFFFFFF
je 0x1a3205
movq %r8, %r12
movl 0x4(%r8), %eax
movl 0x1c(%r8), %r8d
subl %eax, %r8d
movl %r8d, %ebp
negl %ebp
cmovsl %r8d, %ebp
cvtsi2ss %ebp, %xmm3
cvtsi2ss %eax, %xmm2
mulss %xmm0, %xmm2
ucomiss %xmm2, %xmm3
seta %al
movl %ebp, %r8d
cmpq 0x148(%rsp), %r8
setg %r8b
testb %r8b, %al
jne 0x1a3205
movq %rdi, 0x20(%rsp)
movq %rsi, 0x28(%rsp)
movq %rdx, 0x30(%rsp)
movss %xmm3, 0x4(%rsp)
movss %xmm1, (%rsp)
movq 0x150(%rsp), %rsi
leaq 0x38(%rsp), %r15
andq $0x0, (%r15)
movq 0x138(%rsp), %r14
andq $0x0, 0x10(%rsp)
movl 0xc(%r12), %eax
movl $0x3fffffff, %edx       # imm = 0x3FFFFFFF
andq %rdx, %rax
imulq $0x28, %rax, %r13
movslq (%r9), %rax
imulq $0xa8, %rax, %rdi
movq %rcx, 0x18(%rsp)
addq %rcx, %rdi
movslq 0x18(%r14,%r13), %rdx
movq %r15, %rcx
movq %r9, 0x8(%rsp)
callq 0x16b219
movq 0x8(%rsp), %r10
movslq 0x18(%r10), %rbx
movslq 0x18(%r14,%r13), %rcx
subq %rcx, %rbx
movq (%r15), %rdx
movq %rax, %rsi
imulq 0x158(%rsp), %rsi
movl 0xc(%r12), %edi
movl $0x3fffffff, %r8d       # imm = 0x3FFFFFFF
andq %r8, %rdi
movq %rdx, %r8
imulq 0x160(%rsp), %r8
movq 0x140(%rsp), %r11
addq (%r11,%rdi,8), %rbx
addq %rsi, %r8
subq %r8, %rbx
testq %rax, %rax
setg %al
testq %rdx, %rdx
setg %dl
orb %al, %dl
cmpb $0x1, %dl
jne 0x1a31d2
cmpl 0x14(%r10), %ecx
jle 0x1a31d2
movq %r14, %r9
addq %r13, %r9
movq %r9, %r13
leaq 0x44(%rsp), %r15
movq %r15, %rdi
movq %r9, %rsi
movq %r10, %r14
callq 0x16bf75
movq 0x130(%rsp), %rdi
movq %r15, %rsi
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
movq 0x20(%rsp), %r9
callq 0x3d261
movl 0x8(%r14), %edx
xorl $0x1, %edx
movl 0x8(%r13), %ecx
xorl $0x1, %ecx
leaq 0x10(%rsp), %r10
movsd 0x40412(%rip), %xmm0    # 0x1e3538
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
movq 0x148(%rsp), %r8
movq %rax, %r9
pushq %r10
pushq $0x0
callq 0x16b373
popq %rcx
popq %rdx
testq %rax, %rax
je 0x1a3153
cmpq $0x0, 0x10(%rsp)
jne 0x1a31d2
leaq 0x60(%rsp), %rsi
movq $0x7fffffff, (%rsi)     # imm = 0x7FFFFFFF
movl 0xc(%r12), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
movq 0x8(%rsp), %r14
movslq 0x1c(%r14), %r12
movslq (%r13), %rcx
imulq $0xa8, %rcx, %rcx
movq 0x18(%rsp), %rdi
addq %rcx, %rdi
movslq 0x14(%r14), %rdx
movq 0x140(%rsp), %rcx
addq (%rcx,%rax,8), %r12
leaq 0x38(%rsp), %r15
movq %r15, %rcx
callq 0x16b219
movslq 0x18(%r13), %rcx
movslq 0x14(%r14), %rdx
subq %rcx, %rdx
imulq 0x158(%rsp), %rax
movq 0x160(%rsp), %rcx
imulq (%r15), %rcx
addq %r12, %rcx
addq %rdx, %rcx
addq %rax, %rcx
cmpq %rbx, %rcx
cmovgq %rcx, %rbx
movss (%rsp), %xmm1
movss 0x4(%rsp), %xmm2
mulss %xmm2, %xmm1
xorps %xmm0, %xmm0
cmpl $0x2, %ebp
jb 0x1a31fb
movaps %xmm2, %xmm0
movss %xmm1, (%rsp)
callq 0x1a1d6e
movss (%rsp), %xmm1
addss %xmm0, %xmm1
cvttss2si %xmm1, %eax
subl %eax, %ebx
movl %ebx, %eax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq