// File: /workspace/github_cpp_makefile_star2_O3/BenLangmead[P]bowtie/./zbox.h
// Function: void calcZ<SString<char>>(SString<char> const&, unsigned int, EList<unsigned int, 128>&, bool, bool)
void calcZ(const T& s,
		TIndexOffU off,
	   EList<TIndexOffU>& z,
           bool verbose = false,
           bool sanityCheck = false)
{
	size_t lCur = 0, rCur = 0;
	size_t zlen = z.size();
	size_t slen = s.length();
	assert_gt(zlen, 0);
	assert_eq(z[0], 0);
	//assert_leq(zlen, slen);
	for (size_t k = 1; k < zlen && k+off < slen; k++) {
		assert_lt(lCur, k);
		assert(z[lCur] == 0 || z[lCur] == rCur - lCur + 1);
		if(k > rCur) {
			// compare starting at k with prefix starting at 0
			size_t ki = k;
			while(off+ki < s.length() && s[off+ki] == s[off+ki-k]) ki++;
			z[k] = (TIndexOffU)(ki - k);
			assert_lt(off+z[k], slen);
			if(z[k] > 0) {
				lCur = k;
				rCur = k + z[k] - 1;
			}
		} else {
			// position k is contained in a Z-box
			size_t betaLen = rCur - k + 1;
			size_t kPrime = k - lCur;
			assert_eq(s[off+k], s[off+kPrime]);
			if(z[kPrime] < betaLen) {
				z[k] = z[kPrime];
				assert_lt(off+z[k], slen);
				// lCur, rCur unchanged
			} else if (z[kPrime] > 0) {
				int q = 0;
				while (off+q+rCur+1 < s.length() && s[off+q+rCur+1] == s[off+betaLen+q]) q++;
				z[k] = (TIndexOffU)(betaLen + q);
				assert_lt(off+z[k], slen);
				rCur = rCur + q;
				assert_geq(k, lCur);
				lCur = k;
			} else {
				z[k] = 0;
				assert_lt(off+z[k], slen);
				// lCur, rCur unchanged
			}
		}
	}
#ifndef NDEBUG
	if(sanityCheck) {
		// Recalculate Z-boxes using naive quadratic-time algorithm and
		// compare to linear-time result
		assert_eq(0, z[0]);
		for(size_t i = 1; i < z.size(); i++) {
			size_t j;
			for(j = i; off+j < s.length(); j++) {
				if(s[off+j] != s[off+j-i]) break;
			}
			assert_eq(j-i, z[i]);
		}
	}
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq 0x18(%rdx), %r13
cmpq $0x2, %r13
jb 0x1f429
movq 0x18(%rdi), %rbp
movl %esi, %r8d
incl %esi
movl $0x1, %r9d
xorl %ebx, %ebx
movq %r8, %r10
xorl %r11d, %r11d
movq %r13, -0x10(%rsp)
movq %rbp, -0x18(%rsp)
movq %rdi, -0x8(%rsp)
leaq (%r9,%r8), %r15
cmpq %rbp, %r15
jae 0x1f429
movq %r11, %r14
subq %r9, %r14
jae 0x1f354
movq 0x18(%rdi), %r12
movq %r9, %r14
cmpq %r12, %r15
jae 0x1f3ec
movq %r12, %r14
subq %r8, %r14
movq 0x8(%rdi), %rax
addq %r8, %rax
leaq (%rax,%r9), %r13
xorl %ecx, %ecx
movb (%r13,%rcx), %bpl
cmpb (%rax,%rcx), %bpl
jne 0x1f3dc
leaq (%r15,%rcx), %rbp
incq %rbp
incq %rcx
cmpq %r12, %rbp
jb 0x1f331
jmp 0x1f3e2
incq %r14
movq %r9, %rax
subq %rbx, %rax
movq 0x8(%rdx), %r15
movl (%r15,%rax,4), %eax
cmpq %rax, %r14
jbe 0x1f373
movl %eax, (%r15,%r9,4)
jmp 0x1f40e
testl %eax, %eax
je 0x1f41f
movq 0x18(%rdi), %rbx
leaq (%r11,%r8), %r12
incq %r12
xorl %eax, %eax
cmpq %rbx, %r12
jae 0x1f3ce
leaq 0x1(%r11), %r13
movq 0x8(%rdi), %rbp
leaq (%r11,%r10), %rcx
addq %rbp, %rcx
xorl %eax, %eax
movb (%rbp,%r12), %dil
cmpb (%rcx,%rax), %dil
jne 0x1f3bf
leaq 0x1(%rax), %rdi
addl %esi, %eax
movq %rax, %r12
addq %r13, %r12
movq %rdi, %rax
cmpq %rbx, %r12
jb 0x1f39e
movl %edi, %eax
movq -0x8(%rsp), %rdi
movq -0x10(%rsp), %r13
movq -0x18(%rsp), %rbp
movl %eax, %ecx
addl %eax, %r14d
movl %r14d, (%r15,%r9,4)
addq %rcx, %r11
jmp 0x1f40b
addq %r9, %rcx
movq %rcx, %r14
movq -0x10(%rsp), %r13
movq -0x18(%rsp), %rbp
subl %r9d, %r14d
movq 0x8(%rdx), %rax
movl %r14d, (%rax,%r9,4)
movq 0x8(%rdx), %rax
movl (%rax,%r9,4), %eax
testq %rax, %rax
je 0x1f40e
leaq (%r9,%rax), %r11
decq %r11
movq %r9, %rbx
incq %r9
decq %r10
cmpq %r13, %r9
jne 0x1f2f9
jmp 0x1f429
movl $0x0, (%r15,%r9,4)
jmp 0x1f40e
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq