// File: /workspace/github_c_makefile_star2_O3/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 $0xa8, %rsp
movl 0x1f631(%rip), %ecx     # 0x241f8
movq %rsp, %r10
leaq 0xf(,%rcx,8), %rax
andq $-0x10, %rax
subq %rax, %r10
movq %r10, %rsp
movq %rsp, %r13
movq %rcx, %rax
shlq $0x4, %rax
subq %rax, %r13
movq %r13, %rsp
movq %rsp, %r15
imulq $0x818, %rcx, %rax      # imm = 0x818
addq $0xf, %rax
andq $-0x10, %rax
subq %rax, %r15
movq %r15, %rsp
testl %ecx, %ecx
jle 0x4cd1
movl %ecx, %eax
shll $0x8, %eax
shlq $0x3, %rax
leal 0x1(%rcx), %r8d
decq %rcx
movq %rcx, %xmm0
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
shrl %r8d
imulq $0x1030, %r8, %rcx      # imm = 0x1030
movdqa 0x18998(%rip), %xmm1    # 0x1d5d0
xorl %r8d, %r8d
movdqa 0x1899d(%rip), %xmm2    # 0x1d5e0
pxor %xmm2, %xmm0
addq $0xf, %rax
andq $-0x10, %rax
pcmpeqd %xmm3, %xmm3
movdqa 0x18995(%rip), %xmm4    # 0x1d5f0
movdqa %xmm1, %xmm5
pxor %xmm2, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
movd %xmm5, %r9d
notl %r9d
testb $0x1, %r9b
je 0x4ca0
movq %rsp, %r9
subq %rax, %r9
movq %r9, %rsp
movq %r9, 0x810(%r15,%r8)
pxor %xmm3, %xmm5
pextrw $0x4, %xmm5, %r9d
testb $0x1, %r9b
je 0x4cc1
movq %rsp, %r9
subq %rax, %r9
movq %r9, %rsp
movq %r9, 0x1028(%r15,%r8)
paddq %xmm4, %xmm1
addq $0x1030, %r8            # imm = 0x1030
cmpq %r8, %rcx
jne 0x4c5b
pxor %xmm0, %xmm0
movdqa %xmm0, -0xa0(%rbp)
movdqa %xmm0, -0xb0(%rbp)
movdqa %xmm0, -0xc0(%rbp)
movdqa %xmm0, -0xd0(%rbp)
movslq 0x1f4f0(%rip), %r14     # 0x241ec
testq %r14, %r14
jle 0x4e16
leaq -0x1(%r14), %rax
movq %rax, %xmm0
shrq $0x3, %rax
addq $0x4, %rax
andq $-0x4, %rax
pshufd $0x44, %xmm0, %xmm0     # xmm0 = xmm0[0,1,0,1]
psrlq $0x3, %xmm0
xorl %ecx, %ecx
movdqa 0x188d2(%rip), %xmm1    # 0x1d600
movdqa 0x1889a(%rip), %xmm2    # 0x1d5d0
movdqa 0x188a2(%rip), %xmm3    # 0x1d5e0
pxor %xmm3, %xmm0
pcmpeqd %xmm4, %xmm4
movq %rcx, %xmm5
pshufd $0x44, %xmm5, %xmm5     # xmm5 = xmm5[0,1,0,1]
movdqa %xmm5, %xmm6
por %xmm2, %xmm6
pxor %xmm3, %xmm6
movdqa %xmm6, %xmm7
pcmpgtd %xmm0, %xmm7
pcmpeqd %xmm0, %xmm6
pshufd $0xf5, %xmm6, %xmm8     # xmm8 = xmm6[1,1,3,3]
pand %xmm7, %xmm8
pshufd $0xf5, %xmm7, %xmm6     # xmm6 = xmm7[1,1,3,3]
por %xmm8, %xmm6
movd %xmm6, %r8d
notl %r8d
testb $0x1, %r8b
je 0x4d96
movl $0x1, -0xd0(%rbp,%rcx,4)
pxor %xmm4, %xmm6
pextrw $0x4, %xmm6, %r8d
testb $0x1, %r8b
je 0x4db1
movl $0x1, -0xcc(%rbp,%rcx,4)
por %xmm1, %xmm5
pxor %xmm3, %xmm5
movdqa %xmm5, %xmm6
pcmpgtd %xmm0, %xmm6
pcmpeqd %xmm0, %xmm5
pshufd $0xf5, %xmm5, %xmm7     # xmm7 = xmm5[1,1,3,3]
pand %xmm6, %xmm7
pshufd $0xf5, %xmm6, %xmm5     # xmm5 = xmm6[1,1,3,3]
por %xmm7, %xmm5
pxor %xmm4, %xmm5
pextrw $0x0, %xmm5, %r8d
testb $0x1, %r8b
je 0x4df2
movl $0x1, -0xc8(%rbp,%rcx,4)
pextrw $0x4, %xmm5, %r8d
testb $0x1, %r8b
je 0x4e09
movl $0x1, -0xc4(%rbp,%rcx,4)
addq $0x4, %rcx
cmpq %rcx, %rax
jne 0x4d46
movl 0x30(%rdi), %r8d
movq 0x60(%rdi), %rax
movslq %r8d, %r9
leaq (%r9,%r9,4), %rcx
movl 0x10(%rax,%rcx,8), %ecx
movl 0x1f3b1(%rip), %eax     # 0x241e0
imull %r9d, %eax
subl %eax, %ecx
testl %ecx, %ecx
jle 0x50dc
movq %r9, -0x78(%rbp)
movl %r8d, -0x34(%rbp)
movq %r10, -0x40(%rbp)
movq %rdi, -0x50(%rbp)
movq %rdx, -0x88(%rbp)
movq %rsi, -0x48(%rbp)
leal -0x1(%r14), %eax
addl $0x6, %r14d
testl %eax, %eax
cmovnsl %eax, %r14d
movq %rcx, -0x30(%rbp)
movl %ecx, %ebx
movq %rbx, -0x60(%rbp)
shlq $0x4, %rbx
addq $0x10, %rbx
leaq 0x18869(%rip), %rsi     # 0x1d6e8
movq %rbx, %rdi
callq 0x1512d
movq %rax, %r12
movq %rbx, %rdi
leaq 0x18854(%rip), %rsi     # 0x1d6e8
callq 0x1512d
btl $0x3, %r14d
movq %r12, %rbx
cmovaeq %rax, %rbx
cmovaeq %r12, %rax
movq %rax, -0x68(%rbp)
testq %rax, %rax
je 0x4eb7
testq %rbx, %rbx
jne 0x4ec1
movl $0x1, %edi
callq 0x351c
movq %rbx, -0x80(%rbp)
leaq 0x1f308(%rip), %rax     # 0x241d4
cmpl $0x0, (%rax)
xorps %xmm0, %xmm0
cvtsi2sdl -0x30(%rbp), %xmm0
movsd %xmm0, -0x58(%rbp)
je 0x4f24
leaq 0x18821(%rip), %rdi     # 0x1d706
xorl %eax, %eax
callq 0x2150
movq 0x1f0e5(%rip), %rbx     # 0x23fd8
movq (%rbx), %rdx
movq -0x60(%rbp), %rdi
xorl %esi, %esi
callq 0x15585
movsd 0x18727(%rip), %xmm0    # 0x1d630
mulsd -0x58(%rbp), %xmm0
leaq 0x18803(%rip), %rdi     # 0x1d718
movb $0x1, %al
callq 0x2150
movq (%rbx), %rdi
callq 0x2250
movq -0x50(%rbp), %rax
movq %rax, 0x1f2f1(%rip)     # 0x24220
movq -0x68(%rbp), %rax
movq %rax, 0x1f2ee(%rip)     # 0x24228
movslq 0x1f2b7(%rip), %r14     # 0x241f8
testq %r14, %r14
jle 0x5049
movq %r15, -0x70(%rbp)
leaq 0x10(%r15), %r12
leaq 0x8(%r13), %rbx
xorl %r15d, %r15d
movl %r15d, -0x8(%rbx)
movq %r12, (%rbx)
movl $0x800, %edx            # imm = 0x800
movq %r12, %rdi
xorl %esi, %esi
callq 0x2180
incq %r15
addq $0x10, %rbx
addq $0x818, %r12            # imm = 0x818
cmpq %r15, %r14
jne 0x4f59
testl %r14d, %r14d
movq -0x70(%rbp), %r15
jle 0x5049
xorl %ebx, %ebx
leaq 0xf3f(%rip), %r12       # 0x5ed7
movq -0x40(%rbp), %r14
movq %r14, %rdi
xorl %esi, %esi
movq %r12, %rdx
movq %r13, %rcx
callq 0x2280
incq %rbx
movslq 0x1f242(%rip), %rax     # 0x241f8
addq $0x10, %r13
addq $0x8, %r14
cmpq %rax, %rbx
jl 0x4f9c
testl %eax, %eax
movq -0x78(%rbp), %r12
jle 0x5049
xorl %ebx, %ebx
movq -0x40(%rbp), %r14
movq (%r14,%rbx,8), %rdi
xorl %esi, %esi
callq 0x2300
incq %rbx
movslq 0x1f212(%rip), %rsi     # 0x241f8
cmpq %rsi, %rbx
jl 0x4fd1
testl %esi, %esi
jle 0x5049
movl 0x1f207(%rip), %ecx     # 0x241fc
movq -0x50(%rbp), %rax
movq 0x60(%rax), %rax
movl 0x1f1dd(%rip), %edx     # 0x241e0
imulq $0x818, %rsi, %rsi      # imm = 0x818
xorl %edi, %edi
movq %r12, %r8
xorl %r9d, %r9d
movq %r8, %r10
sarq %cl, %r10
movslq %r9d, %r9
movq %r9, (%r15,%rdi)
movslq %r10d, %r10
leaq (%r10,%r10,4), %r9
movq 0x10(%rax,%r9,8), %r9
imull %edx, %r10d
subq %r10, %r9
movslq %r9d, %r10
movq %r10, 0x8(%r15,%rdi)
addq $0x818, %rdi            # imm = 0x818
addq %r12, %r8
cmpq %rdi, %rsi
jne 0x5012
leaq -0xd0(%rbp), %rdi
movq -0x68(%rbp), %rbx
movq %rbx, %rsi
movq -0x80(%rbp), %r14
movq %r14, %rdx
movq %r15, %rcx
callq 0x5190
movq %rax, %r15
movq -0x60(%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 -0x34(%rbp), %eax
movl %eax, 0xc(%r15,%rcx)
movq -0x88(%rbp), %rax
movq %rbx, (%rax)
leaq 0x1f131(%rip), %rax     # 0x241d4
cmpl $0x0, (%rax)
je 0x50d2
movsd -0x58(%rbp), %xmm0
mulsd 0x18583(%rip), %xmm0    # 0x1d638
leaq 0x18677(%rip), %rdi     # 0x1d733
movb $0x1, %al
callq 0x2150
movq 0x1ef0e(%rip), %rax     # 0x23fd8
movq (%rax), %rdi
callq 0x2250
movq -0x48(%rbp), %rsi
movq -0x30(%rbp), %rax
jmp 0x50e1
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