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

  // We can't emit code yet cause we don't know the final destination
  if(ii->condition.value == -1) {
    ir_bb_t *next = TAILQ_NEXT(currentib, ib_link);
    if(next != NULL && next->ib_id == ii->true_branch) {
      // Jump to next bb is NOP as basic-blocks are contiguous in memory
      VECTOR_POP(&iu->iu_branch_fixups);
      return;
    }

    // Unconditional branch
    emit_i16(iu, VM_B);
    emit_i16(iu, ii->true_branch);
  } else {
    // Conditional branch

    ir_value_t *iv = value_get(iu, ii->condition.value);
    switch(iv->iv_class) {
    case IR_VC_REGFRAME:
      emit_i16(iu, VM_BCOND);
      emit_i16(iu, value_reg(iv));
      emit_i16(iu, ii->true_branch);
      emit_i16(iu, ii->false_branch);
      break;

    case IR_VC_CONSTANT:
      emit_i16(iu, VM_B);
      if(value_get_const32(iu, iv))
        emit_i16(iu, ii->true_branch);
      else
        emit_i16(iu, ii->false_branch);
      break;
    default:
      parser_error(iu, "Unable to branch on value class %d", iv->iv_class);
    }
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %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 0x2dbcf
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 -0x10(%rbp), %rax
cmpl $-0x1, 0x58(%rax)
jne 0x2dc64
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
cmpq $0x0, -0x38(%rbp)
je 0x2dc3e
movq -0x38(%rbp), %rax
movl 0x28(%rax), %eax
movq -0x10(%rbp), %rcx
cmpl 0x60(%rcx), %eax
jne 0x2dc3e
movq -0x8(%rbp), %rax
movq 0x310(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x310(%rax)
jmp 0x2dd5a
movq -0x8(%rbp), %rdi
movl $0x16b, %esi            # imm = 0x16B
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
jmp 0x2dd5a
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
callq 0x20ee0
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x44(%rbp)
subl $0x3, %eax
je 0x2dce9
jmp 0x2dc88
movl -0x44(%rbp), %eax
subl $0x5, %eax
jne 0x2dd33
jmp 0x2dc96
movq -0x8(%rbp), %rdi
movl $0x16c, %esi            # imm = 0x16C
callq 0x2bae0
movq -0x8(%rbp), %rax
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rdi
callq 0x321a0
movq -0x50(%rbp), %rdi
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
jmp 0x2dd58
movq -0x8(%rbp), %rdi
movl $0x16b, %esi            # imm = 0x16B
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rsi
callq 0x261a0
cmpl $0x0, %eax
je 0x2dd1e
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
jmp 0x2dd31
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
jmp 0x2dd58
movq -0x8(%rbp), %rdi
movq -0x40(%rbp), %rax
movl (%rax), %r8d
leaq 0x121da(%rip), %rsi     # 0x3ff1f
movl $0xe46, %edx            # imm = 0xE46
leaq 0x125a8(%rip), %rcx     # 0x402f9
movb $0x0, %al
callq 0x18220
jmp 0x2dd5a
addq $0x50, %rsp
popq %rbp
retq