// File: johan-bjareholt[P]lua-compiler/src/convert.cc
// Function: outBlock(BBlock&, std::ostream&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>&, bool, bool)
std::string outBlock(BBlock& block, std::ostream& ss, std::set<std::string>& outputSymbols, std::set<std::string>& inputSymbols, bool exit, bool localScope){
    if (!block.label.empty()){
        return block.label;
    }
    else {
        block.label = newLabel();
        ss << std::endl;
        ss << pre_in << block.label << ":" << post_in;
        ThreeAd* last_op = nullptr;
        for (ThreeAd& op : block.instructions){
            convertThreeAd(op, ss, outputSymbols, inputSymbols, localScope);
            last_op = &op;
        }

        std::stringstream falseblock;
        std::stringstream trueblock;
        std::string bname;
        if (block.falseExit != nullptr && last_op){
            bname = outBlock(*block.falseExit, falseblock, outputSymbols, inputSymbols, exit, localScope);
            switch (last_op->op){
                case '=':
                    ss << pre_in << "jne " << bname << post_in;
                    break;
                case 'e':
                    ss << pre_in << "je " << bname << post_in;
                    break;
                case '<':
                    ss << pre_in << "jle " << bname << post_in;
                    break;
                case '>':
                    ss << pre_in << "jge " << bname << post_in;
                    break;
                default:
                    std::cout << "Unreachable block: " << bname << std::endl;
                    break;
            }
        }
        if (block.trueExit != nullptr){
            bname = outBlock(*block.trueExit, trueblock, outputSymbols, inputSymbols, exit, localScope);
            ss << pre_in << "jmp " << bname << post_in;
        }
        else if (exit){
            ss << pre_in << "jmp label_end" << post_in;
        }
        else {
            // Free local var space
            ss << pre_in << "addq $" << varoffset << ", %%rsp" << post_in;
            // Pop bp
            ss << pre_in << "popq %%rbp" << post_in;
            // Return
            ss << pre_in << "ret" << post_in;
        }
        if (block.falseExit != nullptr)
            ss << falseblock.str();
        if (block.trueExit != nullptr)
            ss << trueblock.str();

    }
    return block.label;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x570, %rsp            # imm = 0x570
movl %r9d, %eax
movq %rcx, -0x460(%rbp)
movq %rdx, %rcx
movq -0x460(%rbp), %rdx
movq %rcx, -0x458(%rbp)
movq %rsi, %rcx
movq -0x458(%rbp), %rsi
movq %rcx, -0x450(%rbp)
movq %rdi, %r9
movq -0x450(%rbp), %rdi
movq %r9, -0x448(%rbp)
movb %al, %cl
movq %r9, %rax
movq %rax, -0x440(%rbp)
movb 0x10(%rbp), %al
movq %r9, -0x8(%rbp)
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movq %r8, -0x28(%rbp)
andb $0x1, %cl
movb %cl, -0x29(%rbp)
andb $0x1, %al
movb %al, -0x2a(%rbp)
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
callq 0x3480
testb $0x1, %al
jne 0x12c30
movq -0x448(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
callq 0x3100
jmp 0x133b5
leaq -0x50(%rbp), %rdi
callq 0x116e0
movq -0x10(%rbp), %rdi
addq $0x28, %rdi
leaq -0x50(%rbp), %rsi
callq 0x3340
leaq -0x50(%rbp), %rdi
callq 0x3528
movq -0x18(%rbp), %rdi
movq 0x2b342(%rip), %rsi     # 0x3dfa0
callq 0x32a0
movq -0x18(%rbp), %rdi
leaq 0x2b762(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
callq 0x3220
movq %rax, %rdi
leaq 0x18a35(%rip), %rsi     # 0x2b6c2
callq 0x3260
movq %rax, %rdi
leaq 0x2b754(%rip), %rsi     # 0x3e3f0
callq 0x3220
movq $0x0, -0x58(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x60(%rbp)
movq -0x60(%rbp), %rdi
callq 0x9c40
movq %rax, -0x68(%rbp)
movq -0x60(%rbp), %rdi
callq 0x9c70
movq %rax, -0x70(%rbp)
leaq -0x68(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x9ca0
testb $0x1, %al
jne 0x12cde
jmp 0x12d1c
leaq -0x68(%rbp), %rdi
callq 0x9cd0
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x28(%rbp), %rcx
movb -0x2a(%rbp), %al
andb $0x1, %al
movzbl %al, %r8d
callq 0x13880
movq -0x78(%rbp), %rax
movq %rax, -0x58(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x9df0
jmp 0x12ccb
leaq -0x200(%rbp), %rdi
callq 0x31d0
leaq -0x388(%rbp), %rdi
callq 0x31d0
jmp 0x12d36
leaq -0x3b8(%rbp), %rdi
callq 0x33a0
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x1302e
cmpq $0x0, -0x58(%rbp)
je 0x1302e
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rsi
leaq -0x1f0(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movzbl -0x29(%rbp), %r9d
movzbl -0x2a(%rbp), %edi
andl $0x1, %edi
movq %rsp, %rax
movl %edi, (%rax)
andl $0x1, %r9d
leaq -0x3d8(%rbp), %rdi
callq 0x12b90
jmp 0x12d96
leaq -0x3b8(%rbp), %rdi
leaq -0x3d8(%rbp), %rsi
movq %rsi, -0x470(%rbp)
callq 0x3340
movq -0x470(%rbp), %rdi
callq 0x3528
movq -0x58(%rbp), %rax
movsbl (%rax), %eax
movl %eax, -0x464(%rbp)
subl $0x3c, %eax
je 0x12f0a
jmp 0x12dd4
movl -0x464(%rbp), %eax
subl $0x3d, %eax
je 0x12e34
jmp 0x12de1
movl -0x464(%rbp), %eax
subl $0x3e, %eax
je 0x12f75
jmp 0x12df2
movl -0x464(%rbp), %eax
subl $0x65, %eax
je 0x12e9f
jmp 0x12fdd
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x390(%rbp)
movl %eax, -0x394(%rbp)
jmp 0x13393
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x390(%rbp)
movl %eax, -0x394(%rbp)
jmp 0x1337b
movq -0x18(%rbp), %rdi
leaq 0x2b591(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x478(%rbp)
jmp 0x12e4d
movq -0x478(%rbp), %rdi
leaq 0x18973(%rip), %rsi     # 0x2b7ce
callq 0x3260
movq %rax, -0x480(%rbp)
jmp 0x12e69
movq -0x480(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x3220
movq %rax, -0x488(%rbp)
jmp 0x12e85
movq -0x488(%rbp), %rdi
leaq 0x2b55d(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x12e9a
jmp 0x1302c
movq -0x18(%rbp), %rdi
leaq 0x2b526(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x490(%rbp)
jmp 0x12eb8
movq -0x490(%rbp), %rdi
leaq 0x1890d(%rip), %rsi     # 0x2b7d3
callq 0x3260
movq %rax, -0x498(%rbp)
jmp 0x12ed4
movq -0x498(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x3220
movq %rax, -0x4a0(%rbp)
jmp 0x12ef0
movq -0x4a0(%rbp), %rdi
leaq 0x2b4f2(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x12f05
jmp 0x1302c
movq -0x18(%rbp), %rdi
leaq 0x2b4bb(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x4a8(%rbp)
jmp 0x12f23
movq -0x4a8(%rbp), %rdi
leaq 0x188a6(%rip), %rsi     # 0x2b7d7
callq 0x3260
movq %rax, -0x4b0(%rbp)
jmp 0x12f3f
movq -0x4b0(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x3220
movq %rax, -0x4b8(%rbp)
jmp 0x12f5b
movq -0x4b8(%rbp), %rdi
leaq 0x2b487(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x12f70
jmp 0x1302c
movq -0x18(%rbp), %rdi
leaq 0x2b450(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x4c0(%rbp)
jmp 0x12f8e
movq -0x4c0(%rbp), %rdi
leaq 0x18840(%rip), %rsi     # 0x2b7dc
callq 0x3260
movq %rax, -0x4c8(%rbp)
jmp 0x12faa
movq -0x4c8(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x3220
movq %rax, -0x4d0(%rbp)
jmp 0x12fc6
movq -0x4d0(%rbp), %rdi
leaq 0x2b41c(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x12fdb
jmp 0x1302c
movq 0x2afe4(%rip), %rdi     # 0x3dfc8
leaq 0x187f6(%rip), %rsi     # 0x2b7e1
callq 0x3260
movq %rax, -0x4d8(%rbp)
jmp 0x12ff9
movq -0x4d8(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x3220
movq %rax, -0x4e0(%rbp)
jmp 0x13015
movq -0x4e0(%rbp), %rdi
movq 0x2af7d(%rip), %rsi     # 0x3dfa0
callq 0x32a0
jmp 0x1302a
jmp 0x1302c
jmp 0x1302e
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x13108
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rsi
leaq -0x378(%rbp), %rdx
movq -0x20(%rbp), %rcx
movq -0x28(%rbp), %r8
movzbl -0x29(%rbp), %r9d
movzbl -0x2a(%rbp), %edi
andl $0x1, %edi
movq %rsp, %rax
movl %edi, (%rax)
andl $0x1, %r9d
leaq -0x3f8(%rbp), %rdi
callq 0x12b90
jmp 0x13077
leaq -0x3b8(%rbp), %rdi
leaq -0x3f8(%rbp), %rsi
movq %rsi, -0x4f0(%rbp)
callq 0x3340
movq -0x4f0(%rbp), %rdi
callq 0x3528
movq -0x18(%rbp), %rdi
leaq 0x2b328(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x4e8(%rbp)
jmp 0x130b6
movq -0x4e8(%rbp), %rdi
leaq 0x18731(%rip), %rsi     # 0x2b7f5
callq 0x3260
movq %rax, -0x4f8(%rbp)
jmp 0x130d2
movq -0x4f8(%rbp), %rdi
leaq -0x3b8(%rbp), %rsi
callq 0x3220
movq %rax, -0x500(%rbp)
jmp 0x130ee
movq -0x500(%rbp), %rdi
leaq 0x2b2f4(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x13103
jmp 0x13276
testb $0x1, -0x29(%rbp)
je 0x1315d
movq -0x18(%rbp), %rdi
leaq 0x2b2b7(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x508(%rbp)
jmp 0x13127
movq -0x508(%rbp), %rdi
leaq 0x186c5(%rip), %rsi     # 0x2b7fa
callq 0x3260
movq %rax, -0x510(%rbp)
jmp 0x13143
movq -0x510(%rbp), %rdi
leaq 0x2b29f(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x13158
jmp 0x13274
movq -0x18(%rbp), %rdi
leaq 0x2b268(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x518(%rbp)
jmp 0x13176
movq -0x518(%rbp), %rdi
leaq 0x18684(%rip), %rsi     # 0x2b808
callq 0x3260
movq %rax, -0x520(%rbp)
jmp 0x13192
movq -0x520(%rbp), %rdi
movl 0x2b2a5(%rip), %esi     # 0x3e444
callq 0x3490
movq %rax, -0x528(%rbp)
jmp 0x131ad
movq -0x528(%rbp), %rdi
leaq 0x18654(%rip), %rsi     # 0x2b80f
callq 0x3260
movq %rax, -0x530(%rbp)
jmp 0x131c9
movq -0x530(%rbp), %rdi
leaq 0x2b219(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x131de
movq -0x18(%rbp), %rdi
leaq 0x2b1e7(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x538(%rbp)
jmp 0x131f7
movq -0x538(%rbp), %rdi
leaq 0x18612(%rip), %rsi     # 0x2b817
callq 0x3260
movq %rax, -0x540(%rbp)
jmp 0x13213
movq -0x540(%rbp), %rdi
leaq 0x2b1cf(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x13228
movq -0x18(%rbp), %rdi
leaq 0x2b19d(%rip), %rsi     # 0x3e3d0
callq 0x3220
movq %rax, -0x548(%rbp)
jmp 0x13241
movq -0x548(%rbp), %rdi
leaq 0x185d3(%rip), %rsi     # 0x2b822
callq 0x3260
movq %rax, -0x550(%rbp)
jmp 0x1325d
movq -0x550(%rbp), %rdi
leaq 0x2b185(%rip), %rsi     # 0x3e3f0
callq 0x3220
jmp 0x13272
jmp 0x13274
jmp 0x13276
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x132e7
movq -0x18(%rbp), %rax
movq %rax, -0x558(%rbp)
leaq -0x418(%rbp), %rdi
leaq -0x200(%rbp), %rsi
callq 0x3250
jmp 0x132a1
movq -0x558(%rbp), %rdi
leaq -0x418(%rbp), %rsi
callq 0x3220
jmp 0x132b6
leaq -0x418(%rbp), %rdi
callq 0x3528
jmp 0x132e7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x390(%rbp)
movl %eax, -0x394(%rbp)
leaq -0x418(%rbp), %rdi
callq 0x3528
jmp 0x1337b
movq -0x10(%rbp), %rax
cmpq $0x0, 0x18(%rax)
je 0x13355
movq -0x18(%rbp), %rax
movq %rax, -0x560(%rbp)
leaq -0x438(%rbp), %rdi
leaq -0x388(%rbp), %rsi
callq 0x3250
jmp 0x13312
movq -0x560(%rbp), %rdi
leaq -0x438(%rbp), %rsi
callq 0x3220
jmp 0x13327
leaq -0x438(%rbp), %rdi
callq 0x3528
jmp 0x13355
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x390(%rbp)
movl %eax, -0x394(%rbp)
leaq -0x438(%rbp), %rdi
callq 0x3528
jmp 0x1337b
leaq -0x3b8(%rbp), %rdi
callq 0x3528
leaq -0x388(%rbp), %rdi
callq 0x31e0
leaq -0x200(%rbp), %rdi
callq 0x31e0
jmp 0x133a1
leaq -0x3b8(%rbp), %rdi
callq 0x3528
leaq -0x388(%rbp), %rdi
callq 0x31e0
leaq -0x200(%rbp), %rdi
callq 0x31e0
jmp 0x133c5
movq -0x448(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x28, %rsi
callq 0x3100
movq -0x440(%rbp), %rax
addq $0x570, %rsp            # imm = 0x570
popq %rbp
retq
movq -0x390(%rbp), %rdi
callq 0x34b0
nopw %cs:(%rax,%rax)