// File: /workspace/github_c_makefile_star2_O0/johnvtan[P]ccccc/asm.c
// Function: fn_def_to_asm
static list_t *fn_def_to_asm(fn_def_t *fn_def) {
    if (!fn_def || !fn_def->name || !fn_def->stmts) {
        UNREACHABLE("fn_def_to_asm: malformed fn_def\n");
    }

    debug("Compiling function %s\n", string_get(fn_def->name));

    // TODO totally skipping params now
    // TODO type checking on return type, but also skipping that for now 
    list_t *ret = list_new();
    output_t *fn_label = new_label(fn_def->name, LABEL_GLOBAL);
    list_push(ret, fn_label);
    list_concat(ret, fn_callee_prologue(fn_def));
    
    // function epilogue label
    string_t *fn_epilogue = unique_label("fn_epilogue");
    output_t *epilogue_label = new_label(fn_epilogue, LABEL_STATIC);

    context_t context;
    context.return_label = fn_epilogue;
    context.iter_continue_label = NULL;
    context.iter_break_label = NULL;
    context.env = fn_def->env;

    stmt_t *curr_stmt = list_pop(fn_def->stmts);
    for (; curr_stmt; curr_stmt = list_pop(fn_def->stmts)) {
        list_t *instrs = stmt_to_instrs(curr_stmt, context);
        list_concat(ret, instrs);
    }

    // function epilogue
    list_push(ret, epilogue_label);
    list_concat(ret, fn_callee_epilogue());
    list_push(ret, instr_noarg(OP_RET));

    debug("fn_def_to_asm done\n");
    return ret;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x8(%rbp)
cmpq $0x0, -0x8(%rbp)
je 0x14db
movq -0x8(%rbp), %rax
cmpq $0x0, (%rax)
je 0x14db
movq -0x8(%rbp), %rax
cmpq $0x0, 0x10(%rax)
jne 0x1508
jmp 0x14dd
leaq 0x7b20(%rip), %rdi      # 0x9004
leaq 0x7b53(%rip), %rsi      # 0x903e
movl $0x32d, %edx            # imm = 0x32D
leaq 0x7b82(%rip), %rcx      # 0x9079
movb $0x0, %al
callq 0x1070
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x1110
jmp 0x150a
jmp 0x150c
callq 0x45f0
movq %rax, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movl $0x1, %esi
callq 0x1660
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
callq 0x46a0
movq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x8(%rbp), %rdi
callq 0x16b0
movq -0x60(%rbp), %rdi
movq %rax, %rsi
callq 0x4740
leaq 0x7b3f(%rip), %rdi      # 0x909a
callq 0x1830
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rdi
xorl %esi, %esi
callq 0x1660
movq %rax, -0x28(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x48(%rbp)
movq $0x0, -0x40(%rbp)
movq $0x0, -0x38(%rbp)
movq -0x8(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x47d0
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
je 0x1602
movq -0x50(%rbp), %rdi
leaq -0x48(%rbp), %rax
movq (%rax), %rcx
movq %rcx, (%rsp)
movq 0x8(%rax), %rcx
movq %rcx, 0x8(%rsp)
movq 0x10(%rax), %rcx
movq %rcx, 0x10(%rsp)
movq 0x18(%rax), %rax
movq %rax, 0x18(%rsp)
callq 0x18e0
movq %rax, -0x58(%rbp)
movq -0x10(%rbp), %rdi
movq -0x58(%rbp), %rsi
callq 0x4740
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x47d0
movq %rax, -0x50(%rbp)
jmp 0x15a8
movq -0x10(%rbp), %rdi
movq -0x28(%rbp), %rsi
callq 0x46a0
movq -0x10(%rbp), %rax
movq %rax, -0x70(%rbp)
callq 0x2500
movq -0x70(%rbp), %rdi
movq %rax, %rsi
callq 0x4740
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movl $0x3, %edi
callq 0x2590
movq -0x68(%rbp), %rdi
movq %rax, %rsi
callq 0x46a0
jmp 0x1648
movq -0x10(%rbp), %rax
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)