// File: /workspace/github_c_makefile_star2_O2/thegenemyers[P]DAMASKER/tandem.c
// Function: Sort_Kmers
static KmerPos *Sort_Kmers(DAZZ_DB *block, int *len, KmerPos **buffer)
{ THREAD    threads[NTHREADS];
  Tuple_Arg parmt[NTHREADS];
  Lex_Arg   parmx[NTHREADS];
  int       mersort[16];

  KmerPos  *src, *trg, *rez;
  int       kmers, nreads;
  int       i, j, x;

  for (i = 0; i < NTHREADS; i++)
    parmx[i].sptr = (int64 *) alloca(NTHREADS*BPOWR*sizeof(int64));

  for (i = 0; i < 16; i++)
    mersort[i] = 0;
  for (i = 0; i < Kshift; i += 8)
    mersort[i>>3] = 1;

  nreads = block->nreads;
  kmers  = block->reads[nreads].boff - Kmer * nreads;

  if (kmers <= 0)
    goto no_mers;

  if (((Kshift-1)/BSHIFT) & 0x1)
    { trg = (KmerPos *) Malloc(sizeof(KmerPos)*(kmers+1),"Allocating Sort_Kmers vectors");
      src = (KmerPos *) Malloc(sizeof(KmerPos)*(kmers+1),"Allocating Sort_Kmers vectors");
    }
  else
    { src = (KmerPos *) Malloc(sizeof(KmerPos)*(kmers+1),"Allocating Sort_Kmers vectors");
      trg = (KmerPos *) Malloc(sizeof(KmerPos)*(kmers+1),"Allocating Sort_Kmers vectors");
    }
  if (src == NULL || trg == NULL)
    Clean_Exit(1);

  if (VERBOSE)
    { printf("\n   Kmer count = ");
      Print_Number((int64) kmers,0,stdout);
      printf("\n   Using %.2fGb of space\n",(1. * kmers) / 33554432);
      fflush(stdout);
    }

  TA_block = block;
  TA_list  = src;

  for (i = 0; i < NTHREADS; i++)
    { parmt[i].tnum = i;
      parmt[i].kptr = parmx[i].tptr;
      for (j = 0; j < BPOWR; j++)
        parmt[i].kptr[j] = 0;
    }

  for (i = 0; i < NTHREADS; i++)
    pthread_create(threads+i,NULL,tuple_thread,parmt+i);

  for (i = 0; i < NTHREADS; i++)
    pthread_join(threads[i],NULL);

  x = 0;
  for (i = 0; i < NTHREADS; i++)
    { parmx[i].beg = x;
      j = (int) ((((int64) nreads) * (i+1)) >> NSHIFT);
      parmx[i].end = x = block->reads[j].boff - j*Kmer;
    }

  rez = (KmerPos *) lex_sort(mersort,(Double *) src,(Double *) trg,parmx);

  if (rez[kmers-1].code == 0xffffffffffffffffllu)
    rez[kmers].code = 0;
  else
    rez[kmers].code = 0xffffffffffffffffllu;
  rez[kmers].read = nreads;
 
  if (src != rez)
    *buffer = src; 
  else
    *buffer = trg; 

#ifdef TEST_KSORT
  { int i;

    printf("\nKMER SORT:\n");
    for (i = 0; i < HOW_MANY && i < kmers; i++)
      { KmerPos *c = rez+i;
        printf(" %5d / %5d / %10lld\n",c->read,c->rpos,c->code);
      }
    fflush(stdout);
  }
#endif

  if (VERBOSE)
    { printf("   Index occupies %.2fGb\n",(1. * kmers) / 67108864);
      fflush(stdout);
    }

  if (kmers <= 0)
    { free(rez);
      goto no_mers;
    }

  *len = kmers;
  return (rez);

no_mers:
  *len = 0;
  return (NULL);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movl 0x1ea6a(%rip), %ecx     # 0x221f8
movslq %ecx, %rax
movq %rsp, %r8
leaq 0xf(,%rcx,8), %r9
andq $-0x10, %r9
subq %r9, %r8
movq %r8, -0x68(%rbp)
movq %r8, %rsp
movq %rsp, %r13
imulq $0x818, %rcx, %r8       # imm = 0x818
shlq $0x4, %rcx
subq %rcx, %r13
movq %r13, %rsp
movq %rsp, %r12
addq $0xf, %r8
andq $-0x10, %r8
subq %r8, %r12
movq %r12, %rsp
movq %rax, %rcx
shlq $0xb, %rcx
xorl %r8d, %r8d
testl %eax, %eax
cmovlel %r8d, %eax
imulq $0x818, %rax, %rax      # imm = 0x818
addq $0xf, %rcx
andq $-0x10, %rcx
cmpq %r8, %rax
je 0x380d
movq %rsp, %r9
subq %rcx, %r9
movq %r9, %rsp
movq %r9, 0x810(%r12,%r8)
addq $0x818, %r8             # imm = 0x818
jmp 0x37ee
xorl %eax, %eax
cmpq $0x10, %rax
je 0x3822
andl $0x0, -0xc0(%rbp,%rax,4)
incq %rax
jmp 0x380f
movslq 0x1e9c3(%rip), %rax     # 0x221ec
leaq -0xc0(%rbp), %rcx
xorl %r8d, %r8d
cmpq %rax, %r8
jge 0x3848
movl $0x1, (%rcx)
addq $0x8, %r8
addq $0x4, %rcx
jmp 0x3833
movl 0x30(%rdi), %r8d
movq 0x60(%rdi), %rcx
movslq %r8d, %r9
imulq $0x28, %r9, %r10
movl 0x10(%rcx,%r10), %r10d
movl 0x1e97e(%rip), %ecx     # 0x221e0
imull %r9d, %ecx
subl %ecx, %r10d
testl %r10d, %r10d
jle 0x3b0e
movq %rdi, -0x60(%rbp)
movq %r9, -0x78(%rbp)
movl %r8d, -0x3c(%rbp)
movq %rdx, -0x80(%rbp)
movq %rsi, -0x48(%rbp)
decl %eax
pushq $0x8
popq %rcx
cltd
idivl %ecx
movl %eax, -0x30(%rbp)
movq %r10, -0x38(%rbp)
movl %r10d, %r14d
movq %r14, -0x58(%rbp)
shlq $0x4, %r14
addq $0x10, %r14
leaq 0x17dfd(%rip), %r15     # 0x1b6a8
movq %r14, %rdi
movq %r15, %rsi
callq 0x134dd
movq %rax, %rbx
movq %r14, %rdi
movq %r15, %rsi
callq 0x134dd
movq %rax, %r14
testb $0x1, -0x30(%rbp)
movq %rbx, %rax
cmoveq %r14, %rax
movq %rax, -0x30(%rbp)
cmoveq %rbx, %r14
testq %r14, %r14
je 0x38e6
cmpq $0x0, -0x30(%rbp)
jne 0x38ee
pushq $0x1
popq %rdi
callq 0x242c
leaq 0x1e8df(%rip), %rax     # 0x221d4
cmpl $0x0, (%rax)
cvtsi2sdl -0x38(%rbp), %xmm0
movsd %xmm0, -0x50(%rbp)
je 0x394a
leaq 0x17dbb(%rip), %rdi     # 0x1b6c6
xorl %eax, %eax
callq 0x2150
movq 0x1e6bf(%rip), %rbx     # 0x21fd8
movq (%rbx), %rdx
movq -0x58(%rbp), %rdi
xorl %esi, %esi
callq 0x1396d
movsd 0x17ca1(%rip), %xmm0    # 0x1b5d0
mulsd -0x50(%rbp), %xmm0
leaq 0x17d9d(%rip), %rdi     # 0x1b6d8
movb $0x1, %al
callq 0x2150
movq (%rbx), %rdi
callq 0x2250
movq -0x60(%rbp), %rax
movq %rax, 0x1e8cb(%rip)     # 0x22220
movq %r14, 0x1e8cc(%rip)     # 0x22228
movl 0x1e896(%rip), %eax     # 0x221f8
xorl %ecx, %ecx
testl %eax, %eax
movl $0x0, %edx
cmovgl %eax, %edx
leaq 0x10(%r12), %rsi
cmpq %rdx, %rcx
je 0x39b8
movq %rcx, %rdi
shlq $0x4, %rdi
movl %ecx, (%r13,%rdi)
imulq $0x818, %rcx, %r8       # imm = 0x818
addq %r12, %r8
addq $0x10, %r8
movq %r8, 0x8(%r13,%rdi)
xorl %edi, %edi
cmpq $0x100, %rdi            # imm = 0x100
je 0x39ac
andq $0x0, (%rsi,%rdi,8)
incq %rdi
jmp 0x3999
incq %rcx
addq $0x818, %rsi            # imm = 0x818
jmp 0x3973
movq %r14, -0x70(%rbp)
xorl %r15d, %r15d
leaq 0xe96(%rip), %r14       # 0x485c
movq -0x68(%rbp), %rbx
movslq %eax, %rcx
cmpq %rcx, %r15
jge 0x39f5
movq %rbx, %rdi
xorl %esi, %esi
movq %r14, %rdx
movq %r13, %rcx
callq 0x2280
incq %r15
movl 0x1e80d(%rip), %eax     # 0x221f8
addq $0x10, %r13
addq $0x8, %rbx
jmp 0x39ca
xorl %ebx, %ebx
movq -0x60(%rbp), %r14
movq -0x68(%rbp), %r15
movslq %eax, %rcx
cmpq %rcx, %rbx
jge 0x3a1d
movq (%r15,%rbx,8), %rdi
xorl %esi, %esi
callq 0x2300
incq %rbx
movl 0x1e7dd(%rip), %eax     # 0x221f8
jmp 0x39ff
movl 0x1e7d9(%rip), %ecx     # 0x221fc
xorl %edx, %edx
testl %eax, %eax
cmovlel %edx, %eax
movl 0x1e7b0(%rip), %esi     # 0x221e0
imulq $0x818, %rax, %rax      # imm = 0x818
movq -0x78(%rbp), %r11
movq %r11, %rdi
xorl %r8d, %r8d
cmpq %rdx, %rax
je 0x3a7e
movq %rdi, %r9
sarq %cl, %r9
movslq %r8d, %r8
movq %r8, (%r12,%rdx)
movq 0x60(%r14), %r8
movslq %r9d, %r9
imulq $0x28, %r9, %r10
movq 0x10(%r8,%r10), %r8
imull %esi, %r9d
subq %r9, %r8
movslq %r8d, %r9
movq %r9, 0x8(%r12,%rdx)
addq $0x818, %rdx            # imm = 0x818
addq %r11, %rdi
jmp 0x3a41
leaq -0xc0(%rbp), %rdi
movq -0x70(%rbp), %rbx
movq %rbx, %rsi
movq -0x30(%rbp), %r14
movq %r14, %rdx
movq %r12, %rcx
callq 0x3bb5
movq %rax, %r15
movq -0x58(%rbp), %rcx
shlq $0x4, %rcx
xorl %eax, %eax
cmpq $-0x1, -0x10(%r15,%rcx)
setne %al
negq %rax
movq %rax, (%r15,%rcx)
cmpq %r15, %rbx
cmoveq %r14, %rbx
movl -0x3c(%rbp), %eax
movl %eax, 0xc(%r15,%rcx)
movq -0x80(%rbp), %rax
movq %rbx, (%rax)
leaq 0x1e6ff(%rip), %rax     # 0x221d4
cmpl $0x0, (%rax)
je 0x3b04
movsd -0x50(%rbp), %xmm0
mulsd 0x17af1(%rip), %xmm0    # 0x1b5d8
leaq 0x17c05(%rip), %rdi     # 0x1b6f3
movb $0x1, %al
callq 0x2150
movq 0x1e4dc(%rip), %rax     # 0x21fd8
movq (%rax), %rdi
callq 0x2250
movq -0x48(%rbp), %rsi
movq -0x38(%rbp), %rax
jmp 0x3b13
xorl %eax, %eax
xorl %r15d, %r15d
movl %eax, (%rsi)
movq %r15, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq