// File: /workspace/github_cpp_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x40, %rsp
movl %edi, %ebp
movl %edi, %r14d
andl $0x3f, %r14d
cmpl $0x2c, %r14d
jae 0x7879
movabsq $0xcff0f0f03dd, %rax    # imm = 0xCFF0F0F03DD
btq %r14, %rax
jae 0x7879
movl %r14d, %eax
leaq 0x8d53(%rip), %rcx      # 0x10578
movq (%rcx,%rax,8), %rbx
movl %ebp, %r14d
shrl $0x6, %r14d
andb $0x1f, %r14b
movl %ebp, %r15d
shrl $0xb, %r15d
andb $0x1f, %r15b
movl %ebp, %r12d
shrl $0x10, %r12d
andb $0x1f, %r12b
shrl $0x15, %ebp
andb $0x1f, %bpl
pushq $0x10
popq %rdi
callq 0x51f0
movb %bpl, 0x8(%rax)
movb %r12b, 0x9(%rax)
movb %r15b, 0xa(%rax)
movb %r14b, 0xb(%rax)
movq %rbx, (%rax)
addq $0x40, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
pushq $0x50
popq %rdi
callq 0x50f0
movq %rax, %rbx
movq %rsp, %rdi
movl %r14d, %esi
callq 0x7ea7
leaq 0x3085(%rip), %rsi      # 0xa91b
leaq 0x20(%rsp), %rdi
movq %rsp, %rdx
callq 0x5d89
movb $0x1, %r15b
leaq 0x20(%rsp), %rdx
movq %rbx, %rdi
movl %ebp, %esi
callq 0x586c
xorl %r15d, %r15d
leaq 0x8501(%rip), %rsi      # 0xfdc0
leaq -0x1954(%rip), %rdx     # 0x5f72
movq %rbx, %rdi
callq 0x5360
movq %rax, %r14
leaq 0x20(%rsp), %rdi
callq 0x50d0
jmp 0x78e3
movq %rax, %r14
movb $0x1, %r15b
movq %rsp, %rdi
callq 0x50d0
testb %r15b, %r15b
jne 0x78f5
jmp 0x78fd
movq %rax, %r14
movq %rbx, %rdi
callq 0x5170
movq %r14, %rdi
callq 0x5390
nop