// File: /workspace/github_cpp_makefile_star2_O3/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, 0x233a4(%rip)     # 0x8f760
movq 0x8(%rdi), %rax
movq (%rax), %rdi
testq %rdi, %rdi
je 0x6ce2d
leaq 0x21275(%rip), %rsi     # 0x8d648
leaq 0x22526(%rip), %rdx     # 0x8e900
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6ce2d
movq %rax, %rdx
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)
addq $0x40, %rax
movq 0x40(%rdx), %rcx
cmpq %rax, %rcx
je 0x6cdb1
leaq 0x20(%rsp), %r15
leaq 0x10(%rsp), %r12
movq %rax, (%rsp)
movq %rcx, 0x30(%rsp)
movq 0x10(%rcx), %rbp
movq 0x30(%rbp), %r14
addq $0x30, %rbp
cmpq %rbp, %r14
je 0x6c47e
movq 0x10(%r14), %r13
movq 0x28(%r13), %rbx
addq $0x28, %r13
cmpq %r13, %rbx
je 0x6c479
movq 0x10(%rbx), %rax
movq %rax, 0x20(%rsp)
leaq 0x40(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movq %r15, %rsi
movq %r12, %rdx
callq 0x497bc
movq (%rbx), %rbx
jmp 0x6c451
movq (%r14), %r14
jmp 0x6c440
movq 0x30(%rsp), %rcx
movq (%rcx), %rcx
movq (%rsp), %rax
cmpq %rax, %rcx
jne 0x6c42f
cmpq $0x0, 0x58(%rsp)
je 0x6cdb1
movabsq $0xfffffffe0, %rax      # imm = 0xFFFFFFFE0
leaq 0x21f1c(%rip), %rbx     # 0x8e3c8
addq $0x10, %rax
movq %rax, 0x30(%rsp)
leaq 0x10(%rsp), %r13
leaq 0x20(%rsp), %rbp
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x38(%rsp)
testq %rax, %rax
je 0x6cdca
leaq 0x40(%rsp), %rdi
leaq 0x38(%rsp), %rsi
callq 0x49a4a
movq 0x38(%rsp), %r15
testq %r15, %r15
je 0x6c74e
movq %r15, %rdi
movq %rbx, %r12
movq %rbx, %rsi
leaq 0x2233d(%rip), %rdx     # 0x8e840
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c598
movq %rax, %r14
movq 0x50(%rax), %rax
subq 0x48(%r14), %rax
andq 0x30(%rsp), %rax
cmpq $0x20, %rax
jne 0x6c615
incl 0x2322d(%rip)           # 0x8f760
movl $0x68, %edi
callq 0x8290
movq %rax, %r15
movq 0x8(%r14), %r12
movq %r14, %rdi
xorl %esi, %esi
callq 0x335d4
movq %r14, %rdx
addq $0x28, %rdx
movq %r15, %rdi
movq %r12, %rsi
movq %rax, %rcx
movq %r14, %r8
callq 0x6d0b2
movq %r15, 0x20(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x333d0
leaq 0x40(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movq %rbp, %rsi
movq %r13, %rdx
callq 0x497bc
movq %r14, %rdi
callq 0x33774
jmp 0x6c745
movq %r15, %rdi
movq %r12, %rsi
leaq 0x2225b(%rip), %rdx     # 0x8e800
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c75f
movq %rax, %r14
incl 0x231a2(%rip)           # 0x8f760
movq %rax, %r15
addq $0x10, %r15
movq 0x10(%rax), %r12
cmpq %r15, %r12
je 0x6c728
movq 0x10(%r12), %rax
movq 0x8(%rax), %rdi
testq %rdi, %rdi
je 0x6c5f3
leaq 0x21fd9(%rip), %rsi     # 0x8e5c0
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x8320
jmp 0x6c5f5
xorl %eax, %eax
movq %rax, 0x20(%rsp)
leaq 0x40(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movq %rbp, %rsi
movq %r13, %rdx
callq 0x6d282
movq (%r12), %r12
jmp 0x6c5c9
movq %r14, %rdi
xorl %esi, %esi
callq 0x335d4
testq %rax, %rax
je 0x6c74e
movq %rax, %rdi
leaq 0x21e4e(%rip), %rsi     # 0x8e480
leaq 0x21e6f(%rip), %rdx     # 0x8e4a8
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c74e
movq %rax, %r12
movq 0x50(%r14), %rax
subq 0x48(%r14), %rax
shrq $0x4, %rax
movl $0x2, %r15d
cmpl $0x3, %eax
jb 0x6c6bb
movq %r14, %rdi
movl %r15d, %esi
callq 0x335d4
testq %rax, %rax
je 0x6c6af
movq %rax, %rdi
leaq 0x21e03(%rip), %rsi     # 0x8e480
leaq 0x21e24(%rip), %rdx     # 0x8e4a8
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c6af
movl 0x48(%rax), %eax
cmpl 0x48(%r12), %eax
jne 0x6c6af
addl $0x2, %r15d
movq 0x50(%r14), %rax
subq 0x48(%r14), %rax
shrq $0x4, %rax
cmpl %eax, %r15d
jb 0x6c663
movq 0x50(%r14), %rax
subq 0x48(%r14), %rax
shrq $0x4, %rax
cmpl %eax, %r15d
jne 0x6c74e
movl $0x68, %edi
callq 0x8290
movq %rax, %r15
movq 0x8(%r14), %rsi
movq %r14, %rdx
addq $0x28, %rdx
movq %rax, %rdi
movq %r12, %rcx
movq %r14, %r8
callq 0x6d0b2
movq %r15, 0x20(%rsp)
movq %r14, %rdi
movq %r15, %rsi
callq 0x333d0
leaq 0x40(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movq %rbp, %rsi
movq %r13, %rdx
callq 0x497bc
movq %r14, %rdi
callq 0x33774
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
incl 0x2303a(%rip)           # 0x8f760
jmp 0x6c74e
movq %r14, %rdi
xorl %esi, %esi
callq 0x335d4
movq %r14, %rdi
movq %rax, %rsi
callq 0x333d0
movq %r14, %rdi
callq 0x33774
movq (%r14), %rax
movq %r14, %rdi
callq *0x8(%rax)
cmpq $0x0, 0x58(%rsp)
jne 0x6c4bf
jmp 0x6cdb1
movq %r15, %rdi
movq %r12, %rsi
leaq 0x21e94(%rip), %rdx     # 0x8e600
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c7ae
movq %rax, %r14
movq %rax, %rdi
xorl %esi, %esi
callq 0x335d4
testq %rax, %rax
je 0x6c893
movq %rax, %rdi
leaq 0x21ce8(%rip), %rsi     # 0x8e480
leaq 0x21d09(%rip), %rdx     # 0x8e4a8
xorl %ecx, %ecx
callq 0x8320
movq %rax, %r12
jmp 0x6c896
movq %r15, %rdi
movq %r12, %rsi
leaq 0x21e85(%rip), %rdx     # 0x8e640
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c996
movq %rax, %r14
movq %rax, %rdi
xorl %esi, %esi
callq 0x335d4
testq %rax, %rax
je 0x6c74e
movq %rax, %rdi
leaq 0x21c95(%rip), %rsi     # 0x8e480
leaq 0x21cb6(%rip), %rdx     # 0x8e4a8
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c74e
incl 0x22f58(%rip)           # 0x8f760
movl 0x48(%rax), %esi
movq %r14, %rdi
callq 0x3380e
movl %eax, %r15d
movl $0x68, %edi
callq 0x8290
movq %rax, (%rsp)
movq 0x8(%r14), %rax
movq %rax, 0x8(%rsp)
movl $0x50, %edi
callq 0x8290
movq %rax, %r12
movq %rax, %rdi
movl %r15d, %esi
callq 0x43db8
movq %r14, %rdx
addq $0x28, %rdx
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
movq %r12, %rcx
movq %r14, %r8
callq 0x6d0b2
movq (%rsp), %rsi
movq %rsi, 0x20(%rsp)
movq %r14, %rdi
callq 0x333d0
leaq 0x40(%rsp), %rdi
movq %rdi, 0x10(%rsp)
movq %rbp, %rsi
movq %r13, %rdx
callq 0x497bc
movq %r14, %rdi
callq 0x33774
jmp 0x6c745
xorl %r12d, %r12d
movq %r14, %rdi
movl $0x1, %esi
callq 0x335d4
testq %rax, %rax
je 0x6c8c2
movq %rax, %rdi
leaq 0x21bce(%rip), %rsi     # 0x8e480
leaq 0x21bef(%rip), %rdx     # 0x8e4a8
xorl %ecx, %ecx
callq 0x8320
jmp 0x6c8c4
xorl %eax, %eax
movq %r12, %rcx
orq %rax, %rcx
je 0x6c74e
testq %r12, %r12
je 0x6c930
cmpl $0x0, 0x48(%r12)
jne 0x6c930
movl 0x68(%r14), %ecx
addl $-0x2, %ecx
cmpl $0x2, %ecx
ja 0x6c930
movl $0x68, %edi
callq 0x8290
movq %rax, (%rsp)
movq 0x8(%r14), %r15
movl $0x50, %edi
callq 0x8290
movq %rax, %r12
movq %rax, %rdi
xorl %esi, %esi
callq 0x43db8
movq %r14, %rdx
addq $0x28, %rdx
movq (%rsp), %rdi
movq %r15, %rsi
movq %r12, %rcx
movq %r14, %r8
callq 0x6d0b2
jmp 0x6c74e
testq %rax, %rax
je 0x6c74e
movl 0x48(%rax), %edx
testl %edx, %edx
jne 0x6cc17
cmpl $0x2, 0x68(%r14)
jne 0x6cc17
movl $0x68, %edi
callq 0x8290
movq %rax, (%rsp)
movq 0x8(%r14), %r15
movl $0x50, %edi
callq 0x8290
movq %rax, %r12
movq %rax, %rdi
xorl %esi, %esi
callq 0x43db8
movq %r14, %rdx
addq $0x28, %rdx
movq (%rsp), %rdi
movq %r15, %rsi
movq %r12, %rcx
movq %r14, %r8
callq 0x6d0b2
jmp 0x6c74e
movq %r15, %rdi
movq %r12, %rsi
leaq 0x21cdd(%rip), %rdx     # 0x8e680
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c74e
movq %rax, %rdi
movq 0x50(%rax), %rax
subq 0x48(%rdi), %rax
andq 0x30(%rsp), %rax
cmpq $0x30, %rax
jne 0x6c74e
movq %rdi, 0x8(%rsp)
xorl %esi, %esi
callq 0x335d4
testq %rax, %rax
movq 0x8(%rsp), %r15
je 0x6c74e
movq %rax, %rdi
leaq 0x21a8f(%rip), %rsi     # 0x8e480
leaq 0x21ab0(%rip), %rdx     # 0x8e4a8
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c74e
movq %rax, %r14
movq %r15, %rdi
movl $0x1, %esi
callq 0x335d4
testq %rax, %rax
movq 0x8(%rsp), %r15
je 0x6c74e
movq %rax, %rdi
leaq 0x21a50(%rip), %rsi     # 0x8e480
leaq 0x21a71(%rip), %rdx     # 0x8e4a8
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6c74e
movq %rax, %r12
movq %r15, %rdi
movl $0x2, %esi
callq 0x335d4
testq %rax, %rax
je 0x6cf46
movq %rax, %rdi
leaq 0x21a16(%rip), %rsi     # 0x8e480
leaq 0x21a4f(%rip), %rdx     # 0x8e4c0
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6cf46
movq %rax, %r15
movq 0x8(%rsp), %rdi
movq 0x60(%rdi), %rax
movq %rax, (%rsp)
movq 0x48(%r15), %rax
movq %rax, 0x28(%rsp)
movl 0x48(%r14), %esi
movl 0x48(%r12), %edx
callq 0x3387c
incl 0x22cb2(%rip)           # 0x8f760
testb %al, %al
je 0x6cc7a
movl $0x70, %edi
callq 0x8290
movq %rax, %r14
movq %rax, %rdi
movq %r15, %rsi
movq 0x8(%rsp), %rdx
callq 0x6d150
movq (%rsp), %rdi
callq 0x35a1a
movq %rax, %r12
testq %rax, %rax
je 0x6cfac
movq %r12, %r14
movq %r12, 0x10(%rsp)
movq (%rsp), %r15
leaq 0x58(%r15), %rdi
movq %r13, %rsi
callq 0x36220
movq %r15, 0x10(%rsp)
leaq 0x40(%r12), %rdi
movq %r13, %rsi
callq 0x36220
addq $0x28, %r12
movq 0x28(%r14), %rax
movq %r12, 0x28(%rsp)
movq %rax, 0x18(%rsp)
cmpq %r12, %rax
je 0x6cc08
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0x6cc08
movq %rbx, %rsi
leaq 0x21cf7(%rip), %rdx     # 0x8e840
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6cc08
movq %rax, %r12
movq 0x50(%rax), %rax
subq 0x48(%r12), %rax
movabsq $0xfffffffe0, %rcx      # imm = 0xFFFFFFFE0
testq %rcx, %rax
je 0x6cbf0
xorl %r15d, %r15d
leal 0x1(%r15), %r14d
movq %r12, %rdi
movl %r14d, %esi
callq 0x335d4
testq %rax, %rax
je 0x6cee0
movq %rax, %rdi
leaq 0x218e7(%rip), %rsi     # 0x8e480
leaq 0x21920(%rip), %rdx     # 0x8e4c0
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6cee0
movq (%rsp), %rcx
cmpq %rcx, 0x48(%rax)
je 0x6cbda
movq 0x50(%r12), %rax
subq 0x48(%r12), %rax
shrq $0x4, %rax
leal 0x2(%r15), %ecx
addl $0x3, %r15d
cmpl %eax, %r15d
movl %ecx, %r15d
jb 0x6cb77
jmp 0x6cbf0
movq %r12, %rdi
movl %r14d, %esi
callq 0x33644
movq %r12, %rdi
movl %r15d, %esi
callq 0x33644
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
cmpq 0x28(%rsp), %rax
jne 0x6cb2d
movq 0x8(%rsp), %rdi
callq 0x33774
jmp 0x6cda4
testq %r12, %r12
je 0x6c74e
movl 0x48(%r12), %esi
movq %r14, %rdi
callq 0x33780
movl %eax, 0x8(%rsp)
movl $0x68, %edi
callq 0x8290
movq %rax, (%rsp)
movq 0x8(%r14), %r15
movl $0x50, %edi
callq 0x8290
movq %rax, %r12
movq %rax, %rdi
movl 0x8(%rsp), %esi
callq 0x43db8
movq %r14, %rdx
addq $0x28, %rdx
movq (%rsp), %rdi
movq %r15, %rsi
movq %r12, %rcx
movq %r14, %r8
callq 0x6d0b2
jmp 0x6c74e
movq (%rsp), %r14
movq %r14, 0x10(%rsp)
movq 0x28(%rsp), %r12
leaq 0x40(%r12), %rdi
movq %r13, %rsi
callq 0x36220
movq %r12, 0x10(%rsp)
leaq 0x58(%r14), %rdi
movq %r13, %rsi
callq 0x36220
movq 0x28(%r12), %rax
addq $0x28, %r12
movq %r12, 0x28(%rsp)
movq %rax, 0x18(%rsp)
cmpq %r12, %rax
je 0x6cd9a
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0x6cd9a
movq %rbx, %rsi
leaq 0x21b62(%rip), %rdx     # 0x8e840
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6cd9a
movq %rax, %r14
movq 0x50(%rax), %rax
subq 0x48(%r14), %rax
movabsq $0xfffffffe0, %rcx      # imm = 0xFFFFFFFE0
testq %rcx, %rax
je 0x6cd82
xorl %r15d, %r15d
leal 0x1(%r15), %r12d
movq %r14, %rdi
movl %r12d, %esi
callq 0x335d4
testq %rax, %rax
je 0x6ce7d
movq %rax, %rdi
leaq 0x21753(%rip), %rsi     # 0x8e480
leaq 0x2178c(%rip), %rdx     # 0x8e4c0
xorl %ecx, %ecx
callq 0x8320
testq %rax, %rax
je 0x6ce7d
movq (%rsp), %rcx
cmpq %rcx, 0x48(%rax)
je 0x6cd6c
movq 0x50(%r14), %rax
subq 0x48(%r14), %rax
shrq $0x4, %rax
leal 0x2(%r15), %ecx
addl $0x3, %r15d
cmpl %eax, %r15d
movl %ecx, %r15d
jb 0x6cd0b
jmp 0x6cd82
movq %r14, %rdi
movl %r12d, %esi
callq 0x33644
movq %r14, %rdi
movl %r15d, %esi
callq 0x33644
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
cmpq 0x28(%rsp), %rax
jne 0x6ccc2
movq 0x8(%rsp), %rdi
callq 0x33774
movq 0x8(%rsp), %rdi
movq (%rdi), %rax
jmp 0x6c74b
leaq 0x40(%rsp), %rdi
callq 0x49600
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x22217(%rip), %rdi     # 0x8efe8
leaq 0x1390(%rip), %rsi      # 0x6e168
movl $0x8, %edx
callq 0x8330
movq 0x221ff(%rip), %rdi     # 0x8efe8
leaq 0x4eb6(%rip), %rsi      # 0x71ca6
movl $0x20, %edx
callq 0x8330
movq 0x221e7(%rip), %rdi     # 0x8efe8
leaq 0x25b8(%rip), %rsi      # 0x6f3c0
movl $0x1, %edx
callq 0x8330
movq 0x221cf(%rip), %rdi     # 0x8efe8
movl $0x2a, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6ce73
movq 0x221b4(%rip), %rdi     # 0x8efe8
leaq 0x132d(%rip), %rsi      # 0x6e168
callq 0x8280
leaq 0x4e5f(%rip), %rsi      # 0x71ca6
movq %rax, %rdi
callq 0x8280
leaq 0x256a(%rip), %rsi      # 0x6f3c0
movq %rax, %rdi
callq 0x8280
movq %rax, %rdi
movl $0x10, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
movl $0xff, %edi
callq 0x8380
movq 0x22164(%rip), %rdi     # 0x8efe8
leaq 0x12dd(%rip), %rsi      # 0x6e168
movl $0x8, %edx
callq 0x8330
movq 0x2214c(%rip), %rdi     # 0x8efe8
leaq 0x4e03(%rip), %rsi      # 0x71ca6
movl $0x20, %edx
callq 0x8330
movq 0x22134(%rip), %rdi     # 0x8efe8
leaq 0x2505(%rip), %rsi      # 0x6f3c0
movl $0x1, %edx
callq 0x8330
movq 0x2211c(%rip), %rdi     # 0x8efe8
movl $0xab, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6ce73
movq 0x22101(%rip), %rdi     # 0x8efe8
leaq 0x127a(%rip), %rsi      # 0x6e168
movl $0x8, %edx
callq 0x8330
movq 0x220e9(%rip), %rdi     # 0x8efe8
leaq 0x4da0(%rip), %rsi      # 0x71ca6
movl $0x20, %edx
callq 0x8330
movq 0x220d1(%rip), %rdi     # 0x8efe8
leaq 0x24a2(%rip), %rsi      # 0x6f3c0
movl $0x1, %edx
callq 0x8330
movq 0x220b9(%rip), %rdi     # 0x8efe8
movl $0x92, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6ce73
movq 0x2209b(%rip), %rdi     # 0x8efe8
leaq 0x1214(%rip), %rsi      # 0x6e168
movl $0x8, %edx
callq 0x8330
movq 0x22083(%rip), %rdi     # 0x8efe8
leaq 0x4d3a(%rip), %rsi      # 0x71ca6
movl $0x20, %edx
callq 0x8330
movq 0x2206b(%rip), %rdi     # 0x8efe8
leaq 0x243c(%rip), %rsi      # 0x6f3c0
movl $0x1, %edx
callq 0x8330
movq 0x22053(%rip), %rdi     # 0x8efe8
movl $0x7d, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6ce73
movq 0x22035(%rip), %rdi     # 0x8efe8
leaq 0x11ae(%rip), %rsi      # 0x6e168
movl $0x8, %edx
callq 0x8330
movq 0x2201d(%rip), %rdi     # 0x8efe8
leaq 0x4cd4(%rip), %rsi      # 0x71ca6
movl $0x20, %edx
callq 0x8330
movq 0x22005(%rip), %rdi     # 0x8efe8
leaq 0x23d6(%rip), %rsi      # 0x6f3c0
movl $0x1, %edx
callq 0x8330
movq 0x21fed(%rip), %rdi     # 0x8efe8
movl $0x89, %esi
callq 0x8520
movq %rax, %rdi
callq 0x8180
jmp 0x6ce73
jmp 0x6d09c
movq %rax, %rbx
movl $0x70, %esi
movq %r14, %rdi
jmp 0x6d08b
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d042
jmp 0x6d042
jmp 0x6d09c
jmp 0x6d05a
jmp 0x6d09c
jmp 0x6d05a
jmp 0x6d042
movq %rax, %rbx
movl $0x50, %esi
movq %r12, %rdi
callq 0x82a0
jmp 0x6d05d
jmp 0x6d09c
jmp 0x6d05a
jmp 0x6d09c
movq %rax, %rbx
movl $0x68, %esi
movq (%rsp), %rdi
jmp 0x6d08b
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d080
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
movq %rax, %rbx
movl $0x68, %esi
movq %r15, %rdi
callq 0x82a0
jmp 0x6d09f
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
jmp 0x6d09c
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x49600
movq %rbx, %rdi
callq 0x8540
nop