// File: /workspace/github_cpp_makefile_star2_O2/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, %r13
movq %rcx, %r15
movq %rdx, %rbx
movq %rsi, 0x50(%rsp)
movq %rdi, %r14
movq %rcx, %rdi
callq 0x231c0
xorl %r12d, %r12d
testq %rax, %rax
je 0x264b3
movq %r13, 0x18(%rsp)
movq %rbx, 0x40(%rsp)
movq %rax, 0x48(%rsp)
movl 0x30(%r15), %eax
movl %eax, 0x14(%rsp)
movl 0x5c(%r15), %eax
movl %eax, 0x20(%rsp)
movzwl 0x4(%r14), %r15d
movzwl 0xc(%r14), %eax
subl %eax, %r15d
testl %r15d, %r15d
cmovlel %r12d, %r15d
imulq $0x30, %r15, %r13
addq $0x20, %r13
movw $0xffff, %ax            # imm = 0xFFFF
movl %eax, 0x10(%rsp)
movw $0xffff, %bp            # imm = 0xFFFF
xorl %ebx, %ebx
movzwl 0xe(%r14), %eax
cmpq %rax, %r15
ja 0x2630a
movq %r14, %rdi
movl %r15d, %esi
callq 0x2534e
testb %al, %al
je 0x2627b
movl %ebp, %eax
jmp 0x262c8
cmpb $0x0, 0xb8(%rsp)
je 0x26296
movq 0x18(%r14), %rax
movq (%rax,%r13), %rax
shrq $0x29, %rax
andl $0x7f, %eax
jmp 0x26298
xorl %eax, %eax
incl %r12d
movzwl 0xc(%r14), %ecx
addl %r15d, %ecx
xorl %edx, %edx
cmpl 0xb0(%rsp), %ecx
setl %dl
shll $0xe, %edx
movzwl %ax, %eax
orl %edx, %eax
cmpw %bp, %ax
jae 0x262d3
movl %r15d, 0x28(%rsp)
movl %ebp, 0x10(%rsp)
pushq $0x1
popq %rbx
incq %r15
addq $0x30, %r13
movl %eax, %ebp
jmp 0x2625a
jne 0x262e6
cmpl $0x2, %ebx
jg 0x262f6
movslq %ebx, %rax
incl %ebx
movl %r15d, 0x28(%rsp,%rax,4)
jmp 0x26277
movl 0x10(%rsp), %ecx
cmpw %cx, %ax
cmovbl %eax, %ecx
movl %ecx, 0x10(%rsp)
jmp 0x26277
movq 0x2c(%rsp), %rax
movq %rax, 0x28(%rsp)
movl %r15d, 0x30(%rsp)
jmp 0x26277
movl 0x14(%rsp), %r15d
shll $0x10, %r15d
cmpl $0x2, %ebx
jl 0x2632b
movq 0x18(%rsp), %r13
movq %r13, %rdi
callq 0x264f6
xorl %edx, %edx
divl %ebx
jmp 0x26332
xorl %edx, %edx
movq 0x18(%rsp), %r13
orl 0x20(%rsp), %r15d
movl %r15d, 0x14(%rsp)
movslq 0x28(%rsp,%rdx,4), %r15
leaq 0xf(%rsp), %rax
movb $0x0, (%rax)
leaq 0x3c(%rsp), %rcx
andl $0x0, (%rcx)
leaq 0x38(%rsp), %r8
andl $0x0, (%r8)
imulq $0x30, %r15, %rdi
addq 0x18(%r14), %rdi
movzwl 0xc(%r14), %esi
addl %r15d, %esi
subq $0x8, %rsp
movq %r13, %rdx
xorl %r9d, %r9d
pushq %rax
callq 0x26518
popq %rcx
popq %rdx
movl %eax, 0x34(%rsp)
movzwl 0xc(%r14), %eax
leal (%r15,%rax), %esi
leal (%r15,%rax), %r8d
incl %r8d
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 0x263b9
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, 0x18(%rsp)
movl 0x3c(%rsp), %esi
movq %rsi, 0x20(%rsp)
movl 0x38(%rsp), %r13d
leaq 0x50(%r14), %r10
movzwl %cx, %ecx
movq %rcx, 0x58(%rsp)
andl %edx, %r8d
movq %r8, 0x60(%rsp)
movzwl %di, %r9d
movq 0x48(%rsp), %rdi
movq 0x50(%rsp), %rsi
movq 0x40(%rsp), %rdx
movl 0x14(%rsp), %ecx
movl 0xa0(%rsp), %r8d
pushq %r10
pushq 0xd0(%rsp)
pushq 0xd0(%rsp)
pushq %r13
pushq 0x40(%rsp)
pushq 0x80(%rsp)
pushq 0x48(%rsp)
pushq $0x0
pushq 0xa0(%rsp)
pushq %r15
pushq %r11
pushq %rax
callq 0x23208
addq $0x60, %rsp
testb %al, %al
je 0x264b3
movq 0x48(%rsp), %r15
movq %r15, %rdi
addq $0x50, %rdi
movl 0xa0(%rsp), %ecx
leaq 0x34(%rsp), %rsi
movq 0x40(%rsp), %rdx
callq 0x239d4
cmpl $0x1, %r12d
jne 0x264c8
cmpb $0x1, 0xf(%rsp)
jne 0x264c8
movb $0x1, 0x83(%r14)
movq 0x18(%r14), %rsi
testq %rsi, %rsi
je 0x264b6
movzwl 0x20(%r14), %edx
movq 0x50(%rsp), %rdi
callq 0x25370
testb %al, %al
je 0x264b6
andq $0x0, 0x18(%r14)
andw $0x0, 0x20(%r14)
jmp 0x264b6
xorl %r15d, %r15d
movq %r15, %rax
addq $0x68, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
cmpl $0x1, %ebx
jne 0x264b6
cmpb $0x1, 0xf(%rsp)
jne 0x264b6
movl 0x10(%rsp), %eax
cmpw %bp, %ax
je 0x264b6
subl %ebp, %eax
addw 0x10(%r14), %ax
movw %ax, 0x80(%r14)
movb $0x1, 0x85(%r14)
jmp 0x264b6