// File: /workspace/github_c_makefile_star2_O0/google[P]multichase/br_asm.c
// Function: convert_pointers_to_branches
int convert_pointers_to_branches(void *head, int chunk_size) {
  int remain = cycle_len(head);
  chunk_size = (remain < chunk_size)
                   ? remain
                   : remain / (1 << lround(log2(1.0 * remain / chunk_size)));
  int base_chunk_size = chunk_size;
  int chunks_remaining = remain / chunk_size;
  int chunk_count = 0;
  const int br_code_len = 12;  // len(mov_imm64) + max(len(jmp), len(ret))
  char *p = (char *)head;
  do {
    if (!chunk_count) chunk_count = remain / chunks_remaining;
    char *next = *((char **)p);
    for (int i = 8; i < br_code_len; i++) {
      if (p[i]) {
        fprintf(stderr, "not enough space to convert a pointer to branches\n");
        exit(1);
      }
    }
    p = x64_emit_mov_imm64_rax(p, (intptr_t)next);
    // At end of branch chunk, return with a pointer to the next chunk.
    --remain;
    if (--chunk_count == 0) {
      p = x64_emit_ret(p);
      --chunks_remaining;
    } else {
      p = x64_emit_jmp_to_rax(p);
    }
    p = next;
  } while (p != head);
  return base_chunk_size;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movl %esi, -0xc(%rbp)
movq -0x8(%rbp), %rdi
callq 0x410a10
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %eax
cmpl -0xc(%rbp), %eax
jge 0x4108cb
movl -0x10(%rbp), %eax
movl %eax, -0x38(%rbp)
jmp 0x41090a
movl -0x10(%rbp), %eax
movl %eax, -0x3c(%rbp)
cvtsi2sdl -0x10(%rbp), %xmm1
movsd 0xc9be2(%rip), %xmm0    # 0x4da4c0
mulsd %xmm1, %xmm0
cvtsi2sdl -0xc(%rbp), %xmm1
divsd %xmm1, %xmm0
callq 0x410c00
callq 0x410f00
movq %rax, %rcx
movl -0x3c(%rbp), %eax
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
cltd
idivl %ecx
movl %eax, -0x38(%rbp)
movl -0x38(%rbp), %eax
movl %eax, -0xc(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x14(%rbp)
movl -0x10(%rbp), %eax
cltd
idivl -0xc(%rbp)
movl %eax, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movl $0xc, -0x20(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x28(%rbp)
cmpl $0x0, -0x1c(%rbp)
jne 0x410946
movl -0x10(%rbp), %eax
cltd
idivl -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movq -0x28(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movl $0x8, -0x34(%rbp)
cmpl $0xc, -0x34(%rbp)
jge 0x41099b
movq -0x28(%rbp), %rax
movslq -0x34(%rbp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x41098e
movq $0x510708, %rax         # imm = 0x510708
movq (%rax), %rdi
leaq 0xc9b4b(%rip), %rsi     # 0x4da4c8
movb $0x0, %al
callq 0x41b3c0
movl $0x1, %edi
callq 0x41a3f0
jmp 0x410990
movl -0x34(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
jmp 0x410958
movq -0x28(%rbp), %rdi
movq -0x30(%rbp), %rsi
callq 0x410a50
movq %rax, -0x28(%rbp)
movl -0x10(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x10(%rbp)
movl -0x1c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x1c(%rbp)
cmpl $0x0, %eax
jne 0x4109db
movq -0x28(%rbp), %rdi
callq 0x410ac0
movq %rax, -0x28(%rbp)
movl -0x18(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x18(%rbp)
jmp 0x4109e8
movq -0x28(%rbp), %rdi
callq 0x410ae0
movq %rax, -0x28(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
cmpq -0x8(%rbp), %rax
jne 0x410936
movl -0x14(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw (%rax,%rax)