// File: /workspace/github_cpp_makefile_star2_O2/Lupo-CalPoly[P]cpe315-thumbsim/decode.cpp
// Function: decode(LD_ST_Type)
LD_ST_Ops decode (const LD_ST_Type data) {
  if (data.instr.class_type.opA == LD_ST_REG_OPA) {
    if (data.instr.class_type.opB == LD_ST_OPB_LDRB) {
      // 315: write code to print ldrb
      return LDRBR;
    }
    else if (data.instr.class_type.opB == LD_ST_OPB_STRB) {
      // 315: write code to print strb
      return STRBR;
    }
    else if (data.instr.class_type.opB == LD_ST_OPB_LDR) {
      // 315: write code to print ldr
      return LDRR;
    }
    else if (data.instr.class_type.opB == LD_ST_OPB_STR) {
      // 315: write code to print str
      return STRR;
    }
  }
  else if (data.instr.class_type.opA == LD_ST_IMM_OPA) {
    if (data.instr.class_type.opB == LD_ST_OPB_STR) {
      if (opts.instrs) { 
        cout << "str r" << data.instr.ld_st_imm.rt << ", [r" << data.instr.ld_st_imm.rn << ", #" << setbase(10) << (data.instr.ld_st_imm.imm*4) << "]" << endl;
      }
      return STRI;
    }
    else if (data.instr.class_type.opB == LD_ST_OPB_LDR) {
      if (opts.instrs) { 
        cout << "ldr r" << data.instr.ld_st_imm.rt << ", [r" << data.instr.ld_st_imm.rn << ", #" << setbase(10) << (data.instr.ld_st_imm.imm*4) << "]" << endl;
      }
      return LDRI;
    }
  }
  else if (data.instr.class_type.opA == LD_ST_IMMB_OPA) {
    if (data.instr.ld_st_imm.op == LD_ST_LDB) {
      // 315: write code to print ldrb 
      return LDRBI;
    }
    else if (data.instr.ld_st_imm.op == LD_ST_STB) {
      // 315: write code to print strb
      return STRBI;
    }
  }
  else if (data.instr.class_type.opA == LD_ST_IMMB_OPA) {
  }
  else if (data.instr.class_type.opA == LD_ST_IMMH_OPA) {
  }
  else if (data.instr.class_type.opA == LD_ST_IMMSP_OPA) {
    if (data.instr.ld_st_sp_imm.opB) {
      if (opts.instrs) {
        cout << "ldr r" << data.instr.ld_st_sp_imm.rt << ", [sp, #" << setbase(10) << data.instr.ld_st_sp_imm.imm << "]" << endl;
        return LDRSP;
      }
    }
    else {
      if (opts.instrs) {
        cout << "str r" << data.instr.ld_st_sp_imm.rt << ", [sp, #" << setbase(10) << data.instr.ld_st_sp_imm.imm << "]" << endl;
        return STRSP;
      }
    }
  }
  cout << "[ERROR] Unknown Instruction to be decoded" << endl;
  exit(1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r14
pushq %rbx
movl %edi, %ebx
movzwl %bx, %eax
movl %eax, %ecx
shrl $0xc, %ecx
addl $-0x5, %ecx
cmpl $0x4, %ecx
ja 0x3a7f
leaq 0x2921(%rip), %rdx      # 0x6158
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
shrl $0x9, %ebx
andl $0x7, %ebx
cmpw $0x7, %bx
je 0x3a7f
pushq $0x55
popq %rax
btl %ebx, %eax
jae 0x3a7f
movzwl %bx, %eax
leaq 0x2906(%rip), %rcx      # 0x616c
movl (%rcx,%rax,4), %r14d
jmp 0x3a77
shrl $0xb, %eax
cmpw $0xf, %ax
je 0x39cf
cmpl $0xe, %eax
jne 0x3a7f
pushq $0xa
jmp 0x39d1
btl $0xb, %ebx
leaq 0x5955(%rip), %rax      # 0x91ec
movb 0x2(%rax), %al
jb 0x395a
testb %al, %al
je 0x3a7f
movq 0x5721(%rip), %rdi      # 0x8fd0
leaq 0x299c(%rip), %rsi      # 0x6252
callq 0x2150
movl %ebx, %esi
shrl $0x8, %esi
andl $0x7, %esi
movq %rax, %rdi
callq 0x2210
leaq 0x2993(%rip), %rsi      # 0x6265
movq %rax, %rdi
callq 0x2150
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
movzbl %bl, %esi
movq %rax, %rdi
callq 0x2210
leaq 0x295c(%rip), %rsi      # 0x625d
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
callq 0x20c0
pushq $0xe
jmp 0x39d1
movl %ebx, %eax
shrl $0x9, %eax
andl $0x7, %eax
cmpw $0x4, %ax
je 0x39d8
testl %eax, %eax
jne 0x3a7f
leaq 0x58b3(%rip), %rax      # 0x91ec
pushq $0x8
popq %r14
cmpb $0x1, 0x2(%rax)
jne 0x3a77
movq 0x5682(%rip), %rdi      # 0x8fd0
leaq 0x28fd(%rip), %rsi      # 0x6252
jmp 0x39fb
testb %al, %al
je 0x3a7f
movq 0x5667(%rip), %rdi      # 0x8fd0
leaq 0x28ef(%rip), %rsi      # 0x625f
callq 0x2150
movl %ebx, %esi
shrl $0x8, %esi
andl $0x7, %esi
movq %rax, %rdi
callq 0x2210
leaq 0x28d9(%rip), %rsi      # 0x6265
movq %rax, %rdi
callq 0x2150
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
movzbl %bl, %esi
movq %rax, %rdi
callq 0x2210
leaq 0x28a2(%rip), %rsi      # 0x625d
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
callq 0x20c0
pushq $0xf
jmp 0x39d1
pushq $0xb
popq %r14
jmp 0x3a77
leaq 0x580d(%rip), %rax      # 0x91ec
pushq $0x9
popq %r14
cmpb $0x1, 0x2(%rax)
jne 0x3a77
movq 0x55dc(%rip), %rdi      # 0x8fd0
leaq 0x2864(%rip), %rsi      # 0x625f
callq 0x2150
movl %ebx, %esi
andl $0x7, %esi
movq %rax, %rdi
callq 0x2210
leaq 0x2844(%rip), %rsi      # 0x6258
movq %rax, %rdi
callq 0x2150
movl %ebx, %esi
shrl $0x3, %esi
andl $0x7, %esi
movq %rax, %rdi
callq 0x2210
leaq 0x2893(%rip), %rsi      # 0x62c6
movq %rax, %rdi
callq 0x2150
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movl 0x18(%rax,%rcx), %edx
andl $-0x4b, %edx
orl $0x2, %edx
movl %edx, 0x18(%rax,%rcx)
shrl $0x4, %ebx
andl $0x7c, %ebx
movq %rax, %rdi
movl %ebx, %esi
callq 0x2230
leaq 0x27f6(%rip), %rsi      # 0x625d
movq %rax, %rdi
callq 0x2150
movq %rax, %rdi
callq 0x20c0
movl %r14d, %eax
popq %rbx
popq %r14
popq %rbp
retq
movq 0x554a(%rip), %rdi      # 0x8fd0
leaq 0x2755(%rip), %rsi      # 0x61e2
callq 0x2150
movq %rax, %rdi
callq 0x20c0
pushq $0x1
popq %rdi
callq 0x2190