// File: /workspace/github_cpp_makefile_star2_O3/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 $0x18, %rsp
movq %r8, %r15
movl %edx, %ebx
movq 0x8(%rdi), %r13
movq 0x18(%r13), %r12
movl %edx, %r14d
movq (%r8), %r11
cmpq %r14, %r11
jge 0x1f46e
movq %r14, (%r15)
movb $0x0, (%r9)
movq (%r15), %r11
xorl %eax, %eax
movq %r9, %rbp
jmp 0x1f573
movq %rdi, %rbp
movq %rsi, %r10
movq %r9, (%rsp)
movq %rcx, 0x10(%rsp)
movl (%rcx), %r8d
movl %ebx, %eax
subl %r8d, %eax
cmpl 0x74(%rdi), %eax
setb %dl
movq 0x78(%rdi), %rdi
testq %rdi, %rdi
sete %sil
orb %dl, %sil
cmpb $0x1, %sil
jne 0x1f4bc
movq 0x50(%rsp), %rsi
movl %eax, %edx
cmpq %rdx, 0x18(%rsi)
jbe 0x1f524
movq 0x8(%rsi), %rax
movl (%rax,%rdx,4), %edx
movq (%rsp), %rbp
jmp 0x1f55d
movl %ebx, %esi
movq %r10, %rdx
movq %r10, 0x8(%rsp)
callq 0x1f70a
movq 0x8(%rsp), %r8
movq (%rsp), %rcx
movb $0x0, (%rcx)
movl %r12d, %ecx
subl %ebx, %ecx
cmpl %ecx, %eax
movl %ecx, %edx
cmovbl %eax, %edx
subl %r8d, %r12d
cmpl %edx, %r12d
cmovbl %r12d, %edx
testl %edx, %edx
je 0x1f656
movq 0x8(%r13), %rsi
movl %edx, %edi
movl %r8d, %r9d
xorl %r8d, %r8d
leal (%r14,%r8), %r10d
movb (%rsi,%r10), %r10b
leal (%r9,%r8), %r11d
cmpb (%rsi,%r11), %r10b
jne 0x1f65a
incq %r8
cmpq %r8, %rdi
jne 0x1f501
jmp 0x1f65d
addl %r10d, %eax
xorl %edx, %edx
cmpq %rax, %r12
movq (%rsp), %rbp
jbe 0x1f55d
movq 0x8(%r13), %rsi
leal (%rbx,%r10), %edi
subl %r8d, %edi
incl %edi
xorl %edx, %edx
leal (%r10,%rdx), %r8d
cmpq %r8, %r12
jbe 0x1f55d
movb (%rsi,%rax), %al
cmpb (%rsi,%r8), %al
jne 0x1f55d
leal (%rdi,%rdx), %eax
incl %edx
cmpq %rax, %r12
ja 0x1f541
leal (%rdx,%rbx), %esi
movl %r12d, %eax
subl %ebx, %eax
cmpl %r12d, %esi
cmovbel %edx, %eax
movq 0x10(%rsp), %rcx
movq %r10, %rsi
leal (%rax,%rbx), %edx
cmpq %rdx, %r11
jne 0x1f5d0
movl %r12d, %edx
subl %esi, %edx
cmpl %edx, %eax
jae 0x1f5c7
movq %rbp, (%rsp)
movl %r12d, %ebp
movl %eax, %eax
movl %edx, %edi
movq %rsi, 0x8(%rsp)
movl %esi, %r8d
cmpq %rbp, %r11
jge 0x1f5be
leal (%r8,%rax), %r9d
movq 0x8(%r13), %r10
movb (%r10,%r9), %r9b
cmpb (%r10,%r11), %r9b
jne 0x1f5be
incq %r11
movq %r11, (%r15)
incq %rax
cmpq %rdi, %rax
jb 0x1f597
movl %edx, %eax
movq 0x8(%rsp), %rsi
movq (%rsp), %rbp
movq %r14, (%rcx)
movb $0x0, (%rbp)
jmp 0x1f625
jge 0x1f625
movl %r11d, %eax
subl %ebx, %eax
movq %r14, (%rcx)
cmpb $0x1, (%rbp)
jne 0x1f625
movl %r12d, %ecx
subl %esi, %ecx
cmpl %ecx, %eax
jae 0x1f5ca
movq (%r15), %rdx
movl %r12d, %r14d
movl %eax, %eax
movl %ecx, %edi
movq %rsi, %r11
movl %esi, %r8d
cmpq %r14, %rdx
jge 0x1f620
leal (%r8,%rax), %r9d
movq 0x8(%r13), %r10
movb (%r10,%r9), %r9b
cmpb (%r10,%rdx), %r9b
jne 0x1f620
incq %rdx
movq %rdx, (%r15)
incq %rax
cmpq %rdi, %rax
jb 0x1f5f9
movl %ecx, %eax
movq %r11, %rsi
jmp 0x1f5ca
addl %eax, %ebx
cmpl %r12d, %ebx
jne 0x1f633
xorl %ecx, %ecx
jmp 0x1f6f9
subl %esi, %r12d
movb $0x1, %cl
cmpl %r12d, %eax
je 0x1f6f9
movl %ebx, %edx
movq 0x8(%r13), %rdi
movb (%rdi,%rdx), %dl
addl %esi, %eax
cmpb (%rdi,%rax), %dl
jge 0x1f62c
jmp 0x1f6f9
xorl %edx, %edx
jmp 0x1f65d
movl %r8d, %edx
cmpl %ecx, %edx
movq 0x10(%rsp), %r8
jne 0x1f66d
xorl %ecx, %ecx
jmp 0x1f6f1
movb $0x1, %cl
cmpl %r12d, %edx
movq 0x8(%rsp), %r10
je 0x1f6f1
cmpl %eax, %edx
jne 0x1f6dd
movq (%rsp), %rcx
movb $0x1, (%rcx)
movq 0x78(%rbp), %rdi
leal (%rax,%rbx), %esi
addl %eax, %r10d
movl 0xbc(%rdi), %eax
notl %eax
movl %esi, %r8d
andl %eax, %r8d
andl %r10d, %eax
movq 0xa0(%rdi), %r9
movb 0xb8(%rdi), %cl
shrl %cl, %esi
shrl %cl, %r10d
movl (%r9,%r8,4), %ecx
movl (%r9,%rax,4), %eax
movq 0x60(%rdi), %r8
movq 0x80(%rdi), %rdi
addl (%r8,%rcx,4), %esi
addl (%r8,%rax,4), %r10d
movq 0x10(%rsp), %r8
movl (%rdi,%rsi,4), %eax
cmpl (%rdi,%r10,4), %eax
setb %cl
jmp 0x1f6f1
leal (%rdx,%rbx), %eax
movq 0x8(%r13), %rcx
movb (%rcx,%rax), %al
addl %edx, %r10d
cmpb (%rcx,%r10), %al
setl %cl
movq %r14, (%r8)
addl %ebx, %edx
movq %rdx, (%r15)
movl %ecx, %eax
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq