// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/src/vmir_vm.c
// Function: instr_emit
static void
instr_emit(ir_unit_t *iu, ir_bb_t *bb, ir_function_t *f
#ifdef VMIR_VM_JIT
           , jitctx_t *jc
#endif
           )
{
  ir_instr_t *ii;
  //  printf("=========== BB %s.%d\n", f->if_name, bb->ib_id);


#ifdef VMIR_VM_JIT
  if(bb->ib_jit) {
    int jitoffset = jit_emit(iu, bb, jc);

    if(bb->ib_only_jit_sucessors)
      return;
    assert(jitoffset >= 0);
#ifdef VM_TRACE
    char tmp[128];
    ir_instr_backref_t *iib = f->if_instr_backrefs + f->if_instr_backref_size;
    iib->offset = iu->iu_text_ptr - iu->iu_text_alloc;
    snprintf(tmp, sizeof(tmp), "JIT CALL to 0x%x", jitoffset);
    iib->str = strdup(tmp);
    iib->bb = bb->ib_id;
    f->if_instr_backref_size++;
#endif
    emit_op(iu, VM_JIT_CALL);
    emit_i32(iu, jitoffset);
    return;
  } else if(bb->ib_force_jit_entrypoint) {
    jit_emit_stub(iu, bb, jc);
  }
#endif


  TAILQ_FOREACH(ii, &bb->ib_instrs, ii_link) {
    //    printf("EMIT INSTR: %s\n", instr_str(iu, ii, 1));
    assert(ii->ii_jit == 0);

#ifdef VM_TRACE
    ir_instr_backref_t *iib = f->if_instr_backrefs + f->if_instr_backref_size;
    iib->offset = iu->iu_text_ptr - iu->iu_text_alloc;
    iib->str = instr_stra(iu, ii, 0);
    iib->bb = bb->ib_id;
    f->if_instr_backref_size++;
#endif


    switch(ii->ii_class) {

    case IR_IC_RET:
      emit_ret(iu, (ir_instr_unary_t *)ii);
      break;
    case IR_IC_BINOP:
      emit_binop(iu, (ir_instr_binary_t *)ii);
      break;
    case IR_IC_LOAD:
      emit_load(iu, (ir_instr_load_t *)ii);
      break;
    case IR_IC_CMP2:
      emit_cmp2(iu, (ir_instr_binary_t *)ii);
      break;
    case IR_IC_BR:
      emit_br(iu, (ir_instr_br_t *)ii, bb);
      break;
    case IR_IC_MOVE:
      emit_move(iu, (ir_instr_move_t *)ii);
      break;
    case IR_IC_STORE:
      emit_store(iu, (ir_instr_store_t *)ii);
      break;
    case IR_IC_LEA:
      emit_lea(iu, (ir_instr_lea_t *)ii);
      break;
    case IR_IC_CAST:
      emit_cast(iu, (ir_instr_unary_t *)ii);
      break;
    case IR_IC_CALL:
      emit_call(iu, (ir_instr_call_t *)ii, f);
      break;
    case IR_IC_INVOKE:
      emit_invoke(iu, (ir_instr_call_t *)ii, f);
      break;
    case IR_IC_SWITCH:
      emit_switch(iu, (ir_instr_switch_t *)ii);
      break;
    case IR_IC_ALLOCA:
      emit_alloca(iu, (ir_instr_alloca_t *)ii);
      break;
    case IR_IC_VAARG:
      emit_vaarg(iu, (ir_instr_unary_t *)ii);
      break;
    case IR_IC_SELECT:
      emit_select(iu, (ir_instr_select_t *)ii);
      break;
    case IR_IC_VMOP:
      emit_vmop(iu, (ir_instr_call_t *)ii);
      break;
    case IR_IC_LANDINGPAD:
      emit_landingpad(iu, (ir_instr_landingpad_t *)ii);
      break;
    case IR_IC_RESUME:
      emit_resume(iu, (ir_instr_resume_t *)ii);
      break;
    case IR_IC_STACKCOPY:
      emit_stackcopy(iu, (ir_instr_stackcopy_t *)ii);
      break;
    case IR_IC_STACKSHRINK:
      emit_stackshrink(iu, (ir_instr_stackshrink_t *)ii);
      break;
    case IR_IC_UNREACHABLE:
      emit_op(iu, VM_UNREACHABLE);
      break;
    case IR_IC_CMP_BRANCH:
      emit_cmp_branch(iu, (ir_instr_cmp_branch_t *)ii);
      break;
    case IR_IC_CMP_SELECT:
      emit_cmp_select(iu, (ir_instr_cmp_select_t *)ii);
      break;
    case IR_IC_MLA:
      emit_mla(iu, (ir_instr_ternary_t *)ii);
      break;
    default:
      parser_error(iu, "Unable to emit instruction %d", ii->ii_class);
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x2b745
movq -0x20(%rbp), %rax
movzbl 0x52(%rax), %eax
cmpl $0x0, %eax
jne 0x2b51a
jmp 0x2b539
leaq 0x14a51(%rip), %rdi     # 0x3ff72
leaq 0x149f7(%rip), %rsi     # 0x3ff1f
movl $0x11ec, %edx           # imm = 0x11EC
leaq 0x14a4e(%rip), %rcx     # 0x3ff82
callq 0x31c0
movq -0x20(%rbp), %rax
movl 0x28(%rax), %eax
movq %rax, -0x28(%rbp)
subq $0x1b, %rax
ja 0x2b70d
movq -0x28(%rbp), %rax
leaq 0x12353(%rip), %rcx     # 0x3d8ac
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2bb70
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2be80
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2ca80
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2cff0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x10(%rbp), %rdx
callq 0x2db30
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2dd60
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2e1e0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2efc0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2f2b0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x2fae0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
movq -0x18(%rbp), %rdx
callq 0x2fc10
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x2fe30
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x306c0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x30860
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x30a00
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x310f0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x31250
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x31310
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x313c0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x31540
jmp 0x2b733
movq -0x8(%rbp), %rdi
movl $0x1d8, %esi            # imm = 0x1D8
callq 0x2b410
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x31580
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x31af0
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x32020
jmp 0x2b733
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rax
movl 0x28(%rax), %r8d
leaq 0x147ff(%rip), %rsi     # 0x3ff1f
movl $0x1242, %edx           # imm = 0x1242
leaq 0x1488f(%rip), %rcx     # 0x3ffbb
movb $0x0, %al
callq 0x18220
jmp 0x2b735
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
jmp 0x2b500
addq $0x30, %rsp
popq %rbp
retq
nopl (%rax,%rax)