// File: QFSW[P]MIPS1-Simulator/src/Instructions.cpp
// Function: Clarkitechture::MIPS::BinaryDecoder::decodeRInstruction(unsigned int)
RInstruction* BinaryDecoder::decodeRInstruction(uint32_t bin)
{
	byte rs = 0b11111 & (bin >> (32 - (6 + 5)));
	byte rt = 0b11111 & (bin >> (32 - (6 + 5 + 5)));
	byte rd = 0b11111 & (bin >> (32 - (6 + 5 + 5 + 5)));
	byte shamt = 0b11111 & (bin >> (32 - (6 + 5 + 5 + 5 + 5)));
	byte funct = 0b111111 & bin;

	switch (funct)
	{
    case 0b100000: return new ADDInstr(rs, rt, rd, shamt);
    case 0b100001: return new ADDUInstr(rs, rt, rd, shamt);
    case 0b100010: return new SUBInstr(rs, rt, rd, shamt);
    case 0b100011: return new SUBUInstr(rs, rt, rd, shamt);
    case 0b100100: return new ANDInstr(rs, rt, rd, shamt);
    case 0b100101: return new ORInstr(rs, rt, rd, shamt);
    case 0b100111: return new NORInstr(rs, rt, rd, shamt);
    case 0b100110: return new XORInstr(rs, rt, rd, shamt);
    case 0b001000: return new JRInstr(rs, rt, rd, shamt);
    case 0b001001: return new JALRInstr(rs, rt, rd, shamt);
    case 0b011000: return new MULTInstr(rs, rt, rd, shamt);
    case 0b011001: return new MULTUInstr(rs, rt, rd, shamt);
    case 0b011010: return new DIVInstr(rs, rt, rd, shamt);
    case 0b011011: return new DIVUInstr(rs, rt, rd, shamt);
    case 0b010000: return new MFHIInstr(rs, rt, rd, shamt);
    case 0b010010: return new MFLOInstr(rs, rt, rd, shamt);
    case 0b010001: return new MTHIInstr(rs, rt, rd, shamt);
    case 0b010011: return new MTLOInstr(rs, rt, rd, shamt);
    case 0b101010: return new SLTInstr(rs, rt, rd, shamt);
    case 0b101011: return new SLTUInstr(rs, rt, rd, shamt);
    case 0b000000: return new SLLInstr(rs, rt, rd, shamt);
    case 0b000100: return new SLLVInstr(rs, rt, rd, shamt);
    case 0b000011: return new SRAInstr(rs, rt, rd, shamt);
    case 0b000111: return new SRAVInstr(rs, rt, rd, shamt);
    case 0b000010: return new SRLInstr(rs, rt, rd, shamt);
    case 0b000110: return new SRLVInstr(rs, rt, rd, shamt);
    default:
        throw BadInstructionDecode(bin, "invalid or unsupported function code - " + toBinStr(funct));
	}
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x160, %rsp            # imm = 0x160
movl %edi, -0xc(%rbp)
movl -0xc(%rbp), %eax
shrl $0x15, %eax
andb $0x1f, %al
movb %al, -0xd(%rbp)
movb -0xa(%rbp), %al
andb $0x1f, %al
movb %al, -0xe(%rbp)
movl -0xc(%rbp), %eax
shrl $0xb, %eax
andb $0x1f, %al
movb %al, -0xf(%rbp)
movl -0xc(%rbp), %eax
shrl $0x6, %eax
andb $0x1f, %al
movb %al, -0x10(%rbp)
movb -0xc(%rbp), %al
andb $0x3f, %al
movb %al, -0x11(%rbp)
movzbl -0x11(%rbp), %eax
movq %rax, -0x78(%rbp)
subq $0x2b, %rax
ja 0xc866
movq -0x78(%rbp), %rax
leaq 0x8968(%rip), %rcx      # 0x147f4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x80(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xd860
jmp 0xbec1
movq -0x80(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x80(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x88(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xd8c0
jmp 0xbf1c
movq -0x88(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x88(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x90(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xd920
jmp 0xbf7d
movq -0x90(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x90(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x98(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xd980
jmp 0xbfde
movq -0x98(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x98(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xa0(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xd9e0
jmp 0xc03f
movq -0xa0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xa0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xa8(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xda40
jmp 0xc0a0
movq -0xa8(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xa8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xb0(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdaa0
jmp 0xc101
movq -0xb0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xb0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xb8(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdb00
jmp 0xc162
movq -0xb8(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xb8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xc0(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdb60
jmp 0xc1c3
movq -0xc0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xc0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xc8(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdbc0
jmp 0xc224
movq -0xc8(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xc8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd0(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdc20
jmp 0xc285
movq -0xd0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xd0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xd8(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdc80
jmp 0xc2e6
movq -0xd8(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xd8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe0(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdce0
jmp 0xc347
movq -0xe0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xe0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xe8(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdd40
jmp 0xc3a8
movq -0xe8(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xe8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xf0(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdda0
jmp 0xc409
movq -0xf0(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xf0(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0xf8(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xde00
jmp 0xc46a
movq -0xf8(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0xf8(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x100(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xde60
jmp 0xc4cb
movq -0x100(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x100(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x108(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdec0
jmp 0xc52c
movq -0x108(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x108(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x110(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdf20
jmp 0xc58d
movq -0x110(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x110(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x118(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdf80
jmp 0xc5ee
movq -0x118(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x118(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x120(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xdfe0
jmp 0xc64f
movq -0x120(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x120(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x128(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xe040
jmp 0xc6b0
movq -0x128(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x128(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x130(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xe0a0
jmp 0xc711
movq -0x130(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x130(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x138(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xe100
jmp 0xc772
movq -0x138(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x138(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x140(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xe160
jmp 0xc7d3
movq -0x140(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x140(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movl $0x10, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x148(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzbl -0xf(%rbp), %ecx
movzbl -0x10(%rbp), %r8d
callq 0xe1c0
jmp 0xc834
movq -0x148(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xc931
movq -0x148(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
movl $0x10, %esi
callq 0x62b0
jmp 0xc93e
movb $0x1, -0x69(%rbp)
movl $0x50, %edi
callq 0x6140
movq %rax, -0x158(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x14c(%rbp)
movzbl -0x11(%rbp), %esi
leaq -0x68(%rbp), %rdi
callq 0xe220
jmp 0xc893
leaq 0x8179(%rip), %rsi      # 0x14a13
leaq -0x48(%rbp), %rdi
leaq -0x68(%rbp), %rdx
callq 0x7350
jmp 0xc8a9
movl -0x14c(%rbp), %esi
movq -0x158(%rbp), %rdi
leaq -0x48(%rbp), %rdx
callq 0x6b50
jmp 0xc8c1
movq -0x158(%rbp), %rdi
movb $0x0, -0x69(%rbp)
leaq 0xf605(%rip), %rsi      # 0x1bed8
leaq -0x509a(%rip), %rdx     # 0x7840
callq 0x6470
jmp 0xc947
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0xc91b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
jmp 0xc912
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x20(%rbp)
movl %eax, -0x24(%rbp)
leaq -0x48(%rbp), %rdi
callq 0x6190
leaq -0x68(%rbp), %rdi
callq 0x6190
testb $0x1, -0x69(%rbp)
jne 0xc923
jmp 0xc92f
movq -0x158(%rbp), %rdi
callq 0x61f0
jmp 0xc93e
movq -0x8(%rbp), %rax
addq $0x160, %rsp            # imm = 0x160
popq %rbp
retq
movq -0x20(%rbp), %rdi
callq 0x64b0
nopw (%rax,%rax)