// File: /workspace/github_cpp_makefile_star2_O3/QFSW[P]MIPS1-Simulator/src/Instructions.cpp
// Function: Clarkitechture::MIPS::BinaryDecoder::decodeIInstruction(unsigned int)
IInstruction* BinaryDecoder::decodeIInstruction(uint32_t bin)
{
	byte opcode = 0b111111 & (bin >> (32 - 6));
	byte rs = 0b11111 & (bin >> (32 - (6 + 5)));
	byte rt = 0b11111 & (bin >> (32 - (6 + 5 + 5)));
	uint16_t constant = 0xFFFF & bin;

	switch (opcode)
	{
	case 0b001000: return new ADDIInstr(rs, rt, constant);
    case 0b001001: return new ADDIUInstr(rs, rt, constant);
	case 0b001100: return new ANDIInstr(rs, rt, constant);
    case 0b001101: return new ORIInstr(rs, rt, constant);
    case 0b001110: return new XORIInstr(rs, rt, constant);
    case 0b001010: return new SLTIInstr(rs, rt, constant);
    case 0b001011: return new SLTIUInstr(rs, rt, constant);
    case 0b001111: return new LUIInstr(rs, rt, constant);
    case 0b100011: return new LWInstr(rs, rt, constant);
    case 0b100000: return new LBInstr(rs, rt, constant);
    case 0b100100: return new LBUInstr(rs, rt, constant);
    case 0b100001: return new LHInstr(rs, rt, constant);
    case 0b100101: return new LHUInstr(rs, rt, constant);
    case 0b101011: return new SWInstr(rs, rt, constant);
    case 0b101000: return new SBInstr(rs, rt, constant);
    case 0b101001: return new SHInstr(rs, rt, constant);
    case 0b000100: return new BEQInstr(rs, rt, constant);
    case 0b000111: return new BGTZInstr(rs, rt, constant);
    case 0b000110: return new BLEZInstr(rs, rt, constant);
    case 0b000101: return new BNEInstr(rs, rt, constant);
    case 0b100010: return new LWLInstr(rs, rt, constant);
    case 0b100110: return new LWRInstr(rs, rt, constant);
    case 0b000001: return decodeBranchInstruction(bin);
    default:
		throw BadInstructionDecode(bin, "invalid or unsupported opcode - " + toBinStr(opcode));
	}
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x48, %rsp
movl %edi, %ebx
movl %edi, %r15d
shrl $0x1a, %r15d
leal -0x1(%r15), %eax
cmpl $0x2a, %eax
ja 0x86b0
movl %ebx, %r14d
shrl $0x15, %r14d
andb $0x1f, %r14b
movl %ebx, %ebp
shrl $0x10, %ebp
andb $0x1f, %bpl
leaq 0x344b(%rip), %rcx      # 0xb7f4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl %ebx, %edi
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
jmp 0x877e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7b18(%rip), %rcx      # 0xfef8
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7d96(%rip), %rcx      # 0x10198
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7a64(%rip), %rcx      # 0xfe88
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7c3a(%rip), %rcx      # 0x10080
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7b38(%rip), %rcx      # 0xffa0
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7a36(%rip), %rcx      # 0xfec0
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x79a4(%rip), %rcx      # 0xfe50
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7a9a(%rip), %rcx      # 0xff68
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7b20(%rip), %rcx      # 0x10010
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7ba6(%rip), %rcx      # 0x100b8
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7c9c(%rip), %rcx      # 0x101d0
jmp 0x869e
movl $0x18, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7dd2(%rip), %rcx      # 0x10328
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7b78(%rip), %rcx      # 0x100f0
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7a3e(%rip), %rcx      # 0xffd8
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7a8c(%rip), %rcx      # 0x10048
jmp 0x869e
movl $0x18, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7c2a(%rip), %rcx      # 0x10208
jmp 0x869e
movl $0x18, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7ce0(%rip), %rcx      # 0x102e0
jmp 0x869e
movl $0x18, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7dde(%rip), %rcx      # 0x10400
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x78ef(%rip), %rcx      # 0xff30
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x77b8(%rip), %rcx      # 0xfe18
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7aa9(%rip), %rcx      # 0x10128
jmp 0x869e
movl $0x10, %edi
callq 0x5200
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x7ac2(%rip), %rcx      # 0x10160
addq $0x10, %rcx
movq %rcx, (%rax)
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movl $0x50, %edi
callq 0x5100
movq %rax, %r14
leaq 0x8(%rsp), %rdi
movl %r15d, %esi
callq 0x89ed
leaq 0x3272(%rip), %rsi      # 0xb943
leaq 0x28(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0x897d
movb $0x1, %bpl
leaq 0x28(%rsp), %rdx
movq %r14, %rdi
movl %ebx, %esi
callq 0x5b82
xorl %ebp, %ebp
leaq 0x76bd(%rip), %rsi      # 0xfdb8
leaq -0x2000(%rip), %rdx     # 0x6702
movq %r14, %rdi
callq 0x5380
movq %rax, %rbx
leaq 0x38(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x8728
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x5210
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x8743
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x5210
testb %bpl, %bpl
jne 0x876d
jmp 0x8775
movq %rax, %rbx
leaq 0x18(%rsp), %rax
movq -0x10(%rax), %rdi
cmpq %rax, %rdi
je 0x876d
movq 0x18(%rsp), %rsi
incq %rsi
callq 0x5210
jmp 0x876d
movq %rax, %rbx
movq %r14, %rdi
callq 0x5190
movq %rbx, %rdi
callq 0x53a0
nop