// File: /workspace/github_cpp_makefile_star2_O3/chhylp123[P]hifiasm/htab.cpp
// Function: ha_pt_gen(hifiasm_opt_t const*, void const*, int, int, All_reads*, int*, int*)
ha_pt_t *ha_pt_gen(const hifiasm_opt_t *asm_opt, const void *flt_tab, int read_from_store, int is_hp_mode, All_reads *rs, int *hom_cov, int *het_cov)
{
	int64_t cnt[YAK_N_COUNTS], tot_cnt;
	int peak_hom, peak_het, i, extra_flag1, extra_flag2;
	ha_ct_t *ct;
	ha_pt_t *pt;
	if (read_from_store) {///if reads have already been read
		extra_flag1 = extra_flag2 = HAF_RS_READ;
	} else if (rs->total_reads == 0) {///if reads & length have not been scanned
		extra_flag1 = HAF_RS_WRITE_LEN;
		extra_flag2 = HAF_RS_WRITE_SEQ;
	} else {///if length has been loaded but reads have not
		extra_flag1 = HAF_RS_WRITE_SEQ;
		extra_flag2 = HAF_RS_READ;
	}
	if(is_hp_mode) extra_flag1 |= HAF_SKIP_READ, extra_flag2 |= HAF_SKIP_READ;

	ct = ha_count(asm_opt, HAF_COUNT_EXACT|extra_flag1,  !(asm_opt->flag&HA_F_NO_HPC), asm_opt->k_mer_length, asm_opt->mz_win, NULL, flt_tab, rs, NULL, 1, NULL, 0);
	fprintf(stderr, "[M::%s::%.3f*%.2f] ==> counted %ld distinct minimizer k-mers\n", __func__,
			yak_realtime(), yak_cpu_usage(), (long)ct->tot);
	ha_ct_hist(ct, cnt, asm_opt->thread_num);
	fprintf(stderr, "[M::%s] count[%d] = %ld (for sanity check)\n", __func__, YAK_MAX_COUNT, (long)cnt[YAK_MAX_COUNT]);
	peak_hom = ha_analyze_count(YAK_N_COUNTS, asm_opt->min_hist_kmer_cnt, asm_opt->hg_size>0?(ct->bs/asm_opt->hg_size):(-1), cnt, &peak_het);
	if (hom_cov) *hom_cov = peak_hom;
	if (het_cov) *het_cov = peak_het;
	if (peak_hom > 0) fprintf(stderr, "[M::%s] peak_hom: %d; peak_het: %d\n", __func__, peak_hom, peak_het);
	///here ha_ct_shrink is mostly used to remove k-mer appearing only 1 time
	if (flt_tab == 0) {
		int cutoff = (int)(peak_hom * asm_opt->high_factor);
		if (cutoff > YAK_MAX_COUNT - 1) cutoff = YAK_MAX_COUNT - 1;
		if((extra_flag1 & HAF_SKIP_READ) && (extra_flag2 & HAF_SKIP_READ)) cutoff = YAK_MAX_COUNT - 1;
		ha_ct_shrink(ct, 2, cutoff, asm_opt->thread_num);
		for (i = 2, tot_cnt = 0; i <= cutoff; ++i) tot_cnt += cnt[i] * i;
	} else {
		///Note: here is just to remove minimizer appearing YAK_MAX_COUNT times
		///minimizer with YAK_MAX_COUNT occ may apper > YAK_MAX_COUNT times, so it may lead to overflow at ha_pt_gen
		ha_ct_shrink(ct, 2, YAK_MAX_COUNT - 1, asm_opt->thread_num);
		for (i = 2, tot_cnt = 0; i <= YAK_MAX_COUNT - 1; ++i) tot_cnt += cnt[i] * i;
	}
	if(!(asm_opt->flag & HA_F_FAST))
	{
		fprintf(stderr, "[M::%s::] counting in normal mode\n", __func__);
		pt = ha_pt_gen(ct, asm_opt->thread_num, 0);
		ha_count(asm_opt, HAF_COUNT_EXACT|extra_flag2,  !(asm_opt->flag&HA_F_NO_HPC), asm_opt->k_mer_length, asm_opt->mz_win, pt, flt_tab, rs, NULL, 1, NULL, 0);
		assert((uint64_t)tot_cnt == pt->tot_pos);
	}
	else
	{
		fprintf(stderr, "[M::%s::] counting in fast mode\n", __func__);
		pt = ha_pt_gen_dp(asm_opt, ct, HAF_COUNT_EXACT|extra_flag2, asm_opt->thread_num, flt_tab, rs, peak_hom, peak_het);
	}
	//ha_pt_sort(pt, asm_opt->thread_num);
	fprintf(stderr, "[M::%s::%.3f*%.2f] ==> indexed %ld positions, counted %ld distinct minimizer k-mers\n", __func__,
			yak_realtime(), yak_cpu_usage(), (long)pt->tot_pos, (long)pt->tot);
	return pt;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x8038, %rsp           # imm = 0x8038
movq %r9, 0x28(%rsp)
movq %r8, %r9
movq %rsi, 0x8(%rsp)
movq %rdi, %r15
testl %edx, %edx
jne 0x13db3
xorl %edx, %edx
cmpq $0x0, 0x50(%r9)
setne %dl
leal 0x4(,%rdx,4), %eax
leal 0x8(,%rdx,8), %edx
jmp 0x13db8
pushq $0x10
popq %rax
movl %eax, %edx
leal 0x40(%rax), %esi
leal 0x40(%rdx), %ebp
movl %ecx, 0x14(%rsp)
testl %ecx, %ecx
cmovel %eax, %esi
cmovel %edx, %ebp
orl $0x1, %esi
movl (%r15), %edx
movl 0x80(%r15), %ecx
notl %edx
andl $0x1, %edx
movl 0x94(%r15), %r8d
subq $0x30, %rsp
andl $0x0, 0x28(%rsp)
andq $0x0, 0x20(%rsp)
movq %r9, 0x48(%rsp)
movq %r9, 0x8(%rsp)
andq $0x0, 0x10(%rsp)
movq 0x38(%rsp), %rax
movq %rax, (%rsp)
movl $0x1, 0x18(%rsp)
movq %r15, %rdi
xorl %r9d, %r9d
callq 0x119f0d
addq $0x30, %rsp
movq %rax, %r12
movq 0x2811b4(%rip), %r14    # 0x294fe0
movq (%r14), %rbx
callq 0x1365ef
movsd %xmm0, 0x20(%rsp)
callq 0x1366b8
movaps %xmm0, %xmm1
movq 0x10(%r12), %rcx
leaq 0x2261dd(%rip), %rsi    # 0x23a02b
leaq 0x2262d6(%rip), %r13    # 0x23a12b
movq %rbx, %rdi
movq %r13, %rdx
movsd 0x20(%rsp), %xmm0
movb $0x2, %al
callq 0x22b0
movl 0x7c(%r15), %edx
leaq 0x30(%rsp), %rbx
movq %r12, %rdi
movq %rbx, %rsi
callq 0x11aaa9
movq (%r14), %rdi
movq 0x7ff8(%rbx), %r8
leaq 0x2262a8(%rip), %rsi    # 0x23a135
movq %r13, %rdx
movl $0xfff, %ecx            # imm = 0xFFF
xorl %eax, %eax
callq 0x22b0
movl 0xec(%r15), %esi
movq 0x200(%r15), %rcx
testq %rcx, %rcx
jle 0x13ebe
movq 0x18(%r12), %rax
xorl %edx, %edx
divq %rcx
movq %rax, %rdx
jmp 0x13ec1
pushq $-0x1
popq %rdx
movq 0x8070(%rsp), %r13
leaq 0x30(%rsp), %rcx
leaq 0x4(%rsp), %r8
movl $0x1000, %edi           # imm = 0x1000
callq 0x11eb5b
movl %eax, %ebx
movq 0x28(%rsp), %rax
testq %rax, %rax
je 0x13eeb
movl %ebx, (%rax)
testq %r13, %r13
je 0x13ef8
movl 0x4(%rsp), %eax
movl %eax, (%r13)
testl %ebx, %ebx
jle 0x13f22
movq 0x2810dd(%rip), %rax    # 0x294fe0
movq (%rax), %rdi
movl 0x4(%rsp), %r8d
leaq 0x2260eb(%rip), %rsi    # 0x239ffd
leaq 0x226212(%rip), %rdx    # 0x23a12b
movl %ebx, %ecx
xorl %eax, %eax
callq 0x22b0
cmpq $0x0, 0x8(%rsp)
jne 0x13f6e
cvtsi2sd %ebx, %xmm0
mulsd 0xb8(%r15), %xmm0
cvttsd2si %xmm0, %r14d
movl $0xffe, %eax            # imm = 0xFFE
cmpl %eax, %r14d
cmovgel %eax, %r14d
cmpl $0x0, 0x14(%rsp)
cmovnel %eax, %r14d
movl 0x7c(%r15), %ecx
pushq $0x2
popq %rsi
movq %r12, %rdi
movl %r14d, %edx
callq 0x137e4
cmpl $0x2, %r14d
jge 0x13fa1
xorl %r13d, %r13d
jmp 0x13fbe
movl 0x7c(%r15), %ecx
pushq $0x2
popq %rsi
movq %r12, %rdi
movl $0xffe, %edx            # imm = 0xFFE
callq 0x137e4
pushq $0x2
popq %rax
xorl %r13d, %r13d
movq 0x30(%rsp,%rax,8), %rcx
imulq %rax, %rcx
addq %rcx, %r13
incq %rax
cmpq $0xfff, %rax            # imm = 0xFFF
jne 0x13f88
jmp 0x13fbe
incl %r14d
pushq $0x2
popq %rax
xorl %r13d, %r13d
movq 0x30(%rsp,%rax,8), %rcx
imulq %rax, %rcx
addq %rcx, %r13
incq %rax
cmpq %rax, %r14
jne 0x13faa
testb $0x10, 0x1(%r15)
movq 0x281016(%rip), %rax    # 0x294fe0
movq (%rax), %rdi
jne 0x14058
leaq 0x226187(%rip), %rsi    # 0x23a161
leaq 0x22614a(%rip), %rdx    # 0x23a12b
xorl %eax, %eax
callq 0x22b0
movl 0x7c(%r15), %esi
movq %r12, %rdi
xorl %edx, %edx
callq 0x118cb9
movq %rax, %rbx
orl $0x1, %ebp
movl (%r15), %edx
movl 0x80(%r15), %ecx
notl %edx
andl $0x1, %edx
movl 0x94(%r15), %r8d
movq %r15, %rdi
movl %ebp, %esi
movq %rax, %r9
pushq $0x0
pushq $0x0
pushq $0x1
pushq $0x0
pushq 0x38(%rsp)
pushq 0x30(%rsp)
callq 0x119f0d
addq $0x30, %rsp
cmpq 0x10(%rbx), %r13
je 0x14096
leaq 0x226144(%rip), %rdi    # 0x23a184
leaq 0x225cf8(%rip), %rsi    # 0x239d3f
leaq 0x226157(%rip), %rcx    # 0x23a1a5
movl $0x4fc, %edx            # imm = 0x4FC
callq 0x2110
leaq 0x2261a3(%rip), %rsi    # 0x23a202
leaq 0x2260c5(%rip), %rdx    # 0x23a12b
xorl %eax, %eax
callq 0x22b0
orl $0x1, %ebp
movl 0x7c(%r15), %ecx
movl 0x4(%rsp), %eax
movq %r15, %rdi
movq %r12, %rsi
movl %ebp, %edx
movq 0x8(%rsp), %r8
movq 0x18(%rsp), %r9
pushq %rax
pushq %rbx
callq 0x11ab5d
popq %rcx
popq %rdx
movq %rax, %rbx
movq 0x280f43(%rip), %rax    # 0x294fe0
movq (%rax), %r14
callq 0x1365ef
movsd %xmm0, 0x8(%rsp)
callq 0x1366b8
movapd %xmm0, %xmm1
movq 0x8(%rbx), %r8
movq 0x10(%rbx), %rcx
leaq 0x226160(%rip), %rsi    # 0x23a223
leaq 0x226061(%rip), %rdx    # 0x23a12b
movq %r14, %rdi
movsd 0x8(%rsp), %xmm0
movb $0x2, %al
callq 0x22b0
movq %rbx, %rax
addq $0x8038, %rsp           # imm = 0x8038
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq