// File: /workspace/github_c_makefile_star2_O0/cogbee[P]vmir-latest/src/vmir_wasm_parser.c
// Function: wasm_parse_block
static ir_bb_t *
wasm_parse_block(ir_unit_t *iu, ir_bb_t *ib,
                 wasm_bytestream_t *wbs, uint32_t local_var_base,
                 label_stack_frame_t *parent, int type, int depth,
                 int yield_value)
{
  unsigned int local_var;
  uint8_t rettype;
  ir_bb_t *exitblock = NULL;
  label_stack_frame_t lsf;
  lsf.parent = parent;

  switch(type) {
  case WASM_OP_BLOCK:
    lsf.label = bb_add_named(iu->iu_current_function, ib, "Block exit");
    exitblock = lsf.label;
    break;

  case WASM_OP_LOOP:
    lsf.label = bb_add_named(iu->iu_current_function, ib, "Loop start");
    unconditional_branch(ib, lsf.label);
    ib = lsf.label;
    break;

  case WASM_OP_IF:
    lsf.label = bb_add_named(iu->iu_current_function, ib, "False");
    exitblock = lsf.label;
    ir_instr_br_t *i = instr_add(ib, sizeof(ir_instr_br_t), IR_IC_BR);
    ib = bb_add_named(iu->iu_current_function, ib, "True");
    i->true_branch = ib->ib_id;
    i->false_branch = lsf.label->ib_id;
    i->condition =  vstack_pop(iu);
    break;

  default:
    abort();
  }

  while(wbs->ptr < wbs->end) {

    uint8_t code = wbs_get_byte(wbs);
    //    printf("%*.scode=%x @ 0x%zx\n", depth * 2, "", code, wbs->ptr - wbs->start);
    if(code == 0xb)
      break;

    switch(code) {
    case WASM_OP_BLOCK:
    case WASM_OP_LOOP:
    case WASM_OP_IF:
      rettype = wasm_parse_value_type(iu, wbs);
      int yielded = rettype ? value_alloc_temporary(iu, rettype).value : -1;
      ib = wasm_parse_block(iu, ib, wbs, local_var_base, &lsf, code, depth + 1,
                            yielded);
      if(yielded != -1)
        vstack_push_value(iu, yielded);
      break;

    case 0x0:
      wasm_unreachable(iu, ib);
      code = wbs_get_byte(wbs);
      while(code == 0)
        code = wbs_get_byte(wbs);
      if(code == 0xb) {
        if(depth == 0)
          return NULL;
        return exitblock;
      } else if(code != WASM_OP_ELSE) {
        parser_error(iu, "unreachable not followed by block termination");
      }
      // fallthru
    case WASM_OP_ELSE:
      if(yield_value != -1)
        wasm_set_local(iu, ib, yield_value);
      lsf.label = bb_add_named(iu->iu_current_function, ib, "Else exit");
      unconditional_branch(ib, lsf.label);
      ib = exitblock;
      exitblock = lsf.label;
      break;


    case 1:
      break;

    case 0xf:  // Return
      wasm_return(iu, ib);
      ib = bb_add_named(iu->iu_current_function, ib, "Return split");
      break;
    case 0xc:  // branch
    case 0xd:  // br_if
      ib = wasm_branch(iu, ib, code, wbs_get_vu32(wbs), &lsf);
      break;
    case 0xe:  // br_table
      ib = wasm_branch_table(iu, ib, wbs, &lsf);
      break;
    case 0x10:
    case 0x11:
      wasm_call(iu, ib, wbs, code == 0x11);
      break;
    case 0x1a:
      vstack_pop(iu);
      break;
    case 0x1b:
      wasm_select(iu, ib);
      break;
    case 0x20:
      vstack_push_value(iu, wbs_get_vu32(wbs) + local_var_base);
      break;
    case 0x21:
      wasm_set_local(iu, ib, wbs_get_vu32(wbs) + local_var_base);
      break;
    case 0x22:
      local_var = wbs_get_vu32(wbs) + local_var_base;
      wasm_set_local(iu, ib, local_var);
      vstack_push_value(iu, local_var);
      break;
    case 0x23:
      wasm_load_global(iu, ib, VECTOR_ITEM(&iu->iu_wasm_globalvar_map,
                                           wbs_get_vu32(wbs)));
      break;
    case 0x24:
      wasm_store_global(iu, ib, VECTOR_ITEM(&iu->iu_wasm_globalvar_map,
                                            wbs_get_vu32(wbs)));
      break;
    case 0x28 ... 0x35:
      wasm_load(iu, ib, code, wbs);
      break;
    case 0x36 ... 0x3e:
      wasm_store(iu, ib, code, wbs);
      break;
    case 0x41 ... 0x44:
      wasm_const(iu, code, wbs);
      break;
    case 0x45 ... 0x66:
      wasm_cmp(iu, ib, code);
      break;
    case 0x67 ... 0xa6:
      wasm_numeric(iu, ib, code);
      break;
    case 0xa7 ... 0xbf:
      wasm_convert(iu, ib, code);
      break;

    default:
      function_print(iu, iu->iu_current_function, "faildump");
      parser_error(iu, "Can't handle opcode 0x%x", code);
    }
  }

  if(yield_value != -1)
    wasm_set_local(iu, ib, yield_value);

  if(exitblock) {
    unconditional_branch(ib, exitblock);
    return exitblock;
  }
  return ib;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x110, %rsp            # imm = 0x110
movl 0x18(%rbp), %eax
movl 0x10(%rbp), %eax
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl %ecx, -0x24(%rbp)
movq %r8, -0x30(%rbp)
movl %r9d, -0x34(%rbp)
movq $0x0, -0x48(%rbp)
movq -0x30(%rbp), %rax
movq %rax, -0x50(%rbp)
movl -0x34(%rbp), %eax
movl %eax, -0x84(%rbp)
subl $0x2, %eax
je 0x20205
jmp 0x201e8
movl -0x84(%rbp), %eax
subl $0x3, %eax
je 0x20231
jmp 0x201f5
movl -0x84(%rbp), %eax
subl $0x4, %eax
je 0x2026a
jmp 0x2030f
movq -0x10(%rbp), %rax
movq 0x1c0(%rax), %rdi
movq -0x18(%rbp), %rsi
leaq 0x1ed15(%rip), %rdx     # 0x3ef30
callq 0x1fe50
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x20314
movq -0x10(%rbp), %rax
movq 0x1c0(%rax), %rdi
movq -0x18(%rbp), %rsi
leaq 0x1ecf4(%rip), %rdx     # 0x3ef3b
callq 0x1fe50
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x20150
movq -0x58(%rbp), %rax
movq %rax, -0x18(%rbp)
jmp 0x20314
movq -0x10(%rbp), %rax
movq 0x1c0(%rax), %rdi
movq -0x18(%rbp), %rsi
leaq 0x1ecc6(%rip), %rdx     # 0x3ef46
callq 0x1fe50
movq %rax, -0x58(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x48(%rbp)
movq -0x18(%rbp), %rdi
movl $0x68, %esi
movl $0x8, %edx
callq 0x20c10
movq %rax, -0x60(%rbp)
movq -0x10(%rbp), %rax
movq 0x1c0(%rax), %rdi
movq -0x18(%rbp), %rsi
leaq 0x1ec8e(%rip), %rdx     # 0x3ef4c
callq 0x1fe50
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rax
movl 0x28(%rax), %ecx
movq -0x60(%rbp), %rax
movl %ecx, 0x60(%rax)
movq -0x58(%rbp), %rax
movl 0x28(%rax), %ecx
movq -0x60(%rbp), %rax
movl %ecx, 0x64(%rax)
movq -0x60(%rbp), %rax
movq %rax, -0x90(%rbp)
movq -0x10(%rbp), %rdi
callq 0x1ea10
movq %rax, %rcx
movq -0x90(%rbp), %rax
movq %rcx, -0x68(%rbp)
movq -0x68(%rbp), %rcx
movq %rcx, 0x58(%rax)
jmp 0x20314
callq 0x3050
jmp 0x20316
movq -0x20(%rbp), %rax
movq (%rax), %rax
movq -0x20(%rbp), %rcx
cmpq 0x8(%rcx), %rax
jae 0x207db
movq -0x20(%rbp), %rdi
callq 0x1e210
movb %al, -0x69(%rbp)
movzbl -0x69(%rbp), %eax
cmpl $0xb, %eax
jne 0x20345
jmp 0x207db
movzbl -0x69(%rbp), %eax
movq %rax, -0x98(%rbp)
subq $0xbf, %rax
ja 0x20798
movq -0x98(%rbp), %rax
leaq 0x1cba2(%rip), %rcx     # 0x3cf0c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rsi
callq 0x1e260
movb %al, -0x39(%rbp)
movzbl -0x39(%rbp), %eax
cmpl $0x0, %eax
je 0x203a8
movq -0x10(%rbp), %rdi
movzbl -0x39(%rbp), %esi
callq 0x20c80
movq %rax, -0x78(%rbp)
movl -0x78(%rbp), %eax
movl %eax, -0x9c(%rbp)
jmp 0x203b5
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %eax, -0x9c(%rbp)
jmp 0x203b5
movl -0x9c(%rbp), %eax
movl %eax, -0x70(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movl -0x24(%rbp), %ecx
movzbl -0x69(%rbp), %r9d
movl 0x10(%rbp), %r10d
addl $0x1, %r10d
movl -0x70(%rbp), %eax
leaq -0x58(%rbp), %r8
movl %r10d, (%rsp)
movl %eax, 0x8(%rsp)
callq 0x201a0
movq %rax, -0x18(%rbp)
cmpl $-0x1, -0x70(%rbp)
je 0x20404
movq -0x10(%rbp), %rdi
movl -0x70(%rbp), %esi
callq 0x20f40
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x20f80
movq -0x20(%rbp), %rdi
callq 0x1e210
movb %al, -0x69(%rbp)
movzbl -0x69(%rbp), %eax
cmpl $0x0, %eax
jne 0x20439
movq -0x20(%rbp), %rdi
callq 0x1e210
movb %al, -0x69(%rbp)
jmp 0x20422
movzbl -0x69(%rbp), %eax
cmpl $0xb, %eax
jne 0x20462
cmpl $0x0, 0x10(%rbp)
jne 0x20455
movq $0x0, -0x8(%rbp)
jmp 0x20817
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x20817
movzbl -0x69(%rbp), %eax
cmpl $0x5, %eax
je 0x20489
movq -0x10(%rbp), %rdi
leaq 0x1e366(%rip), %rsi     # 0x3e7dc
movl $0x471, %edx            # imm = 0x471
leaq 0x1eacf(%rip), %rcx     # 0x3ef51
movb $0x0, %al
callq 0x18220
jmp 0x2048b
jmp 0x2048d
cmpl $-0x1, 0x18(%rbp)
je 0x204a3
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl 0x18(%rbp), %edx
callq 0x20fb0
movq -0x10(%rbp), %rax
movq 0x1c0(%rax), %rdi
movq -0x18(%rbp), %rsi
leaq 0x1eac6(%rip), %rdx     # 0x3ef7f
callq 0x1fe50
movq %rax, -0x58(%rbp)
movq -0x18(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x20150
movq -0x48(%rbp), %rax
movq %rax, -0x18(%rbp)
movq -0x58(%rbp), %rax
movq %rax, -0x48(%rbp)
jmp 0x207d6
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x20830
movq -0x10(%rbp), %rax
movq 0x1c0(%rax), %rdi
movq -0x18(%rbp), %rsi
leaq 0x1ea7d(%rip), %rdx     # 0x3ef89
callq 0x1fe50
movq %rax, -0x18(%rbp)
jmp 0x207d6
movq -0x10(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xa8(%rbp)
movzbl -0x69(%rbp), %eax
movl %eax, -0xa0(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1d450
movq -0xb0(%rbp), %rdi
movq -0xa8(%rbp), %rsi
movl -0xa0(%rbp), %edx
movl %eax, %ecx
leaq -0x58(%rbp), %r8
callq 0x21030
movq %rax, -0x18(%rbp)
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
leaq -0x58(%rbp), %rcx
callq 0x21100
movq %rax, -0x18(%rbp)
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movzbl -0x69(%rbp), %eax
cmpl $0x11, %eax
sete %al
andb $0x1, %al
movzbl %al, %ecx
callq 0x21230
jmp 0x207d6
movq -0x10(%rbp), %rdi
callq 0x1ea10
movq %rax, -0x80(%rbp)
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x21400
jmp 0x207d6
movq -0x10(%rbp), %rax
movq %rax, -0xb8(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1d450
movq -0xb8(%rbp), %rdi
movl %eax, %esi
addl -0x24(%rbp), %esi
callq 0x20f40
jmp 0x207d6
movq -0x10(%rbp), %rax
movq %rax, -0xc8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1d450
movq -0xc8(%rbp), %rdi
movq -0xc0(%rbp), %rsi
movl %eax, %edx
addl -0x24(%rbp), %edx
callq 0x20fb0
jmp 0x207d6
movq -0x20(%rbp), %rdi
callq 0x1d450
addl -0x24(%rbp), %eax
movl %eax, -0x38(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x38(%rbp), %edx
callq 0x20fb0
movq -0x10(%rbp), %rdi
movl -0x38(%rbp), %esi
callq 0x20f40
jmp 0x207d6
movq -0x10(%rbp), %rax
movq %rax, -0xe0(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x10(%rbp), %rax
movq 0x598(%rax), %rax
movq %rax, -0xd0(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1d450
movq -0xe0(%rbp), %rdi
movq -0xd8(%rbp), %rsi
movl %eax, %ecx
movq -0xd0(%rbp), %rax
movl %ecx, %ecx
movq (%rax,%rcx,8), %rdx
callq 0x214c0
jmp 0x207d6
movq -0x10(%rbp), %rax
movq %rax, -0xf8(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq -0x10(%rbp), %rax
movq 0x598(%rax), %rax
movq %rax, -0xe8(%rbp)
movq -0x20(%rbp), %rdi
callq 0x1d450
movq -0xf8(%rbp), %rdi
movq -0xf0(%rbp), %rsi
movl %eax, %ecx
movq -0xe8(%rbp), %rax
movl %ecx, %ecx
movq (%rax,%rcx,8), %rdx
callq 0x21560
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movzbl -0x69(%rbp), %edx
movq -0x20(%rbp), %rcx
callq 0x215d0
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movzbl -0x69(%rbp), %edx
movq -0x20(%rbp), %rcx
callq 0x21810
jmp 0x207d6
movq -0x10(%rbp), %rdi
movzbl -0x69(%rbp), %esi
movq -0x20(%rbp), %rdx
callq 0x1efb0
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movzbl -0x69(%rbp), %edx
callq 0x21950
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movzbl -0x69(%rbp), %edx
callq 0x21c00
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movzbl -0x69(%rbp), %edx
callq 0x21ea0
jmp 0x207d6
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x1c0(%rax), %rsi
leaq 0x1e7e8(%rip), %rdx     # 0x3ef96
callq 0x22140
movq -0x10(%rbp), %rdi
movzbl -0x69(%rbp), %r8d
leaq 0x1e019(%rip), %rsi     # 0x3e7dc
movl $0x4be, %edx            # imm = 0x4BE
leaq 0x1e5ad(%rip), %rcx     # 0x3ed7c
movb $0x0, %al
callq 0x18220
jmp 0x20316
cmpl $-0x1, 0x18(%rbp)
je 0x207f1
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl 0x18(%rbp), %edx
callq 0x20fb0
cmpq $0x0, -0x48(%rbp)
je 0x2080f
movq -0x18(%rbp), %rdi
movq -0x48(%rbp), %rsi
callq 0x20150
movq -0x48(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0x20817
movq -0x18(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x110, %rsp            # imm = 0x110
popq %rbp
retq
nopw %cs:(%rax,%rax)