// File: /workspace/github_c_makefile_star2_O2/jsh58[P]Genrich/Genrich.c
// Function: johnPartition
uint32_t johnPartition(uint16_t* qual, uint32_t* order,
    uint32_t low, uint32_t high, uint16_t* qual0,
    uint16_t* qual1, uint16_t* qual2, uint32_t* order0,
    uint32_t* order1, uint32_t* order2,
    uint32_t* idxHigh) {

  // separate qual values into temp arrays --
  //   qual0 for higher values, qual1 equal, qual2 lower
  uint16_t pivot = qual[high - 1];  // pivot value: last elt
  uint32_t idx0 = 0, idx1 = 0, idx2 = 0; // indexes into temp arrays
  for (uint32_t j = low; j < high; j++) {
    if (qual[j] > pivot) {
      qual0[idx0] = qual[j];
      order0[idx0] = order[j];
      idx0++;
    } else if (qual[j] == pivot) {
      qual1[idx1] = qual[j];
      order1[idx1] = order[j];
      idx1++;
    } else {
      qual2[idx2] = qual[j];
      order2[idx2] = order[j];
      idx2++;
    }
  }

  if (! idx0 && ! idx2)
    return 0; // all equal values, no need to shuffle

  // recombine temp arrays back into qual/order
  uint32_t i = 0;
  bool val0 = (bool) idx0, val1 = true;
  for (uint32_t j = low; j < high; j++) {
    if (val0) {
      qual[j] = qual0[i];
      order[j] = order0[i];
      if (++i == idx0) {
        val0 = false;
        i = 0;
      }
    } else if (val1) {
      qual[j] = qual1[i];
      order[j] = order1[i];
      if (++i == idx1) {
        val1 = false;
        i = 0;
      }
    } else {
      qual[j] = qual2[i];
      order[j] = order2[i];
      i++;
    }
  }

  // return low/high indexes
  *idxHigh = low + idx0 + idx1;
  return low + idx0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
movq 0x40(%rsp), %r14
leal -0x1(%rcx), %eax
movzwl (%rdi,%rax,2), %eax
movl %edx, -0x4(%rsp)
movl %edx, %r11d
movl %ecx, %r13d
xorl %ecx, %ecx
movq %r11, %r12
xorl %ebp, %ebp
xorl %r10d, %r10d
cmpq %r13, %r12
jae 0x8eca
movzwl (%rdi,%r12,2), %edx
cmpw %ax, %dx
jbe 0x8e8e
movl %ecx, %ebx
movw %dx, (%r8,%rbx,2)
movl (%rsi,%r12,4), %edx
movl %edx, (%r14,%rbx,4)
incl %ecx
jmp 0x8ec5
jne 0x8ea8
movl %ebp, %edx
movw %ax, (%r9,%rdx,2)
movl (%rsi,%r12,4), %ebx
movq 0x48(%rsp), %r15
movl %ebx, (%r15,%rdx,4)
incl %ebp
jmp 0x8ec5
movl %r10d, %ebx
movq 0x38(%rsp), %r15
movw %dx, (%r15,%rbx,2)
movl (%rsi,%r12,4), %edx
movq 0x50(%rsp), %r15
movl %edx, (%r15,%rbx,4)
incl %r10d
incq %r12
jmp 0x8e6c
testl %ecx, %ecx
setne %dl
xorl %eax, %eax
orl %ecx, %r10d
je 0x8f71
movb $0x1, %r12b
xorl %eax, %eax
xorl %r10d, %r10d
cmpq %r13, %r11
jae 0x8f62
movl %r10d, %ebx
testb $0x1, %dl
je 0x8f10
movzwl (%r8,%rbx,2), %edx
movw %dx, (%rdi,%r11,2)
movl (%r14,%rbx,4), %edx
movl %edx, (%rsi,%r11,4)
incl %r10d
cmpl %ecx, %r10d
setne %dl
cmovel %eax, %r10d
jmp 0x8f5d
incl %r10d
testb $0x1, %r12b
je 0x8f3e
movzwl (%r9,%rbx,2), %edx
movw %dx, (%rdi,%r11,2)
movq 0x48(%rsp), %rdx
movl (%rdx,%rbx,4), %edx
movl %edx, (%rsi,%r11,4)
xorl %edx, %edx
cmpl %ebp, %r10d
setne %r12b
cmovel %edx, %r10d
jmp 0x8f5d
movq 0x38(%rsp), %rdx
movzwl (%rdx,%rbx,2), %edx
movw %dx, (%rdi,%r11,2)
movq 0x50(%rsp), %rdx
movl (%rdx,%rbx,4), %edx
movl %edx, (%rsi,%r11,4)
xorl %edx, %edx
xorl %r12d, %r12d
incq %r11
jmp 0x8ee2
addl -0x4(%rsp), %ecx
addl %ecx, %ebp
movq 0x58(%rsp), %rax
movl %ebp, (%rax)
movl %ecx, %eax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq