// File: chhylp123[P]hifiasm/Trio.cpp
// Function: yak_ch_restore_core(yak_ch_t*, char const*, int, ...)
static yak_ch_t *yak_ch_restore_core(yak_ch_t *ch0, const char *fn, int mode, ...)
{
	va_list ap;
	FILE *fp;
	uint32_t t[3], f_tmp = 0;
	char magic[4];
	int i, j, absent, min_cnt = 0, mid_cnt = 0, mode_err = 0;
	uint64_t mask = (1ULL<<YAK_COUNTER_BITS) - 1, n_ins = 0, n_new = 0;
	yak_ch_t *ch;

	va_start(ap, mode);
	if (mode == YAK_LOAD_ALL) { // do nothing
	} else if (mode == YAK_LOAD_TRIOBIN1 || mode == YAK_LOAD_TRIOBIN2) {
		assert(YAK_COUNTER_BITS >= 4);
		min_cnt = va_arg(ap, int);
		mid_cnt = va_arg(ap, int);
		if (ch0 == 0 && mode == YAK_LOAD_TRIOBIN2)
			mode_err = 1;
	} else mode_err = 1;
	va_end(ap);
	if (mode_err) return 0;

	if ((fp = fopen(fn, "rb")) == 0) return 0;
	if (fread(magic, 1, 4, fp) != 4) return 0;
	if (strncmp(magic, YAK_MAGIC, 4) != 0) {
		fprintf(stderr, "ERROR: wrong file magic.\n");
		fclose(fp);
		return 0;
	}
	f_tmp += fread(t, 4, 3, fp);
	if (t[2] != YAK_COUNTER_BITS) {
		fprintf(stderr, "ERROR: saved counter bits: %d; compile-time counter bits: %d\n", t[2], YAK_COUNTER_BITS);
		fclose(fp);
		return 0;
	}
	///t[0] = k; t[1] = pre, t[2] = YAK_COUNTER_BITS;
	ch = ch0 == 0? yak_ch_init(t[0], t[1]) : ch0;
	assert((int)t[0] == ch->k && (int)t[1] == ch->pre);
	for (i = 0; i < 1<<ch->pre; ++i) {
		yak_ht_t *h = ch->h[i].h;
		f_tmp += fread(t, 4, 2, fp);
		///t[0] = kh_capacity(h), t[1] = kh_size(h);
		if (ch0 == 0) yak_ht_resize(h, t[0]);
		for (j = 0; j < (int)t[1]; ++j) {
			uint64_t key;
			f_tmp += fread(&key, 8, 1, fp);
			if (mode == YAK_LOAD_ALL) {
				++n_ins;
				yak_ht_put(h, key, &absent);
				if (absent) ++n_new;
			} else if (mode == YAK_LOAD_TRIOBIN1 || mode == YAK_LOAD_TRIOBIN2) {
				int cnt = key & mask, x, shift = mode == YAK_LOAD_TRIOBIN1? 0 : 2;
				//1. filter singleton k-mer; 2. label non-repeat and repeat
				if (cnt >= mid_cnt) x = 2<<shift;
				else if (cnt >= min_cnt) x = 1<<shift;
				else x = -1;
				if (x >= 0) {
					khint_t k;
					///no need cnt at all
					key = (key & ~mask) | x;
					++n_ins;
					k = yak_ht_put(h, key, &absent);
					if (absent) ++n_new;
					else kh_key(h, k) = kh_key(h, k) | x;
				}
			}
		}
	}
	fclose(fp);
	///fprintf(stderr, "[M::%s] inserted %ld k-mers, of which %ld are new\n", __func__, (long)n_ins, (long)n_new);
	return ch;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1b0, %rsp            # imm = 0x1B0
testb %al, %al
je 0x16bc17
movaps %xmm0, -0x140(%rbp)
movaps %xmm1, -0x130(%rbp)
movaps %xmm2, -0x120(%rbp)
movaps %xmm3, -0x110(%rbp)
movaps %xmm4, -0x100(%rbp)
movaps %xmm5, -0xf0(%rbp)
movaps %xmm6, -0xe0(%rbp)
movaps %xmm7, -0xd0(%rbp)
movq %r9, -0x148(%rbp)
movq %r8, -0x150(%rbp)
movq %rcx, -0x158(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movl %edx, -0x1c(%rbp)
movl $0x0, -0x58(%rbp)
movl $0x0, -0x6c(%rbp)
movl $0x0, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
movq $0x3ff, -0x80(%rbp)     # imm = 0x3FF
movq $0x0, -0x88(%rbp)
movq $0x0, -0x90(%rbp)
leaq -0x40(%rbp), %rax
leaq -0x170(%rbp), %rcx
movq %rcx, 0x10(%rax)
leaq 0x10(%rbp), %rcx
movq %rcx, 0x8(%rax)
movl $0x30, 0x4(%rax)
movl $0x18, (%rax)
cmpl $0x1, -0x1c(%rbp)
jne 0x16bca0
jmp 0x16bd97
cmpl $0x2, -0x1c(%rbp)
je 0x16bcb0
cmpl $0x3, -0x1c(%rbp)
jne 0x16bd8e
leaq -0x40(%rbp), %rax
movq %rax, -0x180(%rbp)
movl -0x40(%rbp), %eax
movl %eax, -0x174(%rbp)
cmpl $0x28, %eax
ja 0x16bceb
movq -0x180(%rbp), %rcx
movl -0x174(%rbp), %edx
movslq %edx, %rax
addq 0x10(%rcx), %rax
addl $0x8, %edx
movl %edx, (%rcx)
movq %rax, -0x188(%rbp)
jmp 0x16bd08
movq -0x180(%rbp), %rcx
movq 0x8(%rcx), %rax
movq %rax, %rdx
addq $0x8, %rdx
movq %rdx, 0x8(%rcx)
movq %rax, -0x188(%rbp)
movq -0x188(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x6c(%rbp)
leaq -0x40(%rbp), %rax
movq %rax, -0x198(%rbp)
movl -0x40(%rbp), %eax
movl %eax, -0x18c(%rbp)
cmpl $0x28, %eax
ja 0x16bd4f
movq -0x198(%rbp), %rcx
movl -0x18c(%rbp), %edx
movslq %edx, %rax
addq 0x10(%rcx), %rax
addl $0x8, %edx
movl %edx, (%rcx)
movq %rax, -0x1a0(%rbp)
jmp 0x16bd6c
movq -0x198(%rbp), %rcx
movq 0x8(%rcx), %rax
movq %rax, %rdx
addq $0x8, %rdx
movq %rdx, 0x8(%rcx)
movq %rax, -0x1a0(%rbp)
movq -0x1a0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x70(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x16bd8c
cmpl $0x3, -0x1c(%rbp)
jne 0x16bd8c
movl $0x1, -0x74(%rbp)
jmp 0x16bd95
movl $0x1, -0x74(%rbp)
jmp 0x16bd97
leaq -0x40(%rbp), %rax
cmpl $0x0, -0x74(%rbp)
je 0x16bdae
movq $0x0, -0x8(%rbp)
jmp 0x16c19a
movq -0x18(%rbp), %rdi
leaq 0x215508(%rip), %rsi    # 0x3812c1
callq 0x2200
movq %rax, -0x48(%rbp)
cmpq $0x0, %rax
jne 0x16bdd5
movq $0x0, -0x8(%rbp)
jmp 0x16c19a
leaq -0x5c(%rbp), %rdi
movq -0x48(%rbp), %rcx
movl $0x1, %esi
movl $0x4, %edx
callq 0x22e0
cmpq $0x4, %rax
je 0x16bdff
movq $0x0, -0x8(%rbp)
jmp 0x16c19a
leaq -0x5c(%rbp), %rdi
leaq 0x21e3c9(%rip), %rsi    # 0x38a1d3
movl $0x4, %edx
callq 0x20c0
cmpl $0x0, %eax
je 0x16be47
movq 0x2581c0(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
leaq 0x21e3ae(%rip), %rsi    # 0x38a1d8
movb $0x0, %al
callq 0x22a0
movq -0x48(%rbp), %rdi
callq 0x21a0
movq $0x0, -0x8(%rbp)
jmp 0x16c19a
leaq -0x54(%rbp), %rdi
movq -0x48(%rbp), %rcx
movl $0x4, %esi
movl $0x3, %edx
callq 0x22e0
movq %rax, %rcx
movl -0x58(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x58(%rbp)
cmpl $0xa, -0x4c(%rbp)
je 0x16bea6
movq 0x258169(%rip), %rax    # 0x3c3fe0
movq (%rax), %rdi
movl -0x4c(%rbp), %edx
leaq 0x21e36e(%rip), %rsi    # 0x38a1f2
movl $0xa, %ecx
movb $0x0, %al
callq 0x22a0
movq -0x48(%rbp), %rdi
callq 0x21a0
movq $0x0, -0x8(%rbp)
jmp 0x16c19a
cmpq $0x0, -0x10(%rbp)
jne 0x16bec1
movl -0x54(%rbp), %edi
movl -0x50(%rbp), %esi
callq 0x16c880
movq %rax, -0x1a8(%rbp)
jmp 0x16becc
movq -0x10(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movq -0x1a8(%rbp), %rax
movq %rax, -0x98(%rbp)
movl -0x54(%rbp), %ecx
movq -0x98(%rbp), %rdx
xorl %eax, %eax
cmpl (%rdx), %ecx
movb %al, -0x1a9(%rbp)
jne 0x16bf06
movl -0x50(%rbp), %eax
movq -0x98(%rbp), %rcx
cmpl 0x4(%rcx), %eax
sete %al
movb %al, -0x1a9(%rbp)
movb -0x1a9(%rbp), %al
testb $0x1, %al
jne 0x16bf12
jmp 0x16bf14
jmp 0x16bf33
leaq 0x21e315(%rip), %rdi    # 0x38a230
leaq 0x21e0d7(%rip), %rsi    # 0x389ff9
movl $0x67, %edx
leaq 0x21e32d(%rip), %rcx    # 0x38a25b
callq 0x2130
movl $0x0, -0x60(%rbp)
movl -0x60(%rbp), %eax
movq -0x98(%rbp), %rcx
movl 0x4(%rcx), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
cmpl %ecx, %eax
jge 0x16c186
movq -0x98(%rbp), %rax
movq 0x18(%rax), %rax
movslq -0x60(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, -0xa0(%rbp)
leaq -0x54(%rbp), %rdi
movq -0x48(%rbp), %rcx
movl $0x4, %esi
movl $0x2, %edx
callq 0x22e0
movq %rax, %rcx
movl -0x58(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x58(%rbp)
cmpq $0x0, -0x10(%rbp)
jne 0x16bfab
movq -0xa0(%rbp), %rdi
movl -0x54(%rbp), %esi
callq 0x16c940
movl $0x0, -0x64(%rbp)
movl -0x64(%rbp), %eax
cmpl -0x50(%rbp), %eax
jge 0x16c176
movq -0x48(%rbp), %rcx
leaq -0xa8(%rbp), %rdi
movl $0x8, %esi
movl $0x1, %edx
callq 0x22e0
movq %rax, %rcx
movl -0x58(%rbp), %eax
addq %rcx, %rax
movl %eax, -0x58(%rbp)
cmpl $0x1, -0x1c(%rbp)
jne 0x16c030
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movq -0xa0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
leaq -0x68(%rbp), %rdx
callq 0x16c970
cmpl $0x0, -0x68(%rbp)
je 0x16c02b
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x16c166
cmpl $0x2, -0x1c(%rbp)
je 0x16c040
cmpl $0x3, -0x1c(%rbp)
jne 0x16c164
movq -0xa8(%rbp), %rax
andq -0x80(%rbp), %rax
movl %eax, -0xac(%rbp)
movl -0x1c(%rbp), %edx
movl $0x2, %eax
xorl %ecx, %ecx
cmpl $0x2, %edx
cmovel %ecx, %eax
movl %eax, -0xb4(%rbp)
movl -0xac(%rbp), %eax
cmpl -0x70(%rbp), %eax
jl 0x16c087
movl -0xb4(%rbp), %ecx
movl $0x2, %eax
shll %cl, %eax
movl %eax, -0xb0(%rbp)
jmp 0x16c0b3
movl -0xac(%rbp), %eax
cmpl -0x6c(%rbp), %eax
jl 0x16c0a7
movl -0xb4(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0xb0(%rbp)
jmp 0x16c0b1
movl $0xffffffff, -0xb0(%rbp) # imm = 0xFFFFFFFF
jmp 0x16c0b3
cmpl $0x0, -0xb0(%rbp)
jl 0x16c162
movq -0xa8(%rbp), %rax
movq -0x80(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movslq -0xb0(%rbp), %rcx
orq %rcx, %rax
movq %rax, -0xa8(%rbp)
movq -0x88(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x88(%rbp)
movq -0xa0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
leaq -0x68(%rbp), %rdx
callq 0x16c970
movl %eax, -0xb8(%rbp)
cmpl $0x0, -0x68(%rbp)
je 0x16c12c
movq -0x90(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x90(%rbp)
jmp 0x16c160
movq -0xa0(%rbp), %rax
movq 0x10(%rax), %rax
movl -0xb8(%rbp), %ecx
movq (%rax,%rcx,8), %rdx
movslq -0xb0(%rbp), %rax
orq %rax, %rdx
movq -0xa0(%rbp), %rax
movq 0x10(%rax), %rax
movl -0xb8(%rbp), %ecx
movq %rdx, (%rax,%rcx,8)
jmp 0x16c162
jmp 0x16c164
jmp 0x16c166
jmp 0x16c168
movl -0x64(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x64(%rbp)
jmp 0x16bfb2
jmp 0x16c178
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x16bf3a
movq -0x48(%rbp), %rdi
callq 0x21a0
movq -0x98(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x1b0, %rsp            # imm = 0x1B0
popq %rbp
retq
nopw (%rax,%rax)