// File: /workspace/github_c_makefile_star2_O1/xiongxu[P]bam2bedGraph2/samtools-0.1.19/phase.c
// Function: fragphase
static uint64_t *fragphase(int vpos, const int8_t *path, nseq_t *hash, int flip)
{
	khint_t k;
	uint64_t *pcnt;
	uint32_t *left, *rght, max;
	left = rght = 0; max = 0;
	pcnt = calloc(vpos, 8);
	for (k = 0; k < kh_end(hash); ++k) {
		if (kh_exist(hash, k)) {
			int i, c[2];
			frag_t *f = &kh_val(hash, k);
			if (f->vpos >= vpos) continue;
			// get the phase
			c[0] = c[1] = 0;
			for (i = 0; i < f->vlen; ++i) {
				if (f->seq[i] == 0) continue;
				++c[f->seq[i] == path[f->vpos + i] + 1? 0 : 1];
			}
			f->phase = c[0] > c[1]? 0 : 1;
			f->in = c[f->phase]; f->out = c[1 - f->phase];
			f->phased = f->in == f->out? 0 : 1;
			f->ambig = (f->in && f->out && f->out < 3 && f->in <= f->out + 1)? 1 : 0;
			// fix chimera
			f->flip = 0;
			if (flip && c[0] >= 3 && c[1] >= 3) {
				int sum[2], m, mi, md;
				if (f->vlen > max) { // enlarge the array
					max = f->vlen;
					kroundup32(max);
					left = realloc(left, max * 4);
					rght = realloc(rght, max * 4);
				}
				for (i = 0, sum[0] = sum[1] = 0; i < f->vlen; ++i) { // get left counts
					if (f->seq[i]) {
						int c = f->phase? 2 - f->seq[i] : f->seq[i] - 1;
						++sum[c == path[f->vpos + i]? 0 : 1];
					}
					left[i] = sum[1]<<16 | sum[0];
				}
				for (i = f->vlen - 1, sum[0] = sum[1] = 0; i >= 0; --i) { // get right counts
					if (f->seq[i]) {
						int c = f->phase? 2 - f->seq[i] : f->seq[i] - 1;
						++sum[c == path[f->vpos + i]? 0 : 1];
					}
					rght[i] = sum[1]<<16 | sum[0];
				}
				// find the best flip point
				for (i = m = 0, mi = -1, md = -1; i < f->vlen - 1; ++i) {
					int a[2];
					a[0] = (left[i]&0xffff) + (rght[i+1]>>16&0xffff) - (rght[i+1]&0xffff) * FLIP_PENALTY;
					a[1] = (left[i]>>16&0xffff) + (rght[i+1]&0xffff) - (rght[i+1]>>16&0xffff) * FLIP_PENALTY;
					if (a[0] > a[1]) {
						if (a[0] > m) m = a[0], md = 0, mi = i;
					} else {
						if (a[1] > m) m = a[1], md = 1, mi = i;
					}
				}
				if (m - c[0] >= FLIP_THRES && m - c[1] >= FLIP_THRES) { // then flip
					f->flip = 1;
					if (md == 0) { // flip the tail
						for (i = mi + 1; i < f->vlen; ++i)
							if (f->seq[i] == 1) f->seq[i] = 2;
							else if (f->seq[i] == 2) f->seq[i] = 1;
					} else { // flip the head
						for (i = 0; i <= mi; ++i)
							if (f->seq[i] == 1) f->seq[i] = 2;
							else if (f->seq[i] == 2) f->seq[i] = 1;
					}
				}
			}
			// update pcnt[]
			if (!f->single) {
				for (i = 0; i < f->vlen; ++i) {
					int c;
					if (f->seq[i] == 0) continue;
					c = f->phase? 2 - f->seq[i] : f->seq[i] - 1;
					if (c == path[f->vpos + i]) {
						if (f->phase == 0) ++pcnt[f->vpos + i];
						else pcnt[f->vpos + i] += 1ull<<32;
					} else {
						if (f->phase == 0) pcnt[f->vpos + i] += 1<<16;
						else pcnt[f->vpos + i] += 1ull<<48;
					}
				}
			}
		}
	}
	free(left); free(rght);
	return pcnt;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %ecx, 0x38(%rsp)
movq %rdx, %rbx
movq %rsi, %r15
movl %edi, 0x3c(%rsp)
movslq %edi, %rdi
movl $0x8, %esi
callq 0x3610
movq %rax, 0x48(%rsp)
cmpl $0x0, (%rbx)
je 0x1acd0
movq %rbx, %rdx
xorl %ebx, %ebx
xorl %r14d, %r14d
movq $0x0, 0x18(%rsp)
xorl %ebp, %ebp
movl $0x0, 0x24(%rsp)
movq %rdx, 0x40(%rsp)
movq %r15, 0x50(%rsp)
movq 0x10(%rdx), %rax
movl %r14d, %ecx
shrl $0x4, %ecx
movl (%rax,%rcx,4), %eax
leal (%r14,%r14), %ecx
shrl %cl, %eax
testb $0x3, %al
jne 0x1acb9
movq 0x20(%rdx), %r12
imulq $0x114, %r14, %r13      # imm = 0x114
movslq 0x100(%r12,%r13), %rcx
cmpl 0x3c(%rsp), %ecx
jge 0x1acb9
movq %rbp, 0x28(%rsp)
addq %r12, %r13
movq $0x0, 0x10(%rsp)
movq 0x10c(%r13), %rax
testw %ax, %ax
je 0x1a8ad
movzwl %ax, %edx
addq %r15, %rcx
leaq (%r12,%rbx), %rsi
xorl %edi, %edi
movsbl (%rsi,%rdi), %r8d
testl %r8d, %r8d
je 0x1a8a5
movsbl (%rcx,%rdi), %r9d
incl %r9d
xorl %r10d, %r10d
cmpl %r8d, %r9d
setne %r10b
incl 0x10(%rsp,%r10,4)
incq %rdi
cmpq %rdi, %rdx
jne 0x1a884
cmpl $0x0, 0x38(%rsp)
sete %cl
movl 0x10(%rsp), %esi
movl 0x14(%rsp), %edx
xorl %r9d, %r9d
cmpl %edx, %esi
setle %r9b
movl %r9d, %r8d
shll $0x12, %r8d
movq %rax, %rdi
andq $-0x40001, %rdi         # imm = 0xFFFBFFFF
orq %r8, %rdi
movq %rdi, 0x10c(%r13)
shll $0x2, %r9d
movzwl 0x10(%rsp,%r9), %r8d
movq %r8, %r10
shlq $0x20, %r10
movq %rax, 0x30(%rsp)
movabsq $-0xffff00000001, %rax  # imm = 0xFFFF0000FFFFFFFF
andq %rax, %rdi
orq %r10, %rdi
movq %rdi, 0x10c(%r13)
xorl $0x4, %r9d
movl 0x10(%rsp,%r9), %r10d
movzwl %r10w, %r11d
leal 0x1(%r11), %eax
xorl %r9d, %r9d
cmpl %eax, %r8d
setbe %r9b
xorl %eax, %eax
cmpl %r11d, %r8d
setne %al
shlq $0x30, %r10
movabsq $0xffffffe5ffff, %rbp   # imm = 0xFFFFFFE5FFFF
andq %rbp, %rdi
shll $0x13, %eax
orq %r10, %rax
decl %r11d
shll $0x14, %r9d
cmpl $0x2, %r11d
movl $0x0, %r10d
cmovaeq %r10, %r9
testq %r8, %r8
cmoveq %r8, %r9
orq %rax, %r9
orq %rdi, %r9
movq %r9, 0x10c(%r13)
cmpl $0x3, %esi
setl %al
cmpl $0x3, %edx
setl %dl
orb %al, %dl
orb %cl, %dl
jne 0x1ab68
movzwl 0x30(%rsp), %eax
cmpl 0x24(%rsp), %eax
movq 0x28(%rsp), %rbp
jbe 0x1a9e5
decl %eax
movl %eax, %ecx
shrl %ecx
orl %eax, %ecx
movl %ecx, %eax
shrl $0x2, %eax
orl %ecx, %eax
movl %eax, %ecx
shrl $0x4, %ecx
orl %eax, %ecx
movl %ecx, %eax
shrl $0x8, %eax
orl %ecx, %eax
leal 0x4(,%rax,4), %esi
movq %rsi, 0x30(%rsp)
incl %eax
movl %eax, 0x24(%rsp)
movq 0x18(%rsp), %rdi
callq 0x3720
movq %rax, 0x18(%rsp)
movq %rbp, %rdi
movq 0x30(%rsp), %rsi
callq 0x3720
movq %rax, %rbp
movq $0x0, 0x8(%rsp)
movq 0x10c(%r13), %rdx
movl %edx, %eax
andl $0xffff, %eax           # imm = 0xFFFF
je 0x1aa5e
leaq (%r12,%rbx), %rax
xorl %ecx, %ecx
movsbl (%rax,%rcx), %esi
testl %esi, %esi
je 0x1aa36
movl $0x2, %edi
subl %esi, %edi
decl %esi
btl $0x12, %edx
cmovbl %edi, %esi
movslq 0x100(%r13), %rdx
addq %r15, %rdx
movsbl (%rcx,%rdx), %edx
xorl %edi, %edi
cmpl %edx, %esi
setne %dil
incl 0x8(%rsp,%rdi,4)
movl 0xc(%rsp), %edx
shll $0x10, %edx
orl 0x8(%rsp), %edx
movq 0x18(%rsp), %rsi
movl %edx, (%rsi,%rcx,4)
incq %rcx
movq 0x10c(%r13), %rdx
movzwl %dx, %esi
cmpq %rsi, %rcx
jb 0x1aa04
movzwl %dx, %eax
movq $0x0, 0x8(%rsp)
testl %eax, %eax
je 0x1aac5
movl %eax, %eax
incq %rax
leaq (%r12,%rbx), %rcx
movsbl -0x2(%rcx,%rax), %edx
testl %edx, %edx
je 0x1aaad
movl $0x2, %esi
subl %edx, %esi
decl %edx
btl $0x12, 0x10c(%r13)
cmovbl %esi, %edx
movslq 0x100(%r13), %rsi
addq %r15, %rsi
movsbl -0x2(%rax,%rsi), %esi
xorl %edi, %edi
cmpl %esi, %edx
setne %dil
incl 0x8(%rsp,%rdi,4)
movl 0xc(%rsp), %edx
shll $0x10, %edx
orl 0x8(%rsp), %edx
movl %edx, -0x8(%rbp,%rax,4)
decq %rax
cmpq $0x1, %rax
jg 0x1aa74
movq 0x10c(%r13), %rdi
movzwl %di, %esi
cmpl $0x2, %esi
jb 0x1ab72
movq %rdi, 0x28(%rsp)
movq %rbp, %r15
decl %esi
xorl %edi, %edi
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %edx, %edx
movq 0x18(%rsp), %rcx
movl (%rcx,%rdi,4), %r9d
movl %r9d, %r10d
movl $0xffff, %ebp           # imm = 0xFFFF
andl %ebp, %r10d
movl 0x4(%r15,%rdi,4), %r11d
movl %r11d, %ecx
shrl $0x10, %ecx
addl %ecx, %r10d
andl %ebp, %r11d
subl %r11d, %r10d
subl %r11d, %r10d
shrl $0x10, %r9d
addl %r11d, %r9d
addl %ecx, %ecx
subl %ecx, %r9d
cmpl %r9d, %r10d
jle 0x1ab3a
cmpl %edx, %r10d
jle 0x1ab4a
xorl %r8d, %r8d
movl %r10d, %edx
jmp 0x1ab48
cmpl %edx, %r9d
jle 0x1ab4a
movl $0x1, %r8d
movl %r9d, %edx
movl %edi, %eax
incq %rdi
cmpq %rdi, %rsi
jne 0x1aaf1
testl %r8d, %r8d
sete %sil
movq %r15, %rbp
movq 0x50(%rsp), %r15
movq 0x28(%rsp), %rdi
jmp 0x1ab7b
movq 0x28(%rsp), %rbp
jmp 0x1ac11
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
xorl %edx, %edx
xorl %esi, %esi
movl %edx, %ecx
subl 0x10(%rsp), %ecx
cmpl $0x4, %ecx
jl 0x1ac11
subl 0x14(%rsp), %edx
cmpl $0x4, %edx
jl 0x1ac11
orq $0x20000, %rdi          # imm = 0x20000
movq %rdi, 0x10c(%r13)
testb %sil, %sil
je 0x1abe3
incl %eax
movzwl 0x10c(%r13), %ecx
cmpl %ecx, %eax
jge 0x1ac11
cltq
leaq (%r12,%rbx), %rcx
movzbl (%rcx,%rax), %edx
cmpl $0x1, %edx
je 0x1abcc
cmpl $0x2, %edx
jne 0x1abd1
movb $0x1, %dl
jmp 0x1abce
movb $0x2, %dl
movb %dl, (%rcx,%rax)
incq %rax
movzwl 0x10c(%r13), %edx
cmpq %rdx, %rax
jl 0x1abba
jmp 0x1ac11
testl %eax, %eax
js 0x1ac11
incl %eax
leaq (%r12,%rbx), %rcx
xorl %edx, %edx
movzbl (%rcx,%rdx), %esi
cmpl $0x1, %esi
je 0x1ac02
cmpl $0x2, %esi
jne 0x1ac09
movb $0x1, %sil
jmp 0x1ac05
movb $0x2, %sil
movb %sil, (%rcx,%rdx)
incq %rdx
cmpq %rdx, %rax
jne 0x1abef
movq 0x10c(%r13), %rax
movl %eax, %ecx
shrl $0x10, %ecx
andl $0x1, %ecx
testw %ax, %ax
sete %dl
orb %cl, %dl
jne 0x1acb4
movabsq $0xffffffe5ffff, %rcx   # imm = 0xFFFFFFE5FFFF
addq $0x1a0001, %rcx         # imm = 0x1A0001
btl $0x12, %eax
movzwl %ax, %edx
movabsq $0x100000000, %rsi      # imm = 0x100000000
movl $0x1, %edi
cmovaeq %rdi, %rsi
movl $0x10000, %edi          # imm = 0x10000
cmovaeq %rdi, %rcx
addq %rbx, %r12
xorl %edi, %edi
movsbl (%r12,%rdi), %r8d
testl %r8d, %r8d
je 0x1acac
movl $0x2, %r9d
subl %r8d, %r9d
decl %r8d
btl $0x12, %eax
cmovbl %r9d, %r8d
movslq 0x100(%r13), %r9
leaq (%r15,%r9), %r10
movsbl (%rdi,%r10), %r11d
movq %rsi, %r10
cmpl %r11d, %r8d
je 0x1aca0
movq %rcx, %r10
addq %rdi, %r9
movq 0x48(%rsp), %r8
addq %r10, (%r8,%r9,8)
incq %rdi
cmpq %rdi, %rdx
jne 0x1ac67
movq 0x40(%rsp), %rdx
incq %r14
movl (%rdx), %eax
addq $0x114, %rbx            # imm = 0x114
cmpq %rax, %r14
jb 0x1a823
jmp 0x1acdb
xorl %ebp, %ebp
movq $0x0, 0x18(%rsp)
movq 0x18(%rsp), %rdi
callq 0x3350
movq %rbp, %rdi
callq 0x3350
movq 0x48(%rsp), %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq