// File: chhylp123[P]hifiasm/inter.cpp
// Function: mg_map_frag(void const*, ha_pt_s const*, ma_ug_t const*, asg_t const*, unsigned int, int, char const*, ha_mzl_v*, st_mt_t*, mg_tbuf_s*, int, int, int, int, int, mg_idxopt_t const*, ug_opt_t const*, mg_gchains_t**)
void mg_map_frag(const void *ha_flt_tab, const ha_pt_t *ha_idx, const ma_ug_t *ug, const asg_t *rg, const uint32_t qid, const int qlen, const char *qseq, ha_mzl_v *mz, 
st_mt_t *sp, mg_tbuf_t *b, int32_t w, int32_t k, int32_t hpc, int32_t mz_sd, int32_t mz_rewin, const mg_idxopt_t *opt, const ug_opt_t *uopt, mg_gchains_t **gcs)
{
    mg128_t *a = NULL;
    int64_t n_a;
    int32_t *mini_pos;
    int i, rep_len, n_mini_pos, n_lc, max_chain_gap_qry, max_chain_gap_ref, n_gc;
	uint32_t hash;
    uint64_t *u;
	mg_lchain_t *lc;
	km_stat_t kmst;
	(*gcs) = NULL;

	hash  = qid;
    hash ^= __ac_Wang_hash(qlen) + __ac_Wang_hash(opt->seed);
    hash  = __ac_Wang_hash(hash);

    mz->n = 0;
    mz2_ha_sketch(qseq, qlen, w, k, 0, hpc, mz, ha_flt_tab, mz_sd, NULL, NULL, NULL, -1, -1, -1, sp, mz_rewin, 1, NULL);
	///a[]->y: weight(8)seg_id(8)flag(8)span(8)pos(32);--->query
    ///a[]->x: rid(31)rev(1)rpos(33);--->reference
    a = collect_seed_hits(b->km, opt, 1/**opt->hap_n**/, ha_flt_tab, ha_idx, ug, mz, &n_a, &rep_len, &n_mini_pos, &mini_pos);
	/**
	// might be recover
	if (opt->max_gap_pre > 0 && opt->max_gap_pre * 2 < opt->max_gap) n_a = flt_anchors(n_a, a, opt->max_gap_pre);
    max_chain_gap_qry = max_chain_gap_ref = opt->max_gap;
	**/
	max_chain_gap_qry = max_chain_gap_ref = qlen*2;
    if (n_a == 0) {//no matched minimizer
        if(a) kfree(b->km, a);
        a = 0, n_lc = 0, u = 0;
    } else {
		a = mg_lchain_dp(max_chain_gap_ref, max_chain_gap_qry, opt->bw, opt->max_lc_skip, opt->max_lc_iter, 
		opt->min_lc_cnt, opt->min_lc_score, opt->chn_pen_gap, n_a, a, &n_lc, &u, b->km);
    }
	
	if (n_lc) {///n_lc is how many linear chain we found
		lc = mg_lchain_gen(b->km, qlen, n_lc, u, a, ug);//lc->the status of each chain; u->idx of each chain;
		for (i = 0; i < n_lc; ++i)///update a[] since ref_id|rev has already been saved to lc[].v
			mg_update_anchors(lc[i].cnt, &a[lc[i].off], n_mini_pos, mini_pos);///update a[].x
	} else lc = 0;
	kfree(b->km, mini_pos); kfree(b->km, u);
	// fprintf(stderr, "++0++qid: %u, qlen: %d, n_a: %ld, n_lc: %d\n", qid, qlen, n_a, n_lc);
	/**
	 * up to here, a[] has been changed
	 * a[].x: idx_in_minimizer_arr(32)r_pos(32)
	 * a[].y: weight(8)query_id(8)flag(8)span(8)q_pos(32)
	**/
	// for (i = 0; i < n_lc; i++) {
	// 	mg_lchain_t *ri = &lc[i];
	// 	fprintf(stderr, "+0)))))))))))))))))))))))))))+\tA\tutg%.6d%c\t%c\tqs:%u\tqe:%u\tql:%d\tts:%u\tte:%u\ttl:%u\n", 
    //             (ri->v>>1)+1, "lc"[ug->u.a[ri->v>>1].circ], "+-"[ri->v&1], ri->qs, ri->qe, qlen, ri->rs, ri->re, ug->u.a[ri->v>>1].len);
	// }
	max_chain_gap_qry = max_chain_gap_ref = opt->max_gap;
	n_gc = mg_gchain1_dp(b->km, ug, rg, &n_lc, lc, qlen, max_chain_gap_ref, max_chain_gap_qry, opt->bw, opt->max_gc_skip, opt->ref_bonus,
						opt->chn_pen_gap, opt->mask_level, opt->max_gc_seq_ext, uopt, a, &u);
	// for (i = 0; i < n_lc; i++) {
	// 	mg_lchain_t *ri = &lc[i];
	// 	fprintf(stderr, "-0-\tA\tutg%.6d%c\t%c\tqs:%u\tqe:%u\tql:%d\tts:%u\tte:%u\ttl:%u\n", 
    //             (ri->v>>1)+1, "lc"[ug->u.a[ri->v>>1].circ], "+-"[ri->v&1], ri->qs, ri->qe, qlen, ri->rs, ri->re, ug->u.a[ri->v>>1].len);
	// }
	(*gcs) = mg_gchain_gen(0, b->km, ug->g, n_gc, u, lc, a, hash, opt->min_gc_cnt, opt->min_gc_score);
	(*gcs)->rep_len = rep_len; (*gcs)->qid = qid; (*gcs)->qlen = qlen;
	kfree(b->km, a);
	kfree(b->km, lc);
	kfree(b->km, u);

	mg_gchain_set_parent(b->km, opt->mask_level, (*gcs)->n_gc, (*gcs)->gc, opt->sub_diff, 0);
	mg_gchain_flt_sub(opt->pri_ratio, k * 2, opt->best_n, (*gcs)->n_gc, (*gcs)->gc);
	mg_gchain_drop_flt(b->km, (*gcs));
	mg_gchain_set_mapq(b->km, (*gcs), qlen, mz->n, opt->min_gc_score);

	if (b->km) {
		km_stat(b->km, &kmst);
		if (kmst.n_blocks != kmst.n_cores) {
			fprintf(stderr, "[E::%s] memory leak at %u\n", __func__, qid);
			abort();
		}
		if (kmst.largest > 1U<<28) {
			km_destroy(b->km);
			b->km = km_init();
		}
	}
	// fprintf(stderr, "++6++qid: %u, (*gcs)->n_gc: %d\n", qid, (*gcs)->n_gc);

}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x118, %rsp            # imm = 0x118
movq 0x68(%rbp), %rax
movq 0x60(%rbp), %rax
movq 0x58(%rbp), %rax
movl 0x50(%rbp), %eax
movl 0x48(%rbp), %eax
movl 0x40(%rbp), %eax
movl 0x38(%rbp), %eax
movl 0x30(%rbp), %eax
movq 0x28(%rbp), %rax
movq 0x20(%rbp), %rax
movq 0x18(%rbp), %rax
movq 0x10(%rbp), %rax
movq %rdi, -0x30(%rbp)
movq %rsi, -0x38(%rbp)
movq %rdx, -0x40(%rbp)
movq %rcx, -0x48(%rbp)
movl %r8d, -0x4c(%rbp)
movl %r9d, -0x50(%rbp)
movq $0x0, -0x58(%rbp)
movq 0x68(%rbp), %rax
movq $0x0, (%rax)
movl -0x4c(%rbp), %eax
movl %eax, -0x88(%rbp)
movl -0x50(%rbp), %edi
callq 0x286f50
movl %eax, -0xc4(%rbp)
movq 0x58(%rbp), %rax
movl 0x24(%rax), %edi
callq 0x286f50
movl %eax, %ecx
movl -0xc4(%rbp), %eax
addl %ecx, %eax
xorl -0x88(%rbp), %eax
movl %eax, -0x88(%rbp)
movl -0x88(%rbp), %edi
callq 0x286f50
movl %eax, -0x88(%rbp)
movq 0x18(%rbp), %rax
movl $0x0, (%rax)
movq 0x10(%rbp), %rdi
movl -0x50(%rbp), %esi
movl 0x30(%rbp), %edx
movl 0x38(%rbp), %ecx
movl 0x40(%rbp), %r9d
movq 0x18(%rbp), %r14
movq -0x30(%rbp), %rbx
movl 0x48(%rbp), %r11d
movq 0x20(%rbp), %r10
movl 0x50(%rbp), %eax
xorl %r8d, %r8d
xorl %r15d, %r15d
movss 0xf3100(%rip), %xmm0    # 0x37f070
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movl %r11d, 0x10(%rsp)
movq $0x0, 0x18(%rsp)
movq $0x0, 0x20(%rsp)
movq $0x0, 0x28(%rsp)
movl $0xffffffff, 0x30(%rsp) # imm = 0xFFFFFFFF
movl $0xffffffff, 0x38(%rsp) # imm = 0xFFFFFFFF
movq %r10, 0x40(%rsp)
movl %eax, 0x48(%rsp)
movl $0x1, 0x50(%rsp)
movq $0x0, 0x58(%rsp)
callq 0x1995e0
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq 0x58(%rbp), %rsi
movq -0x30(%rbp), %rcx
movq -0x38(%rbp), %r8
movq -0x40(%rbp), %r9
movq 0x18(%rbp), %r14
movl $0x1, %edx
leaq -0x60(%rbp), %rbx
leaq -0x70(%rbp), %r11
leaq -0x74(%rbp), %r10
leaq -0x68(%rbp), %rax
movq %r14, (%rsp)
movq %rbx, 0x8(%rsp)
movq %r11, 0x10(%rsp)
movq %r10, 0x18(%rsp)
movq %rax, 0x20(%rsp)
callq 0x2830e0
movq %rax, -0x58(%rbp)
movl -0x50(%rbp), %eax
shll %eax
movl %eax, -0x80(%rbp)
movl %eax, -0x7c(%rbp)
cmpq $0x0, -0x60(%rbp)
jne 0x28c05e
cmpq $0x0, -0x58(%rbp)
je 0x28c042
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq -0x58(%rbp), %rsi
callq 0x30e2d0
movq $0x0, -0x58(%rbp)
movl $0x0, -0x78(%rbp)
movq $0x0, -0x90(%rbp)
jmp 0x28c0d3
movl -0x80(%rbp), %edi
movl -0x7c(%rbp), %esi
movq 0x58(%rbp), %rax
movl 0x8(%rax), %edx
movq 0x58(%rbp), %rax
movl 0x28(%rax), %ecx
movq 0x58(%rbp), %rax
movl 0x2c(%rax), %r8d
movq 0x58(%rbp), %rax
movl 0x30(%rax), %r9d
movq 0x58(%rbp), %rax
movl 0x34(%rax), %r15d
movq 0x58(%rbp), %rax
movss 0x50(%rax), %xmm0
movq -0x60(%rbp), %r14
movq -0x58(%rbp), %rbx
movq 0x28(%rbp), %rax
movq (%rax), %rax
leaq -0x78(%rbp), %r11
leaq -0x90(%rbp), %r10
movl %r15d, (%rsp)
movq %r14, 0x8(%rsp)
movq %rbx, 0x10(%rsp)
movq %r11, 0x18(%rsp)
movq %r10, 0x20(%rsp)
movq %rax, 0x28(%rsp)
callq 0x283e90
movq %rax, -0x58(%rbp)
cmpl $0x0, -0x78(%rbp)
je 0x28c166
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movl -0x50(%rbp), %esi
movl -0x78(%rbp), %edx
movq -0x90(%rbp), %rcx
movq -0x58(%rbp), %r8
movq -0x40(%rbp), %r9
callq 0x284ac0
movq %rax, -0x98(%rbp)
movl $0x0, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
cmpl -0x78(%rbp), %eax
jge 0x28c164
movq -0x98(%rbp), %rax
movslq -0x6c(%rbp), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movl 0x4(%rax), %edi
shll %edi
sarl %edi
movq -0x58(%rbp), %rsi
movq -0x98(%rbp), %rax
movslq -0x6c(%rbp), %rcx
imulq $0x28, %rcx, %rcx
addq %rcx, %rax
movslq (%rax), %rax
shlq $0x4, %rax
addq %rax, %rsi
movl -0x74(%rbp), %edx
movq -0x68(%rbp), %rcx
callq 0x284dd0
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
jmp 0x28c10c
jmp 0x28c171
movq $0x0, -0x98(%rbp)
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq -0x68(%rbp), %rsi
callq 0x30e2d0
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq -0x90(%rbp), %rsi
callq 0x30e2d0
movq 0x58(%rbp), %rax
movl 0xc(%rax), %eax
movl %eax, -0x80(%rbp)
movl %eax, -0x7c(%rbp)
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq -0x40(%rbp), %rsi
movq -0x48(%rbp), %rdx
movq -0x98(%rbp), %r8
movl -0x50(%rbp), %r9d
movl -0x80(%rbp), %eax
movl %eax, -0xd4(%rbp)
movl -0x7c(%rbp), %r13d
movq 0x58(%rbp), %rax
movl 0x8(%rax), %r12d
movq 0x58(%rbp), %rax
movl 0x38(%rax), %r15d
movq 0x58(%rbp), %rax
movl 0x3c(%rax), %r14d
movq 0x58(%rbp), %rax
movss 0x50(%rax), %xmm0
movq 0x58(%rbp), %rax
movss 0x54(%rax), %xmm1
movq 0x58(%rbp), %rax
movl 0x20(%rax), %ebx
movq 0x60(%rbp), %r11
movq -0x58(%rbp), %r10
leaq -0x78(%rbp), %rcx
leaq -0x90(%rbp), %rax
movq %rax, -0xd0(%rbp)
movl -0xd4(%rbp), %eax
movl %eax, (%rsp)
movq -0xd0(%rbp), %rax
movl %r13d, 0x8(%rsp)
movl %r12d, 0x10(%rsp)
movl %r15d, 0x18(%rsp)
movl %r14d, 0x20(%rsp)
movl %ebx, 0x28(%rsp)
movq %r11, 0x30(%rsp)
movq %r10, 0x38(%rsp)
movq %rax, 0x40(%rsp)
callq 0x288830
movl %eax, -0x84(%rbp)
movq 0x28(%rbp), %rax
movq (%rax), %rsi
movq -0x40(%rbp), %rax
movq 0x18(%rax), %rdx
movl -0x84(%rbp), %ecx
movq -0x90(%rbp), %r8
movq -0x98(%rbp), %r9
movq -0x58(%rbp), %rbx
movl -0x88(%rbp), %r11d
movq 0x58(%rbp), %rax
movl 0x40(%rax), %r10d
movq 0x58(%rbp), %rax
movl 0x44(%rax), %eax
xorl %edi, %edi
movq %rbx, (%rsp)
movl %r11d, 0x8(%rsp)
movl %r10d, 0x10(%rsp)
movl %eax, 0x18(%rsp)
callq 0x28a420
movq %rax, %rcx
movq 0x68(%rbp), %rax
movq %rcx, (%rax)
movl -0x70(%rbp), %ecx
movq 0x68(%rbp), %rax
movq (%rax), %rax
movl %ecx, 0x14(%rax)
movl -0x4c(%rbp), %eax
movl %eax, %ecx
movq 0x68(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x30(%rax)
movslq -0x50(%rbp), %rcx
movq 0x68(%rbp), %rax
movq (%rax), %rax
movq %rcx, 0x38(%rax)
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq -0x58(%rbp), %rsi
callq 0x30e2d0
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq -0x98(%rbp), %rsi
callq 0x30e2d0
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq -0x90(%rbp), %rsi
callq 0x30e2d0
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq 0x58(%rbp), %rax
movss 0x54(%rax), %xmm0
movq 0x68(%rbp), %rax
movq (%rax), %rax
movl 0x8(%rax), %esi
movq 0x68(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rdx
movq 0x58(%rbp), %rax
movl 0x48(%rax), %ecx
xorl %r8d, %r8d
callq 0x28af20
movq 0x58(%rbp), %rax
movss 0x58(%rax), %xmm0
movl 0x38(%rbp), %edi
shll %edi
movq 0x58(%rbp), %rax
movl 0x4c(%rax), %esi
movq 0x68(%rbp), %rax
movq (%rax), %rax
movl 0x8(%rax), %edx
movq 0x68(%rbp), %rax
movq (%rax), %rax
movq 0x18(%rax), %rcx
callq 0x28b430
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq 0x68(%rbp), %rax
movq (%rax), %rsi
callq 0x28b7a0
movq 0x28(%rbp), %rax
movq (%rax), %rdi
movq 0x68(%rbp), %rax
movq (%rax), %rsi
movl -0x50(%rbp), %edx
movq 0x18(%rbp), %rax
movl (%rax), %ecx
movq 0x58(%rbp), %rax
movl 0x44(%rax), %r8d
callq 0x28bb00
movq 0x28(%rbp), %rax
cmpq $0x0, (%rax)
je 0x28c42f
movq 0x28(%rbp), %rax
movq (%rax), %rdi
leaq -0xc0(%rbp), %rsi
callq 0x30e830
movq -0xb0(%rbp), %rax
cmpq -0xa8(%rbp), %rax
je 0x28c405
movq 0x137bfb(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movl -0x4c(%rbp), %ecx
leaq 0x1049f0(%rip), %rsi    # 0x390de2
leaq 0x104a04(%rip), %rdx    # 0x390dfd
movb $0x0, %al
callq 0x22a0
callq 0x2110
cmpq $0x10000000, -0xa0(%rbp) # imm = 0x10000000
jbe 0x28c42d
movq 0x28(%rbp), %rax
movq (%rax), %rdi
callq 0x30e250
callq 0x30e230
movq %rax, %rcx
movq 0x28(%rbp), %rax
movq %rcx, (%rax)
jmp 0x28c42f
addq $0x118, %rsp            # imm = 0x118
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nopw %cs:(%rax,%rax)