// File: /workspace/github_cpp_makefile_star2_O2/taurheim[P]AgNES/codeGenerator.cpp
// Function: CodeGenerator::generateCodeFromTAC(TAC)
void CodeGenerator::generateCodeFromTAC(TAC tac) {
    switch (tac.op) {
        case IR_DECLARATION: {
            allocateGlobal(tac.first, "type");
            break;
        }
        case IR_NEWLABEL: {
            if (!jumpedToMain) {
                code << "JMP main" << nl;
                jumpedToMain = true;
            }
            code.seekp(-1, code.cur);
            code << tac.first << ":" << nl;
            break;
        } 
        case IR_BEGINFUNC: {
            generateBeginFunc(tac);
            break;
        }
        case IR_ASSIGN: {
            generateAssign(tac);
            break;
        }
        case IR_ADD: {
            generateAddition(tac);
            break;
        }
        case IR_SUBTRACT: {
            generateSubtraction(tac);
            break;
        }
        case IR_IFTRUEGOTO: {
            generateBranchOnCondition(tac, true);
            break;
        }
        case IR_IFFALSEGOTO: {
            generateBranchOnCondition(tac, false);
            break;
        }
        case IR_GOTO: {
            generateJump(tac);
            break;
        }
        case IR_PUSHPARAM: {
            generatePushParam(tac);
            break;
        }
        case IR_POPPARAMS: {
            generatePopParams(tac);
            break;
        }
        case IR_CALL: {
            generateSubroutineCall(tac);
            break;
        }
        case IR_RETURN: {
            code << "RTS" << nl;
            break;
        }
        case IR_ENDFUNC: {
            generateEndFunc(tac);
            break;
        }
        case IR_NES_WAITFORFRAME: {
            code << ";;;;;; NESWAITFORFRAME ;;;;;;" << nl;
            code << "INC 99" << nl;
            code << "wait_for_frame:" << nl;
            code << "LDA 99" << nl;
            code << "BNE wait_for_frame" << nl;
            break;
        }
        case IR_NES_SETSPRITEX: {
            code << ";;;;;; NESSETSPRITEX ;;;;;;" << nl;
            int offset = globalToAddressMap[tac.first];
            loadGlobalIntoA(offset);
            code << "STA $0203" << nl;
            break;
        }
        case IR_NES_SETSPRITEY: {
            code << ";;;;;; NESSETSPRITEY ;;;;;;" << nl;
            int offset = globalToAddressMap[tac.first];
            loadGlobalIntoA(offset);
            code << "STA $0200" << nl;
            break;
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x4c8, %rsp            # imm = 0x4C8
movl (%rsi), %eax
cmpq $0x10, %rax
ja 0xd766
movq %rsi, %r14
movq %rdi, %rbx
leaq 0x3461(%rip), %rcx      # 0x10814
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq -0x408(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xdce4
leaq -0x408(%rbp), %rdi
jmp 0xd761
leaq 0x80(%rbx), %r15
leaq 0x3512(%rip), %rsi      # 0x10905
movq %r15, %rdi
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3210
leaq 0x1f8(%rbx), %rdi
addq $0x8, %r14
movq %r14, %rsi
callq 0xebcc
movl (%rax), %esi
movq %rbx, %rdi
callq 0xe4e2
leaq 0x34f7(%rip), %rsi      # 0x10921
jmp 0xd5dd
leaq 0x80(%rbx), %r14
leaq 0x3453(%rip), %rsi      # 0x10890
movq %r14, %rdi
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3210
leaq 0x3457(%rip), %rsi      # 0x108ae
movq %r14, %rdi
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3210
leaq 0x3444(%rip), %rsi      # 0x108b5
movq %r14, %rdi
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3210
leaq 0x343a(%rip), %rsi      # 0x108c5
movq %r14, %rdi
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3210
leaq 0x3427(%rip), %rsi      # 0x108cc
movq %r14, %rdi
jmp 0xd6d2
leaq -0x198(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xe2fa
leaq -0x198(%rbp), %rdi
jmp 0xd761
leaq -0x268(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xe1ee
leaq -0x268(%rbp), %rdi
jmp 0xd761
addq $0x8, %r14
leaq -0x40(%rbp), %rdi
movq %r14, %rsi
callq 0x32e0
leaq 0x3368(%rip), %rsi      # 0x1087e
leaq -0x60(%rbp), %rdi
leaq -0x19(%rbp), %rdx
callq 0x3110
leaq -0x40(%rbp), %rsi
movq %rbx, %rdi
callq 0xd822
leaq -0x60(%rbp), %rdi
callq 0x3140
leaq -0x40(%rbp), %rdi
callq 0x3140
jmp 0xd766
leaq -0x130(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xe35e
leaq -0x130(%rbp), %rdi
jmp 0xd761
leaq -0x470(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xdac8
leaq -0x470(%rbp), %rdi
jmp 0xd761
leaq 0x80(%rbx), %r15
leaq 0x3339(%rip), %rsi      # 0x108df
movq %r15, %rdi
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3210
leaq 0x1f8(%rbx), %rdi
addq $0x8, %r14
movq %r14, %rsi
callq 0xebcc
movl (%rax), %esi
movq %rbx, %rdi
callq 0xe4e2
leaq 0x331e(%rip), %rsi      # 0x108fb
movq %r15, %rdi
jmp 0xd6d2
cmpb $0x0, 0x290(%rbx)
jne 0xd613
leaq 0x80(%rbx), %rdi
leaq 0x3287(%rip), %rsi      # 0x10883
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
callq 0x3210
movb $0x1, 0x290(%rbx)
leaq 0x80(%rbx), %r15
pushq $-0x1
popq %rsi
pushq $0x1
popq %rdx
movq %r15, %rdi
callq 0x3240
addq $0x8, %r14
movq %r15, %rdi
movq %r14, %rsi
callq 0x3210
leaq 0x3285(%rip), %rsi      # 0x108c3
movq %rax, %rdi
jmp 0xd6d2
leaq -0x4d8(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xd89a
leaq -0x4d8(%rbp), %rdi
jmp 0xd761
leaq -0x3a0(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xdee2
leaq -0x3a0(%rbp), %rdi
jmp 0xd761
leaq -0x338(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
pushq $0x1
popq %rdx
movq %rbx, %rdi
movq %r15, %rsi
callq 0xe0de
leaq -0x338(%rbp), %rdi
jmp 0xd761
leaq 0x80(%rbx), %rdi
leaq 0x31ba(%rip), %rsi      # 0x1088c
callq 0x3230
movq %rax, %rdi
movq %rbx, %rsi
addq $0x4c8, %rsp            # imm = 0x4C8
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x3210
leaq -0x2d0(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
xorl %edx, %edx
callq 0xe0de
leaq -0x2d0(%rbp), %rdi
jmp 0xd761
leaq -0x200(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xe25e
leaq -0x200(%rbp), %rdi
jmp 0xd761
leaq -0xc8(%rbp), %r15
movq %r15, %rdi
movq %r14, %rsi
callq 0x6d4c
movq %rbx, %rdi
movq %r15, %rsi
callq 0xe472
leaq -0xc8(%rbp), %rdi
callq 0x6104
addq $0x4c8, %rsp            # imm = 0x4C8
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x3140
jmp 0xd7f4
movq %rax, %rbx
leaq -0xc8(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x200(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x2d0(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x338(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x3a0(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x4d8(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x470(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x408(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x130(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x40(%rbp), %rdi
callq 0x3140
jmp 0xd81a
movq %rax, %rbx
leaq -0x268(%rbp), %rdi
jmp 0xd815
movq %rax, %rbx
leaq -0x198(%rbp), %rdi
callq 0x6104
movq %rbx, %rdi
callq 0x33e0