// File: /workspace/github_cpp_makefile_star2_O1/BenLangmead[P]bowtie/./blockwise_sa.h
// Function: KarkkainenBlockwiseSA<SString<char>>::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 $0x28, %rsp
movq %r8, %r12
movl %edx, %r14d
movl %esi, %r15d
movq 0x8(%rdi), %r11
movq 0x18(%r11), %r13
movl %edx, %ebx
cmpq %rbx, (%r8)
movq %r9, 0x8(%rsp)
jge 0x1f696
movq %rbx, (%r12)
movb $0x0, (%r9)
xorl %edx, %edx
jmp 0x1f867
movq %rdi, %rbp
movl (%rcx), %esi
movl %r14d, %eax
subl %esi, %eax
cmpl 0x74(%rdi), %eax
setb %dl
movq 0x78(%rdi), %rdi
testq %rdi, %rdi
sete %r9b
orb %dl, %r9b
cmpb $0x1, %r9b
jne 0x1f6d8
movq 0x60(%rsp), %rdx
movl %eax, %edi
cmpq %rdi, 0x18(%rdx)
jbe 0x1f74d
movq 0x8(%rdx), %rax
movl (%rax,%rdi,4), %r8d
jmp 0x1f784
movb %r9b, 0x7(%rsp)
movq %rcx, 0x20(%rsp)
movq %r11, 0x10(%rsp)
movl %r14d, %esi
movl %r15d, %edx
callq 0x1f95c
movq 0x8(%rsp), %rcx
movb $0x0, (%rcx)
movl %r13d, %ecx
subl %r14d, %ecx
cmpl %ecx, %eax
movl %ecx, %edx
cmovbl %eax, %edx
movl %r13d, %esi
subl %r15d, %esi
cmpl %edx, %esi
cmovbl %esi, %edx
testl %edx, %edx
je 0x1f79a
movq 0x10(%rsp), %rdi
movq 0x8(%rdi), %rdi
movl %edx, %r8d
movq %r15, 0x18(%rsp)
movl %r15d, %r10d
xorl %r9d, %r9d
leal (%rbx,%r9), %r11d
movb (%rdi,%r11), %r11b
leal (%r10,%r9), %r15d
cmpb (%rdi,%r15), %r11b
jne 0x1f79e
incq %r9
cmpq %r9, %r8
jne 0x1f731
jmp 0x1f7a1
addl %r15d, %eax
xorl %r8d, %r8d
cmpq %rax, %r13
jbe 0x1f784
movq 0x8(%r11), %rdx
leal (%r14,%r15), %edi
subl %esi, %edi
incl %edi
xorl %r8d, %r8d
leal (%r15,%r8), %esi
cmpq %rsi, %r13
jbe 0x1f784
movb (%rdx,%rax), %al
cmpb (%rdx,%rsi), %al
jne 0x1f784
leal (%rdi,%r8), %eax
incl %r8d
cmpq %rax, %r13
ja 0x1f767
leal (%r8,%r14), %eax
movl %r13d, %edx
subl %r14d, %edx
cmpl %r13d, %eax
cmovbel %r8d, %edx
jmp 0x1f85e
xorl %edx, %edx
jmp 0x1f7a6
movl %r9d, %edx
movq 0x18(%rsp), %r15
cmpl %ecx, %edx
movq 0x20(%rsp), %rcx
movb 0x7(%rsp), %r9b
jne 0x1f7c0
xorl %edi, %edi
movq 0x10(%rsp), %r11
jmp 0x1f853
movb $0x1, %dil
cmpl %esi, %edx
movq 0x10(%rsp), %r11
je 0x1f853
cmpl %eax, %edx
jne 0x1f83d
movq 0x8(%rsp), %rax
movb $0x1, (%rax)
movq 0x78(%rbp), %rdi
leal (%rdx,%r14), %eax
leal (%rdx,%r15), %esi
movl 0xbc(%rdi), %r8d
notl %r8d
movl %eax, %r9d
andl %r8d, %r9d
andl %esi, %r8d
movq 0xa0(%rdi), %r10
movb 0xb8(%rdi), %cl
shrl %cl, %eax
shrl %cl, %esi
movl (%r10,%r9,4), %ecx
movl (%r10,%r8,4), %r8d
movq 0x60(%rdi), %r9
movq 0x80(%rdi), %rdi
addl (%r9,%rcx,4), %eax
addl (%r9,%r8,4), %esi
movb 0x7(%rsp), %r9b
movq 0x20(%rsp), %rcx
movl (%rdi,%rax,4), %eax
cmpl (%rdi,%rsi,4), %eax
setb %dil
jmp 0x1f853
leal (%rdx,%r14), %eax
movq 0x8(%r11), %rdi
movb (%rdi,%rax), %al
leal (%rdx,%r15), %esi
cmpb (%rdi,%rsi), %al
setl %dil
movq %rbx, (%rcx)
leal (%rdx,%r14), %eax
movq %rax, (%r12)
testb %r9b, %r9b
je 0x1f946
leal (%rdx,%r14), %esi
movq (%r12), %rax
cmpq %rsi, %rax
jne 0x1f8c7
movl %r13d, %eax
subl %r15d, %eax
cmpl %eax, %edx
jae 0x1f8ba
movq %rcx, %rbp
movq (%r12), %rcx
movl %r13d, %esi
movl %edx, %edx
movl %eax, %edi
movl %r15d, %r8d
cmpq %rsi, %rcx
jge 0x1f8b7
leal (%r8,%rdx), %r9d
movq 0x8(%r11), %r10
movb (%r10,%r9), %r9b
cmpb (%r10,%rcx), %r9b
jne 0x1f8b7
incq %rcx
movq %rcx, (%r12)
incq %rdx
cmpq %rdi, %rdx
jb 0x1f88f
movl %eax, %edx
movq %rbp, %rcx
movq %rbx, (%rcx)
movq 0x8(%rsp), %rbx
movb $0x0, (%rbx)
jmp 0x1f91d
jge 0x1f91d
movl %eax, %edx
subl %r14d, %edx
movq %rbx, (%rcx)
movq 0x8(%rsp), %rbx
cmpb $0x1, (%rbx)
jne 0x1f91d
movl %r13d, %eax
subl %r15d, %eax
cmpl %eax, %edx
jae 0x1f8c2
movq (%r12), %rcx
movl %r13d, %esi
movl %edx, %edx
movl %eax, %edi
movl %r15d, %r8d
cmpq %rsi, %rcx
jge 0x1f8c2
leal (%r8,%rdx), %r9d
movq 0x8(%r11), %r10
movb (%r10,%r9), %r9b
cmpb (%r10,%rcx), %r9b
jne 0x1f8c2
incq %rcx
movq %rcx, (%r12)
incq %rdx
cmpq %rdi, %rdx
jb 0x1f8f3
movl %eax, %edx
jmp 0x1f8c2
addl %edx, %r14d
cmpl %r13d, %r14d
jne 0x1f929
xorl %edi, %edi
jmp 0x1f946
subl %r15d, %r13d
movb $0x1, %dil
cmpl %r13d, %edx
je 0x1f946
movl %r14d, %eax
movq 0x8(%r11), %rsi
movb (%rsi,%rax), %al
addl %r15d, %edx
cmpb (%rsi,%rdx), %al
jge 0x1f925
andb $0x1, %dil
movl %edi, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
nop