// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/src/vmir_vm.c
// Function: emit_switch
static void
emit_switch(ir_unit_t *iu, ir_instr_switch_t *ii)
{
  const ir_value_t *c = value_get(iu, ii->value.value);
  const ir_type_t *cty = type_get(iu, ii->value.type);

  uint32_t mask32 = 0xffffffff;
  int jumptable_size = 0;
  int width;
  assert(c->iv_class == IR_VC_REGFRAME);
  int reg = value_reg(c);

  switch(cty->it_code) {

  case IR_TYPE_INTx:
    width = type_bitwidth(iu, cty);
    assert(width < 32);

    if(width <= 4) {
      jumptable_size = 1 << width;
      goto jumptable;
    }

    mask32 = (1 << width) - 1;

    assert(c->iv_class == IR_VC_REGFRAME);
    emit_op2(iu, VM_AND_R32C, 0, reg);
    emit_i32(iu, mask32);

    reg = 0;

    goto switch32;
  case IR_TYPE_INT1:
  case IR_TYPE_INT8:

    if(ii->num_paths > 64) {
      jumptable_size = 256;
      goto jumptable;
    }

    VECTOR_PUSH_BACK(&iu->iu_branch_fixups,
                     iu->iu_text_ptr - iu->iu_text_alloc);
    emit_i16(iu, VM_SWITCH8_BS);
    emit_i16(iu, reg);
    emit_i16(iu, ii->num_paths);

    for(int n = 0; n < ii->num_paths; n++)
      emit_i8(iu, ii->paths[n].v64);

    for(int n = 0; n < ii->num_paths; n++)
      emit_i16(iu, ii->paths[n].block);

    emit_i16(iu, ii->defblock);
    break;

  case IR_TYPE_INT16:
    assert(c->iv_class == IR_VC_REGFRAME);
    emit_op2(iu, VM_CAST_16_TRUNC_32, 0, reg);
    reg = 0;
    mask32 = 0xffff;
    goto switch32;


  case IR_TYPE_INT32:

  switch32:
    VECTOR_PUSH_BACK(&iu->iu_branch_fixups,
                     iu->iu_text_ptr - iu->iu_text_alloc);

    emit_i16(iu, VM_SWITCH32_BS);

    emit_i16(iu, reg);
    emit_i16(iu, ii->num_paths);

    for(int n = 0; n < ii->num_paths; n++)
      emit_i32(iu, ii->paths[n].v64 & mask32);

    for(int n = 0; n < ii->num_paths; n++)
      emit_i16(iu, ii->paths[n].block);

    emit_i16(iu, ii->defblock);
    break;

  case IR_TYPE_INT64:
    assert(c->iv_class == IR_VC_REGFRAME);

    vm_align32(iu, 1);

    VECTOR_PUSH_BACK(&iu->iu_branch_fixups,
                     iu->iu_text_ptr - iu->iu_text_alloc);
    emit_i16(iu, VM_SWITCH64_BS);
    emit_i16(iu, reg);
    emit_i16(iu, ii->num_paths);

    for(int n = 0; n < ii->num_paths; n++)
      emit_i64(iu, ii->paths[n].v64);

    for(int n = 0; n < ii->num_paths; n++)
      emit_i16(iu, ii->paths[n].block);

    emit_i16(iu, ii->defblock);
    break;


  jumptable:
    VECTOR_PUSH_BACK(&iu->iu_branch_fixups,
                     iu->iu_text_ptr - iu->iu_text_alloc);
    emit_i16(iu, VM_JUMPTABLE);
    emit_i16(iu, reg);
    emit_i16(iu, jumptable_size);
    const int mask = jumptable_size - 1;
    int16_t *table = emit_data(iu, jumptable_size * 2);

    // Fill table with default paths
    for(int i = 0; i < jumptable_size; i++)
      table[i] = ii->defblock;

    for(int n = 0; n < ii->num_paths; n++)
      table[ii->paths[n].v64 & mask] = ii->paths[n].block;

    break;

  default:
    parser_error(iu, "Bad type in switch (%d paths): %s",
                 ii->num_paths, instr_str(iu, &ii->super, 0));
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xc0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x58(%rax), %esi
callq 0x20ee0
movq %rax, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x5c(%rax), %esi
callq 0x1ee20
movq %rax, -0x20(%rbp)
movl $0xffffffff, -0x24(%rbp) # imm = 0xFFFFFFFF
movl $0x0, -0x28(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x5, (%rax)
jne 0x2fe84
jmp 0x2fea3
leaq 0x10612(%rip), %rdi     # 0x4049d
leaq 0x1008d(%rip), %rsi     # 0x3ff1f
movl $0xe58, %edx            # imm = 0xE58
leaq 0x1061d(%rip), %rcx     # 0x404bb
callq 0x31c0
movq -0x18(%rbp), %rdi
callq 0x321a0
movl %eax, -0x30(%rbp)
movq -0x20(%rbp), %rax
movl (%rax), %eax
addl $-0x2, %eax
movl %eax, %ecx
movq %rcx, -0xa8(%rbp)
subl $0x5, %eax
ja 0x3065f
movq -0xa8(%rbp), %rax
leaq 0xdcd8(%rip), %rcx      # 0x3dbb0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x8(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x32f30
movl %eax, -0x2c(%rbp)
cmpl $0x20, -0x2c(%rbp)
jge 0x2fef9
jmp 0x2ff18
leaq 0x105ee(%rip), %rdi     # 0x404ee
leaq 0x10018(%rip), %rsi     # 0x3ff1f
movl $0xe5f, %edx            # imm = 0xE5F
leaq 0x105a8(%rip), %rcx     # 0x404bb
callq 0x31c0
cmpl $0x4, -0x2c(%rbp)
jg 0x2ff30
movl -0x2c(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0x28(%rbp)
jmp 0x304a3
movl -0x2c(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
subl $0x1, %eax
movl %eax, -0x24(%rbp)
movq -0x18(%rbp), %rax
cmpl $0x5, (%rax)
jne 0x2ff4b
jmp 0x2ff6a
leaq 0x1054b(%rip), %rdi     # 0x4049d
leaq 0xffc6(%rip), %rsi      # 0x3ff1f
movl $0xe68, %edx            # imm = 0xE68
leaq 0x10556(%rip), %rcx     # 0x404bb
callq 0x31c0
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %eax
movl $0x3f, %esi
xorl %edx, %edx
movzwl %ax, %ecx
callq 0x324a0
movq -0x8(%rbp), %rdi
movl -0x24(%rbp), %esi
callq 0x2b450
movl $0x0, -0x30(%rbp)
jmp 0x30179
movq -0x10(%rbp), %rax
cmpl $0x40, 0x64(%rax)
jle 0x2ffae
movl $0x100, -0x28(%rbp)     # imm = 0x100
jmp 0x304a3
jmp 0x2ffb0
movq -0x8(%rbp), %rax
movq 0x310(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x38(%rbp), %rax
addq $0x1, %rax
movq -0x8(%rbp), %rcx
cmpq 0x318(%rcx), %rax
jbe 0x3001f
movq -0x38(%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, -0x40(%rbp)
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rdi
movq -0x40(%rbp), %rsi
callq 0x3390
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x308(%rax)
movq -0x38(%rbp), %rcx
addq $0x1, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x310(%rax)
movq -0x8(%rbp), %rax
movq 0x440(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x438(%rcx), %rcx
subq %rcx, %rax
movl %eax, %edx
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rax
movq -0x38(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x8(%rbp), %rdi
movl $0x178, %esi            # imm = 0x178
callq 0x2bae0
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
movl $0x0, -0x44(%rbp)
movl -0x44(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x64(%rcx), %eax
jge 0x300cf
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
addq $0x68, %rax
movslq -0x44(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movzbl %al, %esi
callq 0x32500
movl -0x44(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x44(%rbp)
jmp 0x30096
movl $0x0, -0x48(%rbp)
movl -0x48(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x64(%rcx), %eax
jge 0x3010f
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
addq $0x68, %rax
movslq -0x48(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
movl -0x48(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x48(%rbp)
jmp 0x300d6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
jmp 0x306b1
movq -0x18(%rbp), %rax
cmpl $0x5, (%rax)
jne 0x30132
jmp 0x30151
leaq 0x10364(%rip), %rdi     # 0x4049d
leaq 0xfddf(%rip), %rsi      # 0x3ff1f
movl $0xe87, %edx            # imm = 0xE87
leaq 0x1036f(%rip), %rcx     # 0x404bb
callq 0x31c0
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %eax
movl $0x18f, %esi            # imm = 0x18F
xorl %edx, %edx
movzwl %ax, %ecx
callq 0x324a0
movl $0x0, -0x30(%rbp)
movl $0xffff, -0x24(%rbp)    # imm = 0xFFFF
jmp 0x30179
jmp 0x30179
jmp 0x3017b
movq -0x8(%rbp), %rax
movq 0x310(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x50(%rbp), %rax
addq $0x1, %rax
movq -0x8(%rbp), %rcx
cmpq 0x318(%rcx), %rax
jbe 0x301ea
movq -0x50(%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, -0x58(%rbp)
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rdi
movq -0x58(%rbp), %rsi
callq 0x3390
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x308(%rax)
movq -0x50(%rbp), %rcx
addq $0x1, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x310(%rax)
movq -0x8(%rbp), %rax
movq 0x440(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x438(%rcx), %rcx
subq %rcx, %rax
movl %eax, %edx
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rax
movq -0x50(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x8(%rbp), %rdi
movl $0x179, %esi            # imm = 0x179
callq 0x2bae0
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
movl $0x0, -0x5c(%rbp)
movl -0x5c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x64(%rcx), %eax
jge 0x3029f
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
addq $0x68, %rax
movslq -0x5c(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rax
movl -0x24(%rbp), %ecx
andq %rcx, %rax
movl %eax, %esi
callq 0x2b450
movl -0x5c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x5c(%rbp)
jmp 0x30261
movl $0x0, -0x60(%rbp)
movl -0x60(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x64(%rcx), %eax
jge 0x302df
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
addq $0x68, %rax
movslq -0x60(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
movl -0x60(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x60(%rbp)
jmp 0x302a6
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
jmp 0x306b1
movq -0x18(%rbp), %rax
cmpl $0x5, (%rax)
jne 0x30302
jmp 0x30321
leaq 0x10194(%rip), %rdi     # 0x4049d
leaq 0xfc0f(%rip), %rsi      # 0x3ff1f
movl $0xea3, %edx            # imm = 0xEA3
leaq 0x1019f(%rip), %rcx     # 0x404bb
callq 0x31c0
movq -0x8(%rbp), %rdi
movl $0x1, %esi
callq 0x321f0
movq -0x8(%rbp), %rax
movq 0x310(%rax), %rax
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
addq $0x1, %rax
movq -0x8(%rbp), %rcx
cmpq 0x318(%rcx), %rax
jbe 0x3039e
movq -0x68(%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, -0x70(%rbp)
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rdi
movq -0x70(%rbp), %rsi
callq 0x3390
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x308(%rax)
movq -0x68(%rbp), %rcx
addq $0x1, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x310(%rax)
movq -0x8(%rbp), %rax
movq 0x440(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x438(%rcx), %rcx
subq %rcx, %rax
movl %eax, %edx
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rax
movq -0x68(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x8(%rbp), %rdi
movl $0x17a, %esi            # imm = 0x17A
callq 0x2bae0
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
movl $0x0, -0x74(%rbp)
movl -0x74(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x64(%rcx), %eax
jge 0x3044b
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
addq $0x68, %rax
movslq -0x74(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movq (%rax), %rsi
callq 0x32240
movl -0x74(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x74(%rbp)
jmp 0x30415
movl $0x0, -0x78(%rbp)
movl -0x78(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x64(%rcx), %eax
jge 0x3048b
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
addq $0x68, %rax
movslq -0x78(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
movl -0x78(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x30452
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movzwl %ax, %esi
callq 0x2bae0
jmp 0x306b1
jmp 0x304a5
movq -0x8(%rbp), %rax
movq 0x310(%rax), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rax
addq $0x1, %rax
movq -0x8(%rbp), %rcx
cmpq 0x318(%rcx), %rax
jbe 0x3051a
movq -0x80(%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, -0x88(%rbp)
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rdi
movq -0x88(%rbp), %rsi
callq 0x3390
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x308(%rax)
movq -0x80(%rbp), %rcx
addq $0x1, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x310(%rax)
movq -0x8(%rbp), %rax
movq 0x440(%rax), %rax
movq -0x8(%rbp), %rcx
movq 0x438(%rcx), %rcx
subq %rcx, %rax
movl %eax, %edx
movq -0x8(%rbp), %rax
movq 0x308(%rax), %rax
movq -0x80(%rbp), %rcx
movl %edx, (%rax,%rcx,4)
movq -0x8(%rbp), %rdi
movl $0x177, %esi            # imm = 0x177
callq 0x2bae0
movq -0x8(%rbp), %rdi
movl -0x30(%rbp), %eax
movzwl %ax, %esi
callq 0x2bae0
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %eax
movzwl %ax, %esi
callq 0x2bae0
movl -0x28(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x8c(%rbp)
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
shll %esi
callq 0x32ff0
movq %rax, -0x98(%rbp)
movl $0x0, -0x9c(%rbp)
movl -0x9c(%rbp), %eax
cmpl -0x28(%rbp), %eax
jge 0x305e9
movq -0x10(%rbp), %rax
movl 0x60(%rax), %eax
movw %ax, %dx
movq -0x98(%rbp), %rax
movslq -0x9c(%rbp), %rcx
movw %dx, (%rax,%rcx,2)
movl -0x9c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x9c(%rbp)
jmp 0x305b1
movl $0x0, -0xa0(%rbp)
movl -0xa0(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x64(%rcx), %eax
jge 0x3065d
movq -0x10(%rbp), %rax
addq $0x68, %rax
movslq -0xa0(%rbp), %rcx
shlq $0x4, %rcx
addq %rcx, %rax
movl 0x8(%rax), %eax
movw %ax, %dx
movq -0x98(%rbp), %rax
movq -0x10(%rbp), %rcx
addq $0x68, %rcx
movslq -0xa0(%rbp), %rsi
shlq $0x4, %rsi
addq %rsi, %rcx
movq (%rcx), %rcx
movslq -0x8c(%rbp), %rsi
andq %rsi, %rcx
movw %dx, (%rax,%rcx,2)
movl -0xa0(%rbp), %eax
addl $0x1, %eax
movl %eax, -0xa0(%rbp)
jmp 0x305f3
jmp 0x306b1
movq -0x8(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x10(%rbp), %rax
movl 0x64(%rax), %eax
movl %eax, -0xac(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
xorl %edx, %edx
callq 0x225c0
movq -0xb8(%rbp), %rdi
movl -0xac(%rbp), %r8d
movq %rax, %r9
leaq 0xf881(%rip), %rsi      # 0x3ff1f
movl $0xecb, %edx            # imm = 0xECB
leaq 0xfe4f(%rip), %rcx      # 0x404f9
movb $0x0, %al
callq 0x18220
addq $0xc0, %rsp
popq %rbp
retq
nopw (%rax,%rax)