// File: /workspace/github_cpp_makefile_star2_O2/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
andl $0x0, 0x2d2bb(%rip)     # 0x81730
movq 0x8(%rdi), %rax
movq (%rax), %rdi
testq %rdi, %rdi
je 0x54e41
leaq 0x2b1bc(%rip), %rsi     # 0x7f648
leaq 0x2c46d(%rip), %rdx     # 0x80900
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54e41
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
leaq 0x40(%rsp), %rbx
leaq 0x28(%rsp), %r15
movq %rax, %rcx
movq %rax, 0x10(%rsp)
movq (%rcx), %rcx
cmpq %rax, %rcx
je 0x54532
movq %rcx, 0x8(%rsp)
movq 0x10(%rcx), %r13
addq $0x30, %r13
movq %r13, %rbp
movq (%rbp), %rbp
cmpq %r13, %rbp
je 0x54526
movq 0x10(%rbp), %r12
addq $0x28, %r12
movq %r12, %r14
movq (%r14), %r14
cmpq %r12, %r14
je 0x544f4
movq 0x10(%r14), %rax
movq %rax, 0x28(%rsp)
movq %rbx, %rdi
movq %r15, %rsi
callq 0x3a8ec
jmp 0x54508
movq 0x10(%rsp), %rax
movq 0x8(%rsp), %rcx
jmp 0x544dc
leaq 0x28(%rsp), %rax
movq %rbx, (%rax)
leaq 0x2be87(%rip), %r12     # 0x803c8
leaq 0x38(%rsp), %r13
cmpq $0x0, 0x58(%rsp)
je 0x54d4c
movq 0x50(%rsp), %rax
movq 0x8(%rax), %rax
movq %rax, 0x30(%rsp)
testq %rax, %rax
je 0x54d65
movq %rbx, %rdi
leaq 0x30(%rsp), %rsi
callq 0x3a7ea
movq 0x30(%rsp), %r14
testq %r14, %r14
je 0x54546
movq %r14, %rdi
movq %r12, %rsi
leaq 0x2c2b3(%rip), %rdx     # 0x80840
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54607
movq %rax, %rbp
movq 0x50(%rax), %rax
subq 0x48(%rbp), %rax
movabsq $0xffffffff0, %rcx      # imm = 0xFFFFFFFF0
andq %rcx, %rax
cmpq $0x20, %rax
jne 0x54678
incl 0x2d16f(%rip)           # 0x81730
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r14
movq 0x8(%rbp), %r15
movq %rbp, %rdi
xorl %esi, %esi
callq 0x269a6
movq %rbp, %rdx
addq $0x28, %rdx
movq %r14, %rdi
movq %r15, %rsi
movq %rax, %rcx
movq %rbp, %r8
callq 0x5500a
leaq 0x28(%rsp), %rdi
movq %rbp, %rsi
movq %r14, %rdx
callq 0x54fc2
jmp 0x54546
movq %r14, %rdi
movq %r12, %rsi
leaq 0x2c1ec(%rip), %rdx     # 0x80800
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x5473b
movq %rax, %r15
incl 0x2d103(%rip)           # 0x81730
movq %rax, %r14
addq $0x10, %r14
movq %r14, %rbp
movq (%rbp), %rbp
cmpq %r14, %rbp
je 0x54710
movq 0x10(%rbp), %rax
movq 0x8(%rax), %rdi
testq %rdi, %rdi
je 0x54664
leaq 0x2bf68(%rip), %rsi     # 0x805c0
movq %r12, %rdx
xorl %ecx, %ecx
callq 0x82c0
jmp 0x54666
xorl %eax, %eax
movq %rax, 0x38(%rsp)
movq %rbx, %rdi
movq %r13, %rsi
callq 0x55160
jmp 0x54637
movq %rbp, %rdi
xorl %esi, %esi
callq 0x269a6
testq %rax, %rax
je 0x54546
movq %rax, %rdi
leaq 0x2bdeb(%rip), %rsi     # 0x80480
leaq 0x2be0c(%rip), %rdx     # 0x804a8
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54546
movq %rax, %r15
pushq $0x2
popq %r14
movq 0x50(%rbp), %rax
subq 0x48(%rbp), %rax
shrq $0x4, %rax
cmpl %eax, %r14d
jae 0x5478e
movq %rbp, %rdi
movl %r14d, %esi
callq 0x269a6
testq %rax, %rax
je 0x5478e
movq %rax, %rdi
leaq 0x2bd9a(%rip), %rsi     # 0x80480
leaq 0x2bdbb(%rip), %rdx     # 0x804a8
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x5478e
movl 0x48(%rax), %eax
cmpl 0x48(%r15), %eax
jne 0x5478e
addl $0x2, %r14d
jmp 0x546b3
movq %r15, %rdi
xorl %esi, %esi
callq 0x269a6
movq %r15, %rdi
movq %rax, %rsi
callq 0x26812
movq %r15, %rdi
callq 0x26b16
movq (%r15), %rax
movq %r15, %rdi
callq *0x8(%rax)
jmp 0x54546
movq %r14, %rdi
movq %r12, %rsi
leaq 0x2beb8(%rip), %rdx     # 0x80600
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x547e2
movq %rax, %rbp
movq %rax, %rdi
xorl %esi, %esi
callq 0x269a6
testq %rax, %rax
je 0x548a9
movq %rax, %rdi
leaq 0x2bd08(%rip), %rsi     # 0x80480
leaq 0x2bd29(%rip), %rdx     # 0x804a8
xorl %ecx, %ecx
callq 0x82c0
movq %rax, %r15
jmp 0x548ac
movq 0x50(%rbp), %rax
subq 0x48(%rbp), %rax
shrq $0x4, %rax
cmpl %r14d, %eax
jne 0x54546
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r14
movq 0x8(%rbp), %rsi
movq %rbp, %rdx
addq $0x28, %rdx
movq %rax, %rdi
movq %r15, %rcx
movq %rbp, %r8
callq 0x5500a
leaq 0x28(%rsp), %rdi
movq %rbp, %rsi
movq %r14, %rdx
callq 0x54fc2
incl 0x2cf53(%rip)           # 0x81730
jmp 0x54546
movq %r14, %rdi
movq %r12, %rsi
leaq 0x2be51(%rip), %rdx     # 0x80640
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x549a3
movq %rax, %rbp
movq %rax, %rdi
xorl %esi, %esi
callq 0x269a6
testq %rax, %rax
je 0x54546
movq %rax, %rdi
leaq 0x2bc61(%rip), %rsi     # 0x80480
leaq 0x2bc82(%rip), %rdx     # 0x804a8
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54546
incl 0x2cef4(%rip)           # 0x81730
movl 0x48(%rax), %esi
movq %rbp, %rdi
callq 0x26bae
movl %eax, %r14d
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, 0x8(%rsp)
movq 0x8(%rbp), %rax
movq %rax, 0x10(%rsp)
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r15
movq %rax, %rdi
movl %r14d, %esi
callq 0x34c2c
movq %rbp, %rdx
addq $0x28, %rdx
movq 0x8(%rsp), %rdi
movq 0x10(%rsp), %rsi
movq %r15, %rcx
movq %rbp, %r8
callq 0x5500a
leaq 0x28(%rsp), %rdi
movq %rbp, %rsi
movq 0x8(%rsp), %rdx
callq 0x54fc2
jmp 0x54546
xorl %r15d, %r15d
movq %rbp, %rdi
pushq $0x1
popq %rsi
callq 0x269a6
testq %rax, %rax
je 0x548d6
movq %rax, %rdi
leaq 0x2bbba(%rip), %rsi     # 0x80480
leaq 0x2bbdb(%rip), %rdx     # 0x804a8
xorl %ecx, %ecx
callq 0x82c0
jmp 0x548d8
xorl %eax, %eax
movq %r15, %rcx
orq %rax, %rcx
je 0x54546
testq %r15, %r15
je 0x54940
cmpl $0x0, 0x48(%r15)
jne 0x54940
movl 0x68(%rbp), %ecx
addl $-0x2, %ecx
cmpl $0x2, %ecx
ja 0x54940
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, 0x8(%rsp)
movq 0x8(%rbp), %r15
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r14
movq %rax, %rdi
xorl %esi, %esi
callq 0x34c2c
movq %rbp, %rdx
addq $0x28, %rdx
movq 0x8(%rsp), %rdi
movq %r15, %rsi
movq %r14, %rcx
movq %rbp, %r8
callq 0x5500a
jmp 0x54546
testq %rax, %rax
je 0x54546
movl 0x48(%rax), %edx
testl %edx, %edx
jne 0x54bdd
cmpl $0x2, 0x68(%rbp)
jne 0x54bdd
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, 0x8(%rsp)
movq 0x8(%rbp), %r15
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r14
movq %rax, %rdi
xorl %esi, %esi
callq 0x34c2c
movq %rbp, %rdx
addq $0x28, %rdx
movq 0x8(%rsp), %rdi
movq %r15, %rsi
movq %r14, %rcx
movq %rbp, %r8
callq 0x5500a
jmp 0x54546
movq %r14, %rdi
movq %r12, %rsi
leaq 0x2bcd0(%rip), %rdx     # 0x80680
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54546
movq %rax, %rdi
movq 0x50(%rax), %rax
subq 0x48(%rdi), %rax
movabsq $0xffffffff0, %rcx      # imm = 0xFFFFFFFF0
andq %rcx, %rax
cmpq $0x30, %rax
jne 0x54546
movq %rdi, 0x10(%rsp)
xorl %esi, %esi
callq 0x269a6
testq %rax, %rax
movq 0x10(%rsp), %r14
je 0x54546
movq %rax, %rdi
leaq 0x2ba7a(%rip), %rsi     # 0x80480
leaq 0x2ba9b(%rip), %rdx     # 0x804a8
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54546
movq %rax, %r15
movq %r14, %rdi
pushq $0x1
popq %rsi
callq 0x269a6
testq %rax, %rax
movq 0x10(%rsp), %r14
je 0x54546
movq %rax, %rdi
leaq 0x2ba3d(%rip), %rsi     # 0x80480
leaq 0x2ba5e(%rip), %rdx     # 0x804a8
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54546
movq %rax, %rbp
movq %r14, %rdi
pushq $0x2
popq %rsi
callq 0x269a6
testq %rax, %rax
je 0x54e8f
movq %rax, %rdi
leaq 0x2ba05(%rip), %rsi     # 0x80480
leaq 0x2ba3e(%rip), %rdx     # 0x804c0
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54e8f
movq %rax, %r14
movq 0x10(%rsp), %rdi
movq 0x60(%rdi), %rax
movq %rax, 0x8(%rsp)
movq 0x48(%r14), %rax
movq %rax, 0x20(%rsp)
movl 0x48(%r15), %esi
movl 0x48(%rbp), %edx
callq 0x26c1a
incl 0x2cc72(%rip)           # 0x81730
testb %al, %al
je 0x54c3d
pushq $0x70
popq %rdi
callq 0x8250
movq %rax, %r15
movq %rax, %rdi
movq %r14, %rsi
movq 0x10(%rsp), %rdx
callq 0x55080
movq 0x8(%rsp), %rdi
callq 0x28406
movq %rax, %r15
testq %rax, %rax
je 0x54ed5
movq 0x8(%rsp), %r14
movq %r14, %rdi
movq %r15, %rsi
callq 0x289be
movq %r15, %rdi
movq %r14, %rsi
callq 0x289d4
addq $0x28, %r15
movq %r15, 0x20(%rsp)
movq %r15, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
cmpq 0x20(%rsp), %rax
je 0x54d35
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0x54d35
movq %r12, %rsi
leaq 0x2bcec(%rip), %rdx     # 0x80840
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54d35
movq %rax, %r15
xorl %ebp, %ebp
leal 0x1(%rbp), %r14d
movq 0x50(%r15), %rax
subq 0x48(%r15), %rax
shrq $0x4, %rax
cmpl %eax, %r14d
jae 0x54b20
movq %r15, %rdi
movl %r14d, %esi
callq 0x269a6
testq %rax, %rax
je 0x54df9
movq %rax, %rdi
leaq 0x2b8e4(%rip), %rsi     # 0x80480
leaq 0x2b91d(%rip), %rdx     # 0x804c0
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54df9
movq 0x8(%rsp), %rcx
cmpq %rcx, 0x48(%rax)
je 0x54bc3
addl $0x2, %ebp
jmp 0x54b69
movq %r15, %rdi
movl %r14d, %esi
callq 0x26a14
movq %r15, %rdi
movl %ebp, %esi
callq 0x26a14
jmp 0x54b20
testq %r15, %r15
je 0x54546
movl 0x48(%r15), %esi
movq %rbp, %rdi
callq 0x26b22
movl %eax, 0x10(%rsp)
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, 0x8(%rsp)
movq 0x8(%rbp), %r14
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r15
movq %rax, %rdi
movl 0x10(%rsp), %esi
callq 0x34c2c
movq %rbp, %rdx
addq $0x28, %rdx
movq 0x8(%rsp), %rdi
movq %r14, %rsi
movq %r15, %rcx
movq %rbp, %r8
callq 0x5500a
jmp 0x54546
movq 0x20(%rsp), %r15
movq %r15, %rdi
movq 0x8(%rsp), %r14
movq %r14, %rsi
callq 0x289d4
movq %r14, %rdi
movq %r15, %rsi
callq 0x289be
movq 0x20(%rsp), %rbp
addq $0x28, %rbp
movq %rbp, 0x20(%rsp)
movq %rbp, 0x18(%rsp)
movq 0x18(%rsp), %rax
movq (%rax), %rax
movq %rax, 0x18(%rsp)
cmpq 0x20(%rsp), %rax
je 0x54d29
movq 0x18(%rsp), %rax
movq 0x10(%rax), %rdi
testq %rdi, %rdi
je 0x54d29
movq %r12, %rsi
leaq 0x2bb9c(%rip), %rdx     # 0x80840
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54d29
movq %rax, %r15
xorl %ebp, %ebp
leal 0x1(%rbp), %r14d
movq 0x50(%r15), %rax
subq 0x48(%r15), %rax
shrq $0x4, %rax
cmpl %eax, %r14d
jae 0x54c70
movq %r15, %rdi
movl %r14d, %esi
callq 0x269a6
testq %rax, %rax
je 0x54dae
movq %rax, %rdi
leaq 0x2b798(%rip), %rsi     # 0x80480
leaq 0x2b7d1(%rip), %rdx     # 0x804c0
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x54dae
movq 0x8(%rsp), %rcx
cmpq %rcx, 0x48(%rax)
je 0x54d0f
addl $0x2, %ebp
jmp 0x54cb5
movq %r15, %rdi
movl %r14d, %esi
callq 0x26a14
movq %r15, %rdi
movl %ebp, %esi
callq 0x26a14
jmp 0x54c70
movq 0x10(%rsp), %rdi
callq 0x26b16
jmp 0x54d3f
movq 0x10(%rsp), %rdi
callq 0x26b16
movq 0x10(%rsp), %rdi
movq (%rdi), %rax
jmp 0x54733
leaq 0x40(%rsp), %rdi
callq 0x3a2a2
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x2c27c(%rip), %rdi     # 0x80fe8
leaq 0x1375(%rip), %rsi      # 0x560e8
callq 0x8240
leaq 0x4e6f(%rip), %rsi      # 0x59bee
movq %rax, %rdi
callq 0x8240
leaq 0x2592(%rip), %rsi      # 0x57320
movq %rax, %rdi
callq 0x8240
pushq $0x2a
popq %rsi
movq %rax, %rdi
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x54e85
movq 0x2c233(%rip), %rdi     # 0x80fe8
leaq 0x132c(%rip), %rsi      # 0x560e8
callq 0x8240
leaq 0x4e26(%rip), %rsi      # 0x59bee
movq %rax, %rdi
callq 0x8240
leaq 0x2549(%rip), %rsi      # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0xab, %esi
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x54e85
movq 0x2c1e8(%rip), %rdi     # 0x80fe8
leaq 0x12e1(%rip), %rsi      # 0x560e8
callq 0x8240
leaq 0x4ddb(%rip), %rsi      # 0x59bee
movq %rax, %rdi
callq 0x8240
leaq 0x24fe(%rip), %rsi      # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x92, %esi
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x54e85
movq 0x2c1a0(%rip), %rdi     # 0x80fe8
leaq 0x1299(%rip), %rsi      # 0x560e8
callq 0x8240
leaq 0x4d93(%rip), %rsi      # 0x59bee
movq %rax, %rdi
callq 0x8240
leaq 0x24b6(%rip), %rsi      # 0x57320
movq %rax, %rdi
callq 0x8240
pushq $0x10
popq %rsi
movq %rax, %rdi
callq 0x84b0
movq %rax, %rdi
callq 0x8170
movl $0xff, %edi
callq 0x8300
movq 0x2c152(%rip), %rdi     # 0x80fe8
leaq 0x124b(%rip), %rsi      # 0x560e8
callq 0x8240
leaq 0x4d45(%rip), %rsi      # 0x59bee
movq %rax, %rdi
callq 0x8240
leaq 0x2468(%rip), %rsi      # 0x57320
movq %rax, %rdi
callq 0x8240
pushq $0x7d
popq %rsi
movq %rax, %rdi
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x54e85
movq 0x2c10c(%rip), %rdi     # 0x80fe8
leaq 0x1205(%rip), %rsi      # 0x560e8
callq 0x8240
leaq 0x4cff(%rip), %rsi      # 0x59bee
movq %rax, %rdi
callq 0x8240
leaq 0x2422(%rip), %rsi      # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x89, %esi
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x54e85
jmp 0x54fac
movq %rax, %rbx
pushq $0x70
popq %rsi
movq %r15, %rdi
jmp 0x54f9b
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54f42
jmp 0x54fac
jmp 0x54fac
movq %rax, %rbx
pushq $0x50
popq %rsi
movq %r14, %rdi
jmp 0x54f60
jmp 0x54fac
jmp 0x54f6f
jmp 0x54fac
jmp 0x54f6f
jmp 0x54f57
movq %rax, %rbx
pushq $0x50
popq %rsi
movq %r15, %rdi
callq 0x8260
jmp 0x54f72
jmp 0x54fac
jmp 0x54f6f
jmp 0x54fac
jmp 0x54fac
movq %rax, %rbx
pushq $0x68
popq %rsi
movq 0x8(%rsp), %rdi
jmp 0x54f9b
jmp 0x54fac
jmp 0x54f92
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
movq %rax, %rbx
pushq $0x68
popq %rsi
movq %r14, %rdi
callq 0x8260
jmp 0x54faf
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
jmp 0x54fac
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x3a2a2
movq %rbx, %rdi
callq 0x84d0
nop