// File: /workspace/github_cpp_makefile_star2_O1/luooofan[P]hblzbd_compiler/src/construct_ir_module.cpp
// Function: ConstructModule(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<ir::IR*, std::allocator<ir::IR*>>&)
IRModule* ConstructModule(const std::string& module_name, std::vector<ir::IR*>& gIRList) {
  // Construct BasicBlocks Functions and Module from gIRList

  // 基本块的首指令
  //  由于IR中使用了label 所有跳转语句都跳到某个label
  //  并且每个出现在四元式中的label都有跳转到该label的指令(不一定)
  //  所以首指令为每个label和每个跳转语句(call,ret,goto,jxx)的下一句
  //  (即便不一定为真正的首指令也可以接受)

  // 先遍历一遍IR 把所有func和有label的BB创建完成 创建两个map
  std::unordered_map<std::string, IRBasicBlock*> label2bb;
  std::unordered_map<std::string, IRFunction*> label2func;

  // add library function to label2func
  // not add them to module
  label2func.insert({"getint", new IRFunction("getint", 0)});
  label2func.insert({"getch", new IRFunction("getch", 0)});
  label2func.insert({"getarray", new IRFunction("getarray", 0)});
  label2func.insert({"putint", new IRFunction("putint", 1)});
  label2func.insert({"putch", new IRFunction("putch", 1)});
  label2func.insert({"putarray", new IRFunction("putarray", 1)});
  label2func.insert({"_sysy_starttime", new IRFunction("_sysy_starttime", 1)});
  label2func.insert({"_sysy_stoptime", new IRFunction("_sysy_stoptime", 1)});
  label2func.insert({"memset", new IRFunction("memset", 3)});

  IRModule* module = new IRModule(module_name, gScopes[0]);

  // fill label2bb label2func. every bb has its first ir. every func has it first bb. module has all funs.
  for (int i = 0; i < gIRList.size(); ++i) {
    auto& ir = *gIRList[i];
    if (ir.op_ == IR::OpKind::LABEL) {
      auto& label_name = ir.opn1_.name_;
      IRBasicBlock* bb = new IRBasicBlock();
      bb->ir_list_.push_back(&ir);
      label2bb.insert({label_name, bb});
      if (ir.opn1_.type_ == Opn::Type::Func) {  // is a function begin
        auto& func_item = (*ir::gFuncTable.find(label_name)).second;
        IRFunction* func = new IRFunction(label_name, func_item.shape_list_.size());
        func->bb_list_.push_back(bb);
        bb->func_ = func;
        label2func.insert({label_name, func});
        module->func_list_.push_back(func);
      }
    }
  }

  bool is_leader = false;
  bool is_succ = true;
  IRFunction* curr_func = nullptr;
  IRBasicBlock* pre_bb = nullptr;
  IRBasicBlock* curr_bb = nullptr;
  // for every ir
  for (int i = 0; i < gIRList.size(); ++i) {
    auto& ir = *gIRList[i];
    if (ir.op_ == IR::OpKind::LABEL) {
      is_leader = true;  // 表示这条一定是首指令
    }
    if (is_leader) {  // 一定已经或者将要把该ir放入到基本块中
      pre_bb = curr_bb;
      // 更新curr_bb curr_func
      if (ir.op_ == IR::OpKind::LABEL) {
        curr_bb = label2bb[ir.opn1_.name_];
        if (ir.opn1_.type_ == Opn::Type::Func) {
          curr_func = label2func[ir.opn1_.name_];
          is_leader = false;  // 下一条语句非首指令
          continue;
        }
      } else {
        // new BB
        curr_bb = new IRBasicBlock();
        curr_bb->ir_list_.push_back(&ir);
      }
      curr_func->bb_list_.push_back(curr_bb);
      curr_bb->func_ = curr_func;
      // 维护两个基本块之间的关系
      if (nullptr != pre_bb && is_succ) {
        pre_bb->succ_.push_back(curr_bb);
        curr_bb->pred_.push_back(pre_bb);
      }
    } else {
      curr_bb->ir_list_.push_back(&ir);
    }
    is_succ = true;
    // 维护当前基本块和跳转目标基本块之间的关系 维护is_leader 之后is_leader表示下一条ir是否为首指令
    switch (ir.op_) {
      case IR::OpKind::RET:
        is_leader = true;
        is_succ = false;
        break;
      case IR::OpKind::CALL:  // NOTE: 此时不维护调用双方两个基本块之间的关系 TODO: call语句的下一条语句是首指令吗
        curr_func->call_func_list_.push_back(label2func[ir.opn1_.name_]);
        is_leader = false;
        break;
      case IR::OpKind::GOTO: {
        auto succ_bb = label2bb[ir.opn1_.name_];
        curr_bb->succ_.push_back(succ_bb);
        succ_bb->pred_.push_back(curr_bb);
        is_leader = true;
        is_succ = false;
        break;
      }
      case IR::OpKind::JEQ:
      case IR::OpKind::JNE:
      case IR::OpKind::JLT:
      case IR::OpKind::JLE:
      case IR::OpKind::JGT:
      case IR::OpKind::JGE: {
        auto succ_bb = label2bb[ir.res_.name_];
        curr_bb->succ_.push_back(succ_bb);
        succ_bb->pred_.push_back(curr_bb);
        is_leader = true;
        break;
      }
      default:
        is_leader = false;
        break;
    }
  }

  return module;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xd8, %rsp
movq %rsi, %rbx
movq %rdi, %r14
leaq 0xd0(%rsp), %rax
movq %rax, -0x30(%rax)
movl $0x1, %ecx
movq %rcx, -0x28(%rax)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, %edx       # imm = 0x3F800000
movl %edx, -0x10(%rax)
movups %xmm0, -0x8(%rax)
leaq 0x88(%rsp), %rax
movq %rax, -0x30(%rax)
movq %rcx, -0x28(%rax)
movups %xmm0, -0x20(%rax)
movl %edx, -0x10(%rax)
movups %xmm0, -0x8(%rax)
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x38(%rsp), %r12
movq %r12, -0x10(%r12)
leaq 0x5facc(%rip), %rsi     # 0x6f91c
leaq 0x5facb(%rip), %rdx     # 0x6f922
leaq 0x28(%rsp), %rdi
callq 0xcaa0
leaq 0x7f1d0(%rip), %r13     # 0x8f038
addq $0x10, %r13
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x0, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
leaq 0x10(%rsp), %rax
movq %rax, -0x10(%rax)
xorl %ebp, %ebp
leaq 0x5fa33(%rip), %rsi     # 0x6f91c
leaq 0x5fa32(%rip), %rdx     # 0x6f922
movq %rsp, %rdi
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0xff24
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0xff3b
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x28(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x5f9cc(%rip), %rsi     # 0x6f923
leaq 0x5f9ca(%rip), %rdx     # 0x6f928
callq 0xcaa0
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x0, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
movq %rsp, %rdi
leaq 0x10(%rsp), %rax
movq %rax, (%rdi)
xorl %ebp, %ebp
leaq 0x5f941(%rip), %rsi     # 0x6f923
leaq 0x5f93f(%rip), %rdx     # 0x6f928
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x1001a
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x10031
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x28(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x5f8dc(%rip), %rsi     # 0x6f929
leaq 0x5f8dd(%rip), %rdx     # 0x6f931
callq 0xcaa0
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x0, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
movq %rsp, %rdi
leaq 0x10(%rsp), %rax
movq %rax, (%rdi)
xorl %ebp, %ebp
leaq 0x5f851(%rip), %rsi     # 0x6f929
leaq 0x5f852(%rip), %rdx     # 0x6f931
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x10110
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x10127
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x28(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x5f7ef(%rip), %rsi     # 0x6f932
leaq 0x5f7ee(%rip), %rdx     # 0x6f938
callq 0xcaa0
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x1, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
movq %rsp, %rdi
leaq 0x10(%rsp), %rax
movq %rax, (%rdi)
xorl %ebp, %ebp
leaq 0x5f764(%rip), %rsi     # 0x6f932
leaq 0x5f763(%rip), %rdx     # 0x6f938
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x10206
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x1021d
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x28(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x5f700(%rip), %rsi     # 0x6f939
leaq 0x5f6fe(%rip), %rdx     # 0x6f93e
callq 0xcaa0
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x1, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
movq %rsp, %rdi
leaq 0x10(%rsp), %rax
movq %rax, (%rdi)
xorl %ebp, %ebp
leaq 0x5f675(%rip), %rsi     # 0x6f939
leaq 0x5f673(%rip), %rdx     # 0x6f93e
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x102fc
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x10313
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x28(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x5f610(%rip), %rsi     # 0x6f93f
leaq 0x5f611(%rip), %rdx     # 0x6f947
callq 0xcaa0
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x1, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
movq %rsp, %rdi
leaq 0x10(%rsp), %rax
movq %rax, (%rdi)
xorl %ebp, %ebp
leaq 0x5f585(%rip), %rsi     # 0x6f93f
leaq 0x5f586(%rip), %rdx     # 0x6f947
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x103f2
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x10409
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x28(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x5f523(%rip), %rsi     # 0x6f948
leaq 0x5f52b(%rip), %rdx     # 0x6f957
callq 0xcaa0
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x1, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
movq %rsp, %rdi
leaq 0x10(%rsp), %rax
movq %rax, (%rdi)
xorl %ebp, %ebp
leaq 0x5f498(%rip), %rsi     # 0x6f948
leaq 0x5f4a0(%rip), %rdx     # 0x6f957
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x104e8
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x104ff
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x28(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x5f43d(%rip), %rsi     # 0x6f958
leaq 0x5f444(%rip), %rdx     # 0x6f966
callq 0xcaa0
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x1, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
movq %rsp, %rdi
leaq 0x10(%rsp), %rax
movq %rax, (%rdi)
xorl %ebp, %ebp
leaq 0x5f3b2(%rip), %rsi     # 0x6f958
leaq 0x5f3b9(%rip), %rdx     # 0x6f966
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x105de
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x105f5
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x98, %edi
callq 0x8290
movq %rax, %r15
leaq 0x28(%rsp), %rdi
movq %r12, (%rdi)
leaq 0x5f356(%rip), %rsi     # 0x6f967
leaq 0x5f355(%rip), %rdx     # 0x6f96d
callq 0xcaa0
movq %r13, (%r15)
leaq 0x8(%r15), %rdi
leaq 0x18(%r15), %rax
movq %rax, 0x8(%r15)
movq 0x28(%rsp), %rsi
movq 0x30(%rsp), %rdx
addq %rsi, %rdx
movb $0x1, %bpl
callq 0xca10
movl $0x3, 0x28(%r15)
movq %r15, %rax
addq $0x90, %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%r15)
movups %xmm0, 0x40(%r15)
movups %xmm0, 0x50(%r15)
movq %rax, 0x60(%r15)
movq $0x1, 0x68(%r15)
movups %xmm0, 0x70(%r15)
movl $0x3f800000, 0x80(%r15) # imm = 0x3F800000
movups %xmm0, 0x88(%r15)
movq %rsp, %rdi
leaq 0x10(%rsp), %rax
movq %rax, (%rdi)
xorl %ebp, %ebp
leaq 0x5f2cb(%rip), %rsi     # 0x6f967
leaq 0x5f2ca(%rip), %rdx     # 0x6f96d
callq 0xcaa0
movq %rsp, %rsi
movq %r15, 0x20(%rsi)
leaq 0x58(%rsp), %rdi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x106d4
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x106eb
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
movl $0x48, %edi
callq 0x8290
movq %rax, %r12
movq %r13, 0x98(%rsp)
leaq 0x7fe71(%rip), %rax     # 0x90578
movq (%rax), %r15
leaq 0x7df27(%rip), %rax     # 0x8e638
movq %rax, (%r12)
leaq 0x8(%r12), %rdi
leaq 0x18(%r12), %rax
movq %rax, 0x8(%r12)
movq (%r14), %rsi
movq 0x8(%r14), %rdx
addq %rsi, %rdx
callq 0xca10
leaq 0x7e8d6(%rip), %rax     # 0x8f010
addq $0x10, %rax
movq %rax, (%r12)
xorps %xmm0, %xmm0
movups %xmm0, 0x28(%r12)
movq $0x0, 0x38(%r12)
movq %r12, 0x50(%rsp)
movq %r15, 0x40(%r12)
movq (%rbx), %rax
cmpq %rax, 0x8(%rbx)
je 0x10993
movq 0x50(%rsp), %rcx
addq $0x28, %rcx
movq %rcx, 0x90(%rsp)
xorl %r15d, %r15d
movq (%rax,%r15,8), %r13
cmpl $0x7, (%r13)
jne 0x10979
movl $0x2a8, %edi            # imm = 0x2A8
callq 0x8290
movq %rax, %r14
movq %rax, %rdi
callq 0x10da0
movq %r14, 0x28(%rsp)
addq $0x8, %r14
movq %r13, (%rsp)
movq %r14, %rdi
movq %rsp, %r14
movq %r14, %rsi
callq 0x114b8
leaq 0x10(%rsp), %rax
movq %rax, (%rsp)
movq 0x10(%r13), %rsi
movq 0x18(%r13), %rdx
addq %rsi, %rdx
movq %r14, %rdi
callq 0xca10
movq 0x28(%rsp), %rax
movq %rax, 0x20(%rsp)
leaq 0xa0(%rsp), %rdi
movq %r14, %rsi
callq 0x11624
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x1080f
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
cmpl $0x3, 0x8(%r13)
jne 0x10979
leaq 0x10(%r13), %rsi
leaq 0x7fd6b(%rip), %rdi     # 0x90590
callq 0x11a14
movq %rax, %r14
movl $0x98, %edi
callq 0x8290
movq %rax, %rbp
movq %rbx, %r12
movq 0x30(%r14), %rbx
movq 0x38(%r14), %r14
movq 0x98(%rsp), %rax
movq %rax, (%rbp)
leaq 0x8(%rbp), %rdi
leaq 0x18(%rbp), %rax
movq %rax, 0x8(%rbp)
movq 0x10(%r13), %rsi
movq 0x18(%r13), %rdx
addq %rsi, %rdx
callq 0xca10
subq %rbx, %r14
shrq $0x3, %r14
imull $0xaaaaaaab, %r14d, %eax # imm = 0xAAAAAAAB
movl %eax, 0x28(%rbp)
leaq 0x90(%rbp), %rax
xorps %xmm0, %xmm0
movups %xmm0, 0x30(%rbp)
movups %xmm0, 0x40(%rbp)
movups %xmm0, 0x50(%rbp)
movq %rax, 0x60(%rbp)
movq $0x1, 0x68(%rbp)
movups %xmm0, 0x70(%rbp)
movl $0x3f800000, 0x80(%rbp) # imm = 0x3F800000
movups %xmm0, 0x88(%rbp)
movq %rbp, 0x48(%rsp)
movq 0x38(%rbp), %rsi
cmpq 0x40(%rbp), %rsi
je 0x108d6
movq 0x28(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x38(%rbp)
movq %r12, %rbx
jmp 0x108ea
addq $0x30, %rbp
movq %rbp, %rdi
leaq 0x28(%rsp), %rdx
callq 0x11b10
movq %r12, %rbx
movq 0x48(%rsp), %rax
movq 0x28(%rsp), %rcx
movq %rax, 0x20(%rcx)
leaq 0x10(%rsp), %rax
movq %rax, (%rsp)
movq 0x10(%r13), %rsi
movq 0x18(%r13), %rdx
addq %rsi, %rdx
movq %rsp, %r14
movq %r14, %rdi
callq 0xca10
movq 0x48(%rsp), %rax
movq %rax, 0x20(%rsp)
leaq 0x58(%rsp), %rdi
movq %r14, %rsi
callq 0x110ac
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x10949
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
movq 0x50(%rsp), %rcx
movq 0x30(%rcx), %rsi
cmpq 0x38(%rcx), %rsi
je 0x10967
movq 0x48(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x30(%rcx)
jmp 0x10979
movq 0x90(%rsp), %rdi
leaq 0x48(%rsp), %rdx
callq 0x11c4c
incq %r15
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r15, %rcx
ja 0x1077f
xorl %eax, %eax
movq %rax, (%rsp)
movq %rax, 0x28(%rsp)
movq (%rbx), %rax
cmpq %rax, 0x8(%rbx)
je 0x10c4b
movb $0x1, %bpl
xorl %r14d, %r14d
xorl %r15d, %r15d
xorl %r13d, %r13d
movq (%rax,%r14,8), %r12
movl (%r12), %eax
movq 0x28(%rsp), %rdi
testb $0x1, %r13b
jne 0x109e7
cmpl $0x7, %eax
je 0x109e7
addq $0x8, %rdi
movq %r12, 0x48(%rsp)
leaq 0x48(%rsp), %rsi
callq 0x114b8
jmp 0x10ae4
movq %rdi, (%rsp)
cmpl $0x7, %eax
jne 0x10a2a
leaq 0x10(%r12), %r13
leaq 0xa0(%rsp), %rdi
movq %r13, %rsi
callq 0x11d88
movq (%rax), %rax
movq %rax, 0x28(%rsp)
cmpl $0x3, 0x8(%r12)
jne 0x10a5a
leaq 0x58(%rsp), %rdi
movq %r13, %rsi
callq 0x11ece
movq (%rax), %r15
jmp 0x10c1c
movl $0x2a8, %edi            # imm = 0x2A8
callq 0x8290
movq %rax, %r13
movq %rax, %rdi
callq 0x10da0
movq %r13, 0x28(%rsp)
addq $0x8, %r13
movq %r12, 0x48(%rsp)
movq %r13, %rdi
leaq 0x48(%rsp), %rsi
callq 0x114b8
movq 0x38(%r15), %rsi
cmpq 0x40(%r15), %rsi
je 0x10a73
movq 0x28(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x38(%r15)
jmp 0x10a81
leaq 0x30(%r15), %rdi
leaq 0x28(%rsp), %rdx
callq 0x11b10
movq 0x28(%rsp), %rax
movq %r15, 0x20(%rax)
movq (%rsp), %rdi
testq %rdi, %rdi
je 0x10ae4
testb $0x1, %bpl
je 0x10ae4
movq 0x48(%rdi), %rsi
cmpq 0x50(%rdi), %rsi
je 0x10aad
movq %rax, (%rsi)
addq $0x8, 0x48(%rdi)
jmp 0x10abb
addq $0x40, %rdi
leaq 0x28(%rsp), %rdx
callq 0x11b10
movq 0x28(%rsp), %rdi
movq 0x30(%rdi), %rsi
cmpq 0x38(%rdi), %rsi
je 0x10ad8
movq (%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x30(%rdi)
jmp 0x10ae4
addq $0x28, %rdi
movq %rsp, %rdx
callq 0x11b10
movl (%r12), %eax
addl $-0x9, %eax
cmpl $0x9, %eax
ja 0x10c19
movb $0x1, %r13b
leaq 0x5edf6(%rip), %rcx     # 0x6f8f4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
addq $0x90, %r12
leaq 0xa0(%rsp), %rdi
movq %r12, %rsi
callq 0x11d88
movq (%rax), %rax
movq %rax, 0x48(%rsp)
movq 0x28(%rsp), %rdi
movq 0x48(%rdi), %rsi
cmpq 0x50(%rdi), %rsi
je 0x10b3f
movq %rax, (%rsi)
addq $0x8, 0x48(%rdi)
jmp 0x10b4d
addq $0x40, %rdi
leaq 0x48(%rsp), %rdx
callq 0x11b10
movq 0x48(%rsp), %rdi
movq 0x30(%rdi), %rsi
cmpq 0x38(%rdi), %rsi
je 0x10b6b
movq 0x28(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x30(%rdi)
jmp 0x10b79
addq $0x28, %rdi
leaq 0x28(%rsp), %rdx
callq 0x11b10
movb $0x1, %r13b
movb $0x1, %bpl
jmp 0x10c31
addq $0x10, %r12
leaq 0xa0(%rsp), %rdi
movq %r12, %rsi
callq 0x11d88
movq (%rax), %rax
movq %rax, 0x48(%rsp)
movq 0x28(%rsp), %rdi
movq 0x48(%rdi), %rsi
cmpq 0x50(%rdi), %rsi
je 0x10be1
movq %rax, (%rsi)
addq $0x8, 0x48(%rdi)
jmp 0x10bef
addq $0x10, %r12
leaq 0x58(%rsp), %rdi
movq %r12, %rsi
callq 0x11ece
movq 0x50(%r15), %rsi
cmpq 0x58(%r15), %rsi
je 0x10c0d
movq (%rax), %rax
movq %rax, (%rsi)
addq $0x8, 0x50(%r15)
jmp 0x10c19
addq $0x40, %rdi
leaq 0x48(%rsp), %rdx
callq 0x11b10
movq 0x48(%rsp), %rdi
movq 0x30(%rdi), %rsi
cmpq 0x38(%rdi), %rsi
je 0x10c21
movq 0x28(%rsp), %rax
movq %rax, (%rsi)
addq $0x8, 0x30(%rdi)
jmp 0x10c2f
leaq 0x48(%r15), %rdi
movq %rax, %rdx
callq 0x11c4c
movb $0x1, %bpl
xorl %r13d, %r13d
jmp 0x10c31
addq $0x28, %rdi
leaq 0x28(%rsp), %rdx
callq 0x11b10
xorl %ebp, %ebp
incq %r14
movq (%rbx), %rax
movq 0x8(%rbx), %rcx
subq %rax, %rcx
sarq $0x3, %rcx
cmpq %r14, %rcx
ja 0x109b7
leaq 0x58(%rsp), %rdi
callq 0x10f70
leaq 0xa0(%rsp), %rdi
callq 0x1100e
movq 0x50(%rsp), %rax
addq $0xd8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movl $0x48, %esi
movq %r12, %rdi
jmp 0x10d71
jmp 0x10d7e
jmp 0x10cd6
jmp 0x10cf8
jmp 0x10d7e
jmp 0x10cd6
jmp 0x10cf8
jmp 0x10d7e
jmp 0x10cd6
jmp 0x10cf8
jmp 0x10d7e
jmp 0x10cd6
jmp 0x10cf8
jmp 0x10d7e
jmp 0x10cd6
jmp 0x10cf8
jmp 0x10d7e
jmp 0x10cd6
jmp 0x10cf8
jmp 0x10d7e
jmp 0x10cd6
jmp 0x10cf8
jmp 0x10d7e
jmp 0x10cd6
jmp 0x10cf8
jmp 0x10d7e
movq %rax, %rbx
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x10cf4
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
xorl %ebp, %ebp
jmp 0x10d15
movq %rax, %rbx
movb $0x1, %bpl
jmp 0x10d2c
jmp 0x10d7e
jmp 0x10d12
jmp 0x10d12
jmp 0x10d12
jmp 0x10d12
jmp 0x10d12
jmp 0x10d12
jmp 0x10d12
jmp 0x10d12
movq %rax, %rbx
movq 0x28(%rsp), %rdi
cmpq %r12, %rdi
je 0x10d2c
movq 0x38(%rsp), %rsi
incq %rsi
callq 0x82a0
testb %bpl, %bpl
je 0x10d81
movl $0x98, %esi
movq %r15, %rdi
jmp 0x10d71
jmp 0x10d7e
jmp 0x10d7e
movq %rax, %rbx
movl $0x98, %esi
movq %rbp, %rdi
jmp 0x10d71
jmp 0x10d7e
jmp 0x10d58
jmp 0x10d7e
jmp 0x10d7e
jmp 0x10d7e
jmp 0x10d7e
movq %rax, %rbx
movq (%rsp), %rdi
leaq 0x10(%rsp), %rax
cmpq %rax, %rdi
je 0x10d81
movq 0x10(%rsp), %rsi
incq %rsi
callq 0x82a0
jmp 0x10d81
jmp 0x10d7e
jmp 0x10d7e
jmp 0x10d7e
movq %rax, %rbx
leaq 0x58(%rsp), %rdi
callq 0x10f70
leaq 0xa0(%rsp), %rdi
callq 0x1100e
movq %rbx, %rdi
callq 0x8540