// File: luooofan[P]hblzbd_compiler/src/main.cpp
// Function: main
int main(int argc, char **argv) {
  // MyAssert(0);
  bool opt = false, print_usage = false;
  char *src = nullptr, *output = nullptr, *log_file = nullptr;
  // parse command line options and check
  for (int ch; (ch = getopt(argc, argv, "Sl:o:O:h")) != -1;) {
    switch (ch) {
      case 'S':
        // do nothing
        break;
      case 'l':
        log_file = strdup(optarg);
        break;
      case 'o':
        output = strdup(optarg);
        break;
      case 'O':
        opt = atoi(optarg) > 0;
        break;
      case 'h':
        print_usage = true;
        break;
      default:
        break;
    }
  }

  if (optind <= argc) {
    src = argv[optind];
  }

  if (src == nullptr || print_usage) {
    std::cerr << "Usage: " << argv[0] << " [-S] [-l log_file] [-o output_file] [-O level] input_file" << std::endl;
    return 1;
  }

  if (nullptr != src) {
    freopen(src, "r", stdin);
  }
  std::ofstream logfile;
  if (nullptr != log_file) {
    logfile.open(log_file);
  }

#ifdef DEBUG_PROCESS
  std::cout << "Parser Start:" << std::endl;
#endif
  yyset_lineno(1);
  yyparse();  // if success, ast_root is valid
  // MyAssert(0);
#ifdef DEBUG_PROCESS
  std::cout << "Parser End." << std::endl;
#endif
  yylex_destroy();

  MyAssert(nullptr != ast_root);
  if (logfile.is_open() && AST_LOG) {
    logfile << "AST:" << std::endl;
    ast_root->PrintNode(0, logfile);
  }

#ifdef DEBUG_PROCESS
  std::cout << "Generate IR Start:" << std::endl;
#endif
  std::vector<IR *> *ir_list_ptr = new std::vector<IR *>();
  {
    ir::ContextInfo ctx;
    ast_root->GenerateIR(ctx, *ir_list_ptr);
  }
#ifdef DEBUG_PROCESS
  std::cout << "Generate IR End." << std::endl;
#endif
  // MyAssert(0);
  delete ast_root;

  if (logfile.is_open() && IRLIST_LOG) {
    ir::PrintFuncTable(logfile);
    ir::PrintScopes(logfile);
    logfile << "IRList:" << std::endl;
    for (auto ir : *ir_list_ptr) {
      ir->PrintIR(logfile);
    }
  }

  // it represents IRModule before GenerateArm Pass and ArmModule after GenerateArm Pass.
  // the source space will be released when running GenerateArm Pass.
  Module *module_ptr = static_cast<Module *>(ConstructModule(std::string(src), *ir_list_ptr));
  delete ir_list_ptr;
  // module_ptr->EmitCode(std::cout);
  Module **const module_ptr_addr = &module_ptr;

#ifdef DEBUG_PROCESS
  std::cout << "Passes Start:" << std::endl;
#endif
  PassManager pm(module_ptr_addr);

  // ==================Add Quad-Pass Below==================
  pm.AddPass<SimplifyCFG>(true);
  pm.AddPass<DeadFunctionEliminate>(true);
  // pm.AddPass<ReachDefine>(false);
  pm.AddPass<ConstantPropagation>(true);
  pm.AddPass<Instruction_Combining>(true);
  pm.AddPass<LoopUnroll>(true);
  pm.AddPass<InvariantExtrapolation>(true);
  // ==================Add Quad-Pass Above==================
  pm.AddPass<SimplifyCFG>(true);  // necessary
  pm.AddPass<ComputeDominance>(false);
  pm.AddPass<ConvertSSA>(true);
  // ==================Add SSA-Pass Below==================
  pm.AddPass<DeadCodeEliminate>(false);
  pm.AddPass<SimpleOptimize>(true);
  pm.AddPass<DeadCodeEliminate>(false);
  pm.AddPass<GlobalValueNumbering>(true);  // actually redundant common expression eliminate
  pm.AddPass<SimpleOptimize>(true);
  pm.AddPass<DeadCodeEliminate>(false);
  // ==================Add SSA-Pass Above==================
  pm.AddPass<GenerateArmFromSSA>(true);  // define macro control MUL_TO_SHIFT DIV_TO_SHIFT MOD_TO_AND optimize
  // ==================Add Arm(vreg)-Pass Below==================
  pm.AddPass<SimplifyArm>(true);
  pm.AddPass<CondBrToInsts>(true);
  // ==================Add Arm(vreg)-Pass Above==================
  pm.AddPass<RegAlloc>(true);
  pm.AddPass<SPOffsetFixup>(true);
  // ==================Add Arm-Pass Below==================
  pm.AddPass<SimplifyArm>(false);
  pm.AddPass<CondBrToInsts>(true);
  // ==================Add Arm-Pass Above==================
  if (logfile.is_open()) {
    pm.Run(PASS_LOG, logfile);
  } else {
    pm.Run();
  }

  // exit(0);
#ifdef DEBUG_PROCESS
  std::cout << "Passes End." << std::endl;
#endif
  MyAssert(typeid(*module_ptr) == typeid(ArmModule));

#ifdef DEBUG_PROCESS
  std::cout << "Emit Start:" << std::endl;
#endif
  {
    std::ofstream outfile;
    std::string file_name = "";
    if (nullptr == output) {
      file_name = std::string(src, src + strlen(src) - 1);
    } else {
      file_name = std::string(output);
    }
    outfile.open(file_name);
    if (logfile.is_open()) {
      logfile << "Emitting code to file: " << file_name << std::endl;
    }
    module_ptr->EmitCode(outfile);
    MyAssert(outfile.is_open());
    outfile << std::endl;
    if (logfile.is_open()) {
      logfile << "EmitCode finish." << std::endl;
    }
    outfile.close();
  }
#ifdef DEBUG_PROCESS
  std::cout << "Emit End." << std::endl;
#endif

  if (logfile.is_open()) {
    logfile.close();
  }

  // release the arm module space.
  delete module_ptr;
  module_ptr = nullptr;

  return 0;
}

// Assembly:
subq $0x8c8, %rsp            # imm = 0x8C8
movl $0x0, 0x8c4(%rsp)
movl %edi, 0x8c0(%rsp)
movq %rsi, 0x8b8(%rsp)
movb $0x0, 0x8b7(%rsp)
movb $0x0, 0x8b6(%rsp)
movq $0x0, 0x8a8(%rsp)
movq $0x0, 0x8a0(%rsp)
movq $0x0, 0x898(%rsp)
movl 0x8c0(%rsp), %edi
movq 0x8b8(%rsp), %rsi
leaq 0xb0359(%rip), %rdx     # 0xfb374
callq 0x80f0
movl %eax, 0x894(%rsp)
cmpl $-0x1, %eax
je 0x4b0c6
movl 0x894(%rsp), %eax
addl $-0x4f, %eax
movl %eax, %ecx
movq %rcx, 0x170(%rsp)
subl $0x20, %eax
ja 0x4b0bf
movq 0x170(%rsp), %rax
leaq 0xb0298(%rip), %rcx     # 0xfb2f0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
jmp 0x4b0c1
movq 0x100f1e(%rip), %rax    # 0x14bf88
movq (%rax), %rdi
callq 0x86a0
movq %rax, 0x898(%rsp)
jmp 0x4b0c1
movq 0x100f05(%rip), %rax    # 0x14bf88
movq (%rax), %rdi
callq 0x86a0
movq %rax, 0x8a0(%rsp)
jmp 0x4b0c1
movq 0x100eec(%rip), %rax    # 0x14bf88
movq (%rax), %rdi
callq 0x85b0
cmpl $0x0, %eax
setg %al
andb $0x1, %al
movb %al, 0x8b7(%rsp)
jmp 0x4b0c1
movb $0x1, 0x8b6(%rsp)
jmp 0x4b0c1
jmp 0x4b0c1
jmp 0x4b005
movq 0x100ef3(%rip), %rax    # 0x14bfc0
movl (%rax), %eax
cmpl 0x8c0(%rsp), %eax
jg 0x4b0f6
movq 0x8b8(%rsp), %rax
movq 0x100ed9(%rip), %rcx    # 0x14bfc0
movslq (%rcx), %rcx
movq (%rax,%rcx,8), %rax
movq %rax, 0x8a8(%rsp)
cmpq $0x0, 0x8a8(%rsp)
je 0x4b10b
testb $0x1, 0x8b6(%rsp)
je 0x4b15f
movq 0x100ed6(%rip), %rdi    # 0x14bfe8
leaq 0xb0264(%rip), %rsi     # 0xfb37d
callq 0x8330
movq %rax, %rdi
movq 0x8b8(%rsp), %rax
movq (%rax), %rsi
callq 0x8330
movq %rax, %rdi
leaq 0xb024a(%rip), %rsi     # 0xfb385
callq 0x8330
movq %rax, %rdi
movq 0x100e36(%rip), %rsi    # 0x14bf80
callq 0x8380
movl $0x1, 0x8c4(%rsp)
jmp 0x4bf14
xorl %eax, %eax
cmpq 0x8a8(%rsp), %rax
je 0x4b189
movq 0x8a8(%rsp), %rdi
movq 0x100e26(%rip), %rax    # 0x14bfa0
movq (%rax), %rdx
leaq 0xaefdf(%rip), %rsi     # 0xfa163
callq 0x83b0
leaq 0x690(%rsp), %rdi
callq 0x8630
xorl %eax, %eax
cmpq 0x898(%rsp), %rax
je 0x4b1d9
movq 0x898(%rsp), %rsi
leaq 0x690(%rsp), %rdi
movl $0x10, %edx
callq 0x8080
jmp 0x4b1be
jmp 0x4b1d9
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
jmp 0x4bf05
movq 0x100dd0(%rip), %rdi    # 0x14bfb0
leaq 0xb01d9(%rip), %rsi     # 0xfb3c0
callq 0x8330
movq %rax, 0x168(%rsp)
jmp 0x4b1f6
movq 0x168(%rsp), %rdi
movq 0x100d7b(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b20c
movl $0x1, %edi
callq 0x5bf30
jmp 0x4b218
callq 0x50940
jmp 0x4b21f
movq 0x100d8a(%rip), %rdi    # 0x14bfb0
leaq 0xb01a1(%rip), %rsi     # 0xfb3ce
callq 0x8330
movq %rax, 0x160(%rsp)
jmp 0x4b23c
movq 0x160(%rsp), %rdi
movq 0x100d35(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b252
callq 0x5bfa0
jmp 0x4b259
xorl %eax, %eax
cmpq 0x10146e(%rip), %rax    # 0x14c6d0
jne 0x4b2fd
movq 0x100d79(%rip), %rdi    # 0x14bfe8
leaq 0xaee82(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, 0x158(%rsp)
jmp 0x4b285
movq 0x158(%rsp), %rdi
leaq 0xb0146(%rip), %rsi     # 0xfb3da
callq 0x8330
movq %rax, 0x150(%rsp)
jmp 0x4b2a3
movq 0x150(%rsp), %rdi
leaq 0xb0138(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, 0x148(%rsp)
jmp 0x4b2c1
movq 0x148(%rsp), %rdi
movl $0x68, %esi
callq 0x8650
movq %rax, 0x140(%rsp)
jmp 0x4b2dd
movq 0x140(%rsp), %rdi
movq 0x100c94(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b2f3
movl $0xff, %edi
callq 0x8460
leaq 0x690(%rsp), %rdi
callq 0x82a0
movb %al, 0x13f(%rsp)
jmp 0x4b313
movb 0x13f(%rsp), %al
testb $0x1, %al
jne 0x4b320
jmp 0x4b37b
testb $0x1, 0x1013b1(%rip)    # 0x14c6d8
je 0x4b37b
leaq 0xb00b7(%rip), %rsi     # 0xfb3e7
leaq 0x690(%rsp), %rdi
callq 0x8330
movq %rax, 0x130(%rsp)
jmp 0x4b347
movq 0x130(%rsp), %rdi
movq 0x100c2a(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b35d
movq 0x10136c(%rip), %rdi    # 0x14c6d0
movq (%rdi), %rax
movq 0x18(%rax), %rax
xorl %esi, %esi
leaq 0x690(%rsp), %rdx
callq *%rax
jmp 0x4b379
jmp 0x4b37b
movq 0x100c2e(%rip), %rdi    # 0x14bfb0
leaq 0xb0063(%rip), %rsi     # 0xfb3ec
callq 0x8330
movq %rax, 0x128(%rsp)
jmp 0x4b398
movq 0x128(%rsp), %rdi
movq 0x100bd9(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b3ae
movl $0x18, %edi
callq 0x8340
movq %rax, 0x120(%rsp)
jmp 0x4b3c2
movq 0x120(%rsp), %rdi
xorps %xmm0, %xmm0
movaps %xmm0, (%rdi)
movq $0x0, 0x10(%rdi)
callq 0x18d70
movq 0x120(%rsp), %rax
movq %rax, 0x678(%rsp)
leaq 0x468(%rsp), %rdi
callq 0x4bf30
jmp 0x4b3fc
movq 0x1012cd(%rip), %rdi    # 0x14c6d0
movq 0x678(%rsp), %rdx
movq (%rdi), %rax
movq 0x10(%rax), %rax
leaq 0x468(%rsp), %rsi
callq *%rax
jmp 0x4b41e
leaq 0x468(%rsp), %rdi
callq 0x4c0e0
movq 0x100b7e(%rip), %rdi    # 0x14bfb0
leaq 0xaffc6(%rip), %rsi     # 0xfb3ff
callq 0x8330
movq %rax, 0x118(%rsp)
jmp 0x4b448
movq 0x118(%rsp), %rdi
movq 0x100b29(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b45e
movq 0x10126b(%rip), %rax    # 0x14c6d0
movq %rax, 0x110(%rsp)
cmpq $0x0, %rax
je 0x4b481
movq 0x110(%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
leaq 0x690(%rsp), %rdi
callq 0x82a0
movb %al, 0x10f(%rsp)
jmp 0x4b497
movb 0x10f(%rsp), %al
testb $0x1, %al
jne 0x4b4a7
jmp 0x4b5c3
testb $0x1, 0x100efa(%rip)    # 0x14c3a8
je 0x4b5c3
leaq 0x690(%rsp), %rdi
callq 0x42a20
jmp 0x4b4c3
leaq 0x690(%rsp), %rdi
callq 0x427c0
jmp 0x4b4d2
leaq 0xaff37(%rip), %rsi     # 0xfb410
leaq 0x690(%rsp), %rdi
callq 0x8330
movq %rax, 0x100(%rsp)
jmp 0x4b4f0
movq 0x100(%rsp), %rdi
movq 0x100a81(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b506
movq 0x678(%rsp), %rax
movq %rax, 0x460(%rsp)
movq 0x460(%rsp), %rdi
callq 0x1b070
movq %rax, 0x458(%rsp)
movq 0x460(%rsp), %rdi
callq 0x1aeb0
movq %rax, 0x450(%rsp)
leaq 0x458(%rsp), %rdi
leaq 0x450(%rsp), %rsi
callq 0x493c0
testb $0x1, %al
jne 0x4b55b
jmp 0x4b5c1
leaq 0x458(%rsp), %rdi
callq 0x1b4d0
movq (%rax), %rax
movq %rax, 0x448(%rsp)
movq 0x448(%rsp), %rdi
leaq 0x690(%rsp), %rsi
callq 0x441d0
jmp 0x4b58a
jmp 0x4b58c
leaq 0x458(%rsp), %rdi
callq 0x49460
jmp 0x4b540
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
leaq 0x468(%rsp), %rdi
callq 0x4c0e0
jmp 0x4bf05
jmp 0x4b5c3
movq 0x8a8(%rsp), %rax
movq %rax, 0xf0(%rsp)
leaq 0x41f(%rsp), %rdi
movq %rdi, 0xf8(%rsp)
callq 0x8680
movq 0xf0(%rsp), %rsi
movq 0xf8(%rsp), %rdx
leaq 0x420(%rsp), %rdi
callq 0xc570
jmp 0x4b607
movq 0x678(%rsp), %rsi
leaq 0x420(%rsp), %rdi
callq 0x16920
movq %rax, 0xe8(%rsp)
jmp 0x4b626
leaq 0x420(%rsp), %rdi
callq 0x8728
leaq 0x41f(%rsp), %rdi
callq 0x83c0
movq 0xe8(%rsp), %rax
movq %rax, 0x440(%rsp)
movq 0x678(%rsp), %rax
movq %rax, 0xe0(%rsp)
cmpq $0x0, %rax
je 0x4b685
movq 0xe0(%rsp), %rdi
callq 0x49500
movq 0xe0(%rsp), %rdi
movl $0x18, %esi
callq 0x8350
leaq 0x440(%rsp), %rax
movq %rax, 0x410(%rsp)
movq 0x100914(%rip), %rdi    # 0x14bfb0
leaq 0xafd75(%rip), %rsi     # 0xfb418
callq 0x8330
movq %rax, 0xd8(%rsp)
jmp 0x4b6b2
movq 0xd8(%rsp), %rdi
movq 0x1008bf(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b6c8
movq 0x410(%rsp), %rsi
leaq 0x3f0(%rsp), %rdi
callq 0x4c190
jmp 0x4b6df
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4c1c0
jmp 0x4b6f3
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4c3d0
jmp 0x4b707
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4c5d0
jmp 0x4b71b
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4c7d0
jmp 0x4b72f
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4c9d0
jmp 0x4b743
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4cbd0
jmp 0x4b757
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4c1c0
jmp 0x4b76b
leaq 0x3f0(%rsp), %rdi
xorl %esi, %esi
callq 0x4cdd0
jmp 0x4b77c
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4cfd0
jmp 0x4b790
leaq 0x3f0(%rsp), %rdi
xorl %esi, %esi
callq 0x4d1d0
jmp 0x4b7a1
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4d3d0
jmp 0x4b7b5
leaq 0x3f0(%rsp), %rdi
xorl %esi, %esi
callq 0x4d1d0
jmp 0x4b7c6
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4d5d0
jmp 0x4b7da
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4d3d0
jmp 0x4b7ee
leaq 0x3f0(%rsp), %rdi
xorl %esi, %esi
callq 0x4d1d0
jmp 0x4b7ff
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4d7d0
jmp 0x4b813
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4d9d0
jmp 0x4b827
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4dbd0
jmp 0x4b83b
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4ddd0
jmp 0x4b84f
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4dfd0
jmp 0x4b863
leaq 0x3f0(%rsp), %rdi
xorl %esi, %esi
callq 0x4d9d0
jmp 0x4b874
leaq 0x3f0(%rsp), %rdi
movl $0x1, %esi
callq 0x4dbd0
jmp 0x4b888
leaq 0x690(%rsp), %rdi
callq 0x82a0
movb %al, 0xd7(%rsp)
jmp 0x4b89e
movb 0xd7(%rsp), %al
testb $0x1, %al
jne 0x4b8ae
jmp 0x4b933
movzbl 0x100e24(%rip), %esi    # 0x14c6d9
andl $0x1, %esi
leaq 0x3f0(%rsp), %rdi
leaq 0x690(%rsp), %rdx
callq 0x4e1d0
jmp 0x4b8cf
jmp 0x4b94d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
jmp 0x4b908
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
leaq 0x420(%rsp), %rdi
callq 0x8728
leaq 0x41f(%rsp), %rdi
callq 0x83c0
jmp 0x4bf05
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
jmp 0x4bef8
movq 0x100676(%rip), %rdx    # 0x14bfb0
leaq 0x3f0(%rsp), %rdi
xorl %esi, %esi
callq 0x4e1d0
jmp 0x4b94b
jmp 0x4b94d
movq 0x10065c(%rip), %rdi    # 0x14bfb0
leaq 0xafacb(%rip), %rsi     # 0xfb426
callq 0x8330
movq %rax, 0xc8(%rsp)
jmp 0x4b96a
movq 0xc8(%rsp), %rdi
movq 0x100607(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4b980
movq 0x440(%rsp), %rax
movq %rax, 0xc0(%rsp)
cmpq $0x0, %rax
jne 0x4b99d
callq 0x83e0
jmp 0x4b99d
movq 0xc0(%rsp), %rax
movq (%rax), %rax
movq -0x8(%rax), %rdi
leaq 0xfec0d(%rip), %rsi     # 0x14a5c0
callq 0x4e410
testb $0x1, %al
jne 0x4ba55
movq 0x100621(%rip), %rdi    # 0x14bfe8
leaq 0xae72a(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, 0xb8(%rsp)
jmp 0x4b9dd
movq 0xb8(%rsp), %rdi
leaq 0xaf9ee(%rip), %rsi     # 0xfb3da
callq 0x8330
movq %rax, 0xb0(%rsp)
jmp 0x4b9fb
movq 0xb0(%rsp), %rdi
leaq 0xaf9e0(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, 0xa8(%rsp)
jmp 0x4ba19
movq 0xa8(%rsp), %rdi
movl $0xba, %esi
callq 0x8650
movq %rax, 0xa0(%rsp)
jmp 0x4ba35
movq 0xa0(%rsp), %rdi
movq 0x10053c(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4ba4b
movl $0xff, %edi
callq 0x8460
movq 0x100554(%rip), %rdi    # 0x14bfb0
leaq 0xaf9cf(%rip), %rsi     # 0xfb432
callq 0x8330
movq %rax, 0x98(%rsp)
jmp 0x4ba72
movq 0x98(%rsp), %rdi
movq 0x1004ff(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4ba88
leaq 0x1f0(%rsp), %rdi
callq 0x8630
jmp 0x4ba97
leaq 0x1cf(%rsp), %rdi
movq %rdi, 0x90(%rsp)
callq 0x8680
movq 0x90(%rsp), %rdx
leaq 0xae69e(%rip), %rsi     # 0xfa159
leaq 0x1d0(%rsp), %rdi
callq 0xc570
jmp 0x4baca
leaq 0x1cf(%rsp), %rdi
callq 0x83c0
xorl %eax, %eax
cmpq 0x8a0(%rsp), %rax
jne 0x4bbc7
movq 0x8a8(%rsp), %rdi
movq %rdi, 0x78(%rsp)
callq 0x81b0
movq %rax, %rcx
movq 0x78(%rsp), %rax
leaq -0x1(%rax,%rcx), %rax
movq %rax, 0x80(%rsp)
leaq 0x1a7(%rsp), %rdi
movq %rdi, 0x88(%rsp)
callq 0x8680
movq 0x78(%rsp), %rsi
movq 0x80(%rsp), %rdx
movq 0x88(%rsp), %rcx
leaq 0x1a8(%rsp), %rdi
callq 0x4e490
jmp 0x4bb47
leaq 0x1d0(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x8480
leaq 0x1a8(%rsp), %rdi
callq 0x8728
leaq 0x1a7(%rsp), %rdi
callq 0x83c0
jmp 0x4bc56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
leaq 0x1cf(%rsp), %rdi
callq 0x83c0
jmp 0x4be9a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
leaq 0x1a7(%rsp), %rdi
callq 0x83c0
jmp 0x4be8d
movq 0x8a0(%rsp), %rax
movq %rax, 0x68(%rsp)
leaq 0x17f(%rsp), %rdi
movq %rdi, 0x70(%rsp)
callq 0x8680
movq 0x68(%rsp), %rsi
movq 0x70(%rsp), %rdx
leaq 0x180(%rsp), %rdi
callq 0xc570
jmp 0x4bbff
leaq 0x1d0(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0x8480
leaq 0x180(%rsp), %rdi
callq 0x8728
leaq 0x17f(%rsp), %rdi
callq 0x83c0
jmp 0x4bc56
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
leaq 0x17f(%rsp), %rdi
callq 0x83c0
jmp 0x4be8d
leaq 0x1f0(%rsp), %rdi
leaq 0x1d0(%rsp), %rsi
movl $0x10, %edx
callq 0x81d0
jmp 0x4bc72
leaq 0x690(%rsp), %rdi
callq 0x82a0
movb %al, 0x67(%rsp)
jmp 0x4bc85
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0x4bc8f
jmp 0x4bcf1
leaq 0xaf7a8(%rip), %rsi     # 0xfb43e
leaq 0x690(%rsp), %rdi
callq 0x8330
movq %rax, 0x58(%rsp)
jmp 0x4bcaa
movq 0x58(%rsp), %rdi
leaq 0x1d0(%rsp), %rsi
callq 0x8310
movq %rax, 0x50(%rsp)
jmp 0x4bcc3
movq 0x50(%rsp), %rdi
movq 0x1002b1(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4bcd6
jmp 0x4bcf1
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x688(%rsp)
movl %eax, 0x684(%rsp)
jmp 0x4be8d
movq 0x440(%rsp), %rdi
movq (%rdi), %rax
movq 0x10(%rax), %rax
leaq 0x1f0(%rsp), %rsi
callq *%rax
jmp 0x4bd0c
leaq 0x1f0(%rsp), %rdi
callq 0x82a0
movb %al, 0x4f(%rsp)
jmp 0x4bd1f
movb 0x4f(%rsp), %al
testb $0x1, %al
jne 0x4bda6
jmp 0x4bd29
movq 0x1002b8(%rip), %rdi    # 0x14bfe8
leaq 0xae3c1(%rip), %rsi     # 0xfa0f8
callq 0x8330
movq %rax, 0x40(%rsp)
jmp 0x4bd43
movq 0x40(%rsp), %rdi
leaq 0xaf68b(%rip), %rsi     # 0xfb3da
callq 0x8330
movq %rax, 0x38(%rsp)
jmp 0x4bd5b
movq 0x38(%rsp), %rdi
leaq 0xaf683(%rip), %rsi     # 0xfb3ea
callq 0x8330
movq %rax, 0x30(%rsp)
jmp 0x4bd73
movq 0x30(%rsp), %rdi
movl $0xcc, %esi
callq 0x8650
movq %rax, 0x28(%rsp)
jmp 0x4bd89
movq 0x28(%rsp), %rdi
movq 0x1001eb(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4bd9c
movl $0xff, %edi
callq 0x8460
movq 0x1001d3(%rip), %rsi    # 0x14bf80
leaq 0x1f0(%rsp), %rdi
callq 0x8380
jmp 0x4bdbc
leaq 0x690(%rsp), %rdi
callq 0x82a0
movb %al, 0x27(%rsp)
jmp 0x4bdcf
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0x4bdd9
jmp 0x4be09
leaq 0xaf676(%rip), %rsi     # 0xfb456
leaq 0x690(%rsp), %rdi
callq 0x8330
movq %rax, 0x18(%rsp)
jmp 0x4bdf4
movq 0x18(%rsp), %rdi
movq 0x100180(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4be07
jmp 0x4be09
leaq 0x1f0(%rsp), %rdi
callq 0x8530
jmp 0x4be18
leaq 0x1d0(%rsp), %rdi
callq 0x8728
leaq 0x1f0(%rsp), %rdi
callq 0x8570
movq 0x100177(%rip), %rdi    # 0x14bfb0
leaq 0xaf627(%rip), %rsi     # 0xfb467
callq 0x8330
movq %rax, 0x10(%rsp)
jmp 0x4be4c
movq 0x10(%rsp), %rdi
movq 0x100128(%rip), %rsi    # 0x14bf80
callq 0x8380
jmp 0x4be5f
leaq 0x690(%rsp), %rdi
callq 0x82a0
movb %al, 0xf(%rsp)
jmp 0x4be72
movb 0xf(%rsp), %al
testb $0x1, %al
jne 0x4be7c
jmp 0x4bea9
leaq 0x690(%rsp), %rdi
callq 0x8530
jmp 0x4be8b
jmp 0x4bea9
leaq 0x1d0(%rsp), %rdi
callq 0x8728
leaq 0x1f0(%rsp), %rdi
callq 0x8570
jmp 0x4bef8
movq 0x440(%rsp), %rax
movq %rax, (%rsp)
cmpq $0x0, %rax
je 0x4bec5
movq (%rsp), %rdi
movq (%rdi), %rax
callq *0x8(%rax)
movq $0x0, 0x440(%rsp)
movl $0x0, 0x8c4(%rsp)
leaq 0x3f0(%rsp), %rdi
callq 0x4e510
leaq 0x690(%rsp), %rdi
callq 0x8570
jmp 0x4bf14
leaq 0x3f0(%rsp), %rdi
callq 0x4e510
leaq 0x690(%rsp), %rdi
callq 0x8570
jmp 0x4bf23
movl 0x8c4(%rsp), %eax
addq $0x8c8, %rsp            # imm = 0x8C8
retq
movq 0x688(%rsp), %rdi
callq 0x8670