// File: Lupo-CalPoly[P]cpe315-thumbsim/execute.cpp
// Function: execute()
void execute() {
  Data16 instr = imem[PC];
  Data16 instr2;
  Data32 temp(0); // Use this for STRB instructions
  Thumb_Types itype;
  // the following counts as a read to PC
  unsigned int pctarget = PC + 2;
  unsigned int addr;
  int i, n, offset;
  unsigned int list, mask;
  int num1, num2, result, BitCount;
  unsigned int bit;

  /* Convert instruction to correct type */
  /* Types are described in Section A5 of the armv7 manual */
  BL_Type blupper(instr);
  ALU_Type alu(instr);
  SP_Type sp(instr);
  DP_Type dp(instr);
  LD_ST_Type ld_st(instr);
  MISC_Type misc(instr);
  COND_Type cond(instr);
  UNCOND_Type uncond(instr);
  LDM_Type ldm(instr);
  STM_Type stm(instr);
  LDRL_Type ldrl(instr);
  ADD_SP_Type addsp(instr);

  BL_Ops bl_ops;
  ALU_Ops add_ops;
  DP_Ops dp_ops;
  SP_Ops sp_ops;
  LD_ST_Ops ldst_ops;
  MISC_Ops misc_ops;

  // This counts as a write to the PC register
  rf.write(PC_REG, pctarget);

  itype = decode(ALL_Types(instr));

  // CPE 315: The bulk of your work is in the following switch statement
  // All instructions will need to have stats and cache access info added
  // as appropriate for that instruction.
  switch(itype) {
    case ALU:
      add_ops = decode(alu);
      switch(add_ops) {
        case ALU_LSLI:
          break;
        case ALU_ADDR:
          // needs stats and flags
          rf.write(alu.instr.addr.rd, rf[alu.instr.addr.rn] + rf[alu.instr.addr.rm]);
          break;
        case ALU_SUBR:
          break;
        case ALU_ADD3I:
          // needs stats and flags
          rf.write(alu.instr.add3i.rd, rf[alu.instr.add3i.rn] + alu.instr.add3i.imm);
          break;
        case ALU_SUB3I:
          break;
        case ALU_MOV:
          // needs stats and flags
          rf.write(alu.instr.mov.rdn, alu.instr.mov.imm);
          break;
        case ALU_CMP:
          break;
        case ALU_ADD8I:
          // needs stats and flags
          rf.write(alu.instr.add8i.rdn, rf[alu.instr.add8i.rdn] + alu.instr.add8i.imm);
          break;
        case ALU_SUB8I:
          break;
        default:
          cout << "instruction not implemented" << endl;
          exit(1);
          break;
      }
      break;
    case BL: 
      // This instruction is complete, nothing needed here
      bl_ops = decode(blupper);
      if (bl_ops == BL_UPPER) {
        // PC has already been incremented above
        instr2 = imem[PC];
        BL_Type bllower(instr2);
        if (blupper.instr.bl_upper.s) {
          addr = static_cast<unsigned int>(0xff<<24) | 
            ((~(bllower.instr.bl_lower.j1 ^ blupper.instr.bl_upper.s))<<23) |
            ((~(bllower.instr.bl_lower.j2 ^ blupper.instr.bl_upper.s))<<22) |
            ((blupper.instr.bl_upper.imm10)<<12) |
            ((bllower.instr.bl_lower.imm11)<<1);
        }
        else {
          addr = ((blupper.instr.bl_upper.imm10)<<12) |
            ((bllower.instr.bl_lower.imm11)<<1);
        }
        // return address is 4-bytes away from the start of the BL insn
        rf.write(LR_REG, PC + 2);
        // Target address is also computed from that point
        rf.write(PC_REG, PC + 2 + addr);

        stats.numRegReads += 1;
        stats.numRegWrites += 2; 
      }
      else {
        cerr << "Bad BL format." << endl;
        exit(1);
      }
      break;
    case DP:
      dp_ops = decode(dp);
      switch(dp_ops) {
        case DP_CMP:
          // need to implement
          break;
      }
      break;
    case SPECIAL:
      sp_ops = decode(sp);
      switch(sp_ops) {
        case SP_MOV:
          // needs stats and flags
          rf.write((sp.instr.mov.d << 3 ) | sp.instr.mov.rd, rf[sp.instr.mov.rm]);
          break;
        case SP_ADD:
          break;
        case SP_CMP:
          // need to implement these
          break;
      }
      break;
    case LD_ST:
      // You'll want to use these load and store models
      // to implement ldrb/strb, ldm/stm and push/pop
      ldst_ops = decode(ld_st);
      switch(ldst_ops) {
        case STRI:
          // functionally complete, needs stats
          addr = rf[ld_st.instr.ld_st_imm.rn] + ld_st.instr.ld_st_imm.imm * 4;
          dmem.write(addr, rf[ld_st.instr.ld_st_imm.rt]);
          break;
        case LDRI:
          // functionally complete, needs stats
          addr = rf[ld_st.instr.ld_st_imm.rn] + ld_st.instr.ld_st_imm.imm * 4;
          rf.write(ld_st.instr.ld_st_imm.rt, dmem[addr]);
          break;
        case STRR:
          // need to implement
          break;
        case LDRR:
          // need to implement
          break;
        case STRBI:
          // functionally complete, needs stats
          addr = rf[ld_st.instr.ld_st_imm.rn] + ld_st.instr.ld_st_imm.imm;
          temp = dmem[addr];
          temp.set_data_ubyte4(0, rf[ld_st.instr.ld_st_imm.rt]&0xFF);
          dmem.write(addr, temp);
          break;
        case LDRBI:
          // need to implement
          break;
        case STRBR:
          // need to implement
          break;
        case LDRBR:
          // need to implement
          break;
      }
      break;
    case MISC:
      misc_ops = decode(misc);
      switch(misc_ops) {
        case MISC_PUSH:
          // need to implement
          break;
        case MISC_POP:
          // need to implement
          break;
        case MISC_SUB:
          // functionally complete, needs stats
          rf.write(SP_REG, SP - (misc.instr.sub.imm*4));
          break;
        case MISC_ADD:
          // functionally complete, needs stats
          rf.write(SP_REG, SP + (misc.instr.add.imm*4));
          break;
      }
      break;
    case COND:
      decode(cond);
      // Once you've completed the checkCondition function,
      // this should work for all your conditional branches.
      // needs stats
      if (checkCondition(cond.instr.b.cond)){
        rf.write(PC_REG, PC + 2 * signExtend8to32ui(cond.instr.b.imm) + 2);
      }
      break;
    case UNCOND:
      // Essentially the same as the conditional branches, but with no
      // condition check, and an 11-bit immediate field
      decode(uncond);
      break;
    case LDM:
      decode(ldm);
      // need to implement
      break;
    case STM:
      decode(stm);
      // need to implement
      break;
    case LDRL:
      // This instruction is complete, nothing needed
      decode(ldrl);
      // Need to check for alignment by 4
      if (PC & 2) {
        addr = PC + 2 + (ldrl.instr.ldrl.imm)*4;
      }
      else {
        addr = PC + (ldrl.instr.ldrl.imm)*4;
      }
      // Requires two consecutive imem locations pieced together
      temp = imem[addr] | (imem[addr+2]<<16);  // temp is a Data32
      rf.write(ldrl.instr.ldrl.rt, temp);

      // One write for updated reg
      stats.numRegWrites++;
      // One read of the PC
      stats.numRegReads++;
      // One mem read, even though it's imem, and there's two of them
      stats.numMemReads++;
      break;
    case ADD_SP:
      // needs stats
      decode(addsp);
      rf.write(addsp.instr.add.rd, SP + (addsp.instr.add.imm*4));
      break;
    default:
      cout << "[ERROR] Unknown Instruction to be executed" << endl;
      exit(1);
      break;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x1e0, %rsp            # imm = 0x1E0
leaq 0x9126(%rip), %rdi      # 0x15258
movq %rdi, -0x188(%rbp)
movl $0xf, %esi
movl %esi, -0x17c(%rbp)
callq 0x8430
movl %eax, -0x8(%rbp)
leaq -0x8(%rbp), %rdi
callq 0x2fd0
movl %eax, %esi
leaq 0x90aa(%rip), %rdi      # 0x15208
callq 0x83f0
movw %ax, -0x2(%rbp)
leaq -0xa(%rbp), %rdi
callq 0x5a10
movl $0x0, -0x14(%rbp)
leaq -0x10(%rbp), %rdi
leaq -0x14(%rbp), %rsi
callq 0x2c80
movq -0x188(%rbp), %rdi
movl -0x17c(%rbp), %esi
callq 0x8430
movl %eax, -0x20(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x2fd0
addl $0x2, %eax
movl %eax, -0x1c(%rbp)
leaq -0x2(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0xcfb0
movq -0x178(%rbp), %rdi
movw %ax, -0x4e(%rbp)
callq 0xcfd0
movq -0x178(%rbp), %rdi
movw %ax, -0x50(%rbp)
callq 0xcff0
movq -0x178(%rbp), %rdi
movw %ax, -0x52(%rbp)
callq 0xd010
movq -0x178(%rbp), %rdi
movw %ax, -0x54(%rbp)
callq 0xd030
movq -0x178(%rbp), %rdi
movw %ax, -0x56(%rbp)
callq 0xd050
movq -0x178(%rbp), %rdi
movw %ax, -0x58(%rbp)
callq 0xd070
movq -0x178(%rbp), %rdi
movw %ax, -0x5a(%rbp)
callq 0xd090
movq -0x178(%rbp), %rdi
movw %ax, -0x5c(%rbp)
callq 0xd0b0
movq -0x178(%rbp), %rdi
movw %ax, -0x5e(%rbp)
callq 0xd0d0
movq -0x178(%rbp), %rdi
movw %ax, -0x60(%rbp)
callq 0xd0f0
movq -0x178(%rbp), %rdi
movw %ax, -0x62(%rbp)
callq 0xd110
movw %ax, -0x64(%rbp)
leaq -0x80(%rbp), %rdi
leaq -0x1c(%rbp), %rsi
callq 0x2c80
movq -0x188(%rbp), %rdi
movl -0x17c(%rbp), %esi
movl -0x80(%rbp), %edx
callq 0x82f0
movq -0x178(%rbp), %rdi
callq 0x8b20
movw %ax, -0x84(%rbp)
leaq -0x82(%rbp), %rdi
leaq -0x84(%rbp), %rsi
callq 0xd130
movzwl -0x82(%rbp), %edi
callq 0x6570
movl %eax, -0x18(%rbp)
movl -0x18(%rbp), %eax
movq %rax, -0x170(%rbp)
subq $0xb, %rax
ja 0xcefa
movq -0x170(%rbp), %rax
leaq 0x2173(%rip), %rcx      # 0xe458
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movw -0x50(%rbp), %ax
movw %ax, -0x86(%rbp)
movzwl -0x86(%rbp), %edi
callq 0x6750
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %eax
movq %rax, -0x190(%rbp)
subq $0xa, %rax
ja 0xc558
movq -0x190(%rbp), %rax
leaq 0x21be(%rip), %rcx      # 0xe4e8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0xc584
movw -0x50(%rbp), %ax
andw $0x7, %ax
movzwl %ax, %eax
movl %eax, -0x194(%rbp)
movw -0x50(%rbp), %ax
shrw $0x3, %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x8ef9(%rip), %rdi      # 0x15258
callq 0x8430
movl %eax, -0x94(%rbp)
leaq -0x94(%rbp), %rdi
callq 0x2fd0
movl %eax, -0x198(%rbp)
movw -0x50(%rbp), %ax
shrw $0x6, %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x8ec6(%rip), %rdi      # 0x15258
callq 0x8430
movl %eax, -0x98(%rbp)
leaq -0x98(%rbp), %rdi
callq 0x2fd0
movl %eax, %ecx
movl -0x198(%rbp), %eax
addl %ecx, %eax
movl %eax, -0x90(%rbp)
leaq -0x8c(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x2c80
movl -0x194(%rbp), %esi
movl -0x8c(%rbp), %edx
leaq 0x8e79(%rip), %rdi      # 0x15258
callq 0x82f0
jmp 0xc584
jmp 0xc584
movw -0x50(%rbp), %ax
andw $0x7, %ax
movzwl %ax, %eax
movl %eax, -0x19c(%rbp)
movw -0x50(%rbp), %ax
shrw $0x3, %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x8e43(%rip), %rdi      # 0x15258
callq 0x8430
movl %eax, -0xa4(%rbp)
leaq -0xa4(%rbp), %rdi
callq 0x2fd0
movw -0x50(%rbp), %cx
shrw $0x6, %cx
andw $0x7, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, -0xa0(%rbp)
leaq -0x9c(%rbp), %rdi
leaq -0xa0(%rbp), %rsi
callq 0x2c80
movl -0x19c(%rbp), %esi
movl -0x9c(%rbp), %edx
leaq 0x8def(%rip), %rdi      # 0x15258
callq 0x82f0
jmp 0xc584
jmp 0xc584
movw -0x50(%rbp), %ax
shrw $0x8, %ax
andw $0x7, %ax
movzwl %ax, %eax
movl %eax, -0x1a0(%rbp)
movw -0x50(%rbp), %ax
andw $0xff, %ax
movzwl %ax, %eax
movl %eax, -0xac(%rbp)
leaq -0xa8(%rbp), %rdi
leaq -0xac(%rbp), %rsi
callq 0x2c80
movl -0x1a0(%rbp), %esi
movl -0xa8(%rbp), %edx
leaq 0x8d94(%rip), %rdi      # 0x15258
callq 0x82f0
jmp 0xc584
jmp 0xc584
movw -0x50(%rbp), %ax
shrw $0x8, %ax
andw $0x7, %ax
movzwl %ax, %eax
movl %eax, -0x1a4(%rbp)
movw -0x50(%rbp), %ax
shrw $0x8, %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x8d5a(%rip), %rdi      # 0x15258
callq 0x8430
movl %eax, -0xb8(%rbp)
leaq -0xb8(%rbp), %rdi
callq 0x2fd0
movw -0x50(%rbp), %cx
andw $0xff, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, -0xb4(%rbp)
leaq -0xb0(%rbp), %rdi
leaq -0xb4(%rbp), %rsi
callq 0x2c80
movl -0x1a4(%rbp), %esi
movl -0xb0(%rbp), %edx
leaq 0x8d09(%rip), %rdi      # 0x15258
callq 0x82f0
jmp 0xc584
jmp 0xc584
movq 0x8a69(%rip), %rdi      # 0x14fc8
leaq 0x2015(%rip), %rsi      # 0xe57b
callq 0x21d0
movq %rax, %rdi
movq 0x8a3b(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x1, %edi
callq 0x2260
jmp 0xcf26
movw -0x4e(%rbp), %ax
movw %ax, -0xba(%rbp)
movzwl -0xba(%rbp), %edi
callq 0x7e50
movl %eax, -0x68(%rbp)
cmpl $0x0, -0x68(%rbp)
jne 0xc78b
leaq 0x8ca4(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x8430
movl %eax, -0xc0(%rbp)
leaq -0xc0(%rbp), %rdi
callq 0x2fd0
movl %eax, %esi
leaq 0x8c2f(%rip), %rdi      # 0x15208
callq 0x83f0
movw %ax, -0xbc(%rbp)
movw -0xbc(%rbp), %ax
movw %ax, -0xa(%rbp)
leaq -0xa(%rbp), %rdi
callq 0xcfb0
movw %ax, -0xc2(%rbp)
movw -0x4e(%rbp), %ax
shrw $0xa, %ax
andw $0x1, %ax
cmpw $0x0, %ax
je 0xc698
movw -0xc2(%rbp), %ax
shrw $0xd, %ax
andw $0x1, %ax
movzwl %ax, %eax
movw -0x4e(%rbp), %cx
shrw $0xa, %cx
andw $0x1, %cx
movzwl %cx, %ecx
xorl %ecx, %eax
xorl $-0x1, %eax
shll $0x17, %eax
orl $0xff000000, %eax       # imm = 0xFF000000
movw -0xc2(%rbp), %cx
shrw $0xb, %cx
andw $0x1, %cx
movzwl %cx, %ecx
movw -0x4e(%rbp), %dx
shrw $0xa, %dx
andw $0x1, %dx
movzwl %dx, %edx
xorl %edx, %ecx
xorl $-0x1, %ecx
shll $0x16, %ecx
orl %ecx, %eax
movw -0x4e(%rbp), %cx
andw $0x3ff, %cx             # imm = 0x3FF
movzwl %cx, %ecx
shll $0xc, %ecx
orl %ecx, %eax
movw -0xc2(%rbp), %cx
andw $0x7ff, %cx             # imm = 0x7FF
movzwl %cx, %ecx
shll %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
jmp 0xc6bc
movw -0x4e(%rbp), %ax
andw $0x3ff, %ax             # imm = 0x3FF
movzwl %ax, %eax
shll $0xc, %eax
movw -0xc2(%rbp), %cx
andw $0x7ff, %cx             # imm = 0x7FF
movzwl %cx, %ecx
shll %ecx
orl %ecx, %eax
movl %eax, -0x24(%rbp)
leaq 0x8b95(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x8430
movl %eax, -0xd0(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x2fd0
addl $0x2, %eax
movl %eax, -0xcc(%rbp)
leaq -0xc8(%rbp), %rdi
leaq -0xcc(%rbp), %rsi
callq 0x2c80
movl -0xc8(%rbp), %edx
leaq 0x8b50(%rip), %rdi      # 0x15258
movl $0xe, %esi
callq 0x82f0
leaq 0x8b3f(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x8430
movl %eax, -0xdc(%rbp)
leaq -0xdc(%rbp), %rdi
callq 0x2fd0
addl $0x2, %eax
addl -0x24(%rbp), %eax
movl %eax, -0xd8(%rbp)
leaq -0xd4(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x2c80
movl -0xd4(%rbp), %edx
leaq 0x8af7(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x82f0
movl 0x8b3b(%rip), %eax      # 0x152ac
addl $0x1, %eax
movl %eax, 0x8b32(%rip)      # 0x152ac
movl 0x8b28(%rip), %eax      # 0x152a8
addl $0x2, %eax
movl %eax, 0x8b1f(%rip)      # 0x152a8
jmp 0xc7b7
movq 0x885e(%rip), %rdi      # 0x14ff0
leaq 0x1dfe(%rip), %rsi      # 0xe597
callq 0x21d0
movq %rax, %rdi
movq 0x8808(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x1, %edi
callq 0x2260
jmp 0xcf26
movw -0x54(%rbp), %ax
movw %ax, -0xde(%rbp)
movzwl -0xde(%rbp), %edi
callq 0x6b90
movl %eax, -0x70(%rbp)
movl -0x70(%rbp), %eax
subl $0xa, %eax
jne 0xc7e2
jmp 0xc7e0
jmp 0xc7e2
jmp 0xcf26
movw -0x52(%rbp), %ax
movw %ax, -0xe0(%rbp)
movzwl -0xe0(%rbp), %edi
callq 0x6bf0
movl %eax, -0x74(%rbp)
movl -0x74(%rbp), %eax
movl %eax, -0x1a8(%rbp)
testl %eax, %eax
je 0xc88a
jmp 0xc810
movl -0x1a8(%rbp), %eax
subl $0x1, %eax
je 0xc88c
jmp 0xc81d
movl -0x1a8(%rbp), %eax
subl $0x2, %eax
jne 0xc88e
jmp 0xc82a
movw -0x52(%rbp), %ax
shrw $0x7, %ax
andw $0x1, %ax
movzwl %ax, %eax
shll $0x3, %eax
movw -0x52(%rbp), %cx
andw $0x7, %cx
movzwl %cx, %ecx
orl %ecx, %eax
movl %eax, -0x1ac(%rbp)
movw -0x52(%rbp), %ax
shrw $0x3, %ax
andw $0xf, %ax
movzwl %ax, %esi
leaq 0x89f3(%rip), %rdi      # 0x15258
callq 0x8430
movl -0x1ac(%rbp), %esi
movl %eax, -0xe4(%rbp)
movl -0xe4(%rbp), %edx
leaq 0x89d5(%rip), %rdi      # 0x15258
callq 0x82f0
jmp 0xc88e
jmp 0xc88e
jmp 0xc88e
jmp 0xcf26
movw -0x56(%rbp), %ax
movw %ax, -0xe6(%rbp)
movzwl -0xe6(%rbp), %edi
callq 0x6f30
movl %eax, -0x78(%rbp)
movl -0x78(%rbp), %eax
movq %rax, -0x1b8(%rbp)
subq $0xb, %rax
ja 0xcab1
movq -0x1b8(%rbp), %rax
leaq 0x1be9(%rip), %rcx      # 0xe4b8
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movw -0x56(%rbp), %ax
shrw $0x3, %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x896a(%rip), %rdi      # 0x15258
callq 0x8430
movl %eax, -0xec(%rbp)
leaq -0xec(%rbp), %rdi
callq 0x2fd0
movw -0x56(%rbp), %cx
shrw $0x6, %cx
andw $0x1f, %cx
movzwl %cx, %ecx
shll $0x2, %ecx
addl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x1bc(%rbp)
movw -0x56(%rbp), %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x8921(%rip), %rdi      # 0x15258
callq 0x8430
movl -0x1bc(%rbp), %esi
movl %eax, -0xf0(%rbp)
movl -0xf0(%rbp), %edx
leaq 0x88db(%rip), %rdi      # 0x15230
callq 0x7fd0
jmp 0xcab1
movw -0x56(%rbp), %ax
shrw $0x3, %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x88e3(%rip), %rdi      # 0x15258
callq 0x8430
movl %eax, -0xf4(%rbp)
leaq -0xf4(%rbp), %rdi
callq 0x2fd0
movw -0x56(%rbp), %cx
shrw $0x6, %cx
andw $0x1f, %cx
movzwl %cx, %ecx
shll $0x2, %ecx
addl %ecx, %eax
movl %eax, -0x24(%rbp)
movw -0x56(%rbp), %ax
andw $0x7, %ax
movzwl %ax, %eax
movl %eax, -0x1c0(%rbp)
movl -0x24(%rbp), %esi
leaq 0x8872(%rip), %rdi      # 0x15230
callq 0x8330
movl -0x1c0(%rbp), %esi
movl %eax, -0xf8(%rbp)
movl -0xf8(%rbp), %edx
leaq 0x887c(%rip), %rdi      # 0x15258
callq 0x82f0
jmp 0xcab1
jmp 0xcab1
jmp 0xcab1
movw -0x56(%rbp), %ax
shrw $0x3, %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x8852(%rip), %rdi      # 0x15258
callq 0x8430
movl %eax, -0xfc(%rbp)
leaq -0xfc(%rbp), %rdi
callq 0x2fd0
movw -0x56(%rbp), %cx
shrw $0x6, %cx
andw $0x1f, %cx
movzwl %cx, %ecx
addl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %esi
leaq 0x87f5(%rip), %rdi      # 0x15230
callq 0x8330
movl %eax, -0x100(%rbp)
movl -0x100(%rbp), %eax
movl %eax, -0x10(%rbp)
movw -0x56(%rbp), %ax
andw $0x7, %ax
movzwl %ax, %esi
leaq 0x87f7(%rip), %rdi      # 0x15258
callq 0x8430
movl %eax, -0x104(%rbp)
leaq -0x104(%rbp), %rdi
callq 0x2fd0
andl $0xff, %eax
leaq -0x10(%rbp), %rdi
xorl %esi, %esi
movzbl %al, %edx
callq 0x8ca0
movl -0x24(%rbp), %esi
movl -0x10(%rbp), %eax
movl %eax, -0x108(%rbp)
movl -0x108(%rbp), %edx
leaq 0x878c(%rip), %rdi      # 0x15230
callq 0x7fd0
jmp 0xcab1
jmp 0xcab1
jmp 0xcab1
jmp 0xcab1
jmp 0xcf26
movw -0x58(%rbp), %ax
movw %ax, -0x10a(%rbp)
movzwl -0x10a(%rbp), %edi
callq 0x7400
movl %eax, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
movq %rax, -0x1c8(%rbp)
subq $0xb, %rax
ja 0xcbcd
movq -0x1c8(%rbp), %rax
leaq 0x1996(%rip), %rcx      # 0xe488
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0xcbcd
jmp 0xcbcd
leaq 0x874c(%rip), %rdi      # 0x15258
movl $0xd, %esi
callq 0x8430
movl %eax, -0x118(%rbp)
leaq -0x118(%rbp), %rdi
callq 0x2fd0
movw -0x58(%rbp), %cx
andw $0x7f, %cx
movzwl %cx, %ecx
shll $0x2, %ecx
subl %ecx, %eax
movl %eax, -0x114(%rbp)
leaq -0x110(%rbp), %rdi
leaq -0x114(%rbp), %rsi
callq 0x2c80
movl -0x110(%rbp), %edx
leaq 0x86fa(%rip), %rdi      # 0x15258
movl $0xd, %esi
callq 0x82f0
jmp 0xcbcd
leaq 0x86e7(%rip), %rdi      # 0x15258
movl $0xd, %esi
callq 0x8430
movl %eax, -0x124(%rbp)
leaq -0x124(%rbp), %rdi
callq 0x2fd0
movw -0x58(%rbp), %cx
andw $0x7f, %cx
movzwl %cx, %ecx
shll $0x2, %ecx
addl %ecx, %eax
movl %eax, -0x120(%rbp)
leaq -0x11c(%rbp), %rdi
leaq -0x120(%rbp), %rsi
callq 0x2c80
movl -0x11c(%rbp), %edx
leaq 0x8695(%rip), %rdi      # 0x15258
movl $0xd, %esi
callq 0x82f0
jmp 0xcf26
movw -0x5a(%rbp), %ax
movw %ax, -0x126(%rbp)
movzwl -0x126(%rbp), %edi
callq 0x7b50
movw -0x5a(%rbp), %ax
shrw $0x8, %ax
andw $0xf, %ax
movzwl %ax, %edi
callq 0xcf30
cmpl $0x0, %eax
je 0xcc7a
leaq 0x864f(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x8430
movl %eax, -0x134(%rbp)
leaq -0x134(%rbp), %rdi
callq 0x2fd0
movl %eax, -0x1cc(%rbp)
movw -0x5a(%rbp), %ax
andw $0xff, %ax
movsbl %al, %edi
callq 0xbf80
movl %eax, %ecx
movl -0x1cc(%rbp), %eax
shll %ecx
addl %ecx, %eax
addl $0x2, %eax
movl %eax, -0x130(%rbp)
leaq -0x12c(%rbp), %rdi
leaq -0x130(%rbp), %rsi
callq 0x2c80
movl -0x12c(%rbp), %edx
leaq 0x85e8(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x82f0
jmp 0xcf26
movw -0x5c(%rbp), %ax
movw %ax, -0x136(%rbp)
movzwl -0x136(%rbp), %edi
callq 0x7db0
jmp 0xcf26
movw -0x5e(%rbp), %ax
movw %ax, -0x138(%rbp)
movzwl -0x138(%rbp), %edi
callq 0x7ec0
jmp 0xcf26
movw -0x60(%rbp), %ax
movw %ax, -0x13a(%rbp)
movzwl -0x13a(%rbp), %edi
callq 0x7ee0
jmp 0xcf26
movw -0x62(%rbp), %ax
movw %ax, -0x13c(%rbp)
movzwl -0x13c(%rbp), %edi
callq 0x7f00
leaq 0x8567(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x8430
movl %eax, -0x140(%rbp)
leaq -0x140(%rbp), %rdi
callq 0x2fd0
andl $0x2, %eax
cmpl $0x0, %eax
je 0xcd51
leaq 0x853c(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x8430
movl %eax, -0x144(%rbp)
leaq -0x144(%rbp), %rdi
callq 0x2fd0
addl $0x2, %eax
movw -0x62(%rbp), %cx
andw $0xff, %cx
movzwl %cx, %ecx
shll $0x2, %ecx
addl %ecx, %eax
movl %eax, -0x24(%rbp)
jmp 0xcd88
leaq 0x8500(%rip), %rdi      # 0x15258
movl $0xf, %esi
callq 0x8430
movl %eax, -0x148(%rbp)
leaq -0x148(%rbp), %rdi
callq 0x2fd0
movw -0x62(%rbp), %cx
andw $0xff, %cx
movzwl %cx, %ecx
shll $0x2, %ecx
addl %ecx, %eax
movl %eax, -0x24(%rbp)
movl -0x24(%rbp), %esi
leaq 0x8476(%rip), %rdi      # 0x15208
callq 0x83f0
movw %ax, -0x152(%rbp)
leaq -0x152(%rbp), %rdi
callq 0x8b20
movzwl %ax, %eax
movl %eax, -0x1d0(%rbp)
movl -0x24(%rbp), %esi
addl $0x2, %esi
leaq 0x8448(%rip), %rdi      # 0x15208
callq 0x83f0
movw %ax, -0x154(%rbp)
leaq -0x154(%rbp), %rdi
callq 0x8b20
movw %ax, %cx
movl -0x1d0(%rbp), %eax
movzwl %cx, %ecx
shll $0x10, %ecx
orl %ecx, %eax
movl %eax, -0x150(%rbp)
leaq -0x14c(%rbp), %rdi
leaq -0x150(%rbp), %rsi
callq 0x2c80
movl -0x14c(%rbp), %eax
movl %eax, -0x10(%rbp)
movw -0x62(%rbp), %ax
shrw $0x8, %ax
andw $0x7, %ax
movzwl %ax, %esi
movl -0x10(%rbp), %eax
movl %eax, -0x158(%rbp)
movl -0x158(%rbp), %edx
leaq 0x8428(%rip), %rdi      # 0x15258
callq 0x82f0
movl 0x846d(%rip), %eax      # 0x152a8
addl $0x1, %eax
movl %eax, 0x8464(%rip)      # 0x152a8
movl 0x8462(%rip), %eax      # 0x152ac
addl $0x1, %eax
movl %eax, 0x8459(%rip)      # 0x152ac
movl 0x8447(%rip), %eax      # 0x152a0
addl $0x1, %eax
movl %eax, 0x843e(%rip)      # 0x152a0
jmp 0xcf26
movw -0x64(%rbp), %ax
movw %ax, -0x15a(%rbp)
movzwl -0x15a(%rbp), %edi
callq 0x7f20
movw -0x64(%rbp), %ax
shrw $0x8, %ax
andw $0x7, %ax
movzwl %ax, %eax
movl %eax, -0x1d4(%rbp)
leaq 0x83be(%rip), %rdi      # 0x15258
movl $0xd, %esi
callq 0x8430
movl %eax, -0x168(%rbp)
leaq -0x168(%rbp), %rdi
callq 0x2fd0
movw -0x64(%rbp), %cx
andw $0xff, %cx
movzwl %cx, %ecx
shll $0x2, %ecx
addl %ecx, %eax
movl %eax, -0x164(%rbp)
leaq -0x160(%rbp), %rdi
leaq -0x164(%rbp), %rsi
callq 0x2c80
movl -0x1d4(%rbp), %esi
movl -0x160(%rbp), %edx
leaq 0x8365(%rip), %rdi      # 0x15258
callq 0x82f0
jmp 0xcf26
movq 0x80c7(%rip), %rdi      # 0x14fc8
leaq 0x169e(%rip), %rsi      # 0xe5a6
callq 0x21d0
movq %rax, %rdi
movq 0x8099(%rip), %rsi      # 0x14fb0
callq 0x2200
movl $0x1, %edi
callq 0x2260
addq $0x1e0, %rsp            # imm = 0x1E0
popq %rbp
retq
nop