// File: /workspace/github_c_makefile_star2_O1/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 0x1f7c2(%rip), %eax     # 0x241f8
movq %rsp, %r11
leaq 0xf(,%rax,8), %rcx
andq $-0x10, %rcx
subq %rcx, %r11
movq %r11, %rsp
movq %rsp, %r14
movq %rax, %rcx
shlq $0x4, %rcx
subq %rcx, %r14
movq %r14, %rsp
movq %rsp, %r9
imulq $0x818, %rax, %rcx      # imm = 0x818
leaq 0xf(%rcx), %r8
andq $-0x10, %r8
subq %r8, %r9
movq %r9, %rsp
testl %eax, %eax
jle 0x4aa6
shll $0x8, %eax
shlq $0x3, %rax
xorl %r8d, %r8d
addq $0xf, %rax
andq $-0x10, %rax
movq %rsp, %r10
subq %rax, %r10
movq %r10, %rsp
movq %r10, 0x810(%r9,%r8)
addq $0x818, %r8             # imm = 0x818
cmpq %r8, %rcx
jne 0x4a89
movq %r11, -0x88(%rbp)
xorpd %xmm0, %xmm0
movapd %xmm0, -0xa0(%rbp)
movapd %xmm0, -0xb0(%rbp)
movapd %xmm0, -0xc0(%rbp)
movapd %xmm0, -0xd0(%rbp)
movslq 0x1f714(%rip), %r12     # 0x241ec
testq %r12, %r12
jle 0x4af9
leaq -0xd0(%rbp), %rax
xorl %ecx, %ecx
movl $0x1, (%rax)
addq $0x8, %rcx
addq $0x4, %rax
cmpq %r12, %rcx
jb 0x4ae6
movl 0x30(%rdi), %r8d
movq 0x60(%rdi), %rax
movslq %r8d, %r10
leaq (%r10,%r10,4), %rcx
movl 0x10(%rax,%rcx,8), %r15d
movl 0x1f6cd(%rip), %eax     # 0x241e0
imull %r10d, %eax
subl %eax, %r15d
testl %r15d, %r15d
jle 0x4dc4
movq %r10, -0x70(%rbp)
movl %r8d, -0x2c(%rbp)
movq %rdi, -0x50(%rbp)
movq %r9, -0x58(%rbp)
movq %rdx, -0x80(%rbp)
movq %rsi, -0x38(%rbp)
leal -0x1(%r12), %eax
addl $0x6, %r12d
testl %eax, %eax
cmovnsl %eax, %r12d
movl %r15d, %ebx
movq %rbx, -0x48(%rbp)
shlq $0x4, %rbx
addq $0x10, %rbx
leaq 0x18b48(%rip), %rsi     # 0x1d6a8
movq %rbx, %rdi
callq 0x14d79
movq %rax, %r13
movq %rbx, %rdi
leaq 0x18b33(%rip), %rsi     # 0x1d6a8
callq 0x14d79
btl $0x3, %r12d
movq %r13, %rbx
cmovaeq %rax, %rbx
cmovaeq %r13, %rax
movq %rax, -0x60(%rbp)
testq %rax, %rax
je 0x4b98
testq %rbx, %rbx
jne 0x4ba2
movl $0x1, %edi
callq 0x359c
movq %rbx, -0x68(%rbp)
leaq 0x1f627(%rip), %rax     # 0x241d4
cmpl $0x0, (%rax)
movq %r15, -0x78(%rbp)
xorps %xmm0, %xmm0
cvtsi2sd %r15d, %xmm0
movsd %xmm0, -0x40(%rbp)
je 0x4c09
leaq 0x18afc(%rip), %rdi     # 0x1d6c6
xorl %eax, %eax
callq 0x2150
movq 0x1f400(%rip), %rbx     # 0x23fd8
movq (%rbx), %rdx
movq -0x48(%rbp), %rdi
xorl %esi, %esi
callq 0x151b4
movsd 0x189e2(%rip), %xmm0    # 0x1d5d0
mulsd -0x40(%rbp), %xmm0
leaq 0x18ade(%rip), %rdi     # 0x1d6d8
movb $0x1, %al
callq 0x2150
movq (%rbx), %rdi
callq 0x2250
movq -0x50(%rbp), %rax
movq %rax, 0x1f60c(%rip)     # 0x24220
movq -0x60(%rbp), %rax
movq %rax, 0x1f609(%rip)     # 0x24228
movslq 0x1f5d2(%rip), %r13     # 0x241f8
testq %r13, %r13
jle 0x4c63
movq -0x58(%rbp), %rax
leaq 0x10(%rax), %r12
leaq 0x8(%r14), %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, %r13
jne 0x4c3a
cmpl $0x0, 0x1f58e(%rip)     # 0x241f8
movq -0x88(%rbp), %r15
jle 0x4ca6
xorl %ebx, %ebx
leaq 0xee2(%rip), %r12       # 0x5b5e
movq %r15, %r13
movq %r13, %rdi
xorl %esi, %esi
movq %r12, %rdx
movq %r14, %rcx
callq 0x2280
incq %rbx
movslq 0x1f55f(%rip), %rax     # 0x241f8
addq $0x10, %r14
addq $0x8, %r13
cmpq %rax, %rbx
jl 0x4c7f
movl 0x1f54c(%rip), %esi     # 0x241f8
testl %esi, %esi
movq -0x70(%rbp), %r14
jle 0x4cd0
xorl %ebx, %ebx
movq (%r15,%rbx,8), %rdi
xorl %esi, %esi
callq 0x2300
incq %rbx
movslq 0x1f52d(%rip), %rsi     # 0x241f8
cmpq %rsi, %rbx
jl 0x4cb6
testl %esi, %esi
movq -0x58(%rbp), %r11
movq -0x78(%rbp), %rbx
jle 0x4d38
movl 0x1f51a(%rip), %ecx     # 0x241fc
movq -0x50(%rbp), %rax
movq 0x60(%rax), %rax
movl 0x1f4f0(%rip), %edx     # 0x241e0
movl %esi, %esi
imulq $0x818, %rsi, %rsi      # imm = 0x818
xorl %edi, %edi
movq %r14, %r8
xorl %r9d, %r9d
movq %r8, %r10
sarq %cl, %r10
movslq %r9d, %r9
movq %r9, (%r11,%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(%r11,%rdi)
addq $0x818, %rdi            # imm = 0x818
addq %r14, %r8
cmpq %rdi, %rsi
jne 0x4d01
leaq -0xd0(%rbp), %rdi
movq -0x60(%rbp), %r15
movq %r15, %rsi
movq -0x68(%rbp), %r12
movq %r12, %rdx
movq %r11, %rcx
callq 0x4e78
movq %rax, %r14
movq -0x48(%rbp), %rcx
shlq $0x4, %rcx
xorl %eax, %eax
cmpq $-0x1, -0x10(%r14,%rcx)
setne %al
negq %rax
movq %rax, (%r14,%rcx)
cmpq %r14, %r15
cmoveq %r12, %r15
movl -0x2c(%rbp), %eax
movl %eax, 0xc(%r14,%rcx)
movq -0x80(%rbp), %rax
movq %r15, (%rax)
leaq 0x1f445(%rip), %rax     # 0x241d4
cmpl $0x0, (%rax)
je 0x4dbe
movsd -0x40(%rbp), %xmm0
mulsd 0x18837(%rip), %xmm0    # 0x1d5d8
leaq 0x1894b(%rip), %rdi     # 0x1d6f3
movb $0x1, %al
callq 0x2150
movq 0x1f222(%rip), %rax     # 0x23fd8
movq (%rax), %rdi
callq 0x2250
movq -0x38(%rbp), %rsi
jmp 0x4dc9
xorl %ebx, %ebx
xorl %r14d, %r14d
movl %ebx, (%rsi)
movq %r14, %rax
leaq -0x28(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq