// File: Lupo-CalPoly[P]cpe315-thumbsim/decode.cpp
// Function: decode(MISC_Type)
MISC_Ops decode (const MISC_Type data) {
  if (data.instr.push.op == MISC_PUSH_OP) {
    // Push is complete
    if (opts.instrs) { 
      bool multiple = FALSE;
      cout << "push ";
      cout << "{";
      if (data.instr.push.reg_list & 1) {
        cout << "r0";
        multiple = TRUE;
      }
      if (data.instr.push.reg_list & 2) {
        if (multiple)
          cout << ", ";
        cout << "r1";
        multiple = TRUE;
      }
      if (data.instr.push.reg_list & 4) {
        if (multiple)
          cout << ", ";
        cout << "r2";
        multiple = TRUE;
      }
      if (data.instr.push.reg_list & 8) {
        if (multiple)
          cout << ", ";
        cout << "r3";
        multiple = TRUE;
      }
      if (data.instr.push.reg_list & 16) {
        if (multiple)
          cout << ", ";
        cout << "r4";
        multiple = TRUE;
      }
      if (data.instr.push.reg_list & 32) {
        if (multiple)
          cout << ", ";
        cout << "r5";
        multiple = TRUE;
      }
      if (data.instr.push.reg_list & 64) {
        if (multiple)
          cout << ", ";
        cout << "r6";
        multiple = TRUE;
      }
      if (data.instr.push.reg_list & 128) {
        if (multiple)
          cout << ", ";
        cout << "r7";
        multiple = TRUE;
      }
      if (data.instr.push.m) {
        if (multiple)
          cout << ", ";
        cout << "lr";
      }
      cout << "}" << endl;
    }
    return MISC_PUSH;
  }
  else if (data.instr.pop.op == MISC_POP_OP) {
    // Pop is complete
    if (opts.instrs) { 
      bool multiple = FALSE;
      cout << "pop ";
      cout << "{";
      if (data.instr.pop.reg_list & 1) {
        cout << "r0";
        multiple = TRUE;
      }
      if (data.instr.pop.reg_list & 2) {
        if (multiple)
          cout << ", ";
        cout << "r1";
        multiple = TRUE;
      }
      if (data.instr.pop.reg_list & 4) {
        if (multiple)
          cout << ", ";
        cout << "r2";
        multiple = TRUE;
      }
      if (data.instr.pop.reg_list & 8) {
        if (multiple)
          cout << ", ";
        cout << "r3";
        multiple = TRUE;
      }
      if (data.instr.pop.reg_list & 16) {
        if (multiple)
          cout << ", ";
        cout << "r4";
        multiple = TRUE;
      }
      if (data.instr.pop.reg_list & 32) {
        if (multiple)
          cout << ", ";
        cout << "r5";
        multiple = TRUE;
      }
      if (data.instr.pop.reg_list & 64) {
        if (multiple)
          cout << ", ";
        cout << "r6";
        multiple = TRUE;
      }
      if (data.instr.pop.reg_list & 128) {
        if (multiple)
          cout << ", ";
        cout << "r7";
        multiple = TRUE;
      }
      if (data.instr.pop.m) {
        if (multiple)
          cout << ", ";
        cout << "pc";
      }
      cout << "}" << endl;
    }
    return MISC_POP;
  }
  else if (data.instr.sub.op == MISC_SUB_OP) {
    // complete
    if (opts.instrs) { 
      cout << "sub sp, #";
      cout << setbase(10) << (static_cast<unsigned int>(data.instr.sub.imm)<< 2) << endl;
    } 
    return MISC_SUB;
  }
  else if (data.instr.add.op == MISC_ADD_OP) {
    // complete
    if (opts.instrs) { 
      cout << "add sp, #";
      cout << setbase(10) << (static_cast<unsigned int>(data.instr.add.imm)<< 2) << endl;
    } 
    return MISC_ADD;
  }
  else if (data.instr.class_type.type_check == ADD_SP8I_TYPE) {
    // complete
    if (opts.instrs) { 
      cout << "add sp, #" << setbase(10) << (data.instr.add.imm<<2)<< endl;
    }
    return MISC_ADD;
  }
  cout << "[ERROR] Unknown Instruction to be decoded" << endl;
  exit(1);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movw %di, %ax
movw %ax, -0x6(%rbp)
movw -0x6(%rbp), %ax
shrw $0x9, %ax
andw $0x7, %ax
movzwl %ax, %eax
cmpl $0x2, %eax
jne 0x76cf
leaq 0xde56(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x76c3
movb $0x0, -0x7(%rbp)
movq 0xdb85(%rip), %rdi      # 0x14fc8
leaq 0x6dfc(%rip), %rsi      # 0xe246
callq 0x21d0
movq 0xdb72(%rip), %rdi      # 0x14fc8
leaq 0x6def(%rip), %rsi      # 0xe24c
callq 0x21d0
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x748c
movq 0xdb4c(%rip), %rdi      # 0x14fc8
leaq 0x6dcb(%rip), %rsi      # 0xe24e
callq 0x21d0
movb $0x1, -0x7(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x74cf
testb $0x1, -0x7(%rbp)
je 0x74b8
movq 0xdb1c(%rip), %rdi      # 0x14fc8
leaq 0x6c91(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xdb09(%rip), %rdi      # 0x14fc8
leaq 0x6d8b(%rip), %rsi      # 0xe251
callq 0x21d0
movb $0x1, -0x7(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x7512
testb $0x1, -0x7(%rbp)
je 0x74fb
movq 0xdad9(%rip), %rdi      # 0x14fc8
leaq 0x6c4e(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xdac6(%rip), %rdi      # 0x14fc8
leaq 0x6d4b(%rip), %rsi      # 0xe254
callq 0x21d0
movb $0x1, -0x7(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x7555
testb $0x1, -0x7(%rbp)
je 0x753e
movq 0xda96(%rip), %rdi      # 0x14fc8
leaq 0x6c0b(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xda83(%rip), %rdi      # 0x14fc8
leaq 0x6d0b(%rip), %rsi      # 0xe257
callq 0x21d0
movb $0x1, -0x7(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x7598
testb $0x1, -0x7(%rbp)
je 0x7581
movq 0xda53(%rip), %rdi      # 0x14fc8
leaq 0x6bc8(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xda40(%rip), %rdi      # 0x14fc8
leaq 0x6ccb(%rip), %rsi      # 0xe25a
callq 0x21d0
movb $0x1, -0x7(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x75db
testb $0x1, -0x7(%rbp)
je 0x75c4
movq 0xda10(%rip), %rdi      # 0x14fc8
leaq 0x6b85(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd9fd(%rip), %rdi      # 0x14fc8
leaq 0x6c8b(%rip), %rsi      # 0xe25d
callq 0x21d0
movb $0x1, -0x7(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x761e
testb $0x1, -0x7(%rbp)
je 0x7607
movq 0xd9cd(%rip), %rdi      # 0x14fc8
leaq 0x6b42(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd9ba(%rip), %rdi      # 0x14fc8
leaq 0x6c4b(%rip), %rsi      # 0xe260
callq 0x21d0
movb $0x1, -0x7(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x7663
testb $0x1, -0x7(%rbp)
je 0x764c
movq 0xd988(%rip), %rdi      # 0x14fc8
leaq 0x6afd(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd975(%rip), %rdi      # 0x14fc8
leaq 0x6c09(%rip), %rsi      # 0xe263
callq 0x21d0
movb $0x1, -0x7(%rbp)
movw -0x6(%rbp), %ax
shrw $0x8, %ax
andw $0x1, %ax
cmpw $0x0, %ax
je 0x76a1
testb $0x1, -0x7(%rbp)
je 0x768e
movq 0xd946(%rip), %rdi      # 0x14fc8
leaq 0x6abb(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd933(%rip), %rdi      # 0x14fc8
leaq 0x6bca(%rip), %rsi      # 0xe266
callq 0x21d0
movq 0xd920(%rip), %rdi      # 0x14fc8
leaq 0x6bba(%rip), %rsi      # 0xe269
callq 0x21d0
movq %rax, %rdi
movq 0xd8f2(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x6, -0x4(%rbp)
jmp 0x7b40
movw -0x6(%rbp), %ax
shrw $0x9, %ax
andw $0x7, %ax
movzwl %ax, %eax
cmpl $0x6, %eax
jne 0x798f
leaq 0xdb96(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x7983
movb $0x0, -0x8(%rbp)
movq 0xd8c5(%rip), %rdi      # 0x14fc8
leaq 0x6b61(%rip), %rsi      # 0xe26b
callq 0x21d0
movq 0xd8b2(%rip), %rdi      # 0x14fc8
leaq 0x6b2f(%rip), %rsi      # 0xe24c
callq 0x21d0
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x774c
movq 0xd88c(%rip), %rdi      # 0x14fc8
leaq 0x6b0b(%rip), %rsi      # 0xe24e
callq 0x21d0
movb $0x1, -0x8(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x778f
testb $0x1, -0x8(%rbp)
je 0x7778
movq 0xd85c(%rip), %rdi      # 0x14fc8
leaq 0x69d1(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd849(%rip), %rdi      # 0x14fc8
leaq 0x6acb(%rip), %rsi      # 0xe251
callq 0x21d0
movb $0x1, -0x8(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x77d2
testb $0x1, -0x8(%rbp)
je 0x77bb
movq 0xd819(%rip), %rdi      # 0x14fc8
leaq 0x698e(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd806(%rip), %rdi      # 0x14fc8
leaq 0x6a8b(%rip), %rsi      # 0xe254
callq 0x21d0
movb $0x1, -0x8(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x8, %eax
cmpl $0x0, %eax
je 0x7815
testb $0x1, -0x8(%rbp)
je 0x77fe
movq 0xd7d6(%rip), %rdi      # 0x14fc8
leaq 0x694b(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd7c3(%rip), %rdi      # 0x14fc8
leaq 0x6a4b(%rip), %rsi      # 0xe257
callq 0x21d0
movb $0x1, -0x8(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x10, %eax
cmpl $0x0, %eax
je 0x7858
testb $0x1, -0x8(%rbp)
je 0x7841
movq 0xd793(%rip), %rdi      # 0x14fc8
leaq 0x6908(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd780(%rip), %rdi      # 0x14fc8
leaq 0x6a0b(%rip), %rsi      # 0xe25a
callq 0x21d0
movb $0x1, -0x8(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x20, %eax
cmpl $0x0, %eax
je 0x789b
testb $0x1, -0x8(%rbp)
je 0x7884
movq 0xd750(%rip), %rdi      # 0x14fc8
leaq 0x68c5(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd73d(%rip), %rdi      # 0x14fc8
leaq 0x69cb(%rip), %rsi      # 0xe25d
callq 0x21d0
movb $0x1, -0x8(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x40, %eax
cmpl $0x0, %eax
je 0x78de
testb $0x1, -0x8(%rbp)
je 0x78c7
movq 0xd70d(%rip), %rdi      # 0x14fc8
leaq 0x6882(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd6fa(%rip), %rdi      # 0x14fc8
leaq 0x698b(%rip), %rsi      # 0xe260
callq 0x21d0
movb $0x1, -0x8(%rbp)
movw -0x6(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
andl $0x80, %eax
cmpl $0x0, %eax
je 0x7923
testb $0x1, -0x8(%rbp)
je 0x790c
movq 0xd6c8(%rip), %rdi      # 0x14fc8
leaq 0x683d(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd6b5(%rip), %rdi      # 0x14fc8
leaq 0x6949(%rip), %rsi      # 0xe263
callq 0x21d0
movb $0x1, -0x8(%rbp)
movw -0x6(%rbp), %ax
shrw $0x8, %ax
andw $0x1, %ax
cmpw $0x0, %ax
je 0x7961
testb $0x1, -0x8(%rbp)
je 0x794e
movq 0xd686(%rip), %rdi      # 0x14fc8
leaq 0x67fb(%rip), %rsi      # 0xe144
callq 0x21d0
movq 0xd673(%rip), %rdi      # 0x14fc8
leaq 0x6914(%rip), %rsi      # 0xe270
callq 0x21d0
movq 0xd660(%rip), %rdi      # 0x14fc8
leaq 0x68fa(%rip), %rsi      # 0xe269
callq 0x21d0
movq %rax, %rdi
movq 0xd632(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0xb, -0x4(%rbp)
jmp 0x7b40
movw -0x6(%rbp), %ax
shrw $0x7, %ax
andw $0x1f, %ax
movzwl %ax, %eax
cmpl $0x1, %eax
jne 0x7a10
leaq 0xd8da(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x7a04
movq 0xd611(%rip), %rdi      # 0x14fc8
leaq 0x68b5(%rip), %rsi      # 0xe273
callq 0x21d0
movl $0xa, %edi
callq 0x7fb0
movl %eax, -0xc(%rbp)
movl -0xc(%rbp), %esi
movq 0xd5ee(%rip), %rdi      # 0x14fc8
callq 0x2190
movq %rax, %rdi
movw -0x6(%rbp), %ax
andw $0x7f, %ax
movzwl %ax, %esi
shll $0x2, %esi
callq 0x22b0
movq %rax, %rdi
movq 0xd5b1(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x1, -0x4(%rbp)
jmp 0x7b40
movw -0x6(%rbp), %ax
shrw $0x7, %ax
andw $0x1f, %ax
movzwl %ax, %eax
cmpl $0x0, %eax
jne 0x7a91
leaq 0xd859(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x7a85
movq 0xd590(%rip), %rdi      # 0x14fc8
leaq 0x683e(%rip), %rsi      # 0xe27d
callq 0x21d0
movl $0xa, %edi
callq 0x7fb0
movl %eax, -0x10(%rbp)
movl -0x10(%rbp), %esi
movq 0xd56d(%rip), %rdi      # 0x14fc8
callq 0x2190
movq %rax, %rdi
movw -0x6(%rbp), %ax
andw $0x7f, %ax
movzwl %ax, %esi
shll $0x2, %esi
callq 0x22b0
movq %rax, %rdi
movq 0xd530(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x0, -0x4(%rbp)
jmp 0x7b40
movw -0x6(%rbp), %ax
shrw $0xc, %ax
movzwl %ax, %eax
cmpl $0x16, %eax
jne 0x7b0c
leaq 0xd7dc(%rip), %rax      # 0x15284
testb $0x1, 0x2(%rax)
je 0x7b03
movq 0xd513(%rip), %rdi      # 0x14fc8
leaq 0x67c1(%rip), %rsi      # 0xe27d
callq 0x21d0
movq %rax, -0x20(%rbp)
movl $0xa, %edi
callq 0x7fb0
movq -0x20(%rbp), %rdi
movl %eax, -0x14(%rbp)
movl -0x14(%rbp), %esi
callq 0x2190
movq %rax, %rdi
movw -0x6(%rbp), %ax
andw $0x7f, %ax
movzwl %ax, %esi
shll $0x2, %esi
callq 0x2360
movq %rax, %rdi
movq 0xd4b2(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x0, -0x4(%rbp)
jmp 0x7b40
jmp 0x7b0e
jmp 0x7b10
jmp 0x7b12
jmp 0x7b14
movq 0xd4ad(%rip), %rdi      # 0x14fc8
leaq 0x6698(%rip), %rsi      # 0xe1ba
callq 0x21d0
movq %rax, %rdi
movq 0xd47f(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x1, %edi
callq 0x2260
movl -0x4(%rbp), %eax
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)