// File: twekkel[P]mzpq/libzpaq.cpp
// Function: libzpaq::divbwt(unsigned char const*, unsigned char*, int*, int)
int
divbwt(const unsigned char *T, unsigned char *U, int *A, int n) {
  int *B;
  int *bucket_A, *bucket_B;
  int m, pidx, i;

  /* Check arguments. */
  if((T == NULL) || (U == NULL) || (n < 0)) { return -1; }
  else if(n <= 1) { if(n == 1) { U[0] = T[0]; } return n; }

  if((B = A) == NULL) { B = (int *)malloc((size_t)(n + 1) * sizeof(int)); }
  bucket_A = (int *)malloc(BUCKET_A_SIZE * sizeof(int));
  bucket_B = (int *)malloc(BUCKET_B_SIZE * sizeof(int));

  /* Burrows-Wheeler Transform. */
  if((B != NULL) && (bucket_A != NULL) && (bucket_B != NULL)) {
    m = sort_typeBstar(T, B, bucket_A, bucket_B, n);
    pidx = construct_BWT(T, B, bucket_A, bucket_B, n, m);

    /* Copy to output string. */
    U[0] = T[n - 1];
    for(i = 0; i < pidx; ++i) { U[i + 1] = (unsigned char)B[i]; }
    for(i += 1; i < n; ++i) { U[i] = (unsigned char)B[i]; }
    pidx += 1;
  } else {
    pidx = -2;
  }

  free(bucket_B);
  free(bucket_A);
  if(A == NULL) { free(B); }

  return pidx;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
cmpq $0x0, -0x10(%rbp)
je 0x21f2b
cmpq $0x0, -0x18(%rbp)
je 0x21f2b
cmpl $0x0, -0x24(%rbp)
jge 0x21f37
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x220b4
cmpl $0x1, -0x24(%rbp)
jg 0x21f5a
cmpl $0x1, -0x24(%rbp)
jne 0x21f4f
movq -0x10(%rbp), %rax
movb (%rax), %cl
movq -0x18(%rbp), %rax
movb %cl, (%rax)
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x220b4
jmp 0x21f5c
movq -0x20(%rbp), %rax
movq %rax, -0x30(%rbp)
cmpq $0x0, %rax
jne 0x21f80
movl -0x24(%rbp), %eax
addl $0x1, %eax
movslq %eax, %rdi
shlq $0x2, %rdi
callq 0x5380
movq %rax, -0x30(%rbp)
movl $0x400, %edi            # imm = 0x400
callq 0x5380
movq %rax, -0x38(%rbp)
movl $0x40000, %edi          # imm = 0x40000
callq 0x5380
movq %rax, -0x40(%rbp)
cmpq $0x0, -0x30(%rbp)
je 0x22085
cmpq $0x0, -0x38(%rbp)
je 0x22085
cmpq $0x0, -0x40(%rbp)
je 0x22085
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
movl -0x24(%rbp), %r8d
callq 0x21400
movl %eax, -0x44(%rbp)
movq -0x10(%rbp), %rdi
movq -0x30(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x40(%rbp), %rcx
movl -0x24(%rbp), %r8d
movl -0x44(%rbp), %r9d
callq 0x220c0
movl %eax, -0x48(%rbp)
movq -0x10(%rbp), %rax
movl -0x24(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movb (%rax,%rcx), %cl
movq -0x18(%rbp), %rax
movb %cl, (%rax)
movl $0x0, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x48(%rbp), %eax
jge 0x22046
movq -0x30(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movb %al, %dl
movq -0x18(%rbp), %rax
movl -0x4c(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movb %dl, (%rax,%rcx)
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x22016
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
movl -0x4c(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x2207a
movq -0x30(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movl (%rax,%rcx,4), %eax
movb %al, %dl
movq -0x18(%rbp), %rax
movslq -0x4c(%rbp), %rcx
movb %dl, (%rax,%rcx)
movl -0x4c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x4c(%rbp)
jmp 0x2204f
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x2208c
movl $0xfffffffe, -0x48(%rbp) # imm = 0xFFFFFFFE
movq -0x40(%rbp), %rdi
callq 0x5320
movq -0x38(%rbp), %rdi
callq 0x5320
cmpq $0x0, -0x20(%rbp)
jne 0x220ae
movq -0x30(%rbp), %rdi
callq 0x5320
movl -0x48(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x50, %rsp
popq %rbp
retq
nopl (%rax)