// File: /workspace/github_cpp_makefile_star2_O2/BenLangmead[P]bowtie/./blockwise_sa.h
// Function: KarkkainenBlockwiseSA<S2bDnaString>::suffixCmp(unsigned int, unsigned int, long&, long&, bool&, EList<unsigned int, 128> const&)
inline
bool KarkkainenBlockwiseSA<TStr>::suffixCmp(
	TIndexOffU cmp,
	TIndexOffU i,
	int64_t& j,
	int64_t& k,
	bool& kSoft,
	const EList<TIndexOffU>& z)
{
	const TStr& t = this->text();
	TIndexOffU len = TIndexOffU(t.length());
	// i is not covered by any previous match
	TIndexOffU l;
	if((int64_t)i > k) {
		k = i; // so that i + lHi == kHi
		l = 0; // erase any previous l
		kSoft = false;
		// To be extended
	}
	// i is covered by a previous match
	else /* i <= k */ {
		assert_gt((int64_t)i, j);
		TIndexOffU zIdx = (TIndexOffU)(i-j);
		assert_leq(zIdx, len-cmp);
		if(zIdx < _dcV || _dc == NULL) {
			// Go as far as the Z-box says
			l = lookupSuffixZ(t, zIdx, cmp, z);
			if(i + l > len) {
				l = len-i;
			}
			assert_leq(i + l, len);
			// Possibly to be extended
		} else {
			// But we're past the point of no-more-Z-boxes
			bool ret = tieBreakingLcp(i, cmp, l, kSoft);
			// Sanity-check tie-breaker
			if(this->sanityCheck()) {
				if(ret) assert(sstr_suf_lt(t, i, t, cmp, false));
				else    assert(sstr_suf_gt(t, i, t, cmp, false));
			}
			j = i;
			k = i + l;
			if(this->sanityCheck()) {
				if(kSoft) { assert_leq(l, suffixLcp(t, i, cmp)); }
				else      { assert_eq (l, suffixLcp(t, i, cmp)); }
			}
			return ret;
		}
	}

	// Z box extends exactly as far as previous match (or there
	// is neither a Z box nor a previous match)
	if((int64_t)(i + l) == k) {
		// Extend
		while(l < len-cmp && k < (int64_t)len && t[(size_t)(cmp+l)] == t[(size_t)k]) {
			k++; l++;
		}
		j = i; // update furthest-extending LHS
		kSoft = false;
		assert_eq(l, suffixLcp(t, i, cmp));
	}
	// Z box extends further than previous match
	else if((int64_t)(i + l) > k) {
		l = (TIndexOffU)(k - i); // point to just after previous match
		j = i; // update furthest-extending LHS
		if(kSoft) {
			while(l < len-cmp && k < (int64_t)len && t[(size_t)(cmp+l)] == t[(size_t)k]) {
				k++; l++;
			}
			kSoft = false;
			assert_eq(l, suffixLcp(t, i, cmp));
		} else assert_eq(l, suffixLcp(t, i, cmp));
	}

	// Check that calculated lcp matches actual lcp
	if(this->sanityCheck()) {
		if(!kSoft) {
			// l should exactly match lcp
			assert_eq(l, suffixLcp(t, i, cmp));
		} else {
			// l is an underestimate of LCP
			assert_leq(l, suffixLcp(t, i, cmp));
		}
	}
	assert_leq(l+i, len);
	assert_leq(l, len-cmp);

	// i and cmp should not be the same suffix
	assert(l != len-cmp || i+l != len);

	// Now we're ready to do a comparison on the next char
	if(l+i != len && (
		   l == len-cmp || // departure from paper algorithm:
		   // falling off pattern implies
		   // pattern is *greater* in our case
		   t[i + l] < t[cmp + l]))
	{
		// Case 2: Text suffix is less than upper sample suffix
#ifndef NDEBUG
		if(this->sanityCheck()) {
			assert(sstr_suf_lt(t, i, t, cmp, false));
		}
#endif

		return true; // suffix at i is less than suffix at cmp
	}
	else {
		// Case 3: Text suffix is greater than upper sample suffix
#ifndef NDEBUG
		if(this->sanityCheck()) {
			assert(sstr_suf_gt(t, i, t, cmp, false));
		}
#endif

		return false; // suffix at i is less than suffix at cmp
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x18, %rsp
movq %r8, %r14
movq %rcx, %r15
movl %edx, %ebx
movl %esi, %edx
movq 0x8(%rdi), %r8
movq 0x18(%r8), %r10
movl %ebx, %r13d
movq (%r14), %rax
cmpq %r13, %rax
jge 0x22106
movq %r13, (%r14)
movb $0x0, (%r9)
movq (%r14), %rax
xorl %esi, %esi
jmp 0x221cd
movl (%r15), %ecx
movl %ebx, %esi
subl %ecx, %esi
cmpl 0x74(%rdi), %esi
jb 0x2213a
cmpq $0x0, 0x78(%rdi)
je 0x2213a
leaq 0x14(%rsp), %r12
movl %ebx, %esi
movq %r12, %rcx
movq %r9, %r8
callq 0x22320
movq %r13, (%r15)
addl (%r12), %ebx
movq %rbx, (%r14)
jmp 0x22310
movq 0x50(%rsp), %r11
movl %esi, %edi
cmpq %rdi, 0x18(%r11)
jbe 0x22150
movq 0x8(%r11), %rcx
movl (%rcx,%rdi,4), %edi
jmp 0x221bf
movq %r13, (%rsp)
movq %r9, 0x8(%rsp)
movq %r15, %r9
movq 0x8(%r8), %r11
leal (%rdx,%rdx), %r12d
leal (%rbx,%rbx), %ebp
addl %ecx, %ecx
subl %ecx, %ebp
addl %edx, %esi
xorl %edi, %edi
leal (%rsi,%rdi), %ecx
cmpq %rcx, %r10
jbe 0x221b3
leal (%rdx,%rdi), %r15d
cmpq %r15, %r10
jbe 0x221b3
shrl $0x4, %ecx
movl (%r11,%rcx,4), %r13d
leal (%r12,%rbp), %ecx
andb $0x1e, %cl
shrl %cl, %r13d
shrl $0x4, %r15d
movl (%r11,%r15,4), %r15d
movl %r12d, %ecx
andb $0x1e, %cl
shrl %cl, %r15d
xorl %r13d, %r15d
testb $0x3, %r15b
jne 0x221b3
incl %edi
addl $0x2, %r12d
jmp 0x2216f
movq %r9, %r15
movq 0x8(%rsp), %r9
movq (%rsp), %r13
leal (%rdi,%rbx), %ecx
movl %r10d, %esi
subl %ebx, %esi
cmpl %r10d, %ecx
cmovbel %edi, %esi
leal (%rsi,%rbx), %ecx
cmpq %rcx, %rax
jne 0x2224c
movq %r13, (%rsp)
movq %r9, 0x8(%rsp)
movq %r15, %r9
movl %r10d, %edi
subl %edx, %edi
movl %r10d, %r11d
leal (%rax,%rax), %ebp
leal (%rsi,%rdx), %r12d
addl %r12d, %r12d
cmpl %edi, %esi
jae 0x222bb
cmpq %r11, %rax
jge 0x222bb
leal (%rdx,%rsi), %ecx
movq 0x8(%r8), %r15
shrl $0x4, %ecx
movl (%r15,%rcx,4), %r13d
movl %r12d, %ecx
andb $0x1e, %cl
shrl %cl, %r13d
movq %rax, %rcx
shrq $0x4, %rcx
movl (%r15,%rcx,4), %r15d
movl %ebp, %ecx
andb $0x1e, %cl
shrl %cl, %r15d
xorl %r13d, %r15d
testb $0x3, %r15b
jne 0x222bb
incq %rax
movq %rax, (%r14)
incl %esi
addl $0x2, %ebp
addl $0x2, %r12d
jmp 0x221f3
jge 0x222cb
movl %eax, %esi
subl %ebx, %esi
movq %r13, (%r15)
cmpb $0x1, (%r9)
jne 0x222cb
movl %r10d, %edi
subl %edx, %edi
movq (%r14), %r11
movl %r10d, %r15d
leal (%r11,%r11), %ebp
addl %edx, %eax
subl %ebx, %eax
addl %eax, %eax
cmpl %edi, %esi
jae 0x222c7
cmpq %r15, %r11
jge 0x222c7
leal (%rdx,%rsi), %ecx
movq 0x8(%r8), %r12
shrl $0x4, %ecx
movl (%r12,%rcx,4), %r13d
movl %eax, %ecx
andb $0x1e, %cl
shrl %cl, %r13d
movq %r11, %rcx
shrq $0x4, %rcx
movl (%r12,%rcx,4), %r12d
movl %ebp, %ecx
andb $0x1e, %cl
shrl %cl, %r12d
xorl %r13d, %r12d
testb $0x3, %r12b
jne 0x222c7
incq %r11
movq %r11, (%r14)
incl %esi
addl $0x2, %ebp
addl $0x2, %eax
jmp 0x22270
movq (%rsp), %rax
movq %rax, (%r9)
movq 0x8(%rsp), %r9
movb $0x0, (%r9)
addl %esi, %ebx
cmpl %r10d, %ebx
jne 0x222d6
xorl %eax, %eax
jmp 0x22310
subl %edx, %r10d
movb $0x1, %al
cmpl %r10d, %esi
je 0x22310
movq 0x8(%r8), %rdi
movl %ebx, %ecx
shrl $0x4, %ecx
movl (%rdi,%rcx,4), %r8d
addl %ebx, %ebx
movl %ebx, %ecx
shrl %cl, %r8d
addl %edx, %esi
movl %esi, %ecx
shrl $0x4, %ecx
movl (%rdi,%rcx,4), %edx
addl %esi, %esi
movl %esi, %ecx
shrl %cl, %edx
andb $0x3, %r8b
andb $0x3, %dl
cmpb %dl, %r8b
jae 0x222d2
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop