// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/src/vmir_vm.c
// Function: emit_invoke
static void
emit_invoke(ir_unit_t *iu, ir_instr_call_t *ii, ir_function_t *f)
{
  const int textpos = iu->iu_text_ptr - iu->iu_text_alloc;
  VECTOR_PUSH_BACK(&iu->iu_branch_fixups, textpos);

  int rf_offset = f->if_regframe_size;
  int return_reg;

  if(ii->super.ii_ret.value != -1) {
    const ir_value_t *ret = value_get(iu, ii->super.ii_ret.value);
    return_reg = value_reg(ret);
  } else {
    return_reg = 0;
  }
  ir_function_t *callee = value_function(iu, ii->callee.value);
  if(callee != NULL) {
    vm_op_t op;

    if(callee->if_ext_func != NULL) {
      op = VM_INVOKE_EXT;
    } else {
      op = VM_INVOKE;
    }

    emit_i16(iu, op);
    emit_i16(iu, callee->if_gfid);

  } else {

    const ir_value_t *iv = value_get(iu, ii->callee.value);

    if(iv->iv_class != IR_VC_REGFRAME)
      parser_error(iu, "Invoke via incompatible value class %d",
                   iv->iv_class);
    emit_i16(iu, VM_INVOKE_R);
    emit_i16(iu, value_reg(iv));

  }
  emit_i16(iu, rf_offset);
  emit_i16(iu, return_reg);
  emit_i16(iu, ii->normal_dest);
  emit_i16(iu, ii->unwind_dest);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x8(%rbp), %rax
movq 0x440(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x438(%rcx), %rcx
subq %rcx, %rax
movl %eax, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq 0x310(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rax
addq $0x1, %rax
movq -0x8(%rbp), %rcx
cmpq 0x318(%rcx), %rax
jbe 0x2fcaf
movq -0x28(%rbp), %rcx
addq $0x1, %rcx
shlq %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x318(%rax)
movq -0x8(%rbp), %rax
movq 0x318(%rax), %rax
shlq $0x2, %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rdi
movq -0x30(%rbp), %rsi
callq 0x3390
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x308(%rax)
movq -0x28(%rbp), %rcx
addq $0x1, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x310(%rax)
movl -0x1c(%rbp), %edx
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rax
movq -0x28(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x18(%rbp), %rax
movl 0x2c(%rax), %eax
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rax
cmpl $-0x1, 0x2c(%rax)
je 0x2fd0d
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %esi
callq 0x20ee0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rdi
callq 0x321a0
movl %eax, -0x38(%rbp)
jmp 0x2fd14
movl $0x0, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
callq 0x24040
movq %rax, -0x48(%rbp)
cmpq $0x0, -0x48(%rbp)
je 0x2fd6e
movq -0x48(%rbp), %rax
cmpq $0x0, 0x70(%rax)
je 0x2fd43
movl $0x174, -0x4c(%rbp)     # imm = 0x174
jmp 0x2fd4a
movl $0x171, -0x4c(%rbp)     # imm = 0x171
movq -0x8(%rbp), %rdi
movl -0x4c(%rbp), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rax
movl 0x34(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
jmp 0x2fddb
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
callq 0x20ee0
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
cmpl $0x5, (%rax)
je 0x2fdb0
movq -0x8(%rbp), %rdi
movq -0x58(%rbp), %rax
movl (%rax), %r8d
leaq 0x10182(%rip), %rsi     # 0x3ff1f
movl $0x10b5, %edx           # imm = 0x10B5
leaq 0x106cd(%rip), %rcx     # 0x40476
movb $0x0, %al
callq 0x18220
movq -0x8(%rbp), %rdi
movl $0x172, %esi            # imm = 0x172
callq 0x2bae0
movq -0x8(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x58(%rbp), %rdi
callq 0x321a0
movq -0x60(%rbp), %rdi
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movl -0x34(%rbp), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movl -0x38(%rbp), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x68(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
addq $0x60, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)