// File: /workspace/github_c_makefile_star2_O0/naleksiev[P]fin/src/fin_mod.c
// Function: fin_mod_compile_func
static void fin_mod_compile_func(fin_mod_func_t* out_func, fin_ctx_t* ctx, fin_mod_t* mod, fin_ast_func_t* func) {
    FIN_LOG("\n");
    FIN_LOG("func %s\n", fin_str_cstr(out_func->sign));

    fin_mod_compiler_t cmp;
    cmp.mod = mod;
    cmp.func = func;
    cmp.locals_count = 0;
    cmp.locals_max = 0;
    cmp.params_count = 0;
    cmp.scopes_count = 0;
    cmp.ret_type = fin_str_clone(out_func->ret_type);
    fin_mod_code_init(&cmp.code);

    for (fin_ast_param_t* param = func->params; param; param = param->next) {
        fin_mod_local_t* l = &cmp.locals[cmp.locals_count++];
        l->name = param->name;
        l->type = param->type->name;
        l->idx = cmp.params_count++;
        l->is_param = true;
    }

    fin_mod_compile_stmt(ctx, &cmp, &func->block->base);
    if (cmp.code.top == cmp.code.begin || cmp.code.top[-1] != fin_op_return) {
        fin_mod_code_emit_uint8(ctx, &cmp.code, fin_op_return);
        FIN_LOG("\tret\n");
    }

    out_func->code_length = (int32_t)(cmp.code.top - cmp.code.begin);
    out_func->code = (uint8_t*)ctx->alloc(NULL, out_func->code_length);
    memcpy(out_func->code, cmp.code.begin, out_func->code_length);
    out_func->locals = cmp.locals_max - cmp.params_count;

    fin_mod_code_reset(ctx, &cmp.code);

    FIN_LOG("\n");
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1a70, %rsp           # imm = 0x1A70
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movq %rcx, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x1a58(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x1a50(%rbp)
movb $0x0, -0x28(%rbp)
movb $0x0, -0x27(%rbp)
movb $0x0, -0x26(%rbp)
movb $0x0, -0x25(%rbp)
movq -0x8(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0xb130
movq %rax, -0x1a48(%rbp)
leaq -0x1a58(%rbp), %rdi
addq $0x18, %rdi
callq 0x8570
movq -0x20(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x1a60(%rbp)
cmpq $0x0, -0x1a60(%rbp)
je 0x816f
leaq -0x1a58(%rbp), %rax
addq $0x130, %rax            # imm = 0x130
movb -0x28(%rbp), %cl
movb %cl, %dl
addb $0x1, %dl
movb %dl, -0x28(%rbp)
movzbl %cl, %ecx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x1a68(%rbp)
movq -0x1a60(%rbp), %rax
movq (%rax), %rcx
movq -0x1a68(%rbp), %rax
movq %rcx, (%rax)
movq -0x1a60(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x8(%rax), %rcx
movq -0x1a68(%rbp), %rax
movq %rcx, 0x8(%rax)
movb -0x26(%rbp), %cl
movb %cl, %al
addb $0x1, %al
movb %al, -0x26(%rbp)
movq -0x1a68(%rbp), %rax
movb %cl, 0x10(%rax)
movq -0x1a68(%rbp), %rax
movb $0x1, 0x11(%rax)
movq -0x1a60(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x1a60(%rbp)
jmp 0x80d4
movq -0x10(%rbp), %rdi
movq -0x20(%rbp), %rax
movq 0x18(%rax), %rdx
leaq -0x1a58(%rbp), %rsi
callq 0x85b0
movq -0x1a40(%rbp), %rax
cmpq -0x1a38(%rbp), %rax
je 0x81a7
movq -0x1a40(%rbp), %rax
movzbl -0x1(%rax), %eax
cmpl $0xb, %eax
je 0x81c0
movq -0x10(%rbp), %rdi
leaq -0x1a58(%rbp), %rsi
addq $0x18, %rsi
movl $0xb, %edx
callq 0x8d90
movq -0x1a40(%rbp), %rax
movq -0x1a38(%rbp), %rcx
subq %rcx, %rax
movl %eax, %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0x30(%rax)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq -0x8(%rbp), %rcx
movl 0x30(%rcx), %esi
xorl %ecx, %ecx
movl %ecx, %edi
callq *%rax
movq %rax, %rcx
movq -0x8(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x8(%rbp), %rax
movq 0x28(%rax), %rdi
movq -0x1a38(%rbp), %rsi
movq -0x8(%rbp), %rax
movslq 0x30(%rax), %rdx
callq 0x31b0
movzbl -0x27(%rbp), %eax
movzbl -0x26(%rbp), %ecx
subl %ecx, %eax
movb %al, %cl
movq -0x8(%rbp), %rax
movb %cl, 0x35(%rax)
movq -0x10(%rbp), %rdi
leaq -0x1a58(%rbp), %rsi
addq $0x18, %rsi
callq 0x8de0
addq $0x1a70, %rsp           # imm = 0x1A70
popq %rbp
retq
nopw %cs:(%rax,%rax)