// File: 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
subq $0x40, %rsp
movw %di, %ax
movw %ax, -0x6(%rbp)
movw -0x6(%rbp), %ax
shrw $0xc, %ax
movzwl %ax, %eax
cmpl $0x5, %eax
jne 0x6fde
movw -0x6(%rbp), %ax
shrw $0x9, %ax
andw $0x7, %ax
movzwl %ax, %eax
cmpl $0x6, %eax
jne 0x6f73
movl $0x6, -0x4(%rbp)
jmp 0x73ea
movw -0x6(%rbp), %ax
shrw $0x9, %ax
andw $0x7, %ax
movzwl %ax, %eax
cmpl $0x2, %eax
jne 0x6f93
movl $0x2, -0x4(%rbp)
jmp 0x73ea
movw -0x6(%rbp), %ax
shrw $0x9, %ax
andw $0x7, %ax
movzwl %ax, %eax
cmpl $0x4, %eax
jne 0x6fb3
movl $0x4, -0x4(%rbp)
jmp 0x73ea
movw -0x6(%rbp), %ax
shrw $0x9, %ax
andw $0x7, %ax
movzwl %ax, %eax
cmpl $0x0, %eax
jne 0x6fd3
movl $0x0, -0x4(%rbp)
jmp 0x73ea
jmp 0x6fd5
jmp 0x6fd7
jmp 0x6fd9
jmp 0x73be
movw -0x6(%rbp), %ax
shrw $0xc, %ax
movzwl %ax, %eax
cmpl $0x6, %eax
jne 0x71c3
movw -0x6(%rbp), %ax
shrw $0x9, %ax
andw $0x7, %ax
movzwl %ax, %eax
cmpl $0x0, %eax
jne 0x70d7
leaq 0xe273(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x70cb
movq 0xdfa6(%rip), %rdi      # 0x14fc8
leaq 0x7201(%rip), %rsi      # 0xe22a
callq 0x21d0
movq %rax, %rdi
movw -0x6(%rbp), %ax
andw $0x7, %ax
movzwl %ax, %esi
callq 0x2340
movq %rax, %rdi
leaq 0x71e5(%rip), %rsi      # 0xe230
callq 0x21d0
movq %rax, %rdi
movw -0x6(%rbp), %ax
shrw $0x3, %ax
andw $0x7, %ax
movzwl %ax, %esi
callq 0x2340
movq %rax, %rdi
leaq 0x722d(%rip), %rsi      # 0xe29e
callq 0x21d0
movq %rax, -0x20(%rbp)
movl $0xa, %edi
callq 0x7fb0
movq -0x20(%rbp), %rdi
movl %eax, -0xc(%rbp)
movl -0xc(%rbp), %esi
callq 0x2190
movq %rax, %rdi
movw -0x6(%rbp), %ax
shrw $0x6, %ax
andw $0x1f, %ax
movzwl %ax, %esi
shll $0x2, %esi
callq 0x2360
movq %rax, %rdi
leaq 0x717e(%rip), %rsi      # 0xe235
callq 0x21d0
movq %rax, %rdi
movq 0xdeea(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x8, -0x4(%rbp)
jmp 0x73ea
movw -0x6(%rbp), %ax
shrw $0x9, %ax
andw $0x7, %ax
movzwl %ax, %eax
cmpl $0x4, %eax
jne 0x71bc
leaq 0xe18e(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x71b0
movq 0xdec1(%rip), %rdi      # 0x14fc8
leaq 0x7129(%rip), %rsi      # 0xe237
callq 0x21d0
movq %rax, %rdi
movw -0x6(%rbp), %ax
andw $0x7, %ax
movzwl %ax, %esi
callq 0x2340
movq %rax, %rdi
leaq 0x7100(%rip), %rsi      # 0xe230
callq 0x21d0
movq %rax, %rdi
movw -0x6(%rbp), %ax
shrw $0x3, %ax
andw $0x7, %ax
movzwl %ax, %esi
callq 0x2340
movq %rax, %rdi
leaq 0x7148(%rip), %rsi      # 0xe29e
callq 0x21d0
movq %rax, -0x28(%rbp)
movl $0xa, %edi
callq 0x7fb0
movq -0x28(%rbp), %rdi
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %esi
callq 0x2190
movq %rax, %rdi
movw -0x6(%rbp), %ax
shrw $0x6, %ax
andw $0x1f, %ax
movzwl %ax, %esi
shll $0x2, %esi
callq 0x2360
movq %rax, %rdi
leaq 0x7099(%rip), %rsi      # 0xe235
callq 0x21d0
movq %rax, %rdi
movq 0xde05(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x9, -0x4(%rbp)
jmp 0x73ea
jmp 0x71be
jmp 0x73bc
movw -0x6(%rbp), %ax
shrw $0xc, %ax
movzwl %ax, %eax
cmpl $0x7, %eax
jne 0x7212
movw -0x6(%rbp), %ax
shrw $0xb, %ax
movzwl %ax, %eax
cmpl $0xf, %eax
jne 0x71ef
movl $0xb, -0x4(%rbp)
jmp 0x73ea
movw -0x6(%rbp), %ax
shrw $0xb, %ax
movzwl %ax, %eax
cmpl $0xe, %eax
jne 0x720b
movl $0xa, -0x4(%rbp)
jmp 0x73ea
jmp 0x720d
jmp 0x73ba
movw -0x6(%rbp), %ax
shrw $0xc, %ax
movzwl %ax, %eax
cmpl $0x7, %eax
jne 0x7227
jmp 0x73b8
movw -0x6(%rbp), %ax
shrw $0xc, %ax
movzwl %ax, %eax
cmpl $0x8, %eax
jne 0x723c
jmp 0x73b6
movw -0x6(%rbp), %ax
shrw $0xc, %ax
movzwl %ax, %eax
cmpl $0x9, %eax
jne 0x73b4
movw -0x6(%rbp), %ax
shrw $0xb, %ax
andw $0x1, %ax
cmpw $0x0, %ax
je 0x730f
leaq 0xe017(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x730a
movq 0xdd4a(%rip), %rdi      # 0x14fc8
leaq 0x6fb2(%rip), %rsi      # 0xe237
callq 0x21d0
movq %rax, %rdi
movw -0x6(%rbp), %ax
shrw $0x8, %ax
andw $0x7, %ax
movzwl %ax, %esi
callq 0x2340
movq %rax, %rdi
leaq 0x6f92(%rip), %rsi      # 0xe23d
callq 0x21d0
movq %rax, -0x30(%rbp)
movl $0xa, %edi
callq 0x7fb0
movq -0x30(%rbp), %rdi
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %esi
callq 0x2190
movq %rax, %rdi
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %esi
callq 0x2340
movq %rax, %rdi
leaq 0x6f4b(%rip), %rsi      # 0xe235
callq 0x21d0
movq %rax, %rdi
movq 0xdcb7(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0xf, -0x4(%rbp)
jmp 0x73ea
jmp 0x73b2
leaq 0xdf6e(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x73b0
movq 0xdca1(%rip), %rdi      # 0x14fc8
leaq 0x6efc(%rip), %rsi      # 0xe22a
callq 0x21d0
movq %rax, %rdi
movw -0x6(%rbp), %ax
shrw $0x8, %ax
andw $0x7, %ax
movzwl %ax, %esi
callq 0x2340
movq %rax, %rdi
leaq 0x6ee9(%rip), %rsi      # 0xe23d
callq 0x21d0
movq %rax, -0x38(%rbp)
movl $0xa, %edi
callq 0x7fb0
movq -0x38(%rbp), %rdi
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %esi
callq 0x2190
movq %rax, %rdi
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %esi
callq 0x2340
movq %rax, %rdi
leaq 0x6ea2(%rip), %rsi      # 0xe235
callq 0x21d0
movq %rax, %rdi
movq 0xdc0e(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0xe, -0x4(%rbp)
jmp 0x73ea
jmp 0x73b2
jmp 0x73b4
jmp 0x73b6
jmp 0x73b8
jmp 0x73ba
jmp 0x73bc
jmp 0x73be
movq 0xdc03(%rip), %rdi      # 0x14fc8
leaq 0x6dee(%rip), %rsi      # 0xe1ba
callq 0x21d0
movq %rax, %rdi
movq 0xdbd5(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x1, %edi
callq 0x2260
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)