// File: /workspace/github_cpp_makefile_star2_O1/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 %r15
pushq %r14
pushq %rbx
pushq %rax
movl %edi, %ebx
movzwl %bx, %eax
movl %eax, %ecx
shrl $0xc, %ecx
addl $-0x5, %ecx
cmpl $0x4, %ecx
ja 0x39ab
leaq 0x2adc(%rip), %rdx      # 0x6174
movslq (%rdx,%rcx,4), %rcx
addq %rdx, %rcx
jmpq *%rcx
shrl $0x9, %ebx
andl $0x7, %ebx
cmpw $0x7, %bx
je 0x39ab
movl $0x55, %eax
btl %ebx, %eax
jae 0x39ab
movzwl %bx, %eax
leaq 0x2af7(%rip), %rcx      # 0x61c0
movl (%rcx,%rax,4), %r14d
jmp 0x399d
shrl $0xb, %eax
movl $0xb, %r14d
cmpw $0xf, %ax
je 0x399d
cmpl $0xe, %eax
jne 0x39ab
movl $0xa, %r14d
jmp 0x399d
btl $0xb, %ebx
leaq 0x5ad0(%rip), %rax      # 0x91d4
movb 0x2(%rax), %al
jb 0x3806
testb %al, %al
je 0x39ab
movq 0x58b4(%rip), %r14      # 0x8fd0
leaq 0x2b4b(%rip), %rsi      # 0x626e
movl $0x5, %edx
movq %r14, %rdi
callq 0x2170
movl %ebx, %esi
shrl $0x8, %esi
andl $0x7, %esi
movq %r14, %rdi
callq 0x20c0
movq %rax, %r14
leaq 0x2b37(%rip), %rsi      # 0x6281
movl $0x8, %edx
movq %rax, %rdi
callq 0x2170
movq (%r14), %rax
movq -0x18(%rax), %rax
movl 0x18(%r14,%rax), %ecx
andl $-0x4b, %ecx
orl $0x2, %ecx
movl %ecx, 0x18(%r14,%rax)
movzbl %bl, %esi
movq %r14, %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x2af6(%rip), %rsi      # 0x6279
movl $0x1, %edx
movq %rax, %rdi
callq 0x2170
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20d0
movl $0xe, %r14d
jmp 0x399d
movl %ebx, %eax
shrl $0x9, %eax
andl $0x7, %eax
cmpw $0x4, %ax
je 0x38bb
testl %eax, %eax
jne 0x39ab
leaq 0x59f1(%rip), %rax      # 0x91d4
movl $0x8, %r14d
cmpb $0x1, 0x2(%rax)
jne 0x399d
movq 0x57d6(%rip), %r15      # 0x8fd0
leaq 0x2a6d(%rip), %rsi      # 0x626e
jmp 0x38e0
testb %al, %al
je 0x39ab
movq 0x57bb(%rip), %r14      # 0x8fd0
leaq 0x2a5f(%rip), %rsi      # 0x627b
movl $0x5, %edx
movq %r14, %rdi
callq 0x2170
movl %ebx, %esi
shrl $0x8, %esi
andl $0x7, %esi
movq %r14, %rdi
callq 0x20c0
movq %rax, %r14
leaq 0x2a3e(%rip), %rsi      # 0x6281
movl $0x8, %edx
movq %rax, %rdi
callq 0x2170
movq (%r14), %rax
movq -0x18(%rax), %rax
movl 0x18(%r14,%rax), %ecx
andl $-0x4b, %ecx
orl $0x2, %ecx
movl %ecx, 0x18(%r14,%rax)
movzbl %bl, %esi
movq %r14, %rdi
callq 0x20c0
movq %rax, %rbx
leaq 0x29fd(%rip), %rsi      # 0x6279
movl $0x1, %edx
movq %rax, %rdi
callq 0x2170
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20d0
movl $0xf, %r14d
jmp 0x399d
leaq 0x5912(%rip), %rax      # 0x91d4
movl $0x9, %r14d
cmpb $0x1, 0x2(%rax)
jne 0x399d
movq 0x56f7(%rip), %r15      # 0x8fd0
leaq 0x299b(%rip), %rsi      # 0x627b
movl $0x5, %edx
movq %r15, %rdi
callq 0x2170
movl %ebx, %esi
andl $0x7, %esi
movq %r15, %rdi
callq 0x20c0
movq %rax, %r15
leaq 0x2970(%rip), %rsi      # 0x6274
movl $0x4, %edx
movq %rax, %rdi
callq 0x2170
movl %ebx, %esi
shrl $0x3, %esi
andl $0x7, %esi
movq %r15, %rdi
callq 0x20c0
movq %rax, %r15
leaq 0x29b7(%rip), %rsi      # 0x62e2
movl $0x3, %edx
movq %rax, %rdi
callq 0x2170
movq (%r15), %rax
movq -0x18(%rax), %rax
movl 0x18(%r15,%rax), %ecx
andl $-0x4b, %ecx
orl $0x2, %ecx
movl %ecx, 0x18(%r15,%rax)
shrl $0x4, %ebx
andl $0x7c, %ebx
movq %r15, %rdi
movl %ebx, %esi
callq 0x2210
movq %rax, %rbx
leaq 0x2910(%rip), %rsi      # 0x6279
movl $0x1, %edx
movq %rax, %rdi
callq 0x2170
movq (%rbx), %rax
movq -0x18(%rax), %rdi
addq %rbx, %rdi
movl $0xa, %esi
callq 0x2120
movsbl %al, %esi
movq %rbx, %rdi
callq 0x2030
movq %rax, %rdi
callq 0x20d0
movl %r14d, %eax
addq $0x8, %rsp
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
movq 0x561e(%rip), %rdi      # 0x8fd0
leaq 0x2845(%rip), %rsi      # 0x61fe
callq 0x2130
movq %rax, %rdi
callq 0x2090
movl $0x1, %edi
callq 0x2180