// File: /workspace/github_cpp_makefile_star2_O2/luooofan[P]hblzbd_compiler/src/Pass/convert_ssa.cpp
// Function: ConvertSSA::ConstructSSA4BB(IRBasicBlock*, SSAFunction*, std::unordered_map<IRBasicBlock*, SSABasicBlock*, std::hash<IRBasicBlock*>, std::equal_to<IRBasicBlock*>, std::allocator<std::pair<IRBasicBlock* const, SSABasicBlock*>>>&)
void ConvertSSA::ConstructSSA4BB(IRBasicBlock* bb, SSAFunction* ssafunc,
                                 std::unordered_map<IRBasicBlock*, SSABasicBlock*>& bb_map) {
  if (nullptr == bb) return;
#ifdef DEBUG_CONSTRUCT_SSA_PROCESS
  std::cout << "---Process BB:" << std::endl;
#endif

  auto ssabb = bb_map[bb];
  MyAssert(nullptr != ssabb);

  // for every ir
  for (auto ir_iter = bb->ir_list_.begin(); ir_iter != bb->ir_list_.end(); ++ir_iter) {
    auto ir = **ir_iter;
#ifdef DEBUG_CONSTRUCT_SSA_PROCESS
    // std::cout << "----Process IR:" << std::endl;
    ir.PrintIR(std::cout);
#endif
    switch (ir.op_) {
      // NOTE: assign和param可能传递i32 pointer 其他传递i32或者void arraytype只在alloca中不会传递
      // 从数组中取元素值只会出现在assign offset ir中 给数组元素赋值只会出现在assign ir中
      case ir::IR::OpKind::ADD:
      case ir::IR::OpKind::SUB:
      case ir::IR::OpKind::MUL:
      case ir::IR::OpKind::DIV:
      case ir::IR::OpKind::MOD: {
        auto lhs = ResolveOpn2Value(&(ir.opn1_), ssabb);
        auto rhs = ResolveOpn2Value(&(ir.opn2_), ssabb);
        auto res_comp_name = ir.res_.GetCompName();
        auto res =
            new BinaryOperator(new Type(Type::IntegerTyID), static_cast<BinaryOperator::OpKind>(GetOpKind(ir.op_)),
                               res_comp_name, lhs, rhs, ssabb);
        ProcessResValue(res_comp_name, &(ir.res_), res, ssabb);
        break;
      }
      case ir::IR::OpKind::NOT:
      case ir::IR::OpKind::NEG: {
        auto lhs = ResolveOpn2Value(&(ir.opn1_), ssabb);
        auto res_comp_name = ir.res_.GetCompName();
        auto res = new UnaryOperator(new Type(Type::IntegerTyID), static_cast<UnaryOperator::OpKind>(GetOpKind(ir.op_)),
                                     res_comp_name, lhs, ssabb);
        ProcessResValue(res_comp_name, &(ir.res_), res, ssabb);
        break;
      }
      case ir::IR::OpKind::LABEL: {  // label ir已经全被删了 执行流不会到这里
        MyAssert(0);
        break;
      }
      case ir::IR::OpKind::PARAM: {  // param ir全部跳过 等call的时候处理
        break;
      }
      case ir::IR::OpKind::CALL: {
        auto func_value = dynamic_cast<FunctionValue*>(glob_map[ir.opn1_.GetCompName()]);
        MyAssert(nullptr != func_value);
        // maintain call_func
        ssafunc->AddCallFunc(func_value);

        CallInst* call_inst = nullptr;
        if (ir.res_.type_ == Opn::Type::Null) {
          call_inst = new CallInst(func_value, ssabb);
        } else {
          auto res_comp_name = ir.res_.GetCompName();
          call_inst = new CallInst(new Type(Type::IntegerTyID), res_comp_name, func_value, ssabb);
          ProcessResValue(res_comp_name, &(ir.res_), call_inst, ssabb);
        }

        // 添加参数
        MyAssert(ir.opn2_.type_ == Opn::Type::Imm);
        // NOTE: a[10][10][10]  func(a[10]) many_params1|2 chaos_token
        static int temp_for_array_address_compute = 1;
        int arg_num = ir.opn2_.imm_num_;
        for (int i = 1; i <= arg_num; ++i) {
          auto param_ir = **(ir_iter - i);
          auto val = ResolveOpn2Value(&(param_ir.opn1_), ssabb);
          if (param_ir.opn1_.type_ == Opn::Type::Array) {
            // 先把基址+偏移算到一个temp value里 再把temp value加到arg里 不必记录
            // param_ir.PrintIR(std::cout);
            auto offset_val = ResolveOpn2Value(param_ir.opn1_.offset_, ssabb) /*一定找得到 不会新加指令*/;
            auto final_address = new BinaryOperator(val->GetType(), BinaryOperator::ADD,
                                                    std::to_string(temp_for_array_address_compute++) + "-temp", val,
                                                    offset_val, call_inst);
            call_inst->AddArg(final_address);
          } else {
            call_inst->AddArg(val);
          }
        }
        break;
      }
      case ir::IR::OpKind::RET: {
        if (ir.opn1_.type_ != ir::Opn::Type::Null) {  // return int;
          auto ret_val = ResolveOpn2Value(&(ir.opn1_), ssabb);
          new ReturnInst(ret_val, ssabb);
        } else {  // return void;
          new ReturnInst(ssabb);
        }
        break;
      }
      case ir::IR::OpKind::GOTO: {
        auto bb_val = dynamic_cast<BasicBlockValue*>(ResolveOpn2Value(&(ir.opn1_), ssabb));
        MyAssert(nullptr != bb_val);
        new BranchInst(bb_val, ssabb);
        break;
      }
      case ir::IR::OpKind::ASSIGN: {
        auto val = ResolveOpn2Value(&(ir.opn1_), ssabb);
        auto res_comp_name = ir.res_.GetCompName();
        Value* res = nullptr;
        if (ir.res_.type_ != ir::Opn::Type::Array) {  // NOTE: consider array address
          if (0 == ir.res_.scope_id_) {
            auto glob_var = glob_map[res_comp_name];
            new StoreInst(val, glob_var, ssabb);

            // maintain used_glob_var
            ssafunc->AddUsedGlobVar(dynamic_cast<GlobalVariable*>(glob_var));
          } else {
            res = new MovInst(val->GetType(), res_comp_name, val, ssabb);
            work_map[res_comp_name] = res;
          }
        } else {
          auto arr_base_ptr = ResolveOpn2Value(&(ir.res_), ssabb);
          MyAssert(arr_base_ptr->GetType()->IsPointer());
          auto offset = ResolveOpn2Value(ir.res_.offset_, ssabb);
          new StoreInst(val, arr_base_ptr, offset, ssabb);
        }
        break;
      }
      case ir::IR::OpKind::ASSIGN_OFFSET: {
        MyAssert(ir.opn1_.type_ == ir::Opn::Type::Array);
        auto arr_base_ptr = ResolveOpn2Value(&(ir.opn1_), ssabb);
        MyAssert(arr_base_ptr->GetType()->IsPointer());
        auto offset = ResolveOpn2Value(ir.opn1_.offset_, ssabb);

        auto res_comp_name = ir.res_.GetCompName();
        auto res = new LoadInst(new Type(Type::IntegerTyID), res_comp_name, arr_base_ptr, offset, ssabb);
        ProcessResValue(res_comp_name, &(ir.res_), res, ssabb);
        break;
      }
      case ir::IR::OpKind::JEQ:
      case ir::IR::OpKind::JNE:
      case ir::IR::OpKind::JLT:
      case ir::IR::OpKind::JLE:
      case ir::IR::OpKind::JGT:
      case ir::IR::OpKind::JGE: {
        auto lhs = ResolveOpn2Value(&(ir.opn1_), ssabb);
        auto rhs = ResolveOpn2Value(&(ir.opn2_), ssabb);
        auto bb_val = dynamic_cast<BasicBlockValue*>(ResolveOpn2Value(&(ir.res_), ssabb));
        MyAssert(nullptr != bb_val);
        new BranchInst(static_cast<BranchInst::Cond>(GetOpKind(ir.op_)), lhs, rhs, bb_val, ssabb);
        break;
      }
      case ir::IR::OpKind::VOID: {
        MyAssert(0);
        break;
      }
      case ir::IR::OpKind::PHI: {
        MyAssert(0 != ir.res_.scope_id_);  // 不会出现全局变量的phi结点
        auto res_comp_name = ir.res_.GetCompName();
        auto phi_inst = new PhiInst(new Type(Type::IntegerTyID), res_comp_name, ssabb);
        // 此时有的变量还未定义 不能在现在填
        // for (int i = 0; i < ir.phi_args_.size(); ++i) {
        //   auto arg_val = ResolveOpn2Value(&ir.phi_args_[i], ssabb);
        //   phi_inst->AddParam(arg_val, bb_map[bb->pred_[i]]->GetValue());
        // }
        ProcessResValue(res_comp_name, &(ir.res_), phi_inst, ssabb);
        break;
      }
      case ir::IR::OpKind::ALLOCA: {
        // alloca opn - imm : alloca quad-ir only for array. regard opn as one dimensional array
        MyAssert(ir.res_.type_ == ir::Opn::Type::Imm);

        // create a value which owns i32 pointer type
        auto ptr_type = new Type(Type::PointerTyID);
        const auto& array_name = ir.opn1_.GetCompName();
        auto value = new Value(ptr_type, array_name);
        work_map[array_name] = value;

        // auto type = new ArrayType(ir.res_.imm_num_);
        // new AllocaInst(type, ssabb);
        new AllocaInst(new ConstantInt(ir.res_.imm_num_), value, ssabb);

        break;
      }
      case ir::IR::OpKind::DECLARE: {
        // 生成argument 记录映射 以防函数参数被认为是未定义变量
        auto arg_comp_name = ir.opn1_.GetCompName();
        if (ir.opn1_.type_ == Opn::Type::Var) {
          work_map[arg_comp_name] =
              new Argument(new Type(Type::IntegerTyID), arg_comp_name, ir.res_.imm_num_, ssafunc->GetValue());
        } else {
          work_map[arg_comp_name] =
              new Argument(new Type(Type::PointerTyID), arg_comp_name, ir.res_.imm_num_, ssafunc->GetValue());
        }
        break;
      }
      default: {
        MyAssert(0);
        break;
      }
    }  // end of ir_op switch
  }    // end of ir for loop
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x2a8, %rsp            # imm = 0x2A8
movq %rdx, 0x30(%rsp)
movq %rsi, 0x38(%rsp)
testq %rsi, %rsi
je 0x342ba
movq %rdi, %rbx
leaq 0x38(%rsp), %rsi
movq %rcx, %rdi
callq 0x3763c
movq (%rax), %rcx
testq %rcx, %rcx
je 0x34602
movq 0x38(%rsp), %rax
movq 0x8(%rax), %rdx
leaq 0xa8(%rbx), %rsi
movq %rsi, 0x28(%rsp)
leaq 0xe0(%rbx), %rsi
movq %rsi, 0x40(%rsp)
movq %rbx, 0x18(%rsp)
movq %rcx, 0x10(%rsp)
cmpq 0x10(%rax), %rdx
je 0x342ba
movq %rdx, 0x50(%rsp)
movq (%rdx), %rsi
leaq 0x68(%rsp), %rdi
callq 0x34faa
movl 0x68(%rsp), %eax
cmpq $0x17, %rax
ja 0x345ba
leaq 0x25d6c(%rip), %rcx     # 0x5964c
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x18(%rsp), %r14
movq %r14, %rdi
leaq 0x70(%rsp), %rsi
movq 0x10(%rsp), %r15
movq %r15, %rdx
callq 0x327cc
movq %rax, %rbx
movq %r14, %rdi
leaq 0xb0(%rsp), %rsi
movq %r15, %rdx
callq 0x327cc
movq %rax, %r13
movq %r14, %rdi
leaq 0xf0(%rsp), %rsi
movq %r15, %rdx
callq 0x327cc
testq %rax, %rax
je 0x342cc
movq %rax, %rdi
leaq 0x4cb3e(%rip), %rsi     # 0x80480
leaq 0x4cb77(%rip), %rdx     # 0x804c0
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x342cc
movq %rax, %r14
pushq $0x70
popq %rdi
callq 0x8250
movq %rax, %r12
movl 0x68(%rsp), %edi
callq 0x32ada
movq %r12, %rdi
movl %eax, %esi
movq %rbx, %rdx
movq %r13, %rcx
movq %r14, %r8
movq 0x10(%rsp), %r9
callq 0x3585c
jmp 0x3400e
movq 0x18(%rsp), %r15
movq %r15, %rdi
leaq 0x70(%rsp), %rsi
movq 0x10(%rsp), %rbx
movq %rbx, %rdx
callq 0x327cc
movq %rax, %r14
movq %r15, %rdi
leaq 0xb0(%rsp), %rsi
movq %rbx, %rdx
callq 0x327cc
movq %rax, %r13
leaq 0x148(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x1dc16
movq %r14, %rbx
pushq $0x70
popq %rdi
callq 0x8250
movq %rax, 0x20(%rsp)
pushq $0x10
popq %rdi
callq 0x8250
leaq 0x288(%rsp), %rbp
movq %rax, %r14
leaq 0x4ce91(%rip), %rax     # 0x80890
movq %rax, (%r14)
movl $0x2, 0x8(%r14)
movl 0x68(%rsp), %r12d
movq %rbp, %rdi
leaq 0x148(%rsp), %rsi
callq 0x8390
movl %r12d, %edi
callq 0x32ada
movq 0x10(%rsp), %r12
movq %r12, (%rsp)
movq 0x20(%rsp), %r15
movq %r15, %rdi
movq %r14, %rsi
movl %eax, %edx
movq %rbp, %rcx
movq %rbx, %r8
movq %r13, %r9
callq 0x35036
movq %rbp, %rdi
callq 0x8578
movq 0x18(%rsp), %rdi
leaq 0x148(%rsp), %rsi
leaq 0xf0(%rsp), %rdx
movq %r15, %rcx
movq %r12, %r8
callq 0x326c6
jmp 0x34001
movq 0x18(%rsp), %r15
movq %r15, %rdi
leaq 0x70(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x1dc16
pushq $0x70
popq %rdi
callq 0x8250
movq %rax, %r13
pushq $0x10
popq %rdi
callq 0x8250
leaq 0x268(%rsp), %r12
movq %rax, %r14
leaq 0x4cdc4(%rip), %rax     # 0x80890
movq %rax, (%r14)
movl $0x2, 0x8(%r14)
movl 0x68(%rsp), %ebp
movq %r12, %rdi
leaq 0x148(%rsp), %rsi
callq 0x8390
movl %ebp, %edi
callq 0x32ada
movq %r13, %rdi
movq %r14, %rsi
movl %eax, %edx
movq %r12, %rcx
movq %rbx, %r8
movq 0x10(%rsp), %rbx
movq %rbx, %r9
callq 0x350f0
movq %r12, %rdi
callq 0x8578
movq %r15, %rdi
leaq 0x148(%rsp), %rsi
leaq 0xf0(%rsp), %rdx
movq %r13, %rcx
movq %rbx, %r8
callq 0x326c6
jmp 0x34001
leaq 0x148(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x1dc16
cmpl $0x0, 0x70(%rsp)
je 0x33fa7
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r13
pushq $0x10
popq %rdi
callq 0x8250
leaq 0x148(%rsp), %rbx
leaq 0x4cd19(%rip), %rcx     # 0x80890
movq %rcx, (%rax)
movl $0x4, 0x8(%rax)
movl 0xf4(%rsp), %ecx
movq 0x30(%rsp), %rdx
movq 0x28(%rdx), %r8
movq %r13, %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x35ace
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x36e30
jmp 0x33ffe
movq 0x18(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq 0x327cc
testq %rax, %rax
je 0x34317
movq %rax, %rdi
leaq 0x4c8a8(%rip), %rsi     # 0x80480
leaq 0x4c8e1(%rip), %rdx     # 0x804c0
xorl %ecx, %ecx
callq 0x82c0
testq %rax, %rax
je 0x34317
movq %rax, %rbx
pushq $0x70
popq %rdi
callq 0x8250
movq %rax, %r14
movq %rax, %rdi
movq %rbx, %rsi
movq 0x10(%rsp), %rdx
callq 0x3552c
jmp 0x3400e
leaq 0x148(%rsp), %rbx
movq %rbx, %rdi
leaq 0x70(%rsp), %rsi
callq 0x1dc16
movq 0x40(%rsp), %rdi
movq %rbx, %rsi
callq 0x371d0
movq (%rax), %rdi
testq %rdi, %rdi
je 0x3402b
leaq 0x4c839(%rip), %rsi     # 0x80480
leaq 0x4c88a(%rip), %rdx     # 0x804d8
xorl %ecx, %ecx
callq 0x82c0
movq %rax, %rbp
jmp 0x3402d
movq 0x18(%rsp), %r14
movq %r14, %rdi
leaq 0x70(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %r13
leaq 0x148(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x1dc16
cmpl $0x5, 0xf0(%rsp)
jne 0x33f5d
movq %r14, %rdi
leaq 0xf0(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %rbx
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
testb %al, %al
je 0x34652
movq 0x120(%rsp), %rsi
movq %r14, %rdi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %r12
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r14
movq %rax, %rdi
movq %r13, %rsi
movq %rbx, %rdx
movq %r12, %rcx
movq 0x10(%rsp), %r8
callq 0x35682
jmp 0x34001
cmpl $0x4, 0x70(%rsp)
jne 0x33f26
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r14
movq %rax, %rdi
movq 0x10(%rsp), %rsi
callq 0x3549e
jmp 0x3400e
cmpl $0x1, 0xf0(%rsp)
jne 0x343ad
pushq $0x10
popq %rdi
callq 0x8250
movq %rax, %rbx
leaq 0x4cb46(%rip), %rax     # 0x80890
movq %rax, (%rbx)
movl $0x4, 0x8(%rbx)
leaq 0x148(%rsp), %rdi
leaq 0x70(%rsp), %rsi
callq 0x1dc16
pushq $0x48
popq %rdi
callq 0x8250
movq %rax, %r13
movq %rax, %rdi
movq %rbx, %rsi
leaq 0x148(%rsp), %rbx
movq %rbx, %rdx
callq 0x276c6
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x36e30
movq %r13, (%rax)
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %rbp
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r14
movl 0xf4(%rsp), %esi
movq %rax, %rdi
callq 0x34c2c
movq %rbp, %rdi
movq %r14, %rsi
movq %r13, %rdx
movq 0x10(%rsp), %rcx
callq 0x359be
jmp 0x34001
cmpl $0x5, 0x70(%rsp)
jne 0x344d9
movq 0x18(%rsp), %r14
movq %r14, %rdi
leaq 0x70(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %r13
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x30(%rax)
testb %al, %al
je 0x34524
movq 0xa0(%rsp), %rsi
movq %r14, %rdi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x1dc16
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r12
pushq $0x10
popq %rdi
callq 0x8250
movq 0x10(%rsp), %r15
leaq 0x148(%rsp), %rbp
leaq 0x4ca31(%rip), %rcx     # 0x80890
movq %rcx, (%rax)
movl $0x2, 0x8(%rax)
movq %r12, %rdi
movq %rax, %rsi
movq %rbp, %rdx
movq %r13, %rcx
movq %rbx, %r8
movq %r15, %r9
callq 0x357c0
movq %r14, %rdi
movq %rbp, %rsi
leaq 0xf0(%rsp), %rdx
movq %r12, %rcx
movq %r15, %r8
callq 0x326c6
jmp 0x34001
cmpl $0x0, 0x118(%rsp)
je 0x3448e
leaq 0x148(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x1dc16
pushq $0x68
popq %rdi
callq 0x8250
movq 0x18(%rsp), %rbx
movq %rax, %r12
pushq $0x10
popq %rdi
callq 0x8250
movq 0x10(%rsp), %r14
leaq 0x148(%rsp), %r15
leaq 0x4c9a3(%rip), %rcx     # 0x80890
movq %rcx, (%rax)
movl $0x2, 0x8(%rax)
movq %r12, %rdi
movq %rax, %rsi
movq %r15, %rdx
movq %r14, %rcx
callq 0x359a4
movq %rbx, %rdi
movq %r15, %rsi
leaq 0xf0(%rsp), %rdx
movq %r12, %rcx
movq %r14, %r8
callq 0x326c6
jmp 0x34001
movq 0x18(%rsp), %rdi
leaq 0x70(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %rbx
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r14
movq %rax, %rdi
movq %rbx, %rsi
movq 0x10(%rsp), %rdx
callq 0x353c2
jmp 0x3400e
cmpl $0x0, 0x118(%rsp)
je 0x34254
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r12
movq 0x8(%r13), %rsi
movq %rax, %rdi
leaq 0x148(%rsp), %rbx
movq %rbx, %rdx
movq %r13, %rcx
movq 0x10(%rsp), %r8
callq 0x3560c
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x36e30
movq %r12, (%rax)
jmp 0x34001
pushq $0x50
popq %rdi
callq 0x8250
movq %rax, %r13
pushq $0x10
popq %rdi
callq 0x8250
leaq 0x148(%rsp), %rbx
leaq 0x4c8c7(%rip), %rcx     # 0x80890
movq %rcx, (%rax)
movl $0x2, 0x8(%rax)
movl 0xf4(%rsp), %ecx
movq 0x30(%rsp), %rdx
movq 0x28(%rdx), %r8
movq %r13, %rdi
movq %rax, %rsi
movq %rbx, %rdx
callq 0x35ace
movq 0x28(%rsp), %rdi
movq %rbx, %rsi
callq 0x36e30
movq %r13, (%rax)
leaq 0x148(%rsp), %rdi
callq 0x8578
leaq 0x68(%rsp), %rdi
callq 0x1fd04
movq 0x50(%rsp), %rdx
addq $0x8, %rdx
movq 0x38(%rsp), %rax
jmp 0x338af
xorl %ebp, %ebp
movq 0x18(%rsp), %rbx
leaq 0x148(%rsp), %rdi
callq 0x8578
testq %rbp, %rbp
je 0x343f8
movq 0x30(%rsp), %rdi
movq %rbp, %rsi
callq 0x281e4
cmpl $0x4, 0xf0(%rsp)
jne 0x3407f
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r12
movq %rax, %rdi
movq %rbp, %rsi
movq 0x10(%rsp), %rdx
callq 0x35168
jmp 0x340ff
leaq 0x148(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0x1dc16
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r12
pushq $0x10
popq %rdi
callq 0x8250
movq 0x10(%rsp), %r14
leaq 0x148(%rsp), %r15
leaq 0x4c7d5(%rip), %rcx     # 0x80890
movq %rcx, (%rax)
movl $0x2, 0x8(%rax)
movq %r12, %rdi
movq %rax, %rsi
movq %r15, %rdx
movq %rbp, %rcx
movq %r14, %r8
callq 0x35244
movq %rbx, %rdi
movq %r15, %rsi
leaq 0xf0(%rsp), %rdx
movq %r12, %rcx
movq %r14, %r8
callq 0x326c6
leaq 0x148(%rsp), %rdi
callq 0x8578
movq %r12, 0x20(%rsp)
cmpl $0x1, 0xb0(%rsp)
jne 0x3456f
movl 0xb4(%rsp), %r14d
testl %r14d, %r14d
movl $0x0, %eax
cmovlel %eax, %r14d
negq %r14
xorl %r15d, %r15d
movq %r14, 0x58(%rsp)
cmpq %r15, %r14
je 0x3400e
movq 0x50(%rsp), %rax
movq -0x8(%rax,%r15,8), %rsi
leaq 0x148(%rsp), %rdi
callq 0x34faa
movq 0x18(%rsp), %rdi
leaq 0x150(%rsp), %rsi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %rbx
cmpl $0x5, 0x150(%rsp)
jne 0x34232
movq 0x180(%rsp), %rsi
movq 0x18(%rsp), %rdi
movq 0x10(%rsp), %rdx
callq 0x327cc
movq %rax, %r12
pushq $0x70
popq %rdi
callq 0x8250
movq %rax, 0x48(%rsp)
movq %r15, 0x60(%rsp)
movq 0x8(%rbx), %r14
movl 0x4d12d(%rip), %esi     # 0x812dc
leal 0x1(%rsi), %eax
movl %eax, 0x4d124(%rip)     # 0x812dc
leaq 0x228(%rsp), %r15
movq %r15, %rdi
callq 0xa36c
leaq 0x248(%rsp), %rbp
movq %rbp, %rdi
movq %r15, %rsi
leaq 0x25551(%rip), %rdx     # 0x5972e
callq 0xa440
movq 0x20(%rsp), %r15
movq %r15, (%rsp)
movq 0x48(%rsp), %r13
movq %r13, %rdi
movq %r14, %rsi
xorl %edx, %edx
movq %rbp, %rcx
movq %rbx, %r8
movq %r12, %r9
callq 0x352ba
movq %rbp, %rdi
callq 0x8578
leaq 0x228(%rsp), %rdi
callq 0x8578
movq %r15, %rdi
movq %r13, %rsi
callq 0x35374
movq 0x58(%rsp), %r14
movq 0x60(%rsp), %r15
jmp 0x3423f
movq 0x20(%rsp), %rdi
movq %rbx, %rsi
callq 0x35374
leaq 0x148(%rsp), %rdi
callq 0x1fd04
decq %r15
jmp 0x34131
movq 0x40(%rsp), %rdi
leaq 0x148(%rsp), %rsi
callq 0x36e30
movq (%rax), %rbx
pushq $0x68
popq %rdi
callq 0x8250
movq %rax, %r14
movq %rax, %rdi
movq %r13, %rsi
movq %rbx, %rdx
movq 0x10(%rsp), %rcx
callq 0x34b1c
testq %rbx, %rbx
je 0x342a9
movq %rbx, %rdi
leaq 0x4c1ea(%rip), %rsi     # 0x80480
leaq 0x4c1f3(%rip), %rdx     # 0x80490
xorl %ecx, %ecx
callq 0x82c0
movq %rax, %rsi
jmp 0x342ab
xorl %esi, %esi
movq 0x30(%rsp), %rdi
callq 0x2824e
jmp 0x34001
addq $0x2a8, %rsp            # imm = 0x2A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x4cd15(%rip), %rdi     # 0x80fe8
leaq 0x21e0e(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x25422(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x2302b(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x19c, %esi            # imm = 0x19C
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4ccca(%rip), %rdi     # 0x80fe8
leaq 0x21dc3(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x253d7(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22fe0(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x16d, %esi            # imm = 0x16D
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4cc7f(%rip), %rdi     # 0x80fe8
leaq 0x21d78(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x2538c(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22f95(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x1a1, %esi            # imm = 0x1A1
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4cc34(%rip), %rdi     # 0x80fe8
leaq 0x21d2d(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x25341(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22f4a(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x1b2, %esi            # imm = 0x1B2
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4cbe9(%rip), %rdi     # 0x80fe8
leaq 0x21ce2(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x252f6(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22eff(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x13f, %esi            # imm = 0x13F
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4cb9e(%rip), %rdi     # 0x80fe8
leaq 0x21c97(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x252ab(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22eb4(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x137, %esi            # imm = 0x137
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4cb53(%rip), %rdi     # 0x80fe8
leaq 0x21c4c(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x25260(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22e69(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x1a5, %esi            # imm = 0x1A5
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4cb08(%rip), %rdi     # 0x80fe8
leaq 0x21c01(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x25215(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22e1e(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x189, %esi            # imm = 0x189
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4cabd(%rip), %rdi     # 0x80fe8
leaq 0x21bb6(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x251ca(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22dd3(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x18b, %esi            # imm = 0x18B
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4ca72(%rip), %rdi     # 0x80fe8
leaq 0x21b6b(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x2517f(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22d88(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x14d, %esi            # imm = 0x14D
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4ca27(%rip), %rdi     # 0x80fe8
leaq 0x21b20(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x25134(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22d3d(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x1cd, %esi            # imm = 0x1CD
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
movq 0x4c9df(%rip), %rdi     # 0x80fe8
leaq 0x21ad8(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x250ec(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22cf5(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x113, %esi            # imm = 0x113
callq 0x84b0
movq %rax, %rdi
callq 0x8170
movl $0xff, %edi
callq 0x8300
movq 0x4c98f(%rip), %rdi     # 0x80fe8
leaq 0x21a88(%rip), %rsi     # 0x560e8
callq 0x8240
leaq 0x2509c(%rip), %rsi     # 0x59708
movq %rax, %rdi
callq 0x8240
leaq 0x22ca5(%rip), %rsi     # 0x57320
movq %rax, %rdi
callq 0x8240
movq %rax, %rdi
movl $0x182, %esi            # imm = 0x182
callq 0x84b0
movq %rax, %rdi
callq 0x8170
jmp 0x34648
jmp 0x346c8
jmp 0x3479a
jmp 0x34814
movq %rax, %rbx
pushq $0x68
jmp 0x347f7
jmp 0x34864
jmp 0x34864
jmp 0x346c1
jmp 0x34864
movq %rax, %rbx
pushq $0x68
jmp 0x34717
movq %rax, %rbx
pushq $0x68
popq %rsi
movq %r14, %rdi
jmp 0x3480d
jmp 0x34814
jmp 0x34814
jmp 0x34769
jmp 0x34864
jmp 0x34864
jmp 0x34864
jmp 0x34814
jmp 0x3479a
jmp 0x34864
jmp 0x34814
jmp 0x34864
jmp 0x34864
movq %rax, %rbx
pushq $0x70
popq %rsi
movq %r14, %rdi
jmp 0x347fb
jmp 0x34814
jmp 0x34814
jmp 0x34864
jmp 0x34864
jmp 0x34864
jmp 0x34864
jmp 0x34864
movq %rax, %rbx
pushq $0x50
popq %rsi
movq %r14, %rdi
callq 0x8260
jmp 0x347a8
movq %rax, %rbx
pushq $0x48
jmp 0x347c5
jmp 0x34864
jmp 0x34864
jmp 0x34864
movq %rax, %rbx
pushq $0x50
jmp 0x347c5
jmp 0x34864
jmp 0x34864
jmp 0x34814
jmp 0x3479a
jmp 0x34864
movq %rax, %rbx
leaq 0x268(%rsp), %rdi
callq 0x8578
jmp 0x347c3
jmp 0x34814
movq %rax, %rbx
pushq $0x68
popq %rsi
movq %r12, %rdi
jmp 0x3480d
movq %rax, %rbx
pushq $0x68
popq %rsi
movq %rbp, %rdi
jmp 0x3480d
jmp 0x34864
jmp 0x34864
jmp 0x34814
jmp 0x34814
jmp 0x34814
movq %rax, %rbx
pushq $0x70
popq %rsi
movq %r13, %rdi
jmp 0x3480d
jmp 0x34864
jmp 0x34864
jmp 0x34864
movq %rax, %rbx
leaq 0x288(%rsp), %rdi
callq 0x8578
jmp 0x34805
jmp 0x34864
jmp 0x34864
jmp 0x34864
movq %rax, %rbx
pushq $0x70
popq %rsi
movq %r12, %rdi
callq 0x8260
jmp 0x34879
movq %rax, %rbx
pushq $0x70
popq %rsi
movq 0x20(%rsp), %rdi
callq 0x8260
jmp 0x34817
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x8578
jmp 0x34879
jmp 0x34864
jmp 0x34864
jmp 0x34869
movq %rax, %rbx
jmp 0x34846
movq %rax, %rbx
jmp 0x34853
movq %rax, %rbx
leaq 0x248(%rsp), %rdi
callq 0x8578
leaq 0x228(%rsp), %rdi
callq 0x8578
pushq $0x70
popq %rsi
movq 0x48(%rsp), %rdi
callq 0x8260
jmp 0x3486c
jmp 0x34869
movq %rax, %rbx
jmp 0x34879
movq %rax, %rbx
leaq 0x148(%rsp), %rdi
callq 0x1fd04
leaq 0x68(%rsp), %rdi
callq 0x1fd04
movq %rbx, %rdi
callq 0x84d0
nop