// File: /workspace/github_cpp_makefile_star2_O1/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 $0x58, %rsp
movq %r9, %r12
movq %rcx, %r15
movq %rdx, %rbp
movq %rsi, 0x40(%rsp)
movq %rdi, %r14
movq %rcx, %rdi
callq 0x2b754
xorl %r13d, %r13d
testq %rax, %rax
je 0x2f359
movq %rax, %rbx
movq %rbp, 0x30(%rsp)
movl 0x30(%r15), %ecx
shll $0x10, %ecx
movzwl 0x4(%r14), %eax
movzwl 0xc(%r14), %r8d
subl %r8d, %eax
movzwl 0xe(%r14), %r9d
cmpl %r9d, %eax
jle 0x2f09b
movw $0xffff, %ax            # imm = 0xFFFF
movl %eax, 0x4(%rsp)
movq $0x0, 0x28(%rsp)
movw $0xffff, %bp            # imm = 0xFFFF
jmp 0x2f19a
movl %ecx, 0x8(%rsp)
movb 0xa8(%rsp), %cl
xorl %r13d, %r13d
testl %eax, %eax
cmovlel %r13d, %eax
movzwl 0x20(%r14), %edx
movq 0x18(%r14), %r10
movslq 0xa0(%rsp), %rsi
cmpl %r9d, %eax
movl %eax, %edi
cmovbel %r9d, %edi
incl %edi
subq %r8, %rsi
leaq (%rax,%rax,2), %r8
shlq $0x4, %r8
addq %r10, %r8
addq $0x28, %r8
movw $0xffff, %bp            # imm = 0xFFFF
movw $0xffff, %r9w           # imm = 0xFFFF
movl %r9d, 0x4(%rsp)
xorl %r9d, %r9d
cmpq %rdx, %rax
jae 0x2f17a
cmpb $0x0, (%r8)
jne 0x2f17a
testb %cl, %cl
je 0x2f10f
movq -0x8(%r8), %r10
shrq $0x29, %r10
andl $0x7f, %r10d
jmp 0x2f112
xorl %r10d, %r10d
incl %r9d
xorl %r11d, %r11d
cmpq %rsi, %rax
setl %r11b
shll $0xe, %r11d
movzwl %r10w, %r10d
orl %r11d, %r10d
cmpw %bp, %r10w
jae 0x2f143
movl %eax, 0x1c(%rsp)
movl $0x1, %r13d
movl %ebp, 0x4(%rsp)
movl %r10d, %ebp
jmp 0x2f17a
jne 0x2f158
cmpl $0x2, %r13d
jg 0x2f16c
movslq %r13d, %r10
incl %r13d
movl %eax, 0x1c(%rsp,%r10,4)
jmp 0x2f17a
movl 0x4(%rsp), %r11d
cmpw %r11w, %r10w
cmovbl %r10d, %r11d
movl %r11d, 0x4(%rsp)
jmp 0x2f17a
movq 0x20(%rsp), %r10
movq %r10, 0x1c(%rsp)
movl %eax, 0x24(%rsp)
incq %rax
addq $0x30, %r8
cmpq %rax, %rdi
jne 0x2f0ee
cmpl $0x1, %r9d
sete %al
movq %rax, 0x28(%rsp)
movl 0x8(%rsp), %ecx
orl 0x5c(%r15), %ecx
xorl %edi, %edi
cmpl $0x2, %r13d
movl %ecx, 0x8(%rsp)
jl 0x2f1de
movl (%r12), %ecx
movl 0x4(%r12), %edx
movl 0x8(%r12), %eax
imull %ecx, %eax
addl %edx, %eax
movl %eax, %esi
shrl $0x10, %esi
imull %ecx, %eax
addl %edx, %eax
movl %eax, 0x8(%r12)
xorl %esi, %eax
movl $0x0, 0xc(%r12)
xorl %edx, %edx
divl %r13d
jmp 0x2f1e0
xorl %edx, %edx
movq %r13, 0x48(%rsp)
movq %rbx, 0x38(%rsp)
movslq 0x1c(%rsp,%rdx,4), %r15
leaq 0x3(%rsp), %rax
movb $0x0, (%rax)
leaq 0x18(%rsp), %rcx
movl %edi, (%rcx)
leaq 0x14(%rsp), %r8
movl %edi, (%r8)
leaq (%r15,%r15,2), %rdi
shlq $0x4, %rdi
addq 0x18(%r14), %rdi
movzwl 0xc(%r14), %esi
addl %r15d, %esi
subq $0x8, %rsp
movq %r12, %rdx
xorl %r9d, %r9d
pushq %rax
callq 0x2f3a2
addq $0x10, %rsp
movl %eax, 0x10(%rsp)
movzwl 0xc(%r14), %eax
leal (%r15,%rax), %esi
leal (%r15,%rax), %r10d
incl %r10d
movl %ebp, 0xc(%rsp)
movl %ebp, %ecx
andl $0x3fff, %ecx           # imm = 0x3FFF
movzwl 0x6(%r14), %eax
movzwl 0x8(%r14), %r11d
movzwl 0xa(%r14), %r15d
movl $0xffff, %edx           # imm = 0xFFFF
andl %edx, %esi
movl %eax, %edi
cmpl %eax, %esi
jb 0x2f26f
movzwl 0x4(%r14), %edi
cmpl %r11d, %esi
cmovbl %r11d, %eax
cmpl %r15d, %esi
cmovbl %r15d, %r11d
addw 0x12(%r14), %cx
movzwl 0x10(%r14), %esi
movq %rsi, 0x50(%rsp)
movl 0x18(%rsp), %r13d
movl 0x14(%rsp), %r12d
leaq 0x50(%r14), %rbx
movzwl %cx, %ebp
andl %edx, %r10d
movzwl %di, %r9d
movq 0x38(%rsp), %rdi
movq 0x40(%rsp), %rsi
movq 0x30(%rsp), %rdx
movl 0x8(%rsp), %ecx
movl 0x90(%rsp), %r8d
pushq %rbx
pushq 0xc0(%rsp)
pushq 0xc0(%rsp)
pushq %r12
pushq %r13
pushq %rbp
pushq 0x80(%rsp)
movl $0x0, %ebx
pushq %rbx
pushq %r10
pushq %r15
pushq %r11
pushq %rax
callq 0x2b79c
addq $0x60, %rsp
testb %al, %al
je 0x2f359
movq 0x38(%rsp), %rbx
movq %rbx, %rdi
addq $0x50, %rdi
movl 0x90(%rsp), %ecx
leaq 0x10(%rsp), %rsi
movq 0x30(%rsp), %rdx
callq 0x2c016
cmpb $0x0, 0x28(%rsp)
je 0x2f36d
cmpb $0x1, 0x3(%rsp)
jne 0x2f36d
movb $0x1, 0x83(%r14)
movq 0x18(%r14), %rsi
testq %rsi, %rsi
je 0x2f35b
movzwl 0x20(%r14), %edx
movq 0x40(%rsp), %rdi
callq 0x2dee2
testb %al, %al
je 0x2f35b
movq $0x0, 0x18(%r14)
movw $0x0, 0x20(%r14)
jmp 0x2f35b
xorl %ebx, %ebx
movq %rbx, %rax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x1, 0x48(%rsp)
jne 0x2f35b
cmpb $0x1, 0x3(%rsp)
jne 0x2f35b
movl 0xc(%rsp), %eax
movl 0x4(%rsp), %ecx
cmpw %ax, %cx
je 0x2f35b
subl %eax, %ecx
addw 0x10(%r14), %cx
movw %cx, 0x80(%r14)
movb $0x1, 0x85(%r14)
jmp 0x2f35b
nop