// File: /workspace/github_c_makefile_star2_O1/ToniWestbrook[P]paladin/bwamem_pair.c
// Function: mem_matesw
int mem_matesw(const mem_opt_t *opt, const bntseq_t *bns, const uint8_t *pac, const mem_pestat_t pes[4], const mem_alnreg_t *a, int l_ms, const uint8_t *ms, mem_alnreg_v *ma)
{
	extern int mem_sort_dedup_patch(const mem_opt_t *opt, const bntseq_t *bns, const uint8_t *pac, uint8_t *query, int n, mem_alnreg_t *a);
	int64_t l_pac = bns->l_pac;
	int i, r, skip[4], n = 0, rid;
	for (r = 0; r < 4; ++r)
		skip[r] = pes[r].failed? 1 : 0;
	for (i = 0; i < ma->n; ++i) { // check which orinentation has been found
		int64_t dist;
		r = mem_infer_dir(l_pac, a->rb, ma->a[i].rb, &dist);
		if (dist >= pes[r].low && dist <= pes[r].high)
			skip[r] = 1;
	}
	if (skip[0] + skip[1] + skip[2] + skip[3] == 4) return 0; // consistent pair exist; no need to perform SW
	for (r = 0; r < 4; ++r) {
		int is_rev, is_larger;
		uint8_t *seq, *rev = 0, *ref = 0;
		int64_t rb, re;
		if (skip[r]) continue;
		is_rev = (r>>1 != (r&1)); // whether to reverse complement the mate
		is_larger = !(r>>1); // whether the mate has larger coordinate
		if (is_rev) {
			rev = malloc(l_ms); // this is the reverse complement of $ms
			for (i = 0; i < l_ms; ++i) rev[l_ms - 1 - i] = ms[i] < 4? 3 - ms[i] : 4;
			seq = rev;
		} else seq = (uint8_t*)ms;
		if (!is_rev) {
			rb = is_larger? a->rb + pes[r].low : a->rb - pes[r].high;
			re = (is_larger? a->rb + pes[r].high: a->rb - pes[r].low) + l_ms; // if on the same strand, end position should be larger to make room for the seq length
		} else {
			rb = (is_larger? a->rb + pes[r].low : a->rb - pes[r].high) - l_ms; // similarly on opposite strands
			re = is_larger? a->rb + pes[r].high: a->rb - pes[r].low;
		}
		if (rb < 0) rb = 0;
		if (re > l_pac<<1) re = l_pac<<1;
		if (rb < re) ref = bns_fetch_seq(bns, pac, &rb, (rb+re)>>1, &re, &rid);
		if (a->rid == rid && re - rb >= opt->min_seed_len) { // no funny things happening
			kswr_t aln;
			mem_alnreg_t b;
			int tmp, xtra = KSW_XSUBO | KSW_XSTART | (l_ms * opt->a < 250? KSW_XBYTE : 0) | (opt->min_seed_len * opt->a);
			aln = ksw_align2(l_ms, seq, re - rb, ref, 5, opt->mat, opt->o_del, opt->e_del, opt->o_ins, opt->e_ins, xtra, 0);
			memset(&b, 0, sizeof(mem_alnreg_t));
			if (aln.score >= opt->min_seed_len && aln.qb >= 0) { // something goes wrong if aln.qb < 0
				b.rid = a->rid;
				b.is_alt = a->is_alt;
				b.qb = is_rev? l_ms - (aln.qe + 1) : aln.qb;                                                                                                                                                                              
				b.qe = is_rev? l_ms - aln.qb : aln.qe + 1; 
				b.rb = is_rev? (l_pac<<1) - (rb + aln.te + 1) : rb + aln.tb;
				b.re = is_rev? (l_pac<<1) - (rb + aln.tb) : rb + aln.te + 1;
				b.score = aln.score;
				b.csub = aln.score2;
				b.secondary = -1;
				b.seedcov = (b.re - b.rb < b.qe - b.qb? b.re - b.rb : b.qe - b.qb) >> 1;
//				printf("*** %d, [%lld,%lld], %d:%d, (%lld,%lld), (%lld,%lld) == (%lld,%lld)\n", aln.score, rb, re, is_rev, is_larger, a->rb, a->re, ma->a[0].rb, ma->a[0].re, b.rb, b.re);
				kv_push(mem_alnreg_t, *ma, b); // make room for a new element
				// move b s.t. ma is sorted
				for (i = 0; i < ma->n - 1; ++i) // find the insertion point
					if (ma->a[i].score < b.score) break;
				tmp = i;
				for (i = ma->n - 1; i > tmp; --i) ma->a[i] = ma->a[i-1];
				ma->a[i] = b;
			}
			++n;
		}
		if (n) ma->n = mem_sort_dedup_patch(opt, 0, 0, 0, ma->n, ma->a);
		if (rev) free(rev);
		free(ref);
	}
	return n;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movl %r9d, (%rsp)
movq %r8, 0x18(%rsp)
movq %rcx, %r15
movq %rdx, 0xa0(%rsp)
movq %rsi, 0x98(%rsp)
movq (%rsi), %rbx
xorl %eax, %eax
xorl %ecx, %ecx
cmpl $0x0, 0x8(%r15,%rax,8)
setne %cl
movl %ecx, 0x70(%rsp,%rax)
addq $0x4, %rax
cmpq $0x10, %rax
jne 0x1fc0e
movq 0x108(%rsp), %rax
movq (%rax), %rax
testq %rax, %rax
je 0x1fcc8
movq 0x18(%rsp), %rcx
movq (%rcx), %rcx
movq 0x108(%rsp), %rdx
movq 0x18(%rdx), %rdx
leaq (%rbx,%rbx), %rsi
cmpq %rbx, %rcx
setge %r10b
movq (%rdx), %r8
cmpq %rbx, %r8
setl %r9b
xorb %r10b, %r9b
movq %r8, %r10
notq %r10
addq %rsi, %r10
testb %r9b, %r9b
cmovneq %r8, %r10
xorl %r8d, %r8d
subq %rcx, %r10
setle %r8b
movq %r10, %r11
negq %r11
cmovsq %r10, %r11
leaq (%r8,%r8,2), %r10
xorb $0x1, %r9b
movzbl %r9b, %r8d
xorq %r10, %r8
movl %r8d, %r9d
shll $0x5, %r9d
movslq (%r15,%r9), %r10
cmpq %r10, %r11
jl 0x1fcbf
addq %r15, %r9
movslq 0x4(%r9), %r9
cmpq %r9, %r11
jg 0x1fcbf
movl $0x1, 0x70(%rsp,%r8,4)
addq $0x60, %rdx
decq %rax
jne 0x1fc53
movq %rbx, 0x28(%rsp)
movq %rdi, 0x40(%rsp)
movl 0x74(%rsp), %eax
addl 0x70(%rsp), %eax
addl 0x78(%rsp), %eax
addl 0x7c(%rsp), %eax
movl $0x0, 0x4(%rsp)
cmpl $0x4, %eax
movq 0x100(%rsp), %rcx
je 0x202c5
movslq (%rsp), %rdx
movq 0x28(%rsp), %rax
addq %rax, %rax
movq %rax, 0x28(%rsp)
movq 0x40(%rsp), %rax
addq $0xc4, %rax
movq %rax, 0x88(%rsp)
movl %edx, %ebp
movq %rdx, 0x48(%rsp)
leaq -0x1(%rdx), %rax
movq %rax, 0x90(%rsp)
xorl %ebx, %ebx
movl $0x0, 0x4(%rsp)
cmpl $0x0, 0x70(%rsp,%rbx,4)
jne 0x202b8
movl %ebx, %r13d
shrl %r13d
movl %ebx, %r12d
andl $0x1, %r12d
cmpl %r12d, %r13d
jne 0x1fd67
movq $0x0, 0x58(%rsp)
movq %rcx, %r14
jmp 0x1fdd2
movq 0x48(%rsp), %rdi
leaq 0x94cd(%rip), %rsi      # 0x29240
movl $0x86, %edx
leaq 0x96a7(%rip), %rcx      # 0x29426
callq 0x22d2b
cmpl $0x0, (%rsp)
movq %rax, 0x58(%rsp)
jle 0x1fdcf
addq 0x90(%rsp), %rax
xorl %ecx, %ecx
movq 0x100(%rsp), %rdi
movl $0x4, %r8d
movb (%rdi,%rcx), %dl
movb $0x3, %sil
subb %dl, %sil
cmpb $0x4, %dl
movzbl %sil, %edx
cmovael %r8d, %edx
movb %dl, (%rax)
incq %rcx
decq %rax
cmpq %rcx, %rbp
jne 0x1fda7
movq 0x58(%rsp), %r14
jmp 0x1fdd2
movq %rax, %r14
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rbx, %rcx
shlq $0x5, %rcx
cmpl %r12d, %r13d
jne 0x1fdf5
cmpq $0x1, %rbx
ja 0x1fe04
movslq (%r15,%rcx), %rcx
addq %rcx, %rax
jmp 0x1fe0c
cmpq $0x1, %rbx
ja 0x1fe30
movslq (%r15,%rcx), %rcx
addq %rcx, %rax
jmp 0x1fe38
movslq 0x4(%r15,%rcx), %rcx
subq %rcx, %rax
movq %rax, 0x8(%rsp)
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rbx, %rcx
shlq $0x5, %rcx
cmpq $0x1, %rbx
ja 0x1fe61
movslq 0x4(%r15,%rcx), %rcx
addq %rcx, %rax
jmp 0x1fe68
movslq 0x4(%r15,%rcx), %rcx
subq %rcx, %rax
subq 0x48(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rbx, %rcx
shlq $0x5, %rcx
cmpq $0x1, %rbx
ja 0x1fe6f
movslq 0x4(%r15,%rcx), %rcx
addq %rcx, %rax
jmp 0x1fe76
movslq (%r15,%rcx), %rcx
subq %rcx, %rax
addq 0x48(%rsp), %rax
jmp 0x1fe76
movslq (%r15,%rcx), %rcx
subq %rcx, %rax
movq %rax, 0x38(%rsp)
cmpq $0x0, 0x8(%rsp)
jns 0x1fe8c
movq $0x0, 0x8(%rsp)
cmpq 0x28(%rsp), %rax
jle 0x1fe9d
movq 0x28(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0x8(%rsp), %rax
movq 0x38(%rsp), %rcx
cmpq %rcx, %rax
jge 0x1fedd
addq %rax, %rcx
sarq %rcx
movq 0x98(%rsp), %rdi
movq 0xa0(%rsp), %rsi
leaq 0x8(%rsp), %rdx
leaq 0x38(%rsp), %r8
leaq 0x6c(%rsp), %r9
callq 0x11404
movq %rax, 0x50(%rsp)
jmp 0x1fee6
movq $0x0, 0x50(%rsp)
movq 0x18(%rsp), %rax
movl 0x18(%rax), %eax
cmpl 0x6c(%rsp), %eax
jne 0x2026c
movq %r14, %rdx
movq 0x38(%rsp), %rcx
subq 0x8(%rsp), %rcx
movq 0x40(%rsp), %r14
movslq 0x78(%r14), %rax
cmpq %rax, %rcx
jl 0x2026c
movl (%r14), %r9d
movl %r9d, %r8d
movl (%rsp), %esi
imull %esi, %r8d
xorl %edi, %edi
cmpl $0xfa, %r8d
setl %dil
shll $0x10, %edi
imull %r9d, %eax
orl %edi, %eax
orl $0xc0000, %eax          # imm = 0xC0000
movl 0x8(%r14), %edi
movq %rdi, 0x20(%rsp)
movl 0xc(%r14), %edi
movq %rdi, 0x30(%rsp)
movl 0x10(%r14), %r10d
movl 0x14(%r14), %r11d
subq $0x8, %rsp
leaq 0xb4(%rsp), %rdi
movq 0x58(%rsp), %r8
movl $0x5, %r9d
pushq $0x0
pushq %rax
pushq %r11
pushq %r10
pushq 0x58(%rsp)
pushq 0x50(%rsp)
pushq 0xc0(%rsp)
callq 0x239fc
addq $0x40, %rsp
movl 0xac(%rsp), %ecx
movl 0xc4(%rsp), %eax
movl %ecx, 0x20(%rsp)
cmpl 0x78(%r14), %ecx
setge %cl
testl %eax, %eax
setns %dl
andb %cl, %dl
cmpb $0x1, %dl
jne 0x20268
movl 0xb4(%rsp), %r14d
movslq 0xb0(%rsp), %rcx
movslq 0xc0(%rsp), %r11
movq 0x18(%rsp), %r9
movl 0x48(%r9), %esi
movl $0xc0000000, %edx       # imm = 0xC0000000
andl %edx, %esi
movl %esi, 0x30(%rsp)
movl %r14d, %r10d
notl %r10d
movl (%rsp), %edx
addl %edx, %r10d
subl %eax, %edx
incl %r14d
movq 0x8(%rsp), %rsi
leaq (%rsi,%rcx), %rdi
notq %rdi
movq 0x28(%rsp), %r8
addq %r8, %rdi
addq %rsi, %r11
subq %r11, %r8
cmpl %r12d, %r13d
movl %r14d, %r12d
cmovel %eax, %r10d
cmovnel %edx, %r12d
cmovneq %rdi, %r11
movl 0xb8(%rsp), %r14d
leaq 0x1(%rsi,%rcx), %r13
cmovneq %r8, %r13
movq %r13, 0x80(%rsp)
subq %r11, %r13
movl %r12d, %eax
subl %r10d, %eax
cltq
cmpq %rax, %r13
cmovgeq %rax, %r13
movl 0x18(%r9), %r9d
movq 0x108(%rsp), %rcx
movq 0x8(%rcx), %rax
cmpq %rax, (%rcx)
jne 0x200d7
leaq (%rax,%rax), %rcx
testq %rax, %rax
movl $0x2, %eax
cmoveq %rax, %rcx
movq 0x108(%rsp), %rax
movl %r14d, 0x64(%rsp)
movq %rcx, 0x8(%rax)
movq 0x18(%rax), %rdi
shlq $0x5, %rcx
leaq (%rcx,%rcx,2), %rsi
leaq 0x91ab(%rip), %rdx      # 0x29240
movl $0xa6, %ecx
leaq 0x9385(%rip), %r8       # 0x29426
movl %r12d, 0x14(%rsp)
movq %r11, %r12
movl %r10d, 0x68(%rsp)
movl %r9d, %r14d
callq 0x22d64
movl %r14d, %r9d
movl 0x68(%rsp), %r10d
movq %r12, %r11
movl 0x14(%rsp), %r12d
movq 0x108(%rsp), %rcx
movq %rax, 0x18(%rcx)
movl 0x64(%rsp), %r14d
shrq %r13
movq 0x108(%rsp), %rdi
movq (%rdi), %rax
movq 0x18(%rdi), %rdx
leaq 0x1(%rax), %rcx
movq %rcx, (%rdi)
leaq (%rax,%rax,2), %rax
shlq $0x5, %rax
movq %r11, (%rdx,%rax)
movq 0x80(%rsp), %rcx
movq %rcx, 0x8(%rdx,%rax)
movl %r10d, 0x10(%rdx,%rax)
movl %r12d, 0x14(%rdx,%rax)
movl %r9d, 0x18(%rdx,%rax)
movl 0x20(%rsp), %ecx
movl %ecx, 0x1c(%rdx,%rax)
xorl %ecx, %ecx
movq %rcx, 0x20(%rdx,%rax)
movl %ecx, 0x28(%rdx,%rax)
movl %r14d, 0x2c(%rdx,%rax)
movq %rcx, 0x30(%rdx,%rax)
movl %r13d, 0x38(%rdx,%rax)
movl $0xffffffff, 0x3c(%rdx,%rax) # imm = 0xFFFFFFFF
movq %rcx, 0x40(%rdx,%rax)
movl 0x30(%rsp), %esi
movl %esi, 0x48(%rdx,%rax)
xorps %xmm0, %xmm0
movups %xmm0, 0x4c(%rdx,%rax)
movl %ecx, 0x5c(%rdx,%rax)
movq (%rdi), %rax
movq %rax, %rdx
decq %rdx
je 0x20195
movq 0x108(%rsp), %rcx
movq 0x18(%rcx), %rsi
leal -0x1(%rax), %ecx
addq $0x1c, %rsi
xorl %edi, %edi
movl 0x20(%rsp), %r8d
cmpl %r8d, (%rsi)
jl 0x20193
incq %rdi
addq $0x60, %rsi
cmpq %rdi, %rdx
jne 0x2017b
jmp 0x20195
movl %edi, %ecx
leal -0x1(%rax), %edx
cmpl %ecx, %edx
jle 0x201ee
movl %r9d, 0x14(%rsp)
movslq %edx, %rdx
movslq %ecx, %r8
movq %rdx, %rcx
shlq $0x5, %rcx
leaq (%rcx,%rcx,2), %r9
movq 0x108(%rsp), %rcx
movq 0x18(%rcx), %rcx
addl $-0x2, %eax
cltq
leaq (%rcx,%r9), %rdi
leaq (%rax,%rax,2), %rsi
shlq $0x5, %rsi
addq %rcx, %rsi
movl $0xc, %ecx
rep  movsq (%rsi), %es:(%rdi)
movq %rdx, %rax
decq %rdx
addq $-0x60, %r9
cmpq %r8, %rdx
jg 0x201b2
movl 0x14(%rsp), %r9d
movq 0x108(%rsp), %rax
movq 0x18(%rax), %rax
movslq %edx, %rcx
leaq (%rcx,%rcx,2), %rcx
shlq $0x5, %rcx
movq %r11, (%rax,%rcx)
movq 0x80(%rsp), %rdx
movq %rdx, 0x8(%rax,%rcx)
movl %r10d, 0x10(%rax,%rcx)
movl %r12d, 0x14(%rax,%rcx)
movl %r9d, 0x18(%rax,%rcx)
movl 0x20(%rsp), %edx
movl %edx, 0x1c(%rax,%rcx)
xorl %edx, %edx
movq %rdx, 0x20(%rax,%rcx)
movl %edx, 0x28(%rax,%rcx)
movl %r14d, 0x2c(%rax,%rcx)
movq %rdx, 0x30(%rax,%rcx)
movl %r13d, 0x38(%rax,%rcx)
movl $0xffffffff, 0x3c(%rax,%rcx) # imm = 0xFFFFFFFF
movq %rdx, 0x40(%rax,%rcx)
movl 0x30(%rsp), %esi
movl %esi, 0x48(%rax,%rcx)
xorps %xmm0, %xmm0
movups %xmm0, 0x4c(%rax,%rcx)
movl %edx, 0x5c(%rax,%rcx)
incl 0x4(%rsp)
cmpl $0x0, 0x4(%rsp)
je 0x20297
movq 0x108(%rsp), %r14
movl (%r14), %r8d
movq 0x18(%r14), %r9
movq 0x40(%rsp), %rdi
xorl %esi, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x19caa
cltq
movq %rax, (%r14)
movq 0x58(%rsp), %rdi
testq %rdi, %rdi
je 0x202a6
callq 0x3390
movq 0x50(%rsp), %rdi
callq 0x3390
movq 0x100(%rsp), %rcx
incq %rbx
cmpq $0x4, %rbx
jne 0x1fd3c
movl 0x4(%rsp), %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq