// File: /workspace/github_cpp_makefile_star2_O3/readmapping[P]alfalfa/src/sparseSA.cpp
// Function: sparseSA::radixStep(int*, int*, long&, long*, long, long, long)
void sparseSA::radixStep(int *t_new, int *SA, long &bucketNr, long *BucketBegin, long l, long r, long h) {
  if(h >= K) return;
  // first pass: count
  vector<long> Sigma(256, 0); // Sigma counts occurring characters in bucket
  for (long i = l; i <= r; i++) Sigma[ S[ SA[i]*K + h ] ]++; // count characters
  BucketBegin[0] = l; for (long i = 1; i < 256; i++) { BucketBegin[i] = Sigma[i-1] + BucketBegin[i-1]; } // accumulate

  // second pass: move (this variant does *not* need an additional array!)
  unsigned char currentKey = 0;    // character of current bucket
  long end = l-1+Sigma[currentKey]; // end of current bucket
  long pos = l;                     // 'pos' is current position in bucket
  while (1) {
    if (pos > end) { // Reached the end of the bucket.
      if (currentKey == 255) break; // Last character?
      currentKey++; // Advance to next characer.
      pos = BucketBegin[currentKey]; // Next bucket start.
      end += Sigma[currentKey]; // Next bucket end.
    }
    else {
      // American flag sort of McIlroy et al. 1993. BucketBegin keeps
      // track of current position where to add to bucket set.
      int tmp = SA[ BucketBegin[ (unsigned char) S[ SA[pos]*K + h ] ] ];
      SA[ BucketBegin[ (unsigned char) S[ SA[pos]*K + h] ]++ ] = SA[pos];  // Move bucket beginning to the right, and replace
      SA[ pos ] = tmp; // Save value at bucket beginning.
      if (S[ SA[pos]*K + h ] == currentKey) pos++; // Advance to next position if the right character.
    }
  }
  // recursively refine buckets and calculate new text:
  long beg = l; end = l-1;
  for (long i = 1; i < 256; i++) { // step through Sigma to find bucket borders
    end += Sigma[i];
    if (beg <= end) {
      if(h == K-1) {
	for (long j = beg; j <= end; j++) {
	  t_new[ SA[j] ] = bucketNr; // set new text
	}
	bucketNr++;
      }
      else {
	radixStep(t_new, SA, bucketNr, BucketBegin, beg, end, h+1); // recursive refinement
      }
      beg = end + 1; // advance to next bucket
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq 0x68(%rsp), %rax
movq %rax, (%rsp)
cmpq %rax, 0xe8(%rdi)
jle 0x12f87
movq %r9, %r14
movq %r8, %rbx
movq %rdx, %r15
movq %rdi, %r13
movq %rsi, 0x10(%rsp)
movq %rcx, 0x18(%rsp)
movq 0x60(%rsp), %r12
movl $0x800, %edi            # imm = 0x800
callq 0x72e0
movq %rax, %rbp
movl $0x800, %edx            # imm = 0x800
movq %rax, %rdi
xorl %esi, %esi
callq 0x7180
cmpq %r12, %r14
jg 0x12ed7
movq 0xe8(%r13), %rax
movq 0x50(%r13), %rcx
addq (%rsp), %rcx
incq %r12
movq %r14, %rdx
movslq (%r15,%rdx,4), %rsi
imulq %rax, %rsi
movsbq (%rcx,%rsi), %rsi
incq (%rbp,%rsi,8)
incq %rdx
cmpq %rdx, %r12
jne 0x12ebd
movq %r14, (%rbx)
movl $0x1, %eax
movq %r14, %rcx
addq -0x8(%rbp,%rax,8), %rcx
movq %rcx, (%rbx,%rax,8)
incq %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x12ee2
leaq -0x1(%r14), %rax
movq %rbp, 0x8(%rsp)
movq (%rbp), %rcx
addq %rax, %rcx
movq 0x50(%r13), %rdx
addq (%rsp), %rdx
xorl %esi, %esi
movq %r14, %rdi
movzbl %sil, %r8d
cmpq %rcx, %rdi
jg 0x12f64
movslq (%r15,%rdi,4), %r9
movq %r9, %r10
imulq 0xe8(%r13), %r10
movzbl (%rdx,%r10), %r10d
movq (%rbx,%r10,8), %r11
movslq (%r15,%r11,4), %r12
leaq 0x1(%r11), %rbp
movq %rbp, (%rbx,%r10,8)
movl %r9d, (%r15,%r11,4)
movl %r12d, (%r15,%rdi,4)
imulq 0xe8(%r13), %r12
movsbl (%rdx,%r12), %r9d
xorl %r10d, %r10d
cmpl %r8d, %r9d
sete %r10b
addq %r10, %rdi
jmp 0x12f17
cmpl $0xff, %r8d
je 0x12f96
incb %sil
movzbl %sil, %r8d
shll $0x3, %r8d
movq (%rbx,%r8), %rdi
movq 0x8(%rsp), %r9
addq (%r9,%r8), %rcx
jmp 0x12f13
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq (%rsp), %rcx
incq %rcx
movq %rcx, 0x20(%rsp)
movl $0x1, %ebp
movq 0x18(%rsp), %rcx
movq 0x10(%rsp), %rsi
movq 0x8(%rsp), %rdx
movq (%rdx,%rbp,8), %rdx
leaq (%rdx,%rax), %r12
cmpq %r12, %r14
jg 0x1301d
movq 0xe8(%r13), %rdi
decq %rdi
cmpq (%rsp), %rdi
jne 0x12ff3
movq (%rcx), %rdi
addq %rdx, %rax
incq %rax
movslq (%r15,%r14,4), %rdx
movl %edi, (%rsi,%rdx,4)
incq %r14
cmpq %r14, %rax
jne 0x12fdc
incq %rdi
movq %rdi, (%rcx)
jmp 0x13018
movq %r13, %rdi
movq %r15, %rdx
movq %rbx, %r8
movq %r14, %r9
pushq 0x20(%rsp)
pushq %r12
callq 0x12e48
movq 0x20(%rsp), %rsi
movq 0x28(%rsp), %rcx
addq $0x10, %rsp
leaq 0x1(%r12), %r14
incq %rbp
movq %r12, %rax
cmpq $0x100, %rbp            # imm = 0x100
jne 0x12fb1
movl $0x800, %esi            # imm = 0x800
movq 0x8(%rsp), %rdi
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x72f0
movq %rax, %rbx
movl $0x800, %esi            # imm = 0x800
movq 0x8(%rsp), %rdi
callq 0x72f0
movq %rbx, %rdi
callq 0x7600
nop