// File: /workspace/github_cpp_makefile_star2_O3/BenLangmead[P]bowtie/./range_source.h
// Function: Branch::splitBranch(AllocOnlyPool<RangeState>&, AllocOnlyPool<Edit>&, AllocOnlyPool<Branch>&, unsigned int, RandomSource&, unsigned int, unsigned int, int, bool, EbwtParams const&, unsigned char const*, bool, bool, bool)
Branch* splitBranch(AllocOnlyPool<RangeState>& rpool,
	                    AllocOnlyPool<Edit>& epool,
	                    AllocOnlyPool<Branch>& bpool,
	                    uint32_t pmSz,
	                    RandomSource& rand, uint32_t qlen,
	                    uint32_t qualLim, int seedLen,
	                    bool qualOrder, const EbwtParams& ep,
	                    const uint8_t* ebwt, bool ebwtFw,
	                    bool verbose,
	                    bool quiet)
	{
		assert(!exhausted_);
		assert(ranges_ != NULL);
		assert(curtailed_);
		assert_gt(pmSz, 0);
		Branch *newBranch = bpool.alloc();
		if(newBranch == NULL) {
			return NULL;
		}
		assert(newBranch != NULL);
		uint32_t id = bpool.lastId();
		int tiedPositions[3];
		int numTiedPositions = 0;
		// Lowest marginal cost incurred by any of the positions with
		// non-eliminated outgoing edges
		uint16_t bestCost = 0xffff;
		// Next-lowest
		uint16_t nextCost = 0xffff;
		int numNotEliminated = 0;
		int i = (int)depth0_;
		i = max(0, i - rdepth_);
		// Iterate over revisitable positions in the path
		for(; i <= len_; i++) {
			// If there are still valid options for leaving out of this
			// position
			if(!eliminated(i)) {
				numNotEliminated++;
				uint16_t stratum = (rdepth_ + i < seedLen) ? (1 << 14) : 0;
				uint16_t cost = stratum;
				cost |= (qualOrder ? ranges_[i].eq.flags.quallo : 0);
				if(cost < bestCost) {
					// Demote the old best to the next-best
					nextCost = bestCost;
					// Update the new best
					bestCost = cost;
					numTiedPositions = 1;
					tiedPositions[0] = i;
				} else if(cost == bestCost) {
					// As good as the best so far
					assert_gt(numTiedPositions, 0);
					if(numTiedPositions < 3) {
						tiedPositions[numTiedPositions++] = i;
					} else {
						tiedPositions[0] = tiedPositions[1];
						tiedPositions[1] = tiedPositions[2];
						tiedPositions[2] = i;
					}
				} else if(cost < nextCost) {
					// 'cost' isn't beter than the best, but it is
					// better than the next-best
					nextCost = cost;
				}
			}
		}
		assert_gt(numNotEliminated, 0);
		assert_gt(numTiedPositions, 0);
		//if(nextCost != 0xffff) assert_gt(nextCost, bestCost);
		int r = 0;
		if(numTiedPositions > 1) {
			r = rand.nextU32() % numTiedPositions;
		}
		int pos = tiedPositions[r];
		bool last = false;
		// Pick an edit from among the edits tied for lowest cost
		// (using randomness to break ties).  If the selected edit is
		// the last remaining one at this position, 'last' is set to
		// true.
		TIndexOffU top = 0, bot = 0;
		Edit e = ranges_[pos].pickEdit(pos + rdepth_, rand, top, bot, false, last);
		assert_gt(bot, top);
		// Create and initialize a new Branch
		uint16_t newRdepth = rdepth_ + pos + 1;
		assert_lt((bestCost >> 14), 4);
		uint32_t hamadd = (bestCost & ~0xc000);
		uint16_t depth = pos + rdepth_;
		assert_geq(depth, depth0_);
		uint16_t newDepth0 = depth0_;
		uint16_t newDepth1 = depth1_;
		uint16_t newDepth2 = depth2_;
		uint16_t newDepth3 = depth3_;
		if(depth < depth1_) newDepth0 = depth1_;
		if(depth < depth2_) newDepth1 = depth2_;
		if(depth < depth3_) newDepth2 = depth3_;
		assert_eq((uint32_t)(cost_ & ~0xc000), (uint32_t)(ham_ + hamadd));
		if(!newBranch->init(
				rpool, epool, id, qlen,
				newDepth0, newDepth1, newDepth2, newDepth3,
				newRdepth, 0, cost_, ham_ + hamadd,
				top, bot, ep, ebwt, &edits_))
		{
			return NULL;
		}
		// Add the new edit
		newBranch->edits_.add(e, epool, qlen);
		if(numNotEliminated == 1 && last) {
			// This branch is totally exhausted; there are no more
			// valid outgoing paths from any positions within it.
			// Remove it from the PathManager and mark it as exhausted.
			// The caller should delete it.
			exhausted_ = true;
			if(ranges_ != NULL) {
				assert_gt(rangesSz_, 0);
				if(rpool.free(ranges_, rangesSz_)) {
					ranges_ = NULL;
					rangesSz_ = 0;
				}
			}
		}
		else if(numTiedPositions == 1 && last) {
			// We exhausted the last outgoing edge at the current best
			// cost; update the best cost to be the next-best
			assert_neq(0xffff, nextCost);
			if(bestCost != nextCost) {
				assert_gt(nextCost, bestCost);
				delayedCost_ = (cost_ - bestCost + nextCost);
				delayedIncrease_ = true;
			}
		}
		return newBranch;
	}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x68, %rsp
movq %r9, %rbx
movq %rcx, %r15
movq %rdx, %r13
movq %rsi, 0x60(%rsp)
movq %rdi, %r12
movq %rcx, %rdi
callq 0x2b39c
testq %rax, %rax
je 0x2f06e
movq %rax, %r14
movq %rbx, 0x18(%rsp)
movl 0x30(%r15), %eax
shll $0x10, %eax
orl 0x5c(%r15), %eax
movl %eax, 0x40(%rsp)
movzwl 0x4(%r12), %eax
movzwl 0xc(%r12), %esi
subl %esi, %eax
movzwl 0xe(%r12), %ecx
cmpl %ecx, %eax
jle 0x2ed41
movq $0x0, 0x10(%rsp)
movw $0xffff, %r15w          # imm = 0xFFFF
movw $0xffff, %ax            # imm = 0xFFFF
movl %eax, 0xc(%rsp)
movq $0x0, 0x28(%rsp)
xorl %edx, %edx
jmp 0x2eee3
xorl %edi, %edi
testl %eax, %eax
movl $0x0, %edx
movq %rdx, 0x10(%rsp)
cmovlel %edi, %eax
movzwl 0x20(%r12), %edi
movq 0x18(%r12), %rdx
movl %esi, %r8d
movslq 0xb0(%rsp), %r10
subq %r8, %r10
cmpq %rax, %rcx
cmovbeq %rax, %rcx
negq %rcx
addq $0x28, %rdx
movw $0xffff, %r15w          # imm = 0xFFFF
movw $0xffff, %bp            # imm = 0xFFFF
xorl %ebx, %ebx
movq %rdx, 0x20(%rsp)
movl %ebp, %r8d
movl %r15d, %ebp
leaq (%rax,%rax,2), %r11
incq %rax
shlq $0x4, %r11
addq %rdx, %r11
movl %ebx, %r9d
movl %ebp, 0xc(%rsp)
leaq -0x1(%rax), %r15
cmpq %rdi, %r15
jae 0x2ee31
cmpb $0x0, (%r11)
jne 0x2ee31
cmpb $0x0, 0xb8(%rsp)
je 0x2edce
movq -0x8(%r11), %rbp
shrq $0x29, %rbp
andl $0x7f, %ebp
jmp 0x2edd0
xorl %ebp, %ebp
leal 0x1(%r9), %ebx
xorl %edx, %edx
cmpq %r10, %r15
setl %dl
shll $0xe, %edx
movzwl %bp, %r15d
orl %edx, %r15d
movl 0xc(%rsp), %ebp
cmpw %bp, %r15w
jb 0x2ee4b
jne 0x2ee13
movq 0x10(%rsp), %r9
cmpl $0x2, %r9d
jg 0x2ee1d
movslq %r9d, %rdx
incl %r9d
movq %r9, 0x10(%rsp)
leal -0x1(%rax), %r9d
movl %r9d, 0x30(%rsp,%rdx,4)
jmp 0x2ee2e
cmpw %r8w, %r15w
cmovbl %r15d, %r8d
jmp 0x2ee2e
movq 0x34(%rsp), %rdx
movq %rdx, 0x30(%rsp)
leal -0x1(%rax), %edx
movl %edx, 0x38(%rsp)
movl %ebx, %r9d
addq $0x30, %r11
leaq (%rcx,%rax), %rdx
incq %rdx
incq %rax
cmpq $0x2, %rdx
jne 0x2eda4
jmp 0x2ee8a
leal -0x1(%rax), %edx
movl %edx, 0x30(%rsp)
leaq (%rcx,%rax), %rdx
movl $0x1, %r8d
movq %r8, 0x10(%rsp)
cmpq $0x1, %rdx
movq 0x20(%rsp), %rdx
jne 0x2ed89
testl %r9d, %r9d
sete %al
movq %rax, 0x28(%rsp)
movl $0x1, %eax
movq %rax, 0x10(%rsp)
jmp 0x2ed3a
cmpl $0x1, %r9d
sete %al
movq 0x10(%rsp), %rdi
cmpl $0x2, %edi
movq %rax, 0x28(%rsp)
jl 0x2eed9
movq 0x18(%rsp), %r9
movl (%r9), %ecx
movl 0x4(%r9), %edx
movl 0x8(%r9), %eax
imull %ecx, %eax
addl %edx, %eax
movl %eax, %esi
shrl $0x10, %esi
imull %ecx, %eax
addl %edx, %eax
movl %eax, 0x8(%r9)
xorl %esi, %eax
movl $0x0, 0xc(%r9)
xorl %edx, %edx
divl %edi
movzwl 0xc(%r12), %esi
jmp 0x2eedb
xorl %edx, %edx
movl %ebp, %r15d
movl %r8d, 0xc(%rsp)
movq %r13, 0x58(%rsp)
movq %r14, 0x20(%rsp)
movslq 0x30(%rsp,%rdx,4), %rbp
leaq 0xb(%rsp), %rax
movb $0x0, (%rax)
xorl %edx, %edx
leaq 0x4c(%rsp), %rcx
movl %edx, (%rcx)
leaq 0x48(%rsp), %r8
movl %edx, (%r8)
leaq (,%rbp,2), %rdi
addq %rbp, %rdi
shlq $0x4, %rdi
addq 0x18(%r12), %rdi
addl %ebp, %esi
subq $0x8, %rsp
movq 0x20(%rsp), %rdx
xorl %r9d, %r9d
pushq %rax
callq 0x2f0b6
addq $0x10, %rsp
movl %eax, 0x44(%rsp)
movzwl 0xc(%r12), %eax
leal (%rax,%rbp), %esi
leal (%rax,%rbp), %r10d
incl %r10d
movl %r15d, %ecx
andl $0x3fff, %ecx           # imm = 0x3FFF
movzwl 0x6(%r12), %eax
movzwl 0x8(%r12), %r11d
movzwl 0xa(%r12), %ebp
movl $0xffff, %edx           # imm = 0xFFFF
andl %edx, %esi
movl %eax, %edi
cmpl %eax, %esi
jb 0x2ef79
movzwl 0x4(%r12), %edi
cmpl %r11d, %esi
cmovbl %r11d, %eax
cmpl %ebp, %esi
cmovbl %ebp, %r11d
addw 0x12(%r12), %cx
movzwl 0x10(%r12), %esi
movq %rsi, 0x18(%rsp)
movl 0x4c(%rsp), %r13d
movq %r12, %rsi
movl 0x48(%rsp), %r12d
movq %rsi, 0x50(%rsp)
leaq 0x50(%rsi), %r14
movzwl %cx, %ebx
andl %edx, %r10d
movzwl %di, %r9d
movq 0x20(%rsp), %rdi
movq 0x60(%rsp), %rsi
movq 0x58(%rsp), %rdx
movl 0x40(%rsp), %ecx
movl 0xa0(%rsp), %r8d
pushq %r14
pushq 0xd0(%rsp)
pushq 0xd0(%rsp)
pushq %r12
pushq %r13
pushq %rbx
pushq 0x48(%rsp)
movl $0x0, %ebx
pushq %rbx
pushq %r10
pushq %rbp
pushq %r11
pushq %rax
callq 0x2b3e8
addq $0x60, %rsp
testb %al, %al
je 0x2f06e
movq 0x20(%rsp), %rbx
movq %rbx, %rdi
addq $0x50, %rdi
movl 0xa0(%rsp), %ecx
leaq 0x44(%rsp), %rsi
movq 0x58(%rsp), %rdx
callq 0x2bc4e
cmpb $0x0, 0x28(%rsp)
je 0x2f082
cmpb $0x1, 0xb(%rsp)
jne 0x2f082
movq 0x50(%rsp), %r14
movb $0x1, 0x83(%r14)
movq 0x18(%r14), %rsi
testq %rsi, %rsi
je 0x2f070
movzwl 0x20(%r14), %edx
movq 0x60(%rsp), %rdi
callq 0x2db5a
testb %al, %al
je 0x2f070
movq $0x0, 0x18(%r14)
movw $0x0, 0x20(%r14)
jmp 0x2f070
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x1, 0x10(%rsp)
movq 0x50(%rsp), %rax
jne 0x2f070
cmpb $0x1, 0xb(%rsp)
jne 0x2f070
movl 0xc(%rsp), %ecx
cmpw %r15w, %cx
je 0x2f070
subl %r15d, %ecx
addw 0x10(%rax), %cx
movw %cx, 0x80(%rax)
movb $0x1, 0x85(%rax)
jmp 0x2f070