// File: /workspace/github_cpp_makefile_star2_O3/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 0x1edf69
movq %r8, %r12
movl 0x4(%r8), %eax
movl 0x1c(%r8), %r8d
subl %eax, %r8d
movl %r8d, %r15d
negl %r15d
cmovsl %r8d, %r15d
cvtsi2ss %r15d, %xmm3
cvtsi2ss %eax, %xmm2
mulss %xmm0, %xmm2
ucomiss %xmm2, %xmm3
seta %al
movl %r15d, %r8d
cmpq 0x148(%rsp), %r8
setg %r8b
testb %r8b, %al
jne 0x1edf69
movq %r9, %r14
movq %rdi, 0x20(%rsp)
movq %rsi, 0x28(%rsp)
movq %rdx, 0x30(%rsp)
movss %xmm3, 0x8(%rsp)
movss %xmm1, 0xc(%rsp)
movq 0x150(%rsp), %rsi
movq 0x138(%rsp), %rbx
xorl %eax, %eax
leaq 0x38(%rsp), %rbp
movq %rax, (%rbp)
movq %rax, 0x10(%rsp)
movl 0xc(%r12), %eax
movl $0x3fffffff, %edx       # imm = 0x3FFFFFFF
andq %rdx, %rax
leaq (%rax,%rax,4), %r13
movslq (%r9), %rax
imulq $0xa8, %rax, %rdi
movq %rcx, 0x18(%rsp)
addq %rcx, %rdi
movslq 0x18(%rbx,%r13,8), %rdx
movq %rbp, %rcx
callq 0x1b4617
movq %rbx, %r9
movslq 0x18(%r14), %rbx
movslq 0x18(%r9,%r13,8), %rcx
subq %rcx, %rbx
movq (%rbp), %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), %r10
addq (%r10,%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 0x1edf00
cmpl 0x14(%r14), %ecx
jle 0x1edf00
movq 0x130(%rsp), %rdi
leaq (%r9,%r13,8), %rbp
movl 0x8(%rbp), %eax
movl %eax, %edx
shrl %edx
leaq 0x44(%rsp), %rsi
movl %edx, 0xc(%rsi)
shll $0x1f, %eax
movl %eax, 0x18(%rsi)
movq 0xc(%rbp), %rax
movq %rax, 0x10(%rsi)
movl 0x14(%rbp), %eax
movl %eax, 0x4(%rsi)
movl %ecx, 0x8(%rsi)
xorl %edx, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
movq 0x20(%rsp), %r9
callq 0x6ea22
movl 0x8(%r14), %edx
xorl $0x1, %edx
movl 0x8(%rbp), %ecx
xorl $0x1, %ecx
leaq 0x10(%rsp), %r10
movsd 0x43792(%rip), %xmm0    # 0x2315e8
movq 0x28(%rsp), %rdi
movq 0x30(%rsp), %rsi
movq 0x148(%rsp), %r8
movq %rax, %r9
pushq %r10
pushq $0x0
callq 0x1b4788
addq $0x10, %rsp
testq %rax, %rax
je 0x1ede85
cmpq $0x0, 0x10(%rsp)
jne 0x1edf00
leaq 0x60(%rsp), %rsi
movq $0x7fffffff, (%rsi)     # imm = 0x7FFFFFFF
movl 0xc(%r12), %eax
andl $0x3fffffff, %eax       # imm = 0x3FFFFFFF
movslq 0x1c(%r14), %r13
movslq (%rbp), %rcx
imulq $0xa8, %rcx, %rcx
movq 0x18(%rsp), %rdi
addq %rcx, %rdi
movslq 0x14(%r14), %rdx
movq 0x140(%rsp), %rcx
addq (%rcx,%rax,8), %r13
leaq 0x38(%rsp), %r12
movq %r12, %rcx
callq 0x1b4617
movslq 0x18(%rbp), %rcx
movslq 0x14(%r14), %rdx
subq %rcx, %rdx
imulq 0x158(%rsp), %rax
movq 0x160(%rsp), %rcx
imulq (%r12), %rcx
addq %r13, %rcx
addq %rdx, %rcx
addq %rax, %rcx
cmpq %rbx, %rcx
cmovgq %rcx, %rbx
movss 0xc(%rsp), %xmm3
movss 0x8(%rsp), %xmm1
mulss %xmm1, %xmm3
xorps %xmm0, %xmm0
cmpl $0x2, %r15d
jb 0x1edf5f
movd %xmm1, %eax
movl %eax, %ecx
shrl $0x17, %ecx
addl $-0x80, %ecx
xorps %xmm1, %xmm1
cvtsi2ss %rcx, %xmm1
andl $0x7fffff, %eax         # imm = 0x7FFFFF
orl $0x3f800000, %eax       # imm = 0x3F800000
movd %eax, %xmm2
movss 0x51c5d(%rip), %xmm0    # 0x23fba0
mulss %xmm2, %xmm0
addss 0x51c55(%rip), %xmm0    # 0x23fba4
mulss %xmm2, %xmm0
addss 0x51c4d(%rip), %xmm0    # 0x23fba8
addss %xmm1, %xmm0
addss %xmm0, %xmm3
cvttss2si %xmm3, %eax
subl %eax, %ebx
movl %ebx, %eax
addq $0xf8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopl (%rax)