// File: QFSW[P]MIPS1-Simulator/src/Simulator.cpp
// Function: Clarkitechture::MIPS::Simulator::loadMachineCode(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>)
void Simulator::loadMachineCode(std::string fileName)
{
    std::ifstream binstream;
    binstream.open(fileName, std::ios_base::binary | std::ios_base::in | std::ios_base::ate);
    if (!binstream.is_open()) { throw BadBinaryIO("could not open file " + fileName); }
    
    size_t size = binstream.tellg();
    if (size <= 0) { throw BadBinaryIO("file was empty"); }
    if (size % 4 > 0) { throw BadBinaryIO("file contained a non integral word count"); }
    if (size > MemoryMap::ADDR_INSTR_LENGTH) { throw BadBinaryIO("file exceeded maximum binary size"); }
    binstream.seekg(0, std::ios::beg);
    
    instrCount = size / 4;
    instrs.resize(instrCount);
    
    uint32_t* words = new uint32_t[instrCount];
    mem.initInstrMemory(reinterpret_cast<byte*>(words), size);
    binstream.read(reinterpret_cast<char*>(words), size);
    
    for (size_t i = 0; i < instrCount; ++i)
    {
        uint32_t flippedWord = __builtin_bswap32(words[i]);
        instrs[i] = std::shared_ptr<Instruction>(BinaryDecoder::decodeInstruction(flippedWord));
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x390, %rsp            # imm = 0x390
movq %rsi, -0x320(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x318(%rbp)
leaq -0x218(%rbp), %rdi
callq 0x6310
movl $0x4, %edi
movl $0x8, %esi
callq 0x11750
movl %eax, -0x30c(%rbp)
jmp 0x10cb8
movl -0x30c(%rbp), %edi
movl $0x2, %esi
callq 0x11750
movl %eax, -0x324(%rbp)
jmp 0x10cd0
movl -0x324(%rbp), %edx
movq -0x320(%rbp), %rsi
leaq -0x218(%rbp), %rdi
callq 0x6250
jmp 0x10ceb
leaq -0x218(%rbp), %rdi
callq 0x6450
movb %al, -0x325(%rbp)
jmp 0x10cff
movb -0x325(%rbp), %al
testb $0x1, %al
jne 0x10de3
jmp 0x10d0f
movb $0x1, -0x249(%rbp)
movl $0x48, %edi
callq 0x6140
movq -0x320(%rbp), %rdx
movq %rax, -0x330(%rbp)
leaq 0x41a2(%rip), %rsi      # 0x14ed7
leaq -0x248(%rbp), %rdi
callq 0x71f0
jmp 0x10d43
movq -0x330(%rbp), %rdi
leaq -0x248(%rbp), %rsi
callq 0x6d30
jmp 0x10d58
movq -0x330(%rbp), %rdi
movb $0x0, -0x249(%rbp)
leaq 0xb183(%rip), %rsi      # 0x1bef0
leaq -0x94c4(%rip), %rdx     # 0x78b0
callq 0x6470
jmp 0x11293
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x1127b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x10dc7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x248(%rbp), %rdi
callq 0x6190
testb $0x1, -0x249(%rbp)
jne 0x10dd2
jmp 0x10dde
movq -0x330(%rbp), %rdi
callq 0x61f0
jmp 0x1127b
leaq -0x218(%rbp), %rdi
callq 0x6490
movq %rdx, -0x340(%rbp)
movq %rax, -0x338(%rbp)
jmp 0x10dff
movq -0x340(%rbp), %rax
movq -0x338(%rbp), %rcx
movq %rcx, -0x268(%rbp)
movq %rax, -0x260(%rbp)
leaq -0x268(%rbp), %rdi
callq 0x11770
movq %rax, -0x348(%rbp)
jmp 0x10e30
movq -0x348(%rbp), %rax
movq %rax, -0x258(%rbp)
cmpq $0x0, -0x258(%rbp)
ja 0x10f28
movb $0x1, -0x28a(%rbp)
movl $0x48, %edi
callq 0x6140
movq %rax, -0x358(%rbp)
leaq -0x289(%rbp), %rdi
movq %rdi, -0x350(%rbp)
callq 0x64c0
movq -0x350(%rbp), %rdx
leaq 0x4067(%rip), %rsi      # 0x14eec
leaq -0x288(%rbp), %rdi
callq 0x8b50
jmp 0x10e93
movq -0x358(%rbp), %rdi
leaq -0x288(%rbp), %rsi
callq 0x6d30
jmp 0x10ea8
movq -0x358(%rbp), %rdi
movb $0x0, -0x28a(%rbp)
leaq 0xb033(%rip), %rsi      # 0x1bef0
leaq -0x9614(%rip), %rdx     # 0x78b0
callq 0x6470
jmp 0x11293
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x10f00
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x288(%rbp), %rdi
callq 0x6190
leaq -0x289(%rbp), %rdi
callq 0x62e0
testb $0x1, -0x28a(%rbp)
jne 0x10f17
jmp 0x10f23
movq -0x358(%rbp), %rdi
callq 0x61f0
jmp 0x1127b
movq -0x258(%rbp), %rax
andq $0x3, %rax
cmpq $0x0, %rax
jbe 0x11019
movb $0x1, -0x2b2(%rbp)
movl $0x48, %edi
callq 0x6140
movq %rax, -0x368(%rbp)
leaq -0x2b1(%rbp), %rdi
movq %rdi, -0x360(%rbp)
callq 0x64c0
movq -0x360(%rbp), %rdx
leaq 0x3f85(%rip), %rsi      # 0x14efb
leaq -0x2b0(%rbp), %rdi
callq 0x8b50
jmp 0x10f84
movq -0x368(%rbp), %rdi
leaq -0x2b0(%rbp), %rsi
callq 0x6d30
jmp 0x10f99
movq -0x368(%rbp), %rdi
movb $0x0, -0x2b2(%rbp)
leaq 0xaf42(%rip), %rsi      # 0x1bef0
leaq -0x9705(%rip), %rdx     # 0x78b0
callq 0x6470
jmp 0x11293
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x10ff1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x2b0(%rbp), %rdi
callq 0x6190
leaq -0x2b1(%rbp), %rdi
callq 0x62e0
testb $0x1, -0x2b2(%rbp)
jne 0x11008
jmp 0x11014
movq -0x368(%rbp), %rdi
callq 0x61f0
jmp 0x1127b
cmpq $0x1000000, -0x258(%rbp) # imm = 0x1000000
jbe 0x11106
movb $0x1, -0x2da(%rbp)
movl $0x48, %edi
callq 0x6140
movq %rax, -0x378(%rbp)
leaq -0x2d9(%rbp), %rdi
movq %rdi, -0x370(%rbp)
callq 0x64c0
movq -0x370(%rbp), %rdx
leaq 0x3ec1(%rip), %rsi      # 0x14f24
leaq -0x2d8(%rbp), %rdi
callq 0x8b50
jmp 0x11071
movq -0x378(%rbp), %rdi
leaq -0x2d8(%rbp), %rsi
callq 0x6d30
jmp 0x11086
movq -0x378(%rbp), %rdi
movb $0x0, -0x2da(%rbp)
leaq 0xae55(%rip), %rsi      # 0x1bef0
leaq -0x97f2(%rip), %rdx     # 0x78b0
callq 0x6470
jmp 0x11293
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
jmp 0x110de
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x220(%rbp)
movl %eax, -0x224(%rbp)
leaq -0x2d8(%rbp), %rdi
callq 0x6190
leaq -0x2d9(%rbp), %rdi
callq 0x62e0
testb $0x1, -0x2da(%rbp)
jne 0x110f5
jmp 0x11101
movq -0x378(%rbp), %rdi
callq 0x61f0
jmp 0x1127b
xorl %edx, %edx
movl %edx, %esi
leaq -0x218(%rbp), %rdi
callq 0x63a0
jmp 0x11118
movq -0x318(%rbp), %rax
movq -0x258(%rbp), %rcx
shrq $0x2, %rcx
movq %rcx, (%rax)
movq %rax, %rdi
addq $0x8, %rdi
movq (%rax), %rsi
callq 0x11790
jmp 0x1113e
movq -0x318(%rbp), %rax
movq (%rax), %rax
movl $0x4, %ecx
mulq %rcx
movq %rax, %rdi
movq $-0x1, %rax
cmovoq %rax, %rdi
callq 0x6030
movq %rax, -0x380(%rbp)
jmp 0x1116c
movq -0x318(%rbp), %rdi
movq -0x380(%rbp), %rax
movq %rax, -0x2e8(%rbp)
addq $0xc0, %rdi
movq -0x2e8(%rbp), %rsi
movq -0x258(%rbp), %rdx
callq 0xf370
jmp 0x1119d
movq -0x2e8(%rbp), %rsi
movq -0x258(%rbp), %rdx
leaq -0x218(%rbp), %rdi
callq 0x6370
jmp 0x111b9
movq $0x0, -0x2f0(%rbp)
movq -0x318(%rbp), %rcx
movq -0x2f0(%rbp), %rax
cmpq (%rcx), %rax
jae 0x11266
movq -0x2e8(%rbp), %rax
movq -0x2f0(%rbp), %rcx
movl (%rax,%rcx,4), %eax
bswapl %eax
movl %eax, -0x2f4(%rbp)
movl -0x2f4(%rbp), %edi
callq 0xbdc0
movq %rax, -0x388(%rbp)
jmp 0x11208
movq -0x388(%rbp), %rsi
leaq -0x308(%rbp), %rdi
callq 0x11820
jmp 0x1121d
movq -0x318(%rbp), %rdi
addq $0x8, %rdi
movq -0x2f0(%rbp), %rsi
callq 0x11850
movq %rax, %rdi
leaq -0x308(%rbp), %rsi
callq 0x11870
leaq -0x308(%rbp), %rdi
callq 0x118a0
movq -0x2f0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x2f0(%rbp)
jmp 0x111c4
leaq -0x218(%rbp), %rdi
callq 0x60a0
addq $0x390, %rsp            # imm = 0x390
popq %rbp
retq
leaq -0x218(%rbp), %rdi
callq 0x60a0
movq -0x220(%rbp), %rdi
callq 0x64b0
nopw %cs:(%rax,%rax)