// File: /workspace/github_cpp_makefile_star2_O2/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 0x7c60
movl %ebx, %r14d
shrl $0x15, %r14d
andb $0x1f, %r14b
movl %ebx, %ebp
shrl $0x10, %ebp
andb $0x1f, %bpl
leaq 0x2e6f(%rip), %rcx      # 0xa7f4
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 0x7cf2
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x8546(%rip), %rcx      # 0xff00
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x87c6(%rip), %rcx      # 0x101a0
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x8496(%rip), %rcx      # 0xfe90
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x866e(%rip), %rcx      # 0x10088
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x856e(%rip), %rcx      # 0xffa8
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x846e(%rip), %rcx      # 0xfec8
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x83de(%rip), %rcx      # 0xfe58
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x84d6(%rip), %rcx      # 0xff70
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x855e(%rip), %rcx      # 0x10018
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x85e6(%rip), %rcx      # 0x100c0
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x86de(%rip), %rcx      # 0x101d8
jmp 0x7c4e
pushq $0x18
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x8816(%rip), %rcx      # 0x10330
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x85be(%rip), %rcx      # 0x100f8
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x8486(%rip), %rcx      # 0xffe0
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x84d6(%rip), %rcx      # 0x10050
jmp 0x7c4e
pushq $0x18
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x8676(%rip), %rcx      # 0x10210
jmp 0x7c4e
pushq $0x18
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x872e(%rip), %rcx      # 0x102e8
jmp 0x7c4e
pushq $0x18
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x882e(%rip), %rcx      # 0x10408
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x8341(%rip), %rcx      # 0xff38
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x820c(%rip), %rcx      # 0xfe20
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x84ff(%rip), %rcx      # 0x10130
jmp 0x7c4e
pushq $0x10
popq %rdi
callq 0x51f0
movb %r14b, 0x8(%rax)
movb %bpl, 0x9(%rax)
movw %bx, 0xa(%rax)
leaq 0x851a(%rip), %rcx      # 0x10168
addq $0x10, %rcx
movq %rcx, (%rax)
addq $0x48, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
pushq $0x50
popq %rdi
callq 0x50f0
movq %rax, %r14
leaq 0x8(%rsp), %rdi
movl %r15d, %esi
callq 0x7ea7
leaq 0x2cc4(%rip), %rsi      # 0xa943
leaq 0x28(%rsp), %rdi
leaq 0x8(%rsp), %rdx
callq 0x5d89
movb $0x1, %bpl
leaq 0x28(%rsp), %rdx
movq %r14, %rdi
movl %ebx, %esi
callq 0x586c
xorl %ebp, %ebp
leaq 0x8117(%rip), %rsi      # 0xfdc0
leaq -0x1d3e(%rip), %rdx     # 0x5f72
movq %r14, %rdi
callq 0x5360
movq %rax, %rbx
leaq 0x28(%rsp), %rdi
callq 0x50d0
jmp 0x7ccd
movq %rax, %rbx
movb $0x1, %bpl
leaq 0x8(%rsp), %rdi
callq 0x50d0
testb %bpl, %bpl
jne 0x7ce1
jmp 0x7ce9
movq %rax, %rbx
movq %r14, %rdi
callq 0x5170
movq %rbx, %rdi
callq 0x5390
nop