// File: /workspace/github_c_makefile_star2_O3/lh3[P]fermi2/match.c
// Function: main_match
int main_match(int argc, char *argv[])
{
	int i, c, use_mmap = 0, batch_size = 10000000, l_seqs;
	gzFile fp;
	char *fn_sa = 0;
	kseq_t *ks;
	global_t g;

	memset(&g, 0, sizeof(global_t));
	g.max_sa_occ = 10, g.min_occ = 1, g.n_threads = 1, g.kmer = 61, g.min_len = 0;
	while ((c = getopt(argc, argv, "Mdps:m:n:b:t:k:l:")) >= 0) {
		if (c == 'M') use_mmap = 1;
		else if (c == 's') fn_sa = optarg;
		else if (c == 'l') g.min_len = atoi(optarg);
		else if (c == 'm') g.max_sa_occ = atoi(optarg);
		else if (c == 'p') g.partial = 1;
		else if (c == 'd') g.discovery = g.partial = 1;
		else if (c == 'n') g.min_occ = atoi(optarg);
		else if (c == 't') g.n_threads = atoi(optarg);
		else if (c == 'k') g.kmer = atoi(optarg), g.discovery = g.partial = 1;
		else if (c == 'b') batch_size = atoi(optarg);
	}

	if (optind + 2 > argc) {
		fprintf(stderr, "Usage: fermi2 match [options] <index.fmd> <seq.fa>\n");
		fprintf(stderr, "Options:\n");
		fprintf(stderr, "  -p        find SMEMs (reqiring both strands in one index)\n");
		fprintf(stderr, "  -d        discovery novel alleles (force -p; experimental)\n");
		fprintf(stderr, "  -k INT    k-mer length in the discovery mode (force -d) [%d]\n", g.kmer);
		fprintf(stderr, "  -t INT    number of threads [%d]\n", g.n_threads);
		fprintf(stderr, "  -b INT    batch size [%d]\n", batch_size);
		fprintf(stderr, "  -s FILE   sampled suffix array []\n");
		fprintf(stderr, "  -m INT    show coordinate if the number of hits is no more than INT [%d]\n", g.max_sa_occ);
		fprintf(stderr, "  -n INT    min occurrences [%d]\n", g.min_occ);
		fprintf(stderr, "  -l INT    min length [%d]\n", g.min_len);
		fprintf(stderr, "Output format:\n");
		fprintf(stderr, "    SQ  seqName seqLen\n");
		fprintf(stderr, "    EM  start   end     occurrence [positions]\n");
//		fprintf(stderr, "    NS  start   leftLen  diffLen  rightLen  leftOcc  rightOcc  strand  seq  qual\n");
//		fprintf(stderr, "  At an 'NS' line, the length of 'seq' always equals leftLen+diffLen+rightLen.\n");
		return 1;
	}

	fp = gzopen(argv[optind+1], "r");
	if (fp == 0) {
		fprintf(stderr, "[E::%s] failed to open the sequence file\n", __func__);
		return 1;
	}
	g.e = use_mmap? rld_restore_mmap(argv[optind]) : rld_restore(argv[optind]);
	if (g.e == 0) {
		fprintf(stderr, "[E::%s] failed to open the index file\n", __func__);
		gzclose(fp);
		return 1;
	}
	if (g.partial && (g.e->mcnt[2] != g.e->mcnt[5] || g.e->mcnt[3] != g.e->mcnt[4])) {
		fprintf(stderr, "[E::%s] with '-p', the index must include both strands\n", __func__);
		rld_destroy((rld_t*)g.e);
		gzclose(fp);
		return 1;
	}
	if (fn_sa) g.sa = fm_sa_restore(fn_sa);
	if (fn_sa && g.sa == 0) {
		fprintf(stderr, "[E::%s] failed to open the sampled SA file\n", __func__);
		rld_destroy((rld_t*)g.e);
		gzclose(fp);
		return 1;
	}

	g.mem = calloc(g.n_threads, sizeof(thrmem_t));

	batch_size *= g.n_threads;
	ks = kseq_init(fp);
	l_seqs = 0;
	while (kseq_read(ks) >= 0) {
		if (g.n_seqs == g.m_seqs) {
			g.m_seqs = g.m_seqs? g.m_seqs<<1 : 4;
			g.name = realloc(g.name, g.m_seqs * sizeof(char*));
			g.seq  = realloc(g.seq,  g.m_seqs * sizeof(char*));
			g.qual = realloc(g.qual, g.m_seqs * sizeof(char*));
			g.out  = realloc(g.out,  g.m_seqs * sizeof(char*));
		}
		g.name[g.n_seqs] = strdup(ks->name.s);
		g.seq[g.n_seqs]  = strdup(ks->seq.s);
		g.qual[g.n_seqs] = ks->qual.l? strdup(ks->qual.s) : 0; // these will be free'd in worker
		++g.n_seqs;
		l_seqs += ks->seq.l;
		if (l_seqs >= batch_size) {
			kt_for(g.n_threads, worker, &g, g.n_seqs);
			for (i = 0; i < g.n_seqs; ++i) {
				puts(g.out[i]);
				free(g.out[i]);
			}
			g.n_seqs = l_seqs = 0;
		}
	}
	// the last batch
	kt_for(g.n_threads, worker, &g, g.n_seqs);
	for (i = 0; i < g.n_seqs; ++i) {
		puts(g.out[i]);
		free(g.out[i]);
	}
	kseq_destroy(ks);

	for (i = 0; i < g.n_threads; ++i) {
		free(g.mem[i].curr.a); free(g.mem[i].prev.a); free(g.mem[i].smem.a);
		free(g.mem[i].cmp[0].s); free(g.mem[i].cmp[1].s); free(g.mem[i].str.s);
	}
	free(g.name); free(g.seq); free(g.qual); free(g.out); free(g.mem);
	if (g.sa) fm_sa_destroy((fmsa_t*)g.sa);
	rld_destroy((rld_t*)g.e);
	gzclose(fp);
	return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rsi, %r13
movl %edi, %r14d
xorps %xmm0, %xmm0
movups %xmm0, 0x40(%rsp)
movups %xmm0, 0x60(%rsp)
movups %xmm0, 0x50(%rsp)
movups %xmm0, 0x80(%rsp)
movups %xmm0, 0x70(%rsp)
movq $0x0, 0x90(%rsp)
movabsq $0x10000000a, %rax      # imm = 0x10000000A
movq %rax, 0x48(%rsp)
movl $0x1, 0x60(%rsp)
movl $0x3d, 0x5c(%rsp)
leaq 0x5391(%rip), %rdx      # 0x1eed0
callq 0x22f0
testl %eax, %eax
js 0x19d35
movl 0x5c(%rsp), %ecx
movl %ecx, 0x2c(%rsp)
movl 0x54(%rsp), %ecx
movl %ecx, 0x18(%rsp)
movl 0x58(%rsp), %ecx
movl %ecx, 0x14(%rsp)
movl 0x60(%rsp), %ecx
movl %ecx, 0x30(%rsp)
movl 0x48(%rsp), %ecx
movl %ecx, 0x34(%rsp)
movl 0x4c(%rsp), %ecx
movl %ecx, 0x28(%rsp)
movl $0x989680, 0x4(%rsp)    # imm = 0x989680
movl $0x3d, 0x8(%rsp)
movl $0xa, 0xc(%rsp)
movl $0x1, 0x10(%rsp)
movq $0x0, 0x98(%rsp)
movl 0x50(%rsp), %ecx
movl %ecx, 0x24(%rsp)
leaq 0x5319(%rip), %r15      # 0x1eed0
leaq 0x52c6(%rip), %r12      # 0x1ee84
movl $0x1, %ebx
xorl %ebp, %ebp
movq $0x0, 0xa0(%rsp)
movl $0x0, 0x20(%rsp)
leal -0x62(%rax), %ecx
cmpl $0x12, %ecx
ja 0x19c02
movslq (%r12,%rcx,4), %rax
addq %r12, %rax
jmpq *%rax
movq 0xb3e7(%rip), %rax      # 0x24fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x4(%rsp)
jmp 0x19cd6
cmpl $0x4d, %eax
jne 0x19cd6
movl $0x1, 0x20(%rsp)
jmp 0x19cd6
movq 0xb3b9(%rip), %rax      # 0x24fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, %ebx
movl %eax, 0x30(%rsp)
jmp 0x19cd6
movq 0xb39f(%rip), %rax      # 0x24fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x24(%rsp)
movq %rax, 0x98(%rsp)
jmp 0x19cd6
movq 0xb37f(%rip), %rax      # 0x24fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x28(%rsp)
movl %eax, 0x10(%rsp)
jmp 0x19cd6
movl $0x1, 0x14(%rsp)
movl $0x1, 0x18(%rsp)
jmp 0x19ca4
movq 0xb354(%rip), %rax      # 0x24fd8
movq (%rax), %rdi
callq 0x2300
movl $0x1, 0x14(%rsp)
movl $0x1, 0x18(%rsp)
movl %eax, 0x2c(%rsp)
movl %eax, 0x8(%rsp)
movl $0x1, %ebp
jmp 0x19cd6
movq 0xb326(%rip), %rax      # 0x24fd8
movq (%rax), %rdi
callq 0x2300
movl %eax, 0x34(%rsp)
movl %eax, 0xc(%rsp)
jmp 0x19cd6
movq 0xb30d(%rip), %rax      # 0x24fd8
movq (%rax), %rax
movq %rax, 0xa0(%rsp)
movl %r14d, %edi
movq %r13, %rsi
movq %r15, %rdx
callq 0x22f0
testl %eax, %eax
jns 0x19bd9
movl 0x2c(%rsp), %eax
movl %eax, 0x5c(%rsp)
movl 0x18(%rsp), %eax
movl %eax, 0x54(%rsp)
movl 0x14(%rsp), %eax
movl %eax, 0x58(%rsp)
movl 0x30(%rsp), %eax
movl %eax, 0x60(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x4c(%rsp)
movl 0x34(%rsp), %eax
movl %eax, 0x48(%rsp)
movl 0x24(%rsp), %eax
movl %eax, 0x50(%rsp)
cmpl $0x0, 0x20(%rsp)
sete %r15b
testl %ebp, %ebp
sete %bpl
jmp 0x19d78
movl $0x989680, 0x4(%rsp)    # imm = 0x989680
movb $0x1, %bpl
movl $0x3d, 0x8(%rsp)
movl $0xa, 0xc(%rsp)
movl $0x1, 0x10(%rsp)
movq $0x0, 0x98(%rsp)
movl $0x1, %ebx
movb $0x1, %r15b
movq $0x0, 0xa0(%rsp)
movq 0xb251(%rip), %r12      # 0x24fd0
movslq (%r12), %rax
leal 0x2(%rax), %ecx
cmpl %r14d, %ecx
jg 0x1a0ee
movq 0x8(%r13,%rax,8), %rdi
leaq 0x3621(%rip), %rsi      # 0x1d3bc
callq 0x22b0
testq %rax, %rax
je 0x1a23f
movq %rax, %r14
movslq (%r12), %rax
movq (%r13,%rax,8), %rdi
testb %r15b, %r15b
je 0x19dc1
callq 0x4119
jmp 0x19dc6
callq 0x4598
movq %rax, %r15
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x1a246
testb %bpl, %bpl
jne 0x19dfc
movq 0x28(%r15), %rax
movq 0x10(%rax), %rcx
cmpq 0x28(%rax), %rcx
jne 0x1a250
movq 0x18(%rax), %rcx
cmpq 0x20(%rax), %rcx
jne 0x1a250
movq 0xa0(%rsp), %rdi
testq %rdi, %rdi
je 0x19e1c
callq 0x18f59
movq %rax, 0x40(%rsp)
testq %rax, %rax
je 0x1a25d
movslq %ebx, %rdi
movl $0x78, %esi
callq 0x2190
movq %rax, 0x68(%rsp)
movq %r14, 0x18(%rsp)
movq %r14, %rdi
callq 0xde96
movq %rax, %r15
movq %rax, %rdi
callq 0xdf28
testl %eax, %eax
js 0x19fb8
imull 0x4(%rsp), %ebx
xorl %r14d, %r14d
leaq 0x422(%rip), %r12       # 0x1a27f
leaq 0x38(%rsp), %r13
movl 0x70(%rsp), %ebp
cmpl 0x74(%rsp), %ebp
jne 0x19ef9
leal (,%rbp,2), %eax
testl %ebp, %ebp
movl $0x4, %ecx
cmovel %ecx, %eax
movl %eax, 0x74(%rsp)
movq 0x78(%rsp), %rdi
movslq %eax, %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x78(%rsp)
movq 0x80(%rsp), %rdi
movslq 0x74(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x80(%rsp)
movq 0x88(%rsp), %rdi
movslq 0x74(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x88(%rsp)
movq 0x90(%rsp), %rdi
movslq 0x74(%rsp), %rsi
shlq $0x3, %rsi
callq 0x2260
movq %rax, 0x90(%rsp)
movl 0x70(%rsp), %ebp
movq 0x8(%r15), %rdi
callq 0x2340
movq 0x78(%rsp), %rcx
movslq %ebp, %rbp
movq %rax, (%rcx,%rbp,8)
movq 0x28(%r15), %rdi
callq 0x2340
movq 0x80(%rsp), %rcx
movq %rax, (%rcx,%rbp,8)
cmpl $0x0, 0x30(%r15)
je 0x19f35
movq 0x38(%r15), %rdi
callq 0x2340
jmp 0x19f37
xorl %eax, %eax
movq 0x88(%rsp), %rcx
movq %rax, (%rcx,%rbp,8)
incl %ebp
movl %ebp, 0x70(%rsp)
addl 0x20(%r15), %r14d
cmpl %ebx, %r14d
jl 0x19fa8
movl 0x60(%rsp), %edi
movslq %ebp, %rcx
movq %r12, %rsi
movq %r13, %rdx
callq 0x340c
cmpl $0x0, 0x70(%rsp)
jle 0x19f9d
xorl %r14d, %r14d
movq 0x90(%rsp), %rax
movq (%rax,%r14,8), %rdi
callq 0x2080
movq 0x90(%rsp), %rax
movq (%rax,%r14,8), %rdi
callq 0x2040
incq %r14
movslq 0x70(%rsp), %rax
cmpq %rax, %r14
jl 0x19f6e
movl $0x0, 0x70(%rsp)
xorl %r14d, %r14d
movq %r15, %rdi
callq 0xdf28
testl %eax, %eax
jns 0x19e62
leaq 0x38(%rsp), %rbx
movl 0x28(%rbx), %edi
movslq 0x38(%rbx), %rcx
leaq 0x2b4(%rip), %rsi       # 0x1a27f
movq %rbx, %rdx
callq 0x340c
cmpl $0x0, 0x38(%rbx)
jle 0x1a00a
xorl %ebx, %ebx
movq 0x90(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2080
movq 0x90(%rsp), %rax
movq (%rax,%rbx,8), %rdi
callq 0x2040
incq %rbx
movslq 0x70(%rsp), %rax
cmpq %rax, %rbx
jl 0x19fdb
movq %r15, %rdi
callq 0xdee8
cmpl $0x0, 0x60(%rsp)
jle 0x1a089
xorl %ebx, %ebx
xorl %r14d, %r14d
movq 0x68(%rsp), %rax
movq 0x10(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x28(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x40(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x60(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x70(%rax,%rbx), %rdi
callq 0x2040
movq 0x68(%rsp), %rax
movq 0x50(%rax,%rbx), %rdi
callq 0x2040
incq %r14
movslq 0x60(%rsp), %rax
addq $0x78, %rbx
cmpq %rax, %r14
jl 0x1a01e
movq 0x78(%rsp), %rdi
callq 0x2040
movq 0x80(%rsp), %rdi
callq 0x2040
movq 0x88(%rsp), %rdi
callq 0x2040
movq 0x90(%rsp), %rdi
callq 0x2040
movq 0x68(%rsp), %rdi
callq 0x2040
movq 0x40(%rsp), %rdi
testq %rdi, %rdi
je 0x1a0d3
callq 0x18d40
movq 0x38(%rsp), %rdi
callq 0x36d4
movq 0x18(%rsp), %rdi
callq 0x2030
xorl %eax, %eax
jmp 0x1a26d
movq 0xaf03(%rip), %r14      # 0x24ff8
movq (%r14), %rcx
leaq 0x4de3(%rip), %rdi      # 0x1eee2
movl $0x33, %esi
movl $0x1, %edx
callq 0x2310
movq (%r14), %rcx
leaq 0x4dfe(%rip), %rdi      # 0x1ef16
movl $0x9, %esi
movl $0x1, %edx
callq 0x2310
movq (%r14), %rcx
leaq 0x4def(%rip), %rdi      # 0x1ef20
movl $0x3c, %esi
movl $0x1, %edx
callq 0x2310
movq (%r14), %rcx
leaq 0x4e13(%rip), %rdi      # 0x1ef5d
movl $0x3d, %esi
movl $0x1, %edx
callq 0x2310
movq (%r14), %rdi
leaq 0x4e38(%rip), %rsi      # 0x1ef9b
movl 0x8(%rsp), %edx
xorl %eax, %eax
callq 0x21c0
movq (%r14), %rdi
leaq 0x4e63(%rip), %rsi      # 0x1efdb
movl %ebx, %edx
xorl %eax, %eax
callq 0x21c0
movq (%r14), %rdi
leaq 0x4e74(%rip), %rsi      # 0x1efff
movl 0x4(%rsp), %edx
xorl %eax, %eax
callq 0x21c0
movq (%r14), %rcx
leaq 0x4e7c(%rip), %rdi      # 0x1f01c
movl $0x24, %esi
movl $0x1, %edx
callq 0x2310
movq (%r14), %rdi
leaq 0x4e88(%rip), %rsi      # 0x1f041
movl 0xc(%rsp), %edx
xorl %eax, %eax
callq 0x21c0
movq (%r14), %rdi
leaq 0x4ebf(%rip), %rsi      # 0x1f08d
movl 0x10(%rsp), %edx
xorl %eax, %eax
callq 0x21c0
movq (%r14), %rdi
leaq 0x4ecc(%rip), %rsi      # 0x1f0af
movq 0x98(%rsp), %rdx
xorl %eax, %eax
callq 0x21c0
movq (%r14), %rcx
leaq 0x4ed0(%rip), %rdi      # 0x1f0cc
movl $0xf, %esi
movl $0x1, %edx
callq 0x2310
movq (%r14), %rcx
leaq 0x4ec7(%rip), %rdi      # 0x1f0dc
movl $0x17, %esi
movl $0x1, %edx
callq 0x2310
movq (%r14), %rcx
leaq 0x4ec6(%rip), %rdi      # 0x1f0f4
movl $0x2f, %esi
movl $0x1, %edx
callq 0x2310
jmp 0x1a268
callq 0x3024
jmp 0x1a268
movq %r14, %rdi
callq 0x2ff8
jmp 0x1a268
movq %r15, %rdi
movq %r14, %rsi
callq 0x2f78
jmp 0x1a268
movq %r15, %rdi
movq %r14, %rsi
callq 0x2fb8
movl $0x1, %eax
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq