// File: /workspace/github_c_makefile_star2_O3/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, 0x48(%rsp)
movq %rdx, %rbx
movq %rsi, %rbp
movl %edi, 0x4c(%rsp)
movslq %edi, %rdi
movl $0x8, %esi
callq 0x3610
movq %rax, %r15
movl (%rbx), %eax
testl %eax, %eax
je 0x1b524
movq %rbx, %rsi
xorl %r14d, %r14d
xorl %ebx, %ebx
movq $0x0, 0x28(%rsp)
movq $0x0, 0x20(%rsp)
movl $0x0, 0x34(%rsp)
movq %rbp, 0x38(%rsp)
movq %r15, 0x40(%rsp)
movq %rsi, 0x50(%rsp)
movq 0x10(%rsi), %rcx
movq %rbx, %rdx
shrq $0x4, %rdx
movl (%rcx,%rdx,4), %edx
leal (%rbx,%rbx), %ecx
shrl %cl, %edx
testb $0x3, %dl
jne 0x1b4cf
movq 0x20(%rsi), %r12
imulq $0x114, %rbx, %r13      # imm = 0x114
movslq 0x100(%r12,%r13), %rax
cmpl 0x4c(%rsp), %eax
jge 0x1b4cd
addq %r12, %r13
movq $0x0, 0x18(%rsp)
movq 0x10c(%r13), %rdx
movl %edx, %ecx
andl $0xffff, %ecx           # imm = 0xFFFF
je 0x1b134
movzwl %dx, %esi
addq %rbp, %rax
leaq (%r12,%r14), %rdi
xorl %r8d, %r8d
movsbl (%rdi,%r8), %r9d
testl %r9d, %r9d
je 0x1b121
movsbl (%rax,%r8), %r10d
incl %r10d
xorl %r11d, %r11d
cmpl %r9d, %r10d
setne %r11b
incl 0x18(%rsp,%r11,4)
incq %r8
cmpq %r8, %rsi
jne 0x1b100
movl 0x18(%rsp), %edi
movl 0x1c(%rsp), %r15d
jmp 0x1b139
xorl %r15d, %r15d
xorl %edi, %edi
cmpl $0x0, 0x48(%rsp)
sete 0xf(%rsp)
xorl %eax, %eax
cmpl %r15d, %edi
setle %al
movl %eax, %r10d
shll $0x12, %r10d
andl $0xffe1ffff, %edx       # imm = 0xFFE1FFFF
shll $0x2, %eax
movzwl 0x18(%rsp,%rax), %ebp
xorl $0x4, %eax
movl 0x18(%rsp,%rax), %r8d
movzwl %r8w, %esi
leal 0x1(%rsi), %r9d
xorl %eax, %eax
cmpl %r9d, %ebp
setbe %al
xorl %r11d, %r11d
cmpl %esi, %ebp
setne %r11b
movq %rbp, %r9
shlq $0x20, %r9
orq %rdx, %r9
orq %r10, %r9
shlq $0x30, %r8
shll $0x13, %r11d
orq %r8, %r11
decl %esi
shll $0x14, %eax
cmpl $0x2, %esi
movl $0x0, %edx
cmovaeq %rdx, %rax
testq %rbp, %rbp
cmoveq %rbp, %rax
orq %r11, %rax
orq %r9, %rax
movq %rax, 0x10c(%r13)
cmpl $0x3, %edi
setl %dl
cmpl $0x3, %r15d
setl %sil
orb %dl, %sil
orb 0xf(%rsp), %sil
jne 0x1b3b8
cmpl 0x34(%rsp), %ecx
movq 0x40(%rsp), %r15
jbe 0x1b23c
decl %ecx
movl %ecx, %eax
shrl %eax
orl %ecx, %eax
movl %eax, %ecx
shrl $0x2, %ecx
orl %eax, %ecx
movl %ecx, %eax
shrl $0x4, %eax
orl %ecx, %eax
movl %eax, %ecx
shrl $0x8, %ecx
orl %eax, %ecx
leal 0x4(,%rcx,4), %ebp
movl %ecx, %eax
incl %eax
movl %eax, 0x34(%rsp)
movq 0x28(%rsp), %rdi
movq %rbp, %rsi
callq 0x3720
movq %rax, 0x28(%rsp)
movq 0x20(%rsp), %rdi
movq %rbp, %rsi
callq 0x3720
movq %rax, 0x20(%rsp)
movq 0x10c(%r13), %rax
movq 0x38(%rsp), %rbp
movq $0x0, 0x10(%rsp)
testw %ax, %ax
je 0x1b321
leaq (%r12,%r14), %rcx
xorl %edx, %edx
movsbl (%rcx,%rdx), %esi
testl %esi, %esi
je 0x1b28b
movl $0x2, %edi
subl %esi, %edi
decl %esi
btl $0x12, %eax
cmovbl %edi, %esi
movslq 0x100(%r13), %rax
addq %rbp, %rax
movsbl (%rdx,%rax), %eax
xorl %edi, %edi
cmpl %eax, %esi
setne %dil
incl 0x10(%rsp,%rdi,4)
movl 0x14(%rsp), %eax
shll $0x10, %eax
orl 0x10(%rsp), %eax
movq 0x28(%rsp), %rsi
movl %eax, (%rsi,%rdx,4)
incq %rdx
movq 0x10c(%r13), %rax
movzwl %ax, %esi
cmpq %rsi, %rdx
jb 0x1b259
movq $0x0, 0x10(%rsp)
testw %ax, %ax
je 0x1b321
movzwl %ax, %eax
incq %rax
movsbl -0x2(%rcx,%rax), %edx
testl %edx, %edx
je 0x1b2fd
movl $0x2, %esi
subl %edx, %esi
decl %edx
btl $0x12, 0x10c(%r13)
cmovbl %esi, %edx
movslq 0x100(%r13), %rsi
addq %rbp, %rsi
movsbl -0x2(%rax,%rsi), %esi
xorl %edi, %edi
cmpl %esi, %edx
setne %dil
incl 0x10(%rsp,%rdi,4)
movl 0x14(%rsp), %edx
shll $0x10, %edx
orl 0x10(%rsp), %edx
movq 0x20(%rsp), %rsi
movl %edx, -0x8(%rsi,%rax,4)
decq %rax
cmpq $0x1, %rax
ja 0x1b2c4
movq 0x10c(%r13), %rax
movzwl %ax, %esi
cmpl $0x2, %esi
jb 0x1b3c4
decl %esi
xorl %edi, %edi
movl $0xffffffff, %r8d       # imm = 0xFFFFFFFF
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
xorl %edx, %edx
movq 0x28(%rsp), %r9
movl (%r9,%rdi,4), %r9d
movl %r9d, %r10d
movl $0xffff, %r15d          # imm = 0xFFFF
andl %r15d, %r10d
movq 0x20(%rsp), %r11
movl 0x4(%r11,%rdi,4), %r11d
movl %r11d, %ebp
shrl $0x10, %ebp
addl %ebp, %r10d
andl %r15d, %r11d
subl %r11d, %r10d
subl %r11d, %r10d
shrl $0x10, %r9d
addl %r11d, %r9d
addl %ebp, %ebp
subl %ebp, %r9d
cmpl %r9d, %r10d
jle 0x1b38d
cmpl %edx, %r10d
jle 0x1b39d
xorl %r8d, %r8d
movl %r10d, %edx
jmp 0x1b39b
cmpl %edx, %r9d
jle 0x1b39d
movl $0x1, %r8d
movl %r9d, %edx
movl %edi, %ecx
incq %rdi
cmpq %rdi, %rsi
jne 0x1b33e
testl %r8d, %r8d
sete %sil
movq 0x40(%rsp), %r15
movq 0x38(%rsp), %rbp
jmp 0x1b3cd
movq 0x38(%rsp), %rbp
movq 0x40(%rsp), %r15
jmp 0x1b43c
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
xorl %edx, %edx
xorl %esi, %esi
movl %edx, %edi
subl 0x18(%rsp), %edi
cmpl $0x4, %edi
jl 0x1b436
subl 0x1c(%rsp), %edx
cmpl $0x4, %edx
jl 0x1b436
movq %rax, %rdx
orq $0x20000, %rdx          # imm = 0x20000
movq %rdx, 0x10c(%r13)
testb %sil, %sil
je 0x1b4e6
incl %ecx
movzwl %ax, %eax
cmpl %eax, %ecx
jge 0x1b439
movslq %ecx, %rax
leaq (%r12,%r14), %rcx
movzbl (%rcx,%rax), %edx
cmpl $0x1, %edx
je 0x1b41d
cmpl $0x2, %edx
jne 0x1b422
movb $0x1, %dl
jmp 0x1b41f
movb $0x2, %dl
movb %dl, (%rcx,%rax)
incq %rax
movq 0x10c(%r13), %rdx
movzwl %dx, %esi
cmpq %rsi, %rax
jl 0x1b40b
jmp 0x1b439
movq %rax, %rdx
movq %rdx, %rax
movl %eax, %ecx
shrl $0x10, %ecx
andl $0x1, %ecx
testw %ax, %ax
sete %dl
orb %cl, %dl
jne 0x1b4c8
btl $0x12, %eax
movzwl %ax, %ecx
movabsq $0x100000000, %rdx      # imm = 0x100000000
movl $0x1, %esi
cmovaeq %rsi, %rdx
movabsq $0x1000000000000, %rsi  # imm = 0x1000000000000
movl $0x10000, %edi          # imm = 0x10000
cmovaeq %rdi, %rsi
addq %r14, %r12
xorl %edi, %edi
movsbl (%r12,%rdi), %r8d
testl %r8d, %r8d
je 0x1b4c0
movl $0x2, %r9d
subl %r8d, %r9d
decl %r8d
btl $0x12, %eax
cmovbl %r9d, %r8d
movslq 0x100(%r13), %r9
leaq (%r9,%rbp), %r10
movsbl (%rdi,%r10), %r11d
movq %rdx, %r10
cmpl %r11d, %r8d
je 0x1b4b9
movq %rsi, %r10
addq %rdi, %r9
addq %r10, (%r15,%r9,8)
incq %rdi
cmpq %rdi, %rcx
jne 0x1b480
movq 0x50(%rsp), %rsi
movl (%rsi), %eax
incq %rbx
movl %eax, %ecx
addq $0x114, %r14            # imm = 0x114
cmpq %rcx, %rbx
jb 0x1b09d
jmp 0x1b536
testl %ecx, %ecx
js 0x1b439
incl %ecx
leaq (%r12,%r14), %rax
xorl %edx, %edx
movzbl (%rax,%rdx), %esi
cmpl $0x1, %esi
je 0x1b509
cmpl $0x2, %esi
jne 0x1b510
movb $0x1, %sil
jmp 0x1b50c
movb $0x2, %sil
movb %sil, (%rax,%rdx)
incq %rdx
cmpq %rdx, %rcx
jne 0x1b4f6
movq 0x10c(%r13), %rdx
jmp 0x1b439
movq $0x0, 0x20(%rsp)
movq $0x0, 0x28(%rsp)
movq 0x28(%rsp), %rdi
callq 0x3350
movq 0x20(%rsp), %rdi
callq 0x3350
movq %r15, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq