// File: /workspace/github_cpp_makefile_star2_O1/luooofan[P]hblzbd_compiler/src/Pass/ssa_simple_optimize.cpp
// Function: SimpleOptimize::Run()
void SimpleOptimize::Run() {
  kCount = 0;
  auto m = dynamic_cast<SSAModule*>(*(this->m_));
  MyAssert(nullptr != m);
  std::unordered_set<SSAInstruction*> worklist;
#ifdef DEBUG_SIMPLE_OPTIMIZE_PROCESS
  std::cout << "SimpleOptimize :" << std::endl;
#endif
  for (auto func : m->GetFuncList()) {
    for (auto bb : func->GetBasicBlocks()) {
      for (auto inst : bb->GetInstList()) {
        worklist.insert(inst);
      }
    }
  }

  auto replace = [&worklist](SSAInstruction* from, SSAInstruction* to) {
#ifdef DEBUG_SIMPLE_OPTIMIZE_PROCESS
    std::cout << "Convert :", from->Print(std::cout);
    std::cout << "      ==>", to->Print(std::cout);
#endif
    from->ReplaceAllUseWith(to);
    worklist.insert(to);
    from->Remove();
    delete from;
  };

  while (!worklist.empty()) {
    auto inst = *worklist.begin();
    MyAssert(nullptr != inst);
    worklist.erase(inst);
    // 如果phi语句的参数全是一个常数 或者phi语句只有一个参数
    // NOTE HERE!!! 应该不用考虑phi指令间的并行赋值 会打破phi指令一定是bb中最前面几条的性质
    if (auto src_inst = dynamic_cast<PhiInst*>(inst)) {
      // 考虑只有一个参数
      if (2 == src_inst->GetNumOperands()) {
        ++kCount;
        auto mov_inst = new MovInst(src_inst->GetType(), src_inst->GetName(), src_inst->GetOperand(0), src_inst);
        replace(src_inst, mov_inst);
        continue;
      }
      // 考虑参数全是常数
      auto constint = dynamic_cast<ConstantInt*>(src_inst->GetOperand(0));
      if (nullptr == constint) continue;
      int i = 2;
      for (; i < src_inst->GetNumOperands(); i += 2) {
        auto operand = src_inst->GetOperand(i);
        auto constint2 = dynamic_cast<ConstantInt*>(operand);
        if (nullptr == constint2) break;
        if (constint2->GetImm() != constint->GetImm()) break;
      }
      if (i == src_inst->GetNumOperands()) {
        auto mov_inst = new MovInst(src_inst->GetType(), src_inst->GetName(), constint, src_inst);
        replace(src_inst, mov_inst);
        ++kCount;
        continue;
      }
    }
    // 如果是一条mov语句 该mov可删 用其操作数代替它自己
    else if (auto src_inst = dynamic_cast<MovInst*>(inst)) {
      ++kCount;
#ifdef DEBUG_SIMPLE_OPTIMIZE_PROCESS
      std::cout << "Remove :", src_inst->Print(std::cout);
#endif
      // 把所有使用该value的加入工作表 实际上只加入mov和phi语句即可
      for (auto use : src_inst->GetUses()) {
        worklist.insert(dynamic_cast<SSAInstruction*>(use->GetUser()));
      }
      src_inst->ReplaceAllUseWith(src_inst->GetOperand(0));
      src_inst->Remove();  // 从基本块中移除
      delete src_inst;
    }
    // 如果是二元运算语句 并且两个操作数都是常数 则转化为一条mov语句
    else if (auto src_inst = dynamic_cast<BinaryOperator*>(inst)) {
      // TODO: 如果有一个数是常数并且为0 并且操作符是mul div mod那么直接转为一条mov语句即可
      auto const_lhs = dynamic_cast<ConstantInt*>(src_inst->GetOperand(0));
      auto const_rhs = dynamic_cast<ConstantInt*>(src_inst->GetOperand(1));
      if (nullptr == const_lhs && nullptr == const_rhs) continue;
      MovInst* mov_inst = nullptr;
      if (nullptr != const_lhs && 0 == const_lhs->GetImm() &&
          (src_inst->op_ == BinaryOperator::DIV || src_inst->op_ == BinaryOperator::MOD ||
           src_inst->op_ == BinaryOperator::MUL)) {
        new MovInst(src_inst->GetType(), src_inst->GetName(), new ConstantInt(0), src_inst);
      } else if (nullptr != const_rhs && 0 == const_rhs->GetImm() && src_inst->op_ == BinaryOperator::MUL) {
        new MovInst(src_inst->GetType(), src_inst->GetName(), new ConstantInt(0), src_inst);
      } else if (nullptr != const_lhs && nullptr != const_rhs) {
        int res = src_inst->ComputeConstInt(const_lhs->GetImm(), const_rhs->GetImm());
        new MovInst(src_inst->GetType(), src_inst->GetName(), new ConstantInt(res), src_inst);
      }
      if (nullptr != mov_inst) {
        ++kCount;
        replace(src_inst, mov_inst);
      }
    }
    // 如果是一元运算语句 并且操作数是常数 则转化为一条mov语句
    else if (auto src_inst = dynamic_cast<UnaryOperator*>(inst)) {
      auto const_lhs = dynamic_cast<ConstantInt*>(src_inst->GetOperand(0));
      if (nullptr == const_lhs) continue;
      ++kCount;
      int res = src_inst->ComputeConstInt(const_lhs->GetImm());
      auto mov_inst = new MovInst(src_inst->GetType(), src_inst->GetName(), new ConstantInt(res), src_inst);
      replace(src_inst, mov_inst);
    }
    // 如果是条件跳转语句 并且两个操作数都是立即数 可转换为无条件跳转或者删除
    // NOTE: 还必须修改基本块的前驱后继关系
    else if (auto src_inst = dynamic_cast<BranchInst*>(inst)) {
      if (3 == src_inst->GetNumOperands()) {
        auto const_lhs = dynamic_cast<ConstantInt*>(src_inst->GetOperand(0));
        if (nullptr == const_lhs) continue;
        auto const_rhs = dynamic_cast<ConstantInt*>(src_inst->GetOperand(1));
        if (nullptr == const_rhs) continue;
        auto bb_val = dynamic_cast<BasicBlockValue*>(src_inst->GetOperand(2));
        MyAssert(nullptr != bb_val);
        auto bb = src_inst->GetParent(), target_bb = bb_val->GetBB();
        // continue;
        if (src_inst->ComputeConstInt(const_lhs->GetImm(), const_rhs->GetImm())) {
          ++kCount;
          // 条件判断永远为真 转换为无条件跳转
          auto new_inst = new BranchInst(bb_val, src_inst);
#ifdef DEBUG_SIMPLE_OPTIMIZE_PROCESS
          std::cout << "Convert :", src_inst->Print(std::cout);
          std::cout << "      ==>", new_inst->Print(std::cout);
#endif
          auto next_bb = bb->GetNextBB();
          MyAssert(nullptr != next_bb);
          bb->RemoveSuccBB(next_bb);
          next_bb->RemovePredBB(bb);
          // 修复next bb中的phi指令
          for (auto inst : next_bb->GetInstList()) {
            auto phi_inst = dynamic_cast<PhiInst*>(inst);
            if (nullptr == phi_inst) break;
            for (int i = 1; i < phi_inst->GetNumOperands(); i += 2) {
              auto bb_val = dynamic_cast<BasicBlockValue*>(phi_inst->GetOperand(i));
              MyAssert(nullptr != bb_val);
              if (bb_val->GetBB() == bb) {
                // NOTE: order and break
                phi_inst->RemoveOperand(i);
                phi_inst->RemoveOperand(i - 1);
                break;
              }
            }
          }
          src_inst->Remove();
          delete src_inst;
        } else {
          ++kCount;
          // 条件判断永远为假 直接删除
#ifdef DEBUG_SIMPLE_OPTIMIZE_PROCESS
          std::cout << "Remove :", src_inst->Print(std::cout);
#endif
          target_bb->RemovePredBB(bb);
          bb->RemoveSuccBB(target_bb);
          // 修复target bb中的phi指令
          for (auto inst : target_bb->GetInstList()) {
            auto phi_inst = dynamic_cast<PhiInst*>(inst);
            if (nullptr == phi_inst) break;
            for (int i = 1; i < phi_inst->GetNumOperands(); i += 2) {
              auto bb_val = dynamic_cast<BasicBlockValue*>(phi_inst->GetOperand(i));
              MyAssert(nullptr != bb_val);
              if (bb_val->GetBB() == bb) {
                // NOTE: order and break
                phi_inst->RemoveOperand(i);
                phi_inst->RemoveOperand(i - 1);
                break;
              }
            }
          }
          src_inst->Remove();
          delete src_inst;
        }
      }
    }
  }
#ifdef DEBUG_SIMPLE_OPTIMIZE_EFFECT
  std::cout << "SSA_SIMPLE_OPTIMIZE Pass works on " << kCount << " insts" << std::endl;
#endif
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl $0x0, 0x2345c(%rip)     # 0x90760
movq 0x8(%rdi), %rax
movq (%rax), %rdi
testq %rdi, %rdi
je 0x6d327
leaq 0x21301(%rip), %rsi     # 0x8e618
leaq 0x22612(%rip), %rdx     # 0x8f930
xorl %ecx, %ecx
callq 0x8320
jmp 0x6d329
xorl %eax, %eax
testq %rax, %rax
je 0x6de6f
leaq 0x70(%rsp), %rcx
movq %rcx, -0x30(%rcx)
movq $0x1, -0x28(%rcx)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rcx)
movl $0x3f800000, -0x10(%rcx) # imm = 0x3F800000
movups %xmm0, -0x8(%rcx)
movq 0x40(%rax), %rcx
addq $0x40, %rax
cmpq %rax, %rcx
je 0x6d3de
leaq 0x40(%rsp), %r14
leaq 0x18(%rsp), %r15
leaq 0x10(%rsp), %r12
movq %rax, 0x8(%rsp)
movq %rcx, (%rsp)
movq 0x10(%rcx), %rax
movq 0x30(%rax), %rbx
addq $0x30, %rax
movq %rax, 0x28(%rsp)
cmpq %rax, %rbx
je 0x6d3cd
movq 0x10(%rbx), %r13
movq 0x28(%r13), %rbp
addq $0x28, %r13
cmpq %r13, %rbp
je 0x6d3c3
movq 0x10(%rbp), %rax
movq %rax, 0x18(%rsp)
movq %r14, 0x10(%rsp)
movq %r14, %rdi
movq %r15, %rsi
movq %r12, %rdx
callq 0x4a158
movq (%rbp), %rbp
jmp 0x6d39c
movq (%rbx), %rbx
cmpq 0x28(%rsp), %rbx
jne 0x6d390
movq (%rsp), %rcx
movq (%rcx), %rcx
movq 0x8(%rsp), %rax
cmpq %rax, %rcx
jne 0x6d376
cmpq $0x0, 0x58(%rsp)
je 0x6dd27
movabsq $0xfffffffe0, %rax      # imm = 0xFFFFFFFE0
leaq 0x40(%rsp), %rbx
addq $0x10, %rax
movq %rax, 0x28(%rsp)
leaq 0x10(%rsp), %r15
leaq 0x18(%rsp), %r14
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x6dd40
movq %rbx, %rdi
leaq 0x38(%rsp), %rsi
callq 0x4a41e
movq 0x38(%rsp), %r13
testq %r13, %r13
je 0x6d457
movq %r13, %rdi
leaq 0x21fb4(%rip), %rsi     # 0x8f3f8
leaq 0x22425(%rip), %rdx     # 0x8f870
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r12
jmp 0x6d45a
xorl %r12d, %r12d
testq %r12, %r12
je 0x6d4e4
movq 0x50(%r12), %rax
subq 0x48(%r12), %rax
andq 0x28(%rsp), %rax
cmpq $0x20, %rax
jne 0x6d506
incl 0x232de(%rip)           # 0x90760
movl $0x68, %edi
callq 0x8290
movq %rax, %r13
movq 0x8(%r12), %rbp
movq %r12, %rdi
xorl %esi, %esi
callq 0x33480
leaq 0x28(%r12), %rdx
movq %r13, %rdi
movq %rbp, %rsi
movq %rax, %rcx
movq %r12, %r8
callq 0x6e052
movq %r13, 0x18(%rsp)
movq %r12, %rdi
movq %r13, %rsi
callq 0x3327c
movq %rbx, 0x10(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x4a158
movq %r12, %rdi
callq 0x33620
jmp 0x6d5bb
testq %r13, %r13
je 0x6d539
movq %r13, %rdi
leaq 0x21f05(%rip), %rsi     # 0x8f3f8
leaq 0x22336(%rip), %rdx     # 0x8f830
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r12
jmp 0x6d53c
movq %r12, %rdi
xorl %esi, %esi
callq 0x33480
testq %rax, %rax
je 0x6d5ff
movq %rax, %rdi
leaq 0x21f8d(%rip), %rsi     # 0x8f4b0
leaq 0x21fae(%rip), %rdx     # 0x8f4d8
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r13
jmp 0x6d602
xorl %r12d, %r12d
testq %r12, %r12
je 0x6d5d6
incl 0x23215(%rip)           # 0x90760
leaq 0x10(%r12), %r13
movq 0x10(%r12), %rbp
cmpq %r13, %rbp
je 0x6d59e
movq 0x10(%rbp), %rax
movq 0x8(%rax), %rdi
testq %rdi, %rdi
je 0x6d57e
leaq 0x22082(%rip), %rsi     # 0x8f5f0
leaq 0x21e83(%rip), %rdx     # 0x8f3f8
xorl %ecx, %ecx
callq 0x8320
jmp 0x6d580
xorl %eax, %eax
movq %rax, 0x18(%rsp)
movq %rbx, 0x10(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x6e222
movq (%rbp), %rbp
jmp 0x6d555
movq %r12, %rdi
xorl %esi, %esi
callq 0x33480
movq %r12, %rdi
movq %rax, %rsi
callq 0x3327c
movq %r12, %rdi
callq 0x33620
movq (%r12), %rax
movq %r12, %rdi
callq *0x8(%rax)
cmpq $0x0, 0x58(%rsp)
jne 0x6d40c
jmp 0x6dd27
testq %r13, %r13
je 0x6d6e8
movq %r13, %rdi
leaq 0x21e0f(%rip), %rsi     # 0x8f3f8
leaq 0x22040(%rip), %rdx     # 0x8f630
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r12
jmp 0x6d6eb
xorl %r13d, %r13d
testq %r13, %r13
je 0x6d5c5
movq 0x50(%r12), %rax
subq 0x48(%r12), %rax
shrq $0x4, %rax
movl $0x2, %ebp
cmpl $0x3, %eax
jb 0x6d66d
movq %r12, %rdi
movl %ebp, %esi
callq 0x33480
testq %rax, %rax
je 0x6d648
movq %rax, %rdi
leaq 0x21e78(%rip), %rsi     # 0x8f4b0
leaq 0x21e99(%rip), %rdx     # 0x8f4d8
xorl %ecx, %ecx
callq 0x8320
jmp 0x6d64a
xorl %eax, %eax
testq %rax, %rax
je 0x6d66d
movl 0x48(%rax), %eax
cmpl 0x48(%r13), %eax
jne 0x6d66d
addl $0x2, %ebp
movq 0x50(%r12), %rax
subq 0x48(%r12), %rax
shrq $0x4, %rax
cmpl %eax, %ebp
jb 0x6d61f
movq 0x50(%r12), %rax
subq 0x48(%r12), %rax
shrq $0x4, %rax
cmpl %eax, %ebp
jne 0x6d5c5
movl $0x68, %edi
callq 0x8290
movq %rax, %rbp
movq 0x8(%r12), %rsi
leaq 0x28(%r12), %rdx
movq %rax, %rdi
movq %r13, %rcx
movq %r12, %r8
callq 0x6e052
movq %rbp, 0x18(%rsp)
movq %r12, %rdi
movq %rbp, %rsi
callq 0x3327c
movq %rbx, 0x10(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x4a158
movq %r12, %rdi
callq 0x33620
movq (%r12), %rax
movq %r12, %rdi
callq *0x8(%rax)
incl 0x2307d(%rip)           # 0x90760
jmp 0x6d5c5
xorl %r12d, %r12d
testq %r12, %r12
je 0x6d71c
movq %r12, %rdi
xorl %esi, %esi
callq 0x33480
testq %rax, %rax
je 0x6d745
movq %rax, %rdi
leaq 0x21da7(%rip), %rsi     # 0x8f4b0
leaq 0x21dc8(%rip), %rdx     # 0x8f4d8
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r13
jmp 0x6d748
testq %r13, %r13
je 0x6d8a9
movq %r13, %rdi
leaq 0x21cc9(%rip), %rsi     # 0x8f3f8
leaq 0x21f3a(%rip), %rdx     # 0x8f670
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r12
jmp 0x6d8ac
xorl %r13d, %r13d
movq %r12, %rdi
movl $0x1, %esi
callq 0x33480
testq %rax, %rax
je 0x6d774
movq %rax, %rdi
leaq 0x21d4c(%rip), %rsi     # 0x8f4b0
leaq 0x21d6d(%rip), %rdx     # 0x8f4d8
xorl %ecx, %ecx
callq 0x8320
jmp 0x6d776
xorl %eax, %eax
movq %r13, %rcx
orq %rax, %rcx
je 0x6d5c5
testq %r13, %r13
je 0x6d7e1
cmpl $0x0, 0x48(%r13)
jne 0x6d7e1
movl 0x68(%r12), %ecx
addl $-0x2, %ecx
cmpl $0x2, %ecx
ja 0x6d7e1
movl $0x68, %edi
callq 0x8290
movq %rax, (%rsp)
movq 0x8(%r12), %r13
movl $0x50, %edi
callq 0x8290
movq %rax, %rbp
movq %rax, %rdi
xorl %esi, %esi
callq 0x4454c
leaq 0x28(%r12), %rdx
movq (%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rcx
movq %r12, %r8
callq 0x6e052
jmp 0x6d5c5
testq %rax, %rax
je 0x6d83a
cmpl $0x0, 0x48(%rax)
jne 0x6d83a
cmpl $0x2, 0x68(%r12)
jne 0x6d83a
movl $0x68, %edi
callq 0x8290
movq %rax, (%rsp)
movq 0x8(%r12), %r13
movl $0x50, %edi
callq 0x8290
movq %rax, %rbp
movq %rax, %rdi
xorl %esi, %esi
callq 0x4454c
leaq 0x28(%r12), %rdx
movq (%rsp), %rdi
movq %r13, %rsi
movq %rbp, %rcx
movq %r12, %r8
callq 0x6e052
jmp 0x6d5c5
testq %rax, %rax
sete %cl
testq %r13, %r13
sete %dl
orb %cl, %dl
jne 0x6d5c5
movl 0x48(%r13), %esi
movl 0x48(%rax), %edx
movq %r12, %rdi
callq 0x3362c
movl %eax, 0x8(%rsp)
movl $0x68, %edi
callq 0x8290
movq %rax, (%rsp)
movq 0x8(%r12), %rbp
movl $0x50, %edi
callq 0x8290
movq %rax, %r13
movq %rax, %rdi
movl 0x8(%rsp), %esi
callq 0x4454c
leaq 0x28(%r12), %rdx
movq (%rsp), %rdi
movq %rbp, %rsi
movq %r13, %rcx
movq %r12, %r8
callq 0x6e052
jmp 0x6d5c5
xorl %r12d, %r12d
testq %r12, %r12
je 0x6d8da
movq %r12, %rdi
xorl %esi, %esi
callq 0x33480
testq %rax, %rax
je 0x6d903
movq %rax, %rdi
leaq 0x21be6(%rip), %rsi     # 0x8f4b0
leaq 0x21c07(%rip), %rdx     # 0x8f4d8
xorl %ecx, %ecx
callq 0x8320
jmp 0x6d905
testq %r13, %r13
je 0x6d99a
movq %r13, %rdi
leaq 0x21b0b(%rip), %rsi     # 0x8f3f8
leaq 0x21dbc(%rip), %rdx     # 0x8f6b0
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r12
jmp 0x6d99d
xorl %eax, %eax
testq %rax, %rax
je 0x6d5c5
incl 0x22e4c(%rip)           # 0x90760
movl 0x48(%rax), %esi
movq %r12, %rdi
callq 0x336ba
movl %eax, %ebp
movl $0x68, %edi
callq 0x8290
movq %rax, (%rsp)
movq 0x8(%r12), %rax
movq %rax, 0x8(%rsp)
movl $0x50, %edi
callq 0x8290
movq %rax, %r13
movq %rax, %rdi
movl %ebp, %esi
callq 0x4454c
leaq 0x28(%r12), %rdx
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
movq %r13, %rcx
movq %r12, %r8
callq 0x6e052
movq (%rsp), %rsi
movq %rsi, 0x18(%rsp)
movq %r12, %rdi
callq 0x3327c
movq %rbx, 0x10(%rsp)
movq %rbx, %rdi
movq %r14, %rsi
movq %r15, %rdx
callq 0x4a158
movq %r12, %rdi
callq 0x33620
jmp 0x6d5bb
xorl %r12d, %r12d
testq %r12, %r12
je 0x6d5c5
movq 0x50(%r12), %rax
subq 0x48(%r12), %rax
andq 0x28(%rsp), %rax
cmpq $0x30, %rax
jne 0x6d5c5
movq %r12, %rdi
xorl %esi, %esi
callq 0x33480
movq %r12, 0x20(%rsp)
testq %rax, %rax
je 0x6d9f0
movq %rax, %rdi
leaq 0x21ad3(%rip), %rsi     # 0x8f4b0
leaq 0x21af4(%rip), %rdx     # 0x8f4d8
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r13
jmp 0x6d9f3
xorl %r13d, %r13d
testq %r13, %r13
movq 0x20(%rsp), %rdi
je 0x6d5c5
movl $0x1, %esi
callq 0x33480
testq %rax, %rax
je 0x6da2d
movq %rax, %rdi
leaq 0x21a96(%rip), %rsi     # 0x8f4b0
leaq 0x21ab7(%rip), %rdx     # 0x8f4d8
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r12
jmp 0x6da30
xorl %r12d, %r12d
testq %r12, %r12
movq 0x20(%rsp), %rdi
je 0x6d5c5
movl $0x2, %esi
callq 0x33480
testq %rax, %rax
je 0x6da67
movq %rax, %rdi
leaq 0x21a59(%rip), %rsi     # 0x8f4b0
leaq 0x21a92(%rip), %rdx     # 0x8f4f0
xorl %ecx, %ecx
callq 0x8320
jmp 0x6da69
xorl %eax, %eax
testq %rax, %rax
je 0x6debf
movq %r12, %rdi
movq 0x20(%rsp), %rdx
movq 0x60(%rdx), %rcx
movq %rcx, (%rsp)
movq %rax, %rbp
movq 0x48(%rax), %r12
movl 0x48(%r13), %esi
movq %rdx, %r13
movl 0x48(%rdi), %edx
movq %r13, %rdi
callq 0x33728
incl 0x22cbf(%rip)           # 0x90760
testb %al, %al
je 0x6dc00
movl $0x70, %edi
callq 0x8290
movq %rax, %r12
movq %rax, %rdi
movq %rbp, %rsi
movq %r13, %rdx
callq 0x6e0f0
movq (%rsp), %rdi
callq 0x358ba
movq %rax, %r13
testq %rax, %rax
je 0x6df22
movq %r13, 0x10(%rsp)
movq (%rsp), %r12
leaq 0x58(%r12), %rdi
movq %r15, %rsi
callq 0x360b8
movq %r12, 0x10(%rsp)
leaq 0x40(%r13), %rdi
movq %r15, %rsi
callq 0x360b8
addq $0x28, %r13
movq %r13, 0x30(%rsp)
movq %r13, 0x8(%rsp)
movq 0x8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x8(%rsp)
cmpq 0x30(%rsp), %rax
je 0x6dbee
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0x6db4e
leaq 0x218bd(%rip), %rsi     # 0x8f3f8
leaq 0x21d2e(%rip), %rdx     # 0x8f870
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r13
jmp 0x6db51
xorl %r13d, %r13d
testq %r13, %r13
je 0x6dbee
movq 0x50(%r13), %rax
subq 0x48(%r13), %rax
movabsq $0xfffffffe0, %rcx      # imm = 0xFFFFFFFE0
testq %rcx, %rax
je 0x6dbe5
xorl %ebp, %ebp
leal 0x1(%rbp), %r12d
movq %r13, %rdi
movl %r12d, %esi
callq 0x33480
testq %rax, %rax
je 0x6dba1
movq %rax, %rdi
leaq 0x2191f(%rip), %rsi     # 0x8f4b0
leaq 0x21958(%rip), %rdx     # 0x8f4f0
xorl %ecx, %ecx
callq 0x8320
jmp 0x6dba3
xorl %eax, %eax
testq %rax, %rax
je 0x6de0c
movq (%rsp), %rcx
cmpq %rcx, 0x48(%rax)
je 0x6dbd0
movq 0x50(%r13), %rax
subq 0x48(%r13), %rax
shrq $0x4, %rax
leal 0x2(%rbp), %ecx
addl $0x3, %ebp
cmpl %eax, %ebp
movl %ecx, %ebp
jb 0x6db73
jmp 0x6dbe5
movq %r13, %rdi
movl %r12d, %esi
callq 0x334f0
movq %r13, %rdi
movl %ebp, %esi
callq 0x334f0
testq %r13, %r13
jne 0x6db0e
movq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x33620
jmp 0x6d5bb
movq (%rsp), %r13
movq %r13, 0x10(%rsp)
leaq 0x40(%r12), %rdi
movq %r15, %rsi
callq 0x360b8
movq %r12, 0x10(%rsp)
leaq 0x58(%r13), %rdi
movq %r15, %rsi
callq 0x360b8
addq $0x28, %r12
movq %r12, 0x30(%rsp)
movq %r12, 0x8(%rsp)
movq 0x8(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x8(%rsp)
cmpq 0x30(%rsp), %rax
je 0x6dd15
movq 0x8(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0x6dc75
leaq 0x21796(%rip), %rsi     # 0x8f3f8
leaq 0x21c07(%rip), %rdx     # 0x8f870
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r13
jmp 0x6dc78
xorl %r13d, %r13d
testq %r13, %r13
je 0x6dd15
movq 0x50(%r13), %rax
subq 0x48(%r13), %rax
movabsq $0xfffffffe0, %rcx      # imm = 0xFFFFFFFE0
testq %rcx, %rax
je 0x6dd0c
xorl %ebp, %ebp
leal 0x1(%rbp), %r12d
movq %r13, %rdi
movl %r12d, %esi
callq 0x33480
testq %rax, %rax
je 0x6dcc8
movq %rax, %rdi
leaq 0x217f8(%rip), %rsi     # 0x8f4b0
leaq 0x21831(%rip), %rdx     # 0x8f4f0
xorl %ecx, %ecx
callq 0x8320
jmp 0x6dcca
xorl %eax, %eax
testq %rax, %rax
je 0x6dda6
movq (%rsp), %rcx
cmpq %rcx, 0x48(%rax)
je 0x6dcf7
movq 0x50(%r13), %rax
subq 0x48(%r13), %rax
shrq $0x4, %rax
leal 0x2(%rbp), %ecx
addl $0x3, %ebp
cmpl %eax, %ebp
movl %ecx, %ebp
jb 0x6dc9a
jmp 0x6dd0c
movq %r13, %rdi
movl %r12d, %esi
callq 0x334f0
movq %r13, %rdi
movl %ebp, %esi
callq 0x334f0
testq %r13, %r13
jne 0x6dc35
movq 0x20(%rsp), %r12
movq %r12, %rdi
callq 0x33620
jmp 0x6d5bb
leaq 0x40(%rsp), %rdi
callq 0x4a002
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x222a9(%rip), %rdi     # 0x8fff0
leaq 0x141a(%rip), %rsi      # 0x6f168
movl $0x8, %edx
callq 0x8330
movq 0x22291(%rip), %rdi     # 0x8fff0
leaq 0x4f40(%rip), %rsi      # 0x72ca6
movl $0x20, %edx
callq 0x8330
movq 0x22279(%rip), %rdi     # 0x8fff0
leaq 0x2642(%rip), %rsi      # 0x703c0
movl $0x1, %edx
callq 0x8330
movq 0x22261(%rip), %rdi     # 0x8fff0
movl $0x2a, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6deb5
movq 0x22243(%rip), %rdi     # 0x8fff0
leaq 0x13b4(%rip), %rsi      # 0x6f168
movl $0x8, %edx
callq 0x8330
movq 0x2222b(%rip), %rdi     # 0x8fff0
leaq 0x4eda(%rip), %rsi      # 0x72ca6
movl $0x20, %edx
callq 0x8330
movq 0x22213(%rip), %rdi     # 0x8fff0
leaq 0x25dc(%rip), %rsi      # 0x703c0
movl $0x1, %edx
callq 0x8330
movq 0x221fb(%rip), %rdi     # 0x8fff0
movl $0xab, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6deb5
movq 0x221dd(%rip), %rdi     # 0x8fff0
leaq 0x134e(%rip), %rsi      # 0x6f168
movl $0x8, %edx
callq 0x8330
movq 0x221c5(%rip), %rdi     # 0x8fff0
leaq 0x4e74(%rip), %rsi      # 0x72ca6
movl $0x20, %edx
callq 0x8330
movq 0x221ad(%rip), %rdi     # 0x8fff0
leaq 0x2576(%rip), %rsi      # 0x703c0
movl $0x1, %edx
callq 0x8330
movq 0x22195(%rip), %rdi     # 0x8fff0
movl $0x92, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6deb5
movq 0x2217a(%rip), %rdi     # 0x8fff0
leaq 0x12eb(%rip), %rsi      # 0x6f168
callq 0x8280
leaq 0x4e1d(%rip), %rsi      # 0x72ca6
movq %rax, %rdi
callq 0x8280
leaq 0x2528(%rip), %rsi      # 0x703c0
movq %rax, %rdi
callq 0x8280
movq %rax, %rdi
movl $0x10, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
movl $0xff, %edi
callq 0x8380
movq 0x2212a(%rip), %rdi     # 0x8fff0
leaq 0x129b(%rip), %rsi      # 0x6f168
movl $0x8, %edx
callq 0x8330
movq 0x22112(%rip), %rdi     # 0x8fff0
leaq 0x4dc1(%rip), %rsi      # 0x72ca6
movl $0x20, %edx
callq 0x8330
movq 0x220fa(%rip), %rdi     # 0x8fff0
leaq 0x24c3(%rip), %rsi      # 0x703c0
movl $0x1, %edx
callq 0x8330
movq 0x220e2(%rip), %rdi     # 0x8fff0
movl $0x7d, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6deb5
movq 0x220c7(%rip), %rdi     # 0x8fff0
leaq 0x1238(%rip), %rsi      # 0x6f168
movl $0x8, %edx
callq 0x8330
movq 0x220af(%rip), %rdi     # 0x8fff0
leaq 0x4d5e(%rip), %rsi      # 0x72ca6
movl $0x20, %edx
callq 0x8330
movq 0x22097(%rip), %rdi     # 0x8fff0
leaq 0x2460(%rip), %rsi      # 0x703c0
movl $0x1, %edx
callq 0x8330
movq 0x2207f(%rip), %rdi     # 0x8fff0
movl $0x89, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6deb5
jmp 0x6e03d
movq %rax, %rbx
movl $0x70, %esi
movq %r12, %rdi
jmp 0x6e02a
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6dfbd
movq %rax, %rbx
movl $0x50, %esi
movq %rbp, %rdi
jmp 0x6dfe3
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6dff2
jmp 0x6e03d
jmp 0x6dff2
jmp 0x6dfd8
movq %rax, %rbx
movl $0x50, %esi
movq %r13, %rdi
callq 0x82a0
jmp 0x6dff5
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6dff2
jmp 0x6e03d
movq %rax, %rbx
movl $0x68, %esi
movq (%rsp), %rdi
jmp 0x6e02a
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
movq %rax, %rbx
movl $0x68, %esi
movq %rbp, %rdi
jmp 0x6e02a
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
movq %rax, %rbx
movl $0x68, %esi
movq %r13, %rdi
callq 0x82a0
jmp 0x6e040
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
jmp 0x6e03d
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x4a002
movq %rbx, %rdi
callq 0x8540