// File: readmapping[P]alfalfa/src/sparseSA.cpp
// Function: sparseSA::top_down_faster(char, long, long&, long&) const
bool sparseSA::top_down_faster(char c, long i, long &start, long &end) const {
  long l, r, m, r2=end, l2=start, vgl;
  bool found = false;
  long cmp_with_first = (long)c - (long)S[SA[start]+i];
  long cmp_with_last = (long)c - (long)S[SA[end]+i];
  if(cmp_with_first < 0) {
    l = start+1; l2 = start; // pattern doesn't occur!
  }
  else if(cmp_with_last > 0) {
    l = end+1; l2 = end;
    // pattern doesn't occur!
  }
  else {
    // search for left border:
    l = start; r = end;
    if (cmp_with_first == 0) {
      found = true; r2 = r;
    }
    else {
      while (r - l > 1) {
	m = (l+r) / 2;
	vgl = (long)c - (long)S[SA[m] + i];
	if (vgl <= 0) {
	  if (!found && vgl == 0) {
	    found = true;
	    l2 = m; r2 = r; // search interval for right border
	  }
	  r = m;
	}
	else l = m;
      }
      l = r;
    }
    // search for right border (in the range [l2:r2])
    if (!found) {
      l2 = l - 1; // pattern not found => right border to the left of 'l'
    }
    if (cmp_with_last == 0) {
      l2 = end; // right border is the end of the array
    }
    else {
      while (r2 - l2 > 1) {
	m = (l2 + r2) / 2;
	vgl = (long)c - (long)S[SA[m] + i];
	if (vgl < 0) r2 = m;
	else l2 = m;
      }
    }
  }
  start = l;
  end = l2;
  return l <= l2;
}

// Assembly:
subq $0xb8, %rsp
movb %sil, %al
movq %rdi, 0xb0(%rsp)
movb %al, 0xaf(%rsp)
movq %rdx, 0xa0(%rsp)
movq %rcx, 0x98(%rsp)
movq %r8, 0x90(%rsp)
movq 0xb0(%rsp), %rdi
movq %rdi, 0x28(%rsp)
movq 0x90(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x70(%rsp)
movq 0x98(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x68(%rsp)
movb $0x0, 0x5f(%rsp)
movsbq 0xaf(%rsp), %rax
movq %rax, 0x30(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, 0x20(%rsp)
addq $0x70, %rdi
movq 0x98(%rsp), %rax
movq (%rax), %rsi
callq 0x1fb90
movq 0x20(%rsp), %rdi
movl (%rax), %eax
movl %eax, %esi
addq 0xa0(%rsp), %rsi
callq 0x8410
movq 0x28(%rsp), %rdi
movq %rax, %rcx
movq 0x30(%rsp), %rax
movsbq (%rcx), %rcx
subq %rcx, %rax
movq %rax, 0x50(%rsp)
movsbq 0xaf(%rsp), %rax
movq %rax, 0x40(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, 0x38(%rsp)
addq $0x70, %rdi
movq 0x90(%rsp), %rax
movq (%rax), %rsi
callq 0x1fb90
movq 0x38(%rsp), %rdi
movl (%rax), %eax
movl %eax, %esi
addq 0xa0(%rsp), %rsi
callq 0x8410
movq %rax, %rcx
movq 0x40(%rsp), %rax
movsbq (%rcx), %rcx
subq %rcx, %rax
movq %rax, 0x48(%rsp)
cmpq $0x0, 0x50(%rsp)
jge 0x1f14c
movq 0x98(%rsp), %rax
movq (%rax), %rax
addq $0x1, %rax
movq %rax, 0x88(%rsp)
movq 0x98(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x68(%rsp)
jmp 0x1f39d
cmpq $0x0, 0x48(%rsp)
jle 0x1f180
movq 0x90(%rsp), %rax
movq (%rax), %rax
addq $0x1, %rax
movq %rax, 0x88(%rsp)
movq 0x90(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x68(%rsp)
jmp 0x1f39b
movq 0x98(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x88(%rsp)
movq 0x90(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x80(%rsp)
cmpq $0x0, 0x50(%rsp)
jne 0x1f1c5
movb $0x1, 0x5f(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1f2bb
jmp 0x1f1c7
movq 0x80(%rsp), %rax
subq 0x88(%rsp), %rax
cmpq $0x1, %rax
jle 0x1f2ab
movq 0x28(%rsp), %rdi
movq 0x88(%rsp), %rax
addq 0x80(%rsp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
movq %rax, 0x78(%rsp)
movsbq 0xaf(%rsp), %rax
movq %rax, 0x18(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, 0x10(%rsp)
addq $0x70, %rdi
movq 0x78(%rsp), %rsi
callq 0x1fb90
movq 0x10(%rsp), %rdi
movl (%rax), %eax
movl %eax, %esi
addq 0xa0(%rsp), %rsi
callq 0x8410
movq %rax, %rcx
movq 0x18(%rsp), %rax
movsbq (%rcx), %rcx
subq %rcx, %rax
movq %rax, 0x60(%rsp)
cmpq $0x0, 0x60(%rsp)
jg 0x1f299
testb $0x1, 0x5f(%rsp)
jne 0x1f28a
cmpq $0x0, 0x60(%rsp)
jne 0x1f28a
movb $0x1, 0x5f(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x68(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x70(%rsp)
movq 0x78(%rsp), %rax
movq %rax, 0x80(%rsp)
jmp 0x1f2a6
movq 0x78(%rsp), %rax
movq %rax, 0x88(%rsp)
jmp 0x1f1c7
movq 0x80(%rsp), %rax
movq %rax, 0x88(%rsp)
testb $0x1, 0x5f(%rsp)
jne 0x1f2d3
movq 0x88(%rsp), %rax
subq $0x1, %rax
movq %rax, 0x68(%rsp)
cmpq $0x0, 0x48(%rsp)
jne 0x1f2f0
movq 0x90(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x68(%rsp)
jmp 0x1f399
jmp 0x1f2f2
movq 0x70(%rsp), %rax
subq 0x68(%rsp), %rax
cmpq $0x1, %rax
jle 0x1f397
movq 0x28(%rsp), %rdi
movq 0x68(%rsp), %rax
addq 0x70(%rsp), %rax
movl $0x2, %ecx
cqto
idivq %rcx
movq %rax, 0x78(%rsp)
movsbq 0xaf(%rsp), %rax
movq %rax, 0x8(%rsp)
movq %rdi, %rax
addq $0x50, %rax
movq %rax, (%rsp)
addq $0x70, %rdi
movq 0x78(%rsp), %rsi
callq 0x1fb90
movq (%rsp), %rdi
movl (%rax), %eax
movl %eax, %esi
addq 0xa0(%rsp), %rsi
callq 0x8410
movq %rax, %rcx
movq 0x8(%rsp), %rax
movsbq (%rcx), %rcx
subq %rcx, %rax
movq %rax, 0x60(%rsp)
cmpq $0x0, 0x60(%rsp)
jge 0x1f388
movq 0x78(%rsp), %rax
movq %rax, 0x70(%rsp)
jmp 0x1f392
movq 0x78(%rsp), %rax
movq %rax, 0x68(%rsp)
jmp 0x1f2f2
jmp 0x1f399
jmp 0x1f39b
jmp 0x1f39d
movq 0x88(%rsp), %rcx
movq 0x98(%rsp), %rax
movq %rcx, (%rax)
movq 0x68(%rsp), %rcx
movq 0x90(%rsp), %rax
movq %rcx, (%rax)
movq 0x88(%rsp), %rax
cmpq 0x68(%rsp), %rax
setle %al
andb $0x1, %al
addq $0xb8, %rsp
retq
nopw (%rax,%rax)