// File: /workspace/github_cpp_makefile_star2_O1/martinferianc[P]CPUSimulator-EIE2/src/test_mips.cpp
// Function: main
int main(){
  mips_test_begin_suite();
  vector<test> instructions;
  mips_error err;

  //Test #1 if the cpu was created correctly
  mips_mem_h mem = mips_mem_create_ram(4096);
  mips_cpu_h cpu = mips_cpu_create(mem);
  int testId = mips_test_begin_test("<INTERNAL>");
  if (cpu!=0){
    mips_test_end_test(testId, true, "CPU Created");
  } else{
    mips_test_end_test(testId, false, "CPU Creation error");
    mips_test_end_suite();
  }
  //ENDTEST

  //Test #2 writing to register 0
  testId = mips_test_begin_test("<INTERNAL>");
  err = mips_cpu_set_register(cpu, 0, 1);
  uint32_t *r0 = new uint32_t;
  mips_cpu_get_register(cpu, 0, r0);
  if ((err!=mips_Success) || (*r0==0))
    mips_test_end_test(testId, true, "R[0] unchanged");
  else
    mips_test_end_test(testId, false, "R[0] changed");
  delete r0;
  //ENDTEST

  //Test #3 checking if registers are 0
  testId = mips_test_begin_test("<INTERNAL>");
  uint32_t *v = new uint32_t;
  for (int i = 0; i < 32; ++i){
    mips_cpu_get_register(cpu,i,v);
    if (v!=0)
    break;
  }
  if (v!=0)
    mips_test_end_test(testId, true, "Registers are zero");
  else
    mips_test_end_test(testId, false, "Registers are non-zero");
  *v=0;
  //ENDTEST


  //Test #4 Accessing invalid index
  testId = mips_test_begin_test("<INTERNAL>");
  err = mips_cpu_get_register(cpu, 32, v);
  if (err!=mips_Success)
    mips_test_end_test(testId, true, "Register could not be loaded");
  else
    mips_test_end_test(testId, false, "Register index error");
  //ENDTEST

  //Test #5 Test the CPU RESET
  testId = mips_test_begin_test("<INTERNAL>");
  mips_cpu_reset(cpu);
  for (int i = 0; i < 32; ++i){
    mips_cpu_get_register(cpu,i,v);
    if (v!=0)
    break;
  }
  if (v!=0)
    mips_test_end_test(testId, true, "Registers are zero");
  else
    mips_test_end_test(testId, false, "Registers are non-zero");
  delete v;

  //////////TEST SUITE//////////////////
  //ALWAYS R1(result), R2, R3(operands)

  //mips_cpu_set_debug_level(cpu, 2, NULL);

  err = load_instructions(instructions);
  err = load_memory(mem, instructions);
  if (err!=mips_Success){
    cout<<"!   (Error) Instructions could not be loaded from the file please check mips_cpu_instructions.txt"<<endl;
    mips_test_end_suite();
    mips_cpu_free(cpu);
    mips_mem_free(mem);
    return 0;
  }

  int skip_count = 0; //To skip the SKIP parts
  for (uint32_t i = 0; i < instructions.size(); ++i){
    uint32_t *pc = new uint32_t;
    mips_cpu_get_pc(cpu,pc);
    if (instructions[i].instruction_code==0){ //In case the CPU tries to execute the skip
      if (*pc==i*4)
        mips_cpu_set_pc(cpu,*pc+4);
      skip_count++;
      continue;
    }
    uint32_t regs_before [32];
    uint32_t regs_after [32];

    bool success = false;
    int testId = mips_test_begin_test(instructions[i].instruction_name.c_str());

    mips_cpu_set_register(cpu, 2, instructions[i].instruction_r1);
    mips_cpu_set_register(cpu, 3, instructions[i].instruction_r2);
    load_registers(regs_before, cpu);

    err = mips_cpu_step(cpu);
    load_registers(regs_after, cpu);

    mips_cpu_get_pc(cpu,pc);
    switch(instructions[i].instruction_name[0]){
      case 'B':
        //Branch should be taken, expected result == 1, pc changed in the next instruction
        if ((*pc==(i+1)*4) && (instructions[i].instruction_result==1) && (err==mips_Success)){
          if (instructions[i].instruction_name.length() > 4) {
            if(regs_after[31] != (i+2)*4)
            break;
          }
          err = mips_cpu_step(cpu); //Step to the instruction from where branch is performed
          if (err!=mips_Success)
            break;

          mips_cpu_get_pc(cpu,pc);
          if ((*pc==(i+3)*4) && (err==mips_Success)) //Branches always by 2
            success = true;

          break;
        }
        //Branch should not be taken, expected result == 0, pc = pc + 4
        if ((*pc==(i+1)*4) && (instructions[i].instruction_result==0) && (err==mips_Success)){

          err = mips_cpu_step(cpu); //Step to the instruction from where branch is performed
          if (err!=mips_Success)
            break;

          mips_cpu_get_pc(cpu,pc);

          if ((*pc==(i+2)*4) && (err==mips_Success))
            success = true;

          break;
          }

      case '<':
        if (err!=mips_Success)
          success = true;
        break;

      case 'J':
        if ((*pc==(i+1)*4) && (err==mips_Success)){
          if (instructions[i].instruction_name.length() >= 3) {
            if(regs_after[31] != (i+2)*4)
            break;
          }
          err = mips_cpu_step(cpu);
          if (err!=mips_Success)
            break;

          err = mips_cpu_get_pc(cpu,pc);
          if ((*pc==(i+3)*4) && (err==mips_Success))
            success = true;

          break;
        }
      break;
      default:

      //Test all other instructions
      if (regs_after[1] == instructions[i].instruction_result)
        success = true;

    }
    if (success){
      mips_test_end_test(testId, true, instructions[i].instruction_name.c_str());
      if (err==mips_ExceptionArithmeticOverflow)
        mips_cpu_set_pc(cpu, *pc + 4);

      switch (instructions[i].instruction_name[0]) {
        case '<':
          //Manually adjust the PC because the instruction resulted in an error
          mips_cpu_set_pc(cpu, *pc + 4);
          break;

        case 'B':
          if (instructions[i].instruction_result==1) {
            i=i+2;
            skip_count=skip_count+2;
          } else {
            i=i+1;
            skip_count=skip_count+1;
          }
          break;

        case 'J':
          i=i+2;
          skip_count=skip_count+2;
          break;
      }
    } else {
      cout<<"-----------------------------------------------------------------------"<<endl;
      cout<<"| Test: "<<i+1-skip_count<<"| To memory: "<<instructions[i].str()<<"|"<<endl;
      cout<<"-----------------------REGISTERS BEFORE-------------------------------"<<endl;
      print_registers(regs_before);
      cout<<endl<<"----------------------REGISTERS AFTER---------------------------"<<endl;
      print_registers(regs_after);
      mips_cpu_get_pc(cpu,pc);
      mips_test_end_test(testId, false, instructions[i].instruction_name.c_str());
      switch (instructions[i].instruction_name[0]) {
        case '<':
          cout<<endl<<"!   (Error) Instruction should have not been executed: Instruction is invalid!"<<endl;
          if (err != mips_Success)
            mips_cpu_set_pc(cpu, *pc + 4);
        break;

        case 'B':
          if (instructions[i].instruction_result==1){
            if (instructions[i].instruction_name.length() > 4) {
              if(regs_after[31] != (i+2)*4)
                cout<<endl<<"!   (Error) PC + 8 not in R[31]:"<<regs_after[31]<<" PC Awaited: "<<(i+3)*4<<endl;
            }
            cout<<endl<<"!   (Error) PC: "<<*pc<<" PC Awaited: "<<(i+3)*4<<endl;
          }else{
            cout<<endl<<"!   (Error) PC: "<<*pc<<" PC Awaited: "<<(i+1)*4<<endl;
          }
          mips_cpu_set_pc(cpu, (i+3)*4);
          i=i+2;
          skip_count=skip_count+2;
        break;

        case 'J':
          cout<<endl<<"!   (Error) PC: "<<*pc<<" PC Awaited: "<<(i+2)*4<<endl;
          mips_cpu_set_pc(cpu, (i+3)*4);
          i=i+2;
          skip_count=skip_count+2;
        break;

        default:
          cout<<endl<<"!   (Error) Got:"<<regs_after[1]<<" Actual Result: "<<instructions[i].instruction_result<<endl;
          if (err != mips_Success)
            mips_cpu_set_pc(cpu, *pc + 4);
        break;
      }
      cout<<"!    Going to the next memory location PC + 4:"<<endl;
      cout<<"-----------------------------------------------------"<<endl;

      delete pc;
    }
  }
  //////////END TEST SUITE//////////////////
  mips_test_end_suite();
  mips_cpu_free(cpu);
  mips_mem_free(mem);
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x178, %rsp            # imm = 0x178
callq 0x377c
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
movq $0x0, 0x20(%rsp)
movl $0x1000, %edi           # imm = 0x1000
callq 0x4a90
movq %rax, %r14
movq %rax, 0x28(%rsp)
movq %rax, %rdi
callq 0x4bac
movq %rax, (%rsp)
leaq 0x1e79(%rip), %rdi      # 0xa4fb
callq 0x382f
cmpq $0x0, (%rsp)
je 0x86a3
leaq 0x2661(%rip), %rdx      # 0xacf6
movl %eax, %edi
movl $0x1, %esi
callq 0x39a6
jmp 0x86b8
leaq 0x2658(%rip), %rdx      # 0xad02
movl %eax, %edi
xorl %esi, %esi
callq 0x39a6
callq 0x3a2e
leaq 0x1e3c(%rip), %rdi      # 0xa4fb
callq 0x382f
movl %eax, %ebp
movq (%rsp), %rdi
xorl %esi, %esi
movl $0x1, %edx
callq 0x4c64
movl %eax, %r12d
movl $0x4, %edi
callq 0x31d0
movq %rax, %r15
movq (%rsp), %rdi
xorl %esi, %esi
movq %rax, %rdx
callq 0x4c44
testl %r12d, %r12d
je 0x8707
leaq 0x2615(%rip), %rdx      # 0xad15
movl $0x1, %esi
jmp 0x8716
cmpl $0x0, (%r15)
je 0x86f9
leaq 0x2610(%rip), %rdx      # 0xad24
xorl %esi, %esi
movl %ebp, %edi
callq 0x39a6
movl $0x4, %esi
movq %r15, %rdi
callq 0x31e0
leaq 0x1dca(%rip), %rdi      # 0xa4fb
callq 0x382f
movl %eax, %ebp
movl $0x4, %edi
callq 0x31d0
movq %rax, %r15
movq (%rsp), %rdi
xorl %esi, %esi
movq %rax, %rdx
callq 0x4c44
leaq 0x25d7(%rip), %rdx      # 0xad31
movl %ebp, %edi
movl $0x1, %esi
callq 0x39a6
movl $0x0, (%r15)
leaq 0x1d87(%rip), %rdi      # 0xa4fb
callq 0x382f
movl %eax, %ebp
movq (%rsp), %rdi
movl $0x20, %esi
movq %r15, %rdx
callq 0x4c44
xorl %esi, %esi
testl %eax, %eax
setne %sil
leaq 0x25a9(%rip), %rax      # 0xad44
leaq 0x25bf(%rip), %rdx      # 0xad61
cmovneq %rax, %rdx
movl %ebp, %edi
callq 0x39a6
leaq 0x1d47(%rip), %rdi      # 0xa4fb
callq 0x382f
movl %eax, %ebp
movq (%rsp), %rdi
callq 0x4bfb
movq (%rsp), %rdi
xorl %esi, %esi
movq %r15, %rdx
callq 0x4c44
leaq 0x2558(%rip), %rdx      # 0xad31
movl %ebp, %edi
movl $0x1, %esi
callq 0x39a6
movl $0x4, %esi
movq %r15, %rdi
callq 0x31e0
leaq 0x10(%rsp), %rdi
callq 0x80b4
leaq 0x58(%rsp), %rdi
leaq 0x10(%rsp), %rsi
callq 0x9356
leaq 0x28(%rsp), %rdi
leaq 0x58(%rsp), %rsi
callq 0x8472
movl %eax, %ebp
leaq 0x58(%rsp), %rdi
callq 0x93ee
testl %ebp, %ebp
je 0x888b
movq 0x6797(%rip), %r15      # 0xefc8
leaq 0x253e(%rip), %rsi      # 0xad76
movl $0x61, %edx
movq %r15, %rdi
callq 0x3210
movq (%r15), %rax
addq -0x18(%rax), %r15
movq %r15, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x6765(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
callq 0x3a2e
movq (%rsp), %rdi
callq 0x522a
movq %r14, %rdi
callq 0x4b86
jmp 0x927a
movq 0x18(%rsp), %rax
cmpq 0x10(%rsp), %rax
je 0x9262
xorl %ebx, %ebx
movl $0x0, 0xc(%rsp)
movl $0x4, %edi
callq 0x31d0
movq %rax, %rbp
movq (%rsp), %rdi
movq %rax, %rsi
callq 0x4c9c
movq 0x10(%rsp), %rax
imulq $0x38, %rbx, %r15
cmpl $0x0, (%rax,%r15)
je 0x89e2
addq %r15, %rax
movq 0x8(%rax), %rdi
callq 0x382f
movl %eax, %r14d
movq 0x10(%rsp), %rax
movl 0x2c(%rax,%r15), %edx
movq (%rsp), %rdi
movl $0x2, %esi
callq 0x4c64
movq 0x10(%rsp), %rax
movl 0x30(%rax,%r15), %edx
movq (%rsp), %rdi
movl $0x3, %esi
callq 0x4c64
leaq 0xf0(%rsp), %rdi
movq (%rsp), %rsi
callq 0x85e0
movq (%rsp), %rdi
callq 0x4cae
movl %eax, %r13d
leaq 0x70(%rsp), %rdi
movq (%rsp), %rsi
callq 0x85e0
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x4c9c
movq 0x10(%rsp), %rax
movq 0x8(%rax,%r15), %rcx
movzbl (%rcx), %ecx
cmpl $0x3c, %ecx
je 0x8a9c
addq %r15, %rax
cmpl $0x42, %ecx
je 0x8a05
cmpl $0x4a, %ecx
jne 0x8a6c
leal 0x4(,%rbx,4), %ecx
xorl (%rbp), %ecx
orl %r13d, %ecx
jne 0x8a98
leal (,%rbx,4), %r12d
cmpq $0x3, 0x10(%rax)
jb 0x89af
leal 0x8(%r12), %ecx
xorl %r13d, %r13d
movl $0x0, %eax
cmpl %ecx, 0xec(%rsp)
jne 0x8aa2
movq (%rsp), %rdi
callq 0x4cae
movl %eax, %r13d
testl %eax, %eax
jne 0x8a98
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x4c9c
movl %eax, %r13d
addl $0xc, %r12d
xorl (%rbp), %r12d
orl %eax, %r12d
jmp 0x8a73
movl (%rbp), %esi
leal (,%rbx,4), %eax
cmpl %eax, %esi
jne 0x89fc
addl $0x4, %esi
movq (%rsp), %rdi
callq 0x4c86
incl 0xc(%rsp)
jmp 0x921a
movl (%rbp), %ecx
leal 0x4(,%rbx,4), %edx
cmpl %edx, %ecx
jne 0x8a9c
leal (,%rbx,4), %r12d
movl 0x28(%rax), %esi
xorl $0x1, %esi
orl %r13d, %esi
jne 0x8a78
cmpq $0x5, 0x10(%rax)
jb 0x8a47
leal 0x8(%r12), %ecx
xorl %r13d, %r13d
movl $0x0, %eax
cmpl %ecx, 0xec(%rsp)
jne 0x8aa2
movq (%rsp), %rdi
callq 0x4cae
movl %eax, %r13d
testl %eax, %eax
jne 0x8a98
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x4c9c
addl $0xc, %r12d
jmp 0x9253
movl 0x74(%rsp), %ecx
cmpl 0x28(%rax), %ecx
sete %al
jmp 0x8aa2
cmpl %edx, %ecx
jne 0x8a9c
movl 0x28(%rax), %eax
orl %r13d, %eax
jne 0x8a9c
movq (%rsp), %rdi
callq 0x4cae
movl %eax, %r13d
testl %eax, %eax
je 0x9243
xorl %eax, %eax
jmp 0x8aa2
testl %r13d, %r13d
setne %al
testb %al, %al
je 0x8b11
movq 0x10(%rsp), %rax
movq 0x8(%rax,%r15), %rdx
movl %r14d, %edi
movl $0x1, %esi
callq 0x39a6
cmpl $0x2006, %r13d          # imm = 0x2006
jne 0x8ad5
movl (%rbp), %esi
addl $0x4, %esi
movq (%rsp), %rdi
callq 0x4c86
movq 0x10(%rsp), %rax
movq 0x8(%rax,%r15), %rcx
movzbl (%rcx), %ecx
cmpl $0x4a, %ecx
je 0x8e01
cmpl $0x42, %ecx
je 0x8df4
cmpl $0x3c, %ecx
jne 0x921a
movl (%rbp), %esi
addl $0x4, %esi
movq (%rsp), %rdi
callq 0x4c86
jmp 0x921a
movl $0x47, %edx
movq 0x64ab(%rip), %rdi      # 0xefc8
leaq 0x22b4(%rip), %rsi      # 0xadd8
callq 0x3210
movq 0x6498(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x647a(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movl $0x8, %edx
movq 0x6461(%rip), %rdi      # 0xefc8
leaq 0x22b2(%rip), %rsi      # 0xae20
callq 0x3210
leal 0x1(%rbx), %esi
movq %rsi, 0x50(%rsp)
subl 0xc(%rsp), %esi
movq 0x6442(%rip), %rdi      # 0xefc8
callq 0x3120
movq %rax, %r12
movl $0xd, %edx
movq %rax, %rdi
leaq 0x228c(%rip), %rsi      # 0xae29
callq 0x3210
movq 0x10(%rsp), %rsi
addq %r15, %rsi
leaq 0x30(%rsp), %rdi
callq 0x944a
movq 0x30(%rsp), %rsi
movq 0x38(%rsp), %rdx
movq %r12, %rdi
callq 0x3210
movq %rax, %r12
movl $0x1, %edx
movq %rax, %rdi
leaq 0x225f(%rip), %rsi      # 0xae37
callq 0x3210
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq %r12, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0x8c21
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x31e0
movl $0x46, %edx
movq 0x639b(%rip), %rdi      # 0xefc8
leaq 0x2205(%rip), %rsi      # 0xae39
callq 0x3210
movq 0x6388(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x636a(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
leaq 0xf0(%rsp), %rdi
callq 0x84e9
movq 0x6349(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x632b(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq %rax, %r12
movl $0x40, %edx
movq %rax, %rdi
leaq 0x21c4(%rip), %rsi      # 0xae80
callq 0x3210
movq (%r12), %rax
movq -0x18(%rax), %rdi
addq %r12, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq %r12, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3130
leaq 0x70(%rsp), %rdi
callq 0x84e9
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x4c9c
movq 0x10(%rsp), %rax
movq 0x8(%rax,%r15), %rdx
movl %r14d, %edi
xorl %esi, %esi
callq 0x39a6
movq 0x10(%rsp), %rax
movq 0x8(%rax,%r15), %rcx
movzbl (%rcx), %ecx
cmpl $0x3c, %ecx
je 0x8f7b
cmpl $0x42, %ecx
je 0x8e0e
cmpl $0x4a, %ecx
jne 0x8ff0
movq 0x6286(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x6268(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq %rax, %r14
movl $0x10, %edx
movq %rax, %rdi
leaq 0x21c0(%rip), %rsi      # 0xaf3f
callq 0x3210
movl (%rbp), %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movl $0xd, %edx
movq %rax, %rdi
leaq 0x2190(%rip), %rsi      # 0xaf31
callq 0x3210
leal 0x8(,%rbx,4), %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3130
leal 0xc(,%rbx,4), %esi
movq (%rsp), %rdi
callq 0x4c86
jmp 0x9171
addq %r15, %rax
cmpl $0x1, 0x28(%rax)
jne 0x90b5
addl $0x2, %ebx
addl $0x2, 0xc(%rsp)
jmp 0x921a
addq %r15, %rax
cmpl $0x1, 0x28(%rax)
jne 0x90bc
cmpq $0x5, 0x10(%rax)
jb 0x8ee5
movl 0xec(%rsp), %r14d
leal 0x8(,%rbx,4), %eax
cmpl %eax, %r14d
je 0x8ee5
movq 0x6183(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x6165(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq %rax, %r15
movl $0x20, %edx
movq %rax, %rdi
leaq 0x208e(%rip), %rsi      # 0xaf10
callq 0x3210
movq %r15, %rdi
movq %r14, %rsi
callq 0x3120
movq %rax, %r14
movl $0xd, %edx
movq %rax, %rdi
leaq 0x208d(%rip), %rsi      # 0xaf31
callq 0x3210
leal (,%rbx,4), %esi
addl $0xc, %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq 0x60dc(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x60be(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq %rax, %r14
movl $0x10, %edx
movq %rax, %rdi
leaq 0x2016(%rip), %rsi      # 0xaf3f
callq 0x3210
movl (%rbp), %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movl $0xd, %edx
movq %rax, %rdi
leaq 0x1fe6(%rip), %rsi      # 0xaf31
callq 0x3210
leal 0xc(,%rbx,4), %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31c0
jmp 0x914e
movq 0x6046(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x6028(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq %rax, %r14
movl $0x4e, %edx
movq %rax, %rdi
leaq 0x1f02(%rip), %rsi      # 0xaec1
callq 0x3210
movq (%r14), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3130
jmp 0x9098
movq 0x5fd1(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x5fb3(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq %rax, %r14
movl $0x10, %edx
movq %rax, %rdi
leaq 0x1f1c(%rip), %rsi      # 0xaf50
callq 0x3210
movl 0x74(%rsp), %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movl $0x10, %edx
movq %rax, %rdi
leaq 0x1f0a(%rip), %rsi      # 0xaf61
callq 0x3210
movq 0x10(%rsp), %rax
movl 0x28(%rax,%r15), %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3130
testl %r13d, %r13d
je 0x9179
movl (%rbp), %esi
addl $0x4, %esi
movq (%rsp), %rdi
callq 0x4c86
jmp 0x9179
incl %ebx
jmp 0x89fc
movq 0x5f05(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x5ee7(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movq %rax, %r14
movl $0x10, %edx
movq %rax, %rdi
leaq 0x1e3f(%rip), %rsi      # 0xaf3f
callq 0x3210
movl (%rbp), %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movl $0xd, %edx
movq %rax, %rdi
leaq 0x1e0f(%rip), %rsi      # 0xaf31
callq 0x3210
movq 0x50(%rsp), %rsi
shll $0x2, %esi
movq %r14, %rdi
callq 0x3120
movq %rax, %r14
movq (%rax), %rax
movq -0x18(%rax), %rdi
addq %r14, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq %r14, %rdi
callq 0x3040
movq %rax, %rdi
callq 0x3130
leal 0xc(,%rbx,4), %esi
movq (%rsp), %rdi
callq 0x4c86
addl $0x2, %ebx
addl $0x2, 0xc(%rsp)
movl $0x2e, %edx
movq 0x5e43(%rip), %rdi      # 0xefc8
leaq 0x1de6(%rip), %rsi      # 0xaf72
callq 0x3210
movq 0x5e30(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x5e12(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movl $0x35, %edx
movq 0x5df9(%rip), %rdi      # 0xefc8
leaq 0x1c14(%rip), %rsi      # 0xadea
callq 0x3210
movq 0x5de6(%rip), %rcx      # 0xefc8
movq (%rcx), %rax
movq -0x18(%rax), %rdi
addq %rcx, %rdi
movl $0xa, %esi
callq 0x31c0
movsbl %al, %esi
movq 0x5dc8(%rip), %rdi      # 0xefc8
callq 0x3040
movq %rax, %rdi
callq 0x3130
movl $0x4, %esi
movq %rbp, %rdi
callq 0x31e0
movq 0x18(%rsp), %rax
subq 0x10(%rsp), %rax
incl %ebx
sarq $0x3, %rax
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rcx, %rax
cmpq %rbx, %rax
ja 0x88a5
jmp 0x9262
movq (%rsp), %rdi
movq %rbp, %rsi
callq 0x4c9c
addl $0x8, %r12d
cmpl %r12d, (%rbp)
sete %al
xorl %r13d, %r13d
jmp 0x8aa2
callq 0x3a2e
movq (%rsp), %rdi
callq 0x522a
movq 0x28(%rsp), %rdi
callq 0x4b86
leaq 0x10(%rsp), %rdi
callq 0x93ee
xorl %eax, %eax
addq $0x178, %rsp            # imm = 0x178
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x93ee
jmp 0x92df
jmp 0x92dc
jmp 0x92dc
jmp 0x92dc
jmp 0x92dc
jmp 0x92dc
jmp 0x92dc
jmp 0x92dc
jmp 0x92dc
movq %rax, %rbx
movq 0x30(%rsp), %rdi
leaq 0x40(%rsp), %rax
cmpq %rax, %rdi
je 0x92df
movq 0x40(%rsp), %rsi
incq %rsi
callq 0x31e0
jmp 0x92df
jmp 0x92dc
jmp 0x92dc
movq %rax, %rbx
leaq 0x10(%rsp), %rdi
callq 0x93ee
movq %rbx, %rdi
callq 0x3330
nop