// File: QFSW[P]MIPS1-Simulator/src/Instructions.cpp
// Function: Clarkitechture::MIPS::BinaryDecoder::decodeBranchInstruction(unsigned int)
BranchIInstruction* BinaryDecoder::decodeBranchInstruction(uint32_t bin)
{
    byte rs = 0b11111 & (bin >> (32 - (6 + 5)));
    byte cond = 0b11111 & (bin >> (32 - (6 + 5 + 5)));
    uint16_t constant = 0xFFFF & bin;
    
    switch (cond)
    {
        case 0b00001: return new BGEZInstr(rs, cond, constant);
        case 0b10001: return new BGEZALInstr(rs, cond, constant);
        case 0b00000: return new BLTZInstr(rs, cond, constant);
        case 0b10000: return new BLTZALInstr(rs, cond, constant);
        default:
            throw BadInstructionDecode(bin, "invalid or unsupported branch condition - " + toBinStr(cond));
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
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)
movw -0xc(%rbp), %ax
movw %ax, -0x10(%rbp)
movzbl -0xe(%rbp), %eax
movq %rax, -0x70(%rbp)
subq $0x11, %rax
ja 0xd50d
movq -0x70(%rbp), %rax
leaq 0x75aa(%rip), %rcx      # 0x14950
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x18, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x78(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzwl -0x10(%rbp), %ecx
callq 0xeb80
jmp 0xd3d6
movq -0x78(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd5d8
movq -0x78(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x18, %esi
callq 0x62b0
jmp 0xd5e5
movl $0x18, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x80(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzwl -0x10(%rbp), %ecx
callq 0xebe0
jmp 0xd429
movq -0x80(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd5d8
movq -0x80(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x18, %esi
callq 0x62b0
jmp 0xd5e5
movl $0x18, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x88(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzwl -0x10(%rbp), %ecx
callq 0xec40
jmp 0xd47f
movq -0x88(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd5d8
movq -0x88(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x18, %esi
callq 0x62b0
jmp 0xd5e5
movl $0x18, %edi
callq 0x62a0
movq %rax, %rdi
movq %rdi, %rax
movq %rax, -0x90(%rbp)
movzbl -0xd(%rbp), %esi
movzbl -0xe(%rbp), %edx
movzwl -0x10(%rbp), %ecx
callq 0xeca0
jmp 0xd4db
movq -0x90(%rbp), %rax
movq %rax, -0x8(%rbp)
jmp 0xd5d8
movq -0x90(%rbp), %rdi
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
movl $0x18, %esi
callq 0x62b0
jmp 0xd5e5
movb $0x1, -0x61(%rbp)
movl $0x50, %edi
callq 0x6140
movq %rax, -0xa0(%rbp)
movl -0xc(%rbp), %eax
movl %eax, -0x94(%rbp)
movzbl -0xe(%rbp), %esi
leaq -0x60(%rbp), %rdi
callq 0xe220
jmp 0xd53a
leaq 0x751b(%rip), %rsi      # 0x14a5c
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x7350
jmp 0xd550
movl -0x94(%rbp), %esi
movq -0xa0(%rbp), %rdi
leaq -0x40(%rbp), %rdx
callq 0x6b50
jmp 0xd568
movq -0xa0(%rbp), %rdi
movb $0x0, -0x61(%rbp)
leaq 0xe95e(%rip), %rsi      # 0x1bed8
leaq -0x5d41(%rip), %rdx     # 0x7840
callq 0x6470
jmp 0xd5ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0xd5c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
jmp 0xd5b9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x18(%rbp)
movl %eax, -0x1c(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x6190
leaq -0x60(%rbp), %rdi
callq 0x6190
testb $0x1, -0x61(%rbp)
jne 0xd5ca
jmp 0xd5d6
movq -0xa0(%rbp), %rdi
callq 0x61f0
jmp 0xd5e5
movq -0x8(%rbp), %rax
addq $0xa0, %rsp
popq %rbp
retq
movq -0x18(%rbp), %rdi
callq 0x64b0
nop