// File: QFSW[P]MIPS1-Simulator/src/MemoryMap.hpp
// Function: unsigned int Clarkitechture::MIPS::MemoryMap::read<unsigned int>(unsigned long)
T read(size_t address)
            {
                if (address % sizeof(T) > 0) { throw BadMemoryAccess(address, "read data address was misaligned"); }
                else if (address >= ADDR_GETC && address <= ADDR_GETC + 4 - sizeof(T))
                {
                    int input = std::getchar();
                    if (input == EOF || feof(stdin))
                    {
                        int error = ferror(stdin);
                        if (error) { throw BadIO("stdin", error); }
                        else { return -1; }
                    }
                    else if (address == ADDR_GETC + 4 - sizeof(T)) { return input; }
                    else { return 0; }
                }
                else if (address >= ADDR_DATA && address < ADDR_DATA + ADDR_DATA_LENGTH)
                {
                    T data = 0;
                    size_t memLocation = address - ADDR_DATA;
                    for (int i = 0; i < sizeof(T); i++)
                    {
                        int shamt = 8 * (sizeof(T) - i - 1);
                        data |= (memory[memLocation + i] << shamt);
                    }   

                    return data;
                }
                else if (address >= ADDR_INSTR && address < ADDR_INSTR + instrMemorySize)
                {
                    byte* memLocation = instrMemory + (address - ADDR_INSTR);
                    T data = *reinterpret_cast<T*>(memLocation);
                    return bswap(data);
                }
                else if (address >= ADDR_INSTR && address < ADDR_INSTR + ADDR_INSTR_LENGTH) { return 0; }
                else { throw BadMemoryAccess(address, "address was outside of the valid R/W memory range."); }
            }

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0xd8(%rbp)
movq -0x18(%rbp), %rax
andq $0x3, %rax
cmpq $0x0, %rax
jbe 0x8cfa
movb $0x1, -0x4d(%rbp)
movl $0x50, %edi
callq 0x6140
movq %rax, -0xf0(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0xe8(%rbp)
leaq -0x39(%rbp), %rdi
movq %rdi, -0xe0(%rbp)
callq 0x64c0
movq -0xe0(%rbp), %rdx
leaq 0xb772(%rip), %rsi      # 0x143e0
leaq -0x38(%rbp), %rdi
callq 0x8b50
jmp 0x8c79
movq -0xe8(%rbp), %rsi
movq -0xf0(%rbp), %rdi
leaq -0x38(%rbp), %rdx
callq 0x6970
jmp 0x8c92
movq -0xf0(%rbp), %rdi
movb $0x0, -0x4d(%rbp)
leaq 0x1321c(%rip), %rsi     # 0x1bec0
leaq -0x14db(%rip), %rdx     # 0x77d0
callq 0x6470
jmp 0x9077
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x8cd8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x6190
leaq -0x39(%rbp), %rdi
callq 0x62e0
testb $0x1, -0x4d(%rbp)
jne 0x8ce9
jmp 0x8cf5
movq -0xf0(%rbp), %rdi
callq 0x61f0
jmp 0x906e
cmpq $0x30000000, -0x18(%rbp) # imm = 0x30000000
jb 0x8e40
cmpq $0x30000000, -0x18(%rbp) # imm = 0x30000000
ja 0x8e40
callq 0x63d0
movl %eax, -0x54(%rbp)
cmpl $-0x1, -0x54(%rbp)
je 0x8d3c
movq 0x14295(%rip), %rax     # 0x1cfc0
movq (%rax), %rdi
callq 0x6420
cmpl $0x0, %eax
je 0x8e1f
movq 0x1427d(%rip), %rax     # 0x1cfc0
movq (%rax), %rdi
callq 0x64f0
movl %eax, -0x58(%rbp)
cmpl $0x0, -0x58(%rbp)
je 0x8e13
movb $0x1, -0x7a(%rbp)
movl $0x50, %edi
callq 0x6140
movq %rax, -0x100(%rbp)
leaq -0x79(%rbp), %rdi
movq %rdi, -0xf8(%rbp)
callq 0x64c0
movq -0xf8(%rbp), %rdx
leaq 0xb676(%rip), %rsi      # 0x14401
leaq -0x78(%rbp), %rdi
callq 0x8b50
jmp 0x8d96
movq -0x100(%rbp), %rdi
movl -0x58(%rbp), %edx
leaq -0x78(%rbp), %rsi
callq 0x6e20
jmp 0x8dab
movq -0x100(%rbp), %rdi
movb $0x0, -0x7a(%rbp)
leaq 0x1314b(%rip), %rsi     # 0x1bf08
leaq -0x14a4(%rip), %rdx     # 0x7920
callq 0x6470
jmp 0x9077
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x8df1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x78(%rbp), %rdi
callq 0x6190
leaq -0x79(%rbp), %rdi
callq 0x62e0
testb $0x1, -0x7a(%rbp)
jne 0x8e02
jmp 0x8e0e
movq -0x100(%rbp), %rdi
callq 0x61f0
jmp 0x906e
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x9062
cmpq $0x30000000, -0x18(%rbp) # imm = 0x30000000
jne 0x8e34
movl -0x54(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x9062
movl $0x0, -0x4(%rbp)
jmp 0x9062
cmpq $0x20000000, -0x18(%rbp) # imm = 0x20000000
jb 0x8eff
cmpq $0x24000000, -0x18(%rbp) # imm = 0x24000000
jae 0x8eff
movl $0x0, -0x80(%rbp)
movq -0x18(%rbp), %rax
subq $0x20000000, %rax       # imm = 0x20000000
movq %rax, -0x88(%rbp)
movl $0x0, -0x8c(%rbp)
movslq -0x8c(%rbp), %rax
cmpq $0x4, %rax
jae 0x8ef4
movq -0xd8(%rbp), %rdi
movslq -0x8c(%rbp), %rcx
movl $0x4, %eax
subq %rcx, %rax
subq $0x1, %rax
shlq $0x3, %rax
movl %eax, -0x90(%rbp)
movq -0x88(%rbp), %rax
movslq -0x8c(%rbp), %rcx
addq %rcx, %rax
movl %eax, -0x94(%rbp)
leaq -0x94(%rbp), %rsi
callq 0xa710
movzbl (%rax), %eax
movl -0x90(%rbp), %ecx
shll %cl, %eax
orl -0x80(%rbp), %eax
movl %eax, -0x80(%rbp)
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x8e7e
movl -0x80(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x9062
cmpq $0x10000000, -0x18(%rbp) # imm = 0x10000000
jb 0x8f66
movq -0xd8(%rbp), %rcx
movq -0x18(%rbp), %rax
movq 0x40(%rcx), %rcx
addq $0x10000000, %rcx       # imm = 0x10000000
cmpq %rcx, %rax
jae 0x8f66
movq -0xd8(%rbp), %rdi
movq 0x38(%rdi), %rax
movq -0x18(%rbp), %rcx
subq $0x10000000, %rcx       # imm = 0x10000000
addq %rcx, %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
movl (%rax), %eax
movl %eax, -0xa4(%rbp)
movl -0xa4(%rbp), %esi
callq 0xa740
movl %eax, -0x4(%rbp)
jmp 0x9062
cmpq $0x10000000, -0x18(%rbp) # imm = 0x10000000
jb 0x8f86
cmpq $0x11000000, -0x18(%rbp) # imm = 0x11000000
jae 0x8f86
movl $0x0, -0x4(%rbp)
jmp 0x9062
movb $0x1, -0xca(%rbp)
movl $0x50, %edi
callq 0x6140
movq %rax, -0x118(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x110(%rbp)
leaq -0xc9(%rbp), %rdi
movq %rdi, -0x108(%rbp)
callq 0x64c0
movq -0x108(%rbp), %rdx
leaq 0xb43d(%rip), %rsi      # 0x14407
leaq -0xc8(%rbp), %rdi
callq 0x8b50
jmp 0x8fd8
movq -0x110(%rbp), %rsi
movq -0x118(%rbp), %rdi
leaq -0xc8(%rbp), %rdx
callq 0x6970
jmp 0x8ff4
movq -0x118(%rbp), %rdi
movb $0x0, -0xca(%rbp)
leaq 0x12eb7(%rip), %rsi     # 0x1bec0
leaq -0x1840(%rip), %rdx     # 0x77d0
callq 0x6470
jmp 0x9077
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x903d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xc8(%rbp), %rdi
callq 0x6190
leaq -0xc9(%rbp), %rdi
callq 0x62e0
testb $0x1, -0xca(%rbp)
jne 0x9054
jmp 0x9060
movq -0x118(%rbp), %rdi
callq 0x61f0
jmp 0x906e
movl -0x4(%rbp), %eax
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
movq -0x48(%rbp), %rdi
callq 0x64b0
nopw (%rax,%rax)