// File: /workspace/github_c_makefile_star2_O2/naleksiev[P]fin/src/fin_mod.c
// Function: fin_mod_compile_stmt
static void fin_mod_compile_stmt(fin_ctx_t* ctx, fin_mod_compiler_t* cmp, fin_ast_stmt_t* stmt) {
    switch (stmt->type) {
        case fin_ast_stmt_type_expr: {
            fin_ast_expr_stmt_t* expr_stmt = (fin_ast_expr_stmt_t*)stmt;
            fin_mod_compile_expr(ctx, cmp, expr_stmt->expr);
            break;
        }
        case fin_ast_stmt_type_ret: {
            fin_ast_ret_stmt_t* ret_stmt = (fin_ast_ret_stmt_t*)stmt;
            if (ret_stmt->expr) {
                if (ret_stmt->expr->type == fin_ast_expr_type_init)
                    fin_mod_compile_init_expr(ctx, cmp, (fin_ast_init_expr_t*)ret_stmt->expr, cmp->ret_type);
                else
                    fin_mod_compile_expr(ctx, cmp, ret_stmt->expr);
            }
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_return);
            FIN_LOG("\tret\n");
            break;
        }
        case fin_ast_stmt_type_if: {
            fin_ast_if_stmt_t* if_stmt = (fin_ast_if_stmt_t*)stmt;
            fin_mod_compile_expr(ctx, cmp, if_stmt->cond);
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch_if_n);
            uint8_t* lbl_else = cmp->code.top;
            fin_mod_code_emit_uint16(ctx, &cmp->code, 0);
            FIN_LOG("\tbr_if_n     lbl_%d\n", (int32_t)(lbl_else - cmp->code.begin));
            fin_mod_scope_begin(cmp);
            fin_mod_compile_stmt(ctx, cmp, if_stmt->true_stmt);
            fin_mod_scope_end(cmp);
            if (if_stmt->false_stmt) {
                fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch);
                uint8_t* lbl_end = cmp->code.top;
                fin_mod_code_emit_uint16(ctx, &cmp->code, 0);
                FIN_LOG("\tbr          lbl_%d\n", (int32_t)(lbl_end - cmp->code.begin));
                FIN_LOG("lbl_%d:\n", (int32_t)(lbl_else - cmp->code.begin));
                uint16_t offset = cmp->code.top - lbl_else - 2;
                *lbl_else++ = offset & 0xFF;
                *lbl_else++ = (offset >> 8) & 0xFF;
                fin_mod_scope_begin(cmp);
                fin_mod_compile_stmt(ctx, cmp, if_stmt->false_stmt);
                fin_mod_scope_end(cmp);
                FIN_LOG("lbl_%d:\n", (int32_t)(lbl_end - cmp->code.begin));
                offset = cmp->code.top - lbl_end - 2;
                *lbl_end++ = offset & 0xFF;
                *lbl_end++ = (offset >> 8) & 0xFF;
            }
            else {
                FIN_LOG("lbl_%d:\n", (int32_t)(lbl_else - cmp->code.begin));
                uint16_t offset = cmp->code.top - lbl_else - 2;
                *lbl_else++ = offset & 0xFF;
                *lbl_else++ = (offset >> 8) & 0xFF;
            }
            break;
        }
        case fin_ast_stmt_type_for: {
            fin_ast_for_stmt_t* for_stmt = (fin_ast_for_stmt_t*)stmt;
            fin_mod_scope_begin(cmp);
            fin_mod_compile_expr(ctx, cmp, for_stmt->init);
            uint8_t* lbl_loop = cmp->code.top;
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_loop - cmp->code.begin));
            fin_mod_compile_expr(ctx, cmp, for_stmt->cond);
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch_if_n);
            uint8_t* lbl_end = cmp->code.top;
            fin_mod_code_emit_uint16(ctx, &cmp->code, 0);
            FIN_LOG("\tbr_if_n     lbl_%d\n", (int32_t)(lbl_end - cmp->code.begin));
            fin_mod_scope_begin(cmp);
            fin_mod_compile_stmt(ctx, cmp, for_stmt->stmt);
            fin_mod_scope_end(cmp);
            fin_mod_compile_expr(ctx, cmp, for_stmt->loop);
            uint16_t offset = lbl_loop - cmp->code.top - 3;
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch);
            fin_mod_code_emit_uint16(ctx, &cmp->code, offset);
            FIN_LOG("\tbr          lbl_%d\n", (int32_t)(lbl_loop - cmp->code.begin));
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_end - cmp->code.begin));
            offset = cmp->code.top - lbl_end - 2;
            *lbl_end++ = offset & 0xFF;
            *lbl_end++ = (offset >> 8) & 0xFF;
            fin_mod_scope_end(cmp);
            break;
        }
        case fin_ast_stmt_type_while: {
            fin_ast_while_stmt_t* while_stmt = (fin_ast_while_stmt_t*)stmt;
            fin_mod_scope_begin(cmp);
            uint8_t* lbl_loop = cmp->code.top;
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_loop - cmp->code.begin));
            fin_mod_compile_expr(ctx, cmp, while_stmt->cond);
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch_if_n);
            uint8_t* lbl_end = cmp->code.top;
            fin_mod_code_emit_uint16(ctx, &cmp->code, 0);
            FIN_LOG("\tbr_if_n     lbl_%d\n", (int32_t)(lbl_end - cmp->code.begin));
            fin_mod_scope_begin(cmp);
            fin_mod_compile_stmt(ctx, cmp, while_stmt->stmt);
            fin_mod_scope_end(cmp);
            uint16_t offset = lbl_loop - cmp->code.top - 3;
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch);
            fin_mod_code_emit_uint16(ctx, &cmp->code, offset);
            FIN_LOG("\tbr          lbl_%d\n", (int32_t)(lbl_loop - cmp->code.begin));
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_end - cmp->code.begin));
            offset = cmp->code.top - lbl_end - 2;
            *lbl_end++ = offset & 0xFF;
            *lbl_end++ = (offset >> 8) & 0xFF;
            fin_mod_scope_end(cmp);
            break;
        }
        case fin_ast_stmt_type_do: {
            fin_ast_do_stmt_t* do_stmt = (fin_ast_do_stmt_t*)stmt;
            uint8_t* lbl_loop = cmp->code.top;
            FIN_LOG("lbl_%d:\n", (int32_t)(lbl_loop - cmp->code.begin));
            fin_mod_scope_begin(cmp);
            fin_mod_compile_stmt(ctx, cmp, do_stmt->stmt);
            fin_mod_scope_end(cmp);
            fin_mod_compile_expr(ctx, cmp, do_stmt->cond);
            fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_branch_if);
            FIN_LOG("\tbr_if       lbl_%d\n", (int32_t)(lbl_loop - cmp->code.begin));
            uint16_t offset = lbl_loop - cmp->code.top - 2;
            fin_mod_code_emit_uint16(ctx, &cmp->code, offset);
            break;
        }
        case fin_ast_stmt_type_decl: {
            fin_ast_decl_stmt_t* decl_stmt = (fin_ast_decl_stmt_t*)stmt;
            assert(!fin_mod_resolve_local(cmp, decl_stmt->name));
            fin_mod_local_t* local = &cmp->locals[cmp->locals_count++];
            local->name = decl_stmt->name;
            local->type = decl_stmt->type->name;
            local->idx = cmp->locals_count - cmp->params_count - 1;
            local->is_param = false;
            if (decl_stmt->init) {
                if (decl_stmt->init->type == fin_ast_expr_type_init)
                    fin_mod_compile_init_expr(ctx, cmp, (fin_ast_init_expr_t*)decl_stmt->init, decl_stmt->type->name);
                else
                    fin_mod_compile_expr(ctx, cmp, decl_stmt->init);
                fin_mod_code_emit_uint8(ctx, &cmp->code, fin_op_store_local);
                fin_mod_code_emit_uint8(ctx, &cmp->code, local->idx);
                FIN_LOG("\tstore_loc  %2d\n", local->idx);
            }
            break;
        }
        case fin_ast_stmt_type_block: {
            fin_ast_block_stmt_t* block_stmt = (fin_ast_block_stmt_t*)stmt;
            fin_mod_scope_begin(cmp);
            for (fin_ast_stmt_t* s = block_stmt->stmts; s; s = s->next)
                fin_mod_compile_stmt(ctx, cmp, s);
            fin_mod_scope_end(cmp);
            break;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl (%rdx), %eax
cmpq $0x7, %rax
ja 0x64c0
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x328a(%rip), %rcx      # 0x9340
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x655f
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
leaq 0x18(%rbx), %r12
movl 0x18(%rbx), %r13d
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x655f
pushq $0xa
popq %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x653a
movq 0x18(%rbx), %rax
movq %rax, -0x30(%rbp)
movq %r14, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x6c2d
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x18(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x608c
movq %rbx, %rdi
callq 0x6c5e
jmp 0x62ff
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x655f
leaq 0x18(%rbx), %r12
pushq $0xa
popq %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x653a
movq 0x18(%rbx), %r13
movq %r14, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x6c2d
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x18(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x608c
movq %rbx, %rdi
callq 0x6c5e
cmpq $0x0, 0x20(%r15)
je 0x64b1
pushq $0x8
popq %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x653a
movq 0x18(%rbx), %rax
movq %rax, -0x30(%rbp)
movq %r14, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x6c2d
movl 0x18(%rbx), %eax
subl %r13d, %eax
addl $-0x2, %eax
movw %ax, (%r13)
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x20(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x608c
movq %rbx, %rdi
callq 0x6c5e
movl 0x18(%rbx), %eax
movq -0x30(%rbp), %rcx
subl %ecx, %eax
addl $-0x2, %eax
movw %ax, (%rcx)
jmp 0x64c0
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x655f
leaq 0x18(%rbx), %r12
movl 0x18(%rbx), %r13d
movq 0x18(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x655f
pushq $0xa
popq %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x653a
movq 0x18(%rbx), %rax
movq %rax, -0x30(%rbp)
movq %r14, %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x6c2d
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x28(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x608c
movq %rbx, %rdi
callq 0x6c5e
movq 0x20(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x655f
subl 0x18(%rbx), %r13d
addl $-0x3, %r13d
pushq $0x8
popq %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x653a
movzwl %r13w, %edx
movq %r14, %rdi
movq %r12, %rsi
callq 0x6c2d
movl 0x18(%rbx), %eax
movq -0x30(%rbp), %rcx
subl %ecx, %eax
addl $-0x2, %eax
movw %ax, (%rcx)
movq %rbx, %rdi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6c5e
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
addq $0x10, %r15
movq (%r15), %r15
testq %r15, %r15
je 0x6333
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x608c
addq $0x8, %r15
jmp 0x636a
movq 0x10(%r15), %rdx
testq %rdx, %rdx
je 0x64da
cmpl $0xb, (%rdx)
jne 0x64cf
movq 0x10(%rbx), %rcx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6b03
jmp 0x64da
leaq 0x18(%rbx), %r12
movl 0x18(%rbx), %r13d
movb 0x1a30(%rbx), %al
movzbl 0x1a33(%rbx), %ecx
leal 0x1(%rcx), %edx
movb %dl, 0x1a33(%rbx)
movb %al, 0x1930(%rbx,%rcx)
movq 0x10(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x608c
movq %rbx, %rdi
callq 0x6c5e
movq 0x18(%r15), %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x655f
pushq $0x9
popq %rdx
movq %r14, %rdi
movq %r12, %rsi
callq 0x653a
subl 0x18(%rbx), %r13d
addl $-0x2, %r13d
movzwl %r13w, %edx
movq %r14, %rdi
movq %r12, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x6c2d
movq 0x18(%r15), %r12
movq %rbx, %rdi
movq %r12, %rsi
callq 0x6c96
testq %rax, %rax
jne 0x651b
movzbl 0x1a30(%rbx), %edx
leal 0x1(%rdx), %eax
movb %al, 0x1a30(%rbx)
imulq $0x18, %rdx, %rax
movq %r12, 0x130(%rbx,%rax)
movq 0x10(%r15), %rcx
movq 0x8(%rcx), %rcx
movq %rcx, 0x138(%rbx,%rax)
movb 0x1a32(%rbx), %sil
subb %sil, %dl
movb %dl, 0x140(%rbx,%rax)
movb $0x0, 0x141(%rbx,%rax)
movq 0x20(%r15), %rdx
testq %rdx, %rdx
je 0x64c0
leaq (%rbx,%rax), %r15
addq $0x130, %r15            # imm = 0x130
cmpl $0xb, (%rdx)
jne 0x64e3
movq %r14, %rdi
movq %rbx, %rsi
callq 0x6b03
jmp 0x64ee
movl (%r12), %eax
subl %r13d, %eax
addl $-0x2, %eax
movw %ax, (%r13)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %r14, %rdi
movq %rbx, %rsi
callq 0x655f
addq $0x18, %rbx
pushq $0xb
popq %rdx
jmp 0x6505
movq %r14, %rdi
movq %rbx, %rsi
callq 0x655f
addq $0x18, %rbx
pushq $0x4
popq %rdx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x653a
movzbl 0x10(%r15), %edx
movq %r14, %rdi
movq %rbx, %rsi
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x653a
leaq 0x2f6e(%rip), %rdi      # 0x9490
leaq 0x2f29(%rip), %rsi      # 0x9452
leaq 0x2f8d(%rip), %rcx      # 0x94bd
movl $0x29d, %edx            # imm = 0x29D
callq 0x3120