// File: /workspace/github_cpp_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xa8, %rsp
movq %rdi, %r15
movq %rsi, -0xa8(%rbp)
movq 0x8(%rsi), %rax
movq 0x8(%rax), %r13
leaq 0x10(%rdi), %r14
leaq -0x90(%rbp), %rdi
movl $0x3, -0x8(%rdi)
leaq -0x80(%rbp), %rbx
movq %rbx, -0x10(%rbx)
movq 0x20(%r13), %rsi
movq 0x28(%r13), %rdx
addq %rsi, %rdx
callq 0x6906
leaq -0x60(%rbp), %rcx
movq %rcx, -0x10(%rcx)
xorl %eax, %eax
movq %rax, -0x8(%rcx)
movb %al, (%rcx)
leaq -0x40(%rbp), %r12
movq %r12, -0x10(%r12)
movq %rax, -0x8(%r12)
movb %al, (%r12)
leaq -0x98(%rbp), %rdx
movq %r14, %rdi
movq %r14, -0x30(%rbp)
movq %r14, %rsi
callq 0xe2c0
movq -0x50(%rbp), %rdi
cmpq %r12, %rdi
je 0xdb56
callq 0x3250
movq -0x70(%rbp), %rdi
leaq -0x60(%rbp), %rax
cmpq %rax, %rdi
je 0xdb68
callq 0x3250
movq -0x90(%rbp), %rdi
cmpq %rbx, %rdi
je 0xdb79
callq 0x3250
leaq -0x90(%rbp), %r14
movl $0x7, -0x8(%r14)
movq %rbx, (%r14)
movq 0x20(%r13), %rsi
movq 0x28(%r13), %rdx
addq %rsi, %rdx
movq %r14, %rdi
callq 0x6906
leaq -0x60(%rbp), %rax
movq %rax, 0x20(%r14)
xorl %eax, %eax
movq %rax, 0x28(%r14)
movb %al, 0x30(%r14)
movq %r12, 0x40(%r14)
movq %rax, 0x48(%r14)
movb %al, 0x50(%r14)
leaq -0x98(%rbp), %rdx
movq -0x30(%rbp), %rdi
movq %rdi, %rsi
callq 0xe2c0
movq -0x50(%rbp), %rdi
cmpq %r12, %rdi
je 0xdbdd
callq 0x3250
movq -0x70(%rbp), %rdi
leaq -0x60(%rbp), %rax
cmpq %rax, %rdi
je 0xdbef
callq 0x3250
movq -0x90(%rbp), %rdi
cmpq %rbx, %rdi
je 0xdc00
callq 0x3250
movq 0x18(%r15), %rax
movq %rax, -0xa0(%rbp)
movl 0x8(%r15), %r14d
movq -0xa8(%rbp), %rax
movq 0x8(%rax), %rax
movq 0x18(%rax), %rax
movq 0x8(%rax), %r13
movq 0x10(%rax), %rbx
movl %r14d, %r12d
cmpq %rbx, %r13
je 0xdc47
movq (%r13), %rsi
movq %r15, %rdi
callq 0xcd06
addq $0x8, %r13
cmpq %rbx, %r13
jne 0xdc2e
movl 0x8(%r15), %r12d
subl %r14d, %r12d
movl %r12d, %r15d
negl %r15d
cmovsl %r12d, %r15d
movl $0x1, %r13d
cmpl $0xa, %r15d
leaq -0x80(%rbp), %rbx
jb 0xdcae
movl $0x4, %r13d
movl $0xd1b71759, %eax       # imm = 0xD1B71759
movl %r15d, %ecx
cmpl $0x63, %ecx
jbe 0xdca5
cmpl $0x3e7, %ecx            # imm = 0x3E7
jbe 0xdcab
cmpl $0x2710, %ecx           # imm = 0x2710
jb 0xdcae
movl %ecx, %edx
imulq %rax, %rdx
shrq $0x2d, %rdx
addl $0x4, %r13d
cmpl $0x1869f, %ecx          # imm = 0x1869F
movl %edx, %ecx
ja 0xdc72
addl $-0x3, %r13d
jmp 0xdcae
addl $-0x2, %r13d
jmp 0xdcae
decl %r13d
shrl $0x1f, %r12d
leal (%r12,%r13), %esi
leaq -0xb8(%rbp), %rax
movq %rax, -0x10(%rax)
leaq -0xc8(%rbp), %r14
movq %r14, %rdi
movl $0x2d, %edx
callq 0x32e0
addq (%r14), %r12
movq %r12, %rdi
movl %r13d, %esi
movl %r15d, %edx
callq 0xa88a
leaq -0x90(%rbp), %rdi
movl $0x8, -0x8(%rdi)
movq %rbx, (%rdi)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
callq 0x6906
leaq -0x98(%rbp), %rdx
leaq -0x60(%rbp), %rax
movq %rax, 0x28(%rdx)
xorl %eax, %eax
movq %rax, 0x30(%rdx)
movb %al, 0x38(%rdx)
leaq -0x40(%rbp), %r14
movq %r14, 0x48(%rdx)
movq %rax, 0x50(%rdx)
movb %al, 0x58(%rdx)
movq -0x30(%rbp), %rdi
movq %rdi, %rsi
callq 0xe2c0
movq -0x50(%rbp), %rdi
cmpq %r14, %rdi
je 0xdd47
callq 0x3250
movq -0x70(%rbp), %rdi
leaq -0x60(%rbp), %rax
cmpq %rax, %rdi
je 0xdd59
callq 0x3250
movq -0x90(%rbp), %rdi
cmpq %rbx, %rdi
je 0xdd6a
callq 0x3250
movq -0xa0(%rbp), %rdi
addq $0x38, %rdi
leaq -0xc8(%rbp), %rsi
callq 0x3180
movq -0xc8(%rbp), %rdi
leaq -0xb8(%rbp), %rax
cmpq %rax, %rdi
je 0xdd99
callq 0x3250
addq $0xa8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0xddbe
movq %rax, %rbx
leaq -0x98(%rbp), %rdi
callq 0xe1ce
jmp 0xddc1
movq %rax, %rbx
movq -0xc8(%rbp), %rdi
leaq -0xb8(%rbp), %rax
cmpq %rax, %rdi
je 0xddec
callq 0x3250
jmp 0xddec
jmp 0xdddd
movq %rax, %rbx
leaq -0x98(%rbp), %rdi
callq 0xe1ce
movq %rbx, %rdi
callq 0x3420