// File: BenLangmead[P]bowtie/./ebwt_search_backtrack.h
// Function: GreedyDFSRangeSource::hhCheckTop(unsigned int, unsigned int, unsigned int, EList<unsigned int, 128> const&, unsigned long)
bool hhCheckTop(uint32_t stackDepth,
	                uint32_t d,
	                uint32_t iham,
	                const EList<TIndexOffU>& mms,
	                uint64_t prehits = 0xffffffffffffffffllu)
	{
		assert_eq(0, _reportPartials);
		// Crossing from the hi-half into the lo-half
		if(d == _5depth) {
			if(_3revOff == _2revOff) {
				// Total of 2 mismatches allowed: 1 hi, 1 lo
				// The backtracking logic should have prevented us from
				// backtracking more than once into this region
				assert_leq(stackDepth, 1);
				// Reject if we haven't encountered mismatch by this point
				if(stackDepth == 0) {
					return false;
				}
			} else { // if(_3revOff != _2revOff)
				// Total of 3 mismatches allowed: 1 hi, 1 or 2 lo
				// The backtracking logic should have prevented us from
				// backtracking more than twice into this region
				assert_leq(stackDepth, 2);
				// Reject if we haven't encountered mismatch by this point
				if(stackDepth < 1) {
					return false;
				}
			}
		} else if(d == _3depth) {
			// Crossing from lo-half to outside of the seed
			if(_3revOff == _2revOff) {
				// Total of 2 mismatches allowed: 1 hi, 1 lo
				// The backtracking logic should have prevented us from
				// backtracking more than twice within this region
				assert_leq(stackDepth, 2);
				// Must have encountered two mismatches by this point
				if(stackDepth < 2) {
					// We're returning from the bottommost frame
					// without having found any hits; let's
					// sanity-check that there really aren't any
					return false;
				}
			} else { // if(_3revOff != _2revOff)
				// Total of 3 mismatches allowed: 1 hi, 1 or 2 lo
				// Count the mismatches in the lo and hi halves
				int loHalfMms = 0, hiHalfMms = 0;
				assert_geq(mms.size(), stackDepth);
				for(size_t i = 0; i < stackDepth; i++) {
					TIndexOffU d = (TIndexOffU)(_qlen - mms[i] - 1);
					if     (d < _5depth) hiHalfMms++;
					else if(d < _3depth) loHalfMms++;
					else assert(false);
				}
				assert_leq(loHalfMms + hiHalfMms, 3);
				assert_gt(hiHalfMms, 0);
				if(loHalfMms == 0) {
					// We're returning from the bottommost frame
					// without having found any hits; let's
					// sanity-check that there really aren't any
					return false;
				}
				assert_geq(stackDepth, 2);
				// The backtracking logic should have prevented us from
				// backtracking more than twice within this region
				assert_leq(stackDepth, 3);
			}
		} else {
			// We didn't just cross a boundary, so do an in-between check
			if(d >= _5depth) {
				assert_geq(stackDepth, 1);
			} else if(d >= _3depth) {
				assert_geq(stackDepth, 2);
			}
		}
		return true;
	}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movl %ecx, -0x1c(%rbp)
movq %r8, -0x28(%rbp)
movq %r9, -0x30(%rbp)
movq -0x10(%rbp), %rcx
movq %rcx, -0x50(%rbp)
movl -0x18(%rbp), %eax
cmpl 0xc4(%rcx), %eax
jne 0x693b3
movq -0x50(%rbp), %rcx
movl 0x3c(%rcx), %eax
cmpl 0x38(%rcx), %eax
jne 0x6939d
cmpl $0x0, -0x14(%rbp)
jne 0x6939b
movb $0x0, -0x1(%rbp)
jmp 0x694b8
jmp 0x693ae
cmpl $0x1, -0x14(%rbp)
jae 0x693ac
movb $0x0, -0x1(%rbp)
jmp 0x694b8
jmp 0x693ae
jmp 0x694b4
movq -0x50(%rbp), %rcx
movl -0x18(%rbp), %eax
cmpl 0xc8(%rcx), %eax
jne 0x6948c
movq -0x50(%rbp), %rcx
movl 0x3c(%rcx), %eax
cmpl 0x38(%rcx), %eax
jne 0x693e6
cmpl $0x2, -0x14(%rbp)
jae 0x693e1
movb $0x0, -0x1(%rbp)
jmp 0x694b8
jmp 0x6948a
movl $0x0, -0x34(%rbp)
movl $0x0, -0x38(%rbp)
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl -0x14(%rbp), %ecx
cmpq %rcx, %rax
jae 0x6947c
movq -0x50(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x58(%rbp)
movq -0x28(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x4d670
movq -0x50(%rbp), %rcx
movq %rax, %rdx
movq -0x58(%rbp), %rax
movl (%rdx), %edx
subq %rdx, %rax
subq $0x1, %rax
movl %eax, -0x44(%rbp)
movl -0x44(%rbp), %eax
cmpl 0xc4(%rcx), %eax
jae 0x6944e
movl -0x38(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x38(%rbp)
jmp 0x6946c
movq -0x50(%rbp), %rcx
movl -0x44(%rbp), %eax
cmpl 0xc8(%rcx), %eax
jae 0x69468
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x6946a
jmp 0x6946a
jmp 0x6946c
jmp 0x6946e
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x693fc
cmpl $0x0, -0x34(%rbp)
jne 0x69488
movb $0x0, -0x1(%rbp)
jmp 0x694b8
jmp 0x6948a
jmp 0x694b2
movq -0x50(%rbp), %rcx
movl -0x18(%rbp), %eax
cmpl 0xc4(%rcx), %eax
jb 0x6949d
jmp 0x694b0
movq -0x50(%rbp), %rcx
movl -0x18(%rbp), %eax
cmpl 0xc8(%rcx), %eax
jb 0x694ae
jmp 0x694ae
jmp 0x694b0
jmp 0x694b2
jmp 0x694b4
movb $0x1, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)