// File: taurheim[P]AgNES/irGenerator.cpp
// Function: IRGenerator::genTACFunction(ASTNode*)
void IRGenerator::genTACFunction(ASTNode * func) {
    IdentifierNode * functionName = (IdentifierNode*) func->children[1];
    intermediateCode.push_back({ IR_NEWLABEL, functionName->name});

    // TODO this doesn't support variables with different sizes
    intermediateCode.push_back({ IR_BEGINFUNC, functionName->name });
    auto beginFuncRef = std::prev(intermediateCode.end());
    int startingRegisterCount = registerCount;

    ASTNode * functionBody = func->children[3];
    for(auto & statement : functionBody->children) {
        genTACStatement(statement);
    }

    // How many locals are there
    std::string localsCount = std::to_string((registerCount - startingRegisterCount));
    intermediateCode.push_back({ IR_ENDFUNC, localsCount });
    // Now that we know how many labels are used
    (*beginFuncRef).second = localsCount;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1f0, %rsp            # imm = 0x1F0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x1d0(%rbp)
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movl $0x1, %esi
callq 0x19310
movq %rax, %rcx
movq -0x1d0(%rbp), %rax
movq (%rcx), %rcx
movq %rcx, -0x18(%rbp)
addq $0x10, %rax
movq %rax, -0x1c8(%rbp)
movl $0x3, -0x80(%rbp)
leaq -0x78(%rbp), %rdi
movq -0x18(%rbp), %rsi
addq $0x20, %rsi
callq 0x3140
leaq -0x58(%rbp), %rdi
callq 0x3410
leaq -0x38(%rbp), %rdi
callq 0x3410
movq -0x1c8(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x1e430
jmp 0x1dea8
leaq -0x80(%rbp), %rdi
callq 0x94e0
movq -0x1d0(%rbp), %rax
addq $0x10, %rax
movq %rax, -0x1d8(%rbp)
movl $0x7, -0xf8(%rbp)
leaq -0xf0(%rbp), %rdi
movq -0x18(%rbp), %rsi
addq $0x20, %rsi
callq 0x3140
leaq -0xd0(%rbp), %rdi
callq 0x3410
leaq -0xb0(%rbp), %rdi
callq 0x3410
movq -0x1d8(%rbp), %rdi
leaq -0xf8(%rbp), %rsi
callq 0x1e430
jmp 0x1df0e
leaq -0xf8(%rbp), %rdi
callq 0x94e0
movq -0x1d0(%rbp), %rdi
addq $0x10, %rdi
callq 0xca00
movq %rax, -0x108(%rbp)
movq -0x108(%rbp), %rdi
movl $0x1, %esi
callq 0x1e470
movq %rax, %rcx
movq -0x1d0(%rbp), %rax
movq %rcx, -0x100(%rbp)
movl 0x8(%rax), %eax
movl %eax, -0x10c(%rbp)
movq -0x10(%rbp), %rdi
addq $0x8, %rdi
movl $0x3, %esi
callq 0x19310
movq (%rax), %rax
movq %rax, -0x118(%rbp)
movq -0x118(%rbp), %rax
addq $0x8, %rax
movq %rax, -0x120(%rbp)
movq -0x120(%rbp), %rdi
callq 0x14e60
movq %rax, -0x128(%rbp)
movq -0x120(%rbp), %rdi
callq 0x14ed0
movq %rax, -0x130(%rbp)
leaq -0x128(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x14e90
testb $0x1, %al
jne 0x1dfc9
jmp 0x1e043
leaq -0x128(%rbp), %rdi
callq 0x14f70
movq -0x1d0(%rbp), %rdi
movq %rax, -0x138(%rbp)
movq -0x138(%rbp), %rax
movq (%rax), %rsi
callq 0x1ce40
leaq -0x128(%rbp), %rdi
callq 0x14f90
jmp 0x1dfb0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x80(%rbp), %rdi
callq 0x94e0
jmp 0x1e146
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0xf8(%rbp), %rdi
callq 0x94e0
jmp 0x1e146
movq -0x1d0(%rbp), %rax
movl 0x8(%rax), %esi
movl -0x10c(%rbp), %eax
subl %eax, %esi
leaq -0x158(%rbp), %rdi
movq %rdi, -0x1e8(%rbp)
callq 0x14c90
movq -0x1d0(%rbp), %rax
movq -0x1e8(%rbp), %rsi
addq $0x10, %rax
movq %rax, -0x1e0(%rbp)
movl $0x8, -0x1c0(%rbp)
leaq -0x1b8(%rbp), %rdi
callq 0x3140
jmp 0x1e099
leaq -0x198(%rbp), %rdi
callq 0x3410
leaq -0x178(%rbp), %rdi
callq 0x3410
movq -0x1e0(%rbp), %rdi
leaq -0x1c0(%rbp), %rsi
callq 0x1e430
jmp 0x1e0c6
leaq -0x1c0(%rbp), %rdi
callq 0x94e0
leaq -0x100(%rbp), %rdi
callq 0x1e4b0
movq %rax, %rdi
addq $0x28, %rdi
leaq -0x158(%rbp), %rsi
callq 0x3040
jmp 0x1e0f3
leaq -0x158(%rbp), %rdi
callq 0x31d0
addq $0x1f0, %rsp            # imm = 0x1F0
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0x1e13a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x1c0(%rbp), %rdi
callq 0x94e0
leaq -0x158(%rbp), %rdi
callq 0x31d0
movq -0x88(%rbp), %rdi
callq 0x3520
nopw %cs:(%rax,%rax)