// File: /workspace/github_c_makefile_star2_O0/google[P]multichase/permutation.c
// Function: generate_chase_mixer
void generate_chase_mixer(struct generate_chase_common_args *args,
                          size_t nr_mixers) {
  size_t nr_mixer_indices = args->nr_mixer_indices;
  void (*gen_permutation)(perm_t *, size_t, size_t) = args->gen_permutation;

  /* Set number of mixers rounded up to the power of two */
  if (nr_mixers > 1) {
    args->nr_mixers = 1 << (CHAR_BIT * sizeof(long) -
                            __builtin_clzl(nr_mixers - 1));
  } else {
    args->nr_mixers = 1;
  }

  if (args->nr_mixers < 64) {
    args->nr_mixers = 64;
  }

  if (verbosity > 1)
    printf("nr_mixers = %zu\n", args->nr_mixers);
  perm_t *t = malloc(nr_mixer_indices * sizeof(*t));
  if (t == NULL) {
    fprintf(stderr, "Could not allocate %lu bytes, check stride/memory size?\n",
            nr_mixer_indices * sizeof(*t));
    exit(1);
  }
  perm_t *r = malloc(nr_mixer_indices * args->nr_mixers * sizeof(*r));
  if (r == NULL) {
    fprintf(stderr, "Could not allocate %lu bytes, check stride/memory size?\n",
            nr_mixer_indices * args->nr_mixers * sizeof(*r));
    exit(1);
  }
  size_t i;
  size_t j;

  // we arrange r in a transposed manner so that all of the
  // data for a particular mixer_idx is packed together.
  for (i = 0; i < args->nr_mixers; ++i) {
    gen_permutation(t, nr_mixer_indices, 0);
    for (j = 0; j < nr_mixer_indices; ++j) {
      r[j * args->nr_mixers + i] = t[j];
    }
  }
  free(t);

  args->mixer = r;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq 0x30(%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x1, -0x10(%rbp)
jbe 0x40f160
movq -0x10(%rbp), %rax
subq $0x1, %rax
bsrq %rax, %rax
xorq $0x3f, %rax
movslq %eax, %rcx
movl $0x40, %eax
subq %rcx, %rax
movl %eax, %ecx
movl $0x1, %eax
shll %cl, %eax
movslq %eax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x20(%rax)
jmp 0x40f16c
movq -0x8(%rbp), %rax
movq $0x1, 0x20(%rax)
movq -0x8(%rbp), %rax
cmpq $0x40, 0x20(%rax)
jae 0x40f183
movq -0x8(%rbp), %rax
movq $0x40, 0x20(%rax)
movq $0x512310, %rax         # imm = 0x512310
cmpl $0x1, (%rax)
jle 0x40f1a5
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rsi
leaq 0xcaed2(%rip), %rdi     # 0x4da070
movb $0x0, %al
callq 0x41b480
movq -0x18(%rbp), %rdi
shlq $0x3, %rdi
callq 0x43d330
movq %rax, -0x28(%rbp)
cmpq $0x0, -0x28(%rbp)
jne 0x40f1e7
movq $0x510708, %rax         # imm = 0x510708
movq (%rax), %rdi
movq -0x18(%rbp), %rdx
shlq $0x3, %rdx
leaq 0xcaeab(%rip), %rsi     # 0x4da081
movb $0x0, %al
callq 0x41b3c0
movl $0x1, %edi
callq 0x41a3f0
movq -0x18(%rbp), %rdi
movq -0x8(%rbp), %rax
imulq 0x20(%rax), %rdi
shlq $0x3, %rdi
callq 0x43d330
movq %rax, -0x30(%rbp)
cmpq $0x0, -0x30(%rbp)
jne 0x40f23b
movq $0x510708, %rax         # imm = 0x510708
movq (%rax), %rdi
movq -0x18(%rbp), %rdx
movq -0x8(%rbp), %rax
imulq 0x20(%rax), %rdx
shlq $0x3, %rdx
leaq 0xcae57(%rip), %rsi     # 0x4da081
movb $0x0, %al
callq 0x41b3c0
movl $0x1, %edi
callq 0x41a3f0
movq $0x0, -0x38(%rbp)
movq -0x38(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x20(%rcx), %rax
jae 0x40f2b8
movq -0x20(%rbp), %rax
movq -0x28(%rbp), %rdi
movq -0x18(%rbp), %rsi
xorl %ecx, %ecx
movl %ecx, %edx
callq *%rax
movq $0x0, -0x40(%rbp)
movq -0x40(%rbp), %rax
cmpq -0x18(%rbp), %rax
jae 0x40f2a8
movq -0x28(%rbp), %rax
movq -0x40(%rbp), %rcx
movq (%rax,%rcx,8), %rdx
movq -0x30(%rbp), %rax
movq -0x40(%rbp), %rcx
movq -0x8(%rbp), %rsi
imulq 0x20(%rsi), %rcx
addq -0x38(%rbp), %rcx
movq %rdx, (%rax,%rcx,8)
movq -0x40(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x40(%rbp)
jmp 0x40f26b
jmp 0x40f2aa
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x38(%rbp)
jmp 0x40f243
movq -0x28(%rbp), %rdi
callq 0x43d670
movq -0x30(%rbp), %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x38(%rax)
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)