// File: /workspace/github_cpp_makefile_star2_O2/cpottamus[P]btree_lab/btree.cc
// Function: BTreeIndex::Rebalance(unsigned int const&, std::vector<unsigned int, std::allocator<unsigned int>>)
ERROR_T BTreeIndex::Rebalance(const SIZE_T &node, std::vector<SIZE_T> ptrPath)
{
  BTreeNode b;
  BTreeNode leftNode;
  BTreeNode rightNode;
  ERROR_T rc;
  SIZE_T offset;
    
  int newType;
  //SIZE_T ptr;
  rc = b.Unserialize(buffercache, node);
  if (rc) { return rc;}
  //std::cout<<":::: Allocating new Nodes :::::"<<std::endl;
  //Allocate 2 new nodes, fill them from the place you're splitting
  SIZE_T leftPtr;
  SIZE_T rightPtr;
  AllocateNode(leftPtr);
  if(b.info.nodetype == BTREE_LEAF_NODE){
    newType = BTREE_LEAF_NODE;
  }else{
    newType = BTREE_INTERIOR_NODE;
  }
  leftNode = BTreeNode(newType, superblock.info.keysize, superblock.info.valuesize, superblock.info.blocksize);
  rc = leftNode.Serialize(buffercache, leftPtr);
  AllocateNode(rightPtr);
  rightNode = BTreeNode(newType, superblock.info.keysize, superblock.info.valuesize, superblock.info.blocksize);
  rc = rightNode.Serialize(buffercache, rightPtr);
  //Unserialize to write to new nodes
  rc = leftNode.Unserialize(buffercache, leftPtr);
  if (rc) { return rc;}
  rc = rightNode.Unserialize(buffercache, rightPtr);
  if (rc) { return rc;}

  //Variables to hold spot/key vals  
  KEY_T keySpot;
  KEY_T testKey;
  VALUE_T valSpot;
  SIZE_T ptrSpot;

  //Find splitting point
  int midpoint = (b.info.numkeys+0.5)/2;

  //If A leafNode
  if(b.info.nodetype==BTREE_LEAF_NODE){
  //Build left leaf node, include the splitting key (this is a <= B+ tree)
    for(offset = 0; (int)offset < midpoint; offset++){
      //std::cout<<":::: OFFSET for building new left leaf node = "<<offset<<std::endl;
      leftNode.info.numkeys++;

    //Get old node values
      rc = b.GetKey(offset, keySpot);
      if (rc) { return rc;}
      rc = b.GetVal(offset, valSpot);
      if (rc) { return rc;}
    //set values in new left node.
      rc = leftNode.SetKey(offset, keySpot);
      if (rc) { return rc;}
      rc = leftNode.SetVal(offset, valSpot);
      if (rc) { return rc;}
    }
  //Build right leaf node
    int spot=0;
    for(offset = midpoint; offset<b.info.numkeys; offset++){
      //std::cout<<":::: OFFSET (spot) for building new right leaf node = "<<spot<<std::endl;
      //std::cout<<":::: Total Block OFFSET (offset), while rebuilding right leaf node"<<offset<<std::endl;
    //Get values from old node.
      rightNode.info.numkeys++;
      rc = b.GetKey(offset, keySpot);
      if (rc) { return rc;}
      rc = b.GetVal(offset, valSpot);
      if (rc) { return rc;}
    //set values in new right node.
      rc = rightNode.SetKey(spot, keySpot);
      if (rc) { return rc;}
      rc = rightNode.SetVal(spot, valSpot);
      if (rc) { return rc;}
      spot++;
    }
  } else {//if it's an interior node.
      //Build left interior node
  for(offset = 0; (int)offset < midpoint; offset++){
    //std::cout<<":::: OFFSET for building new left interior node = "<<offset<<std::endl;
    leftNode.info.numkeys++;
        //Get old key and pointers
    rc = b.GetKey(offset, keySpot);
    if (rc) { return rc;}
    rc = b.GetPtr(offset, ptrSpot);
    if (rc) { return rc;}
        //Set new key and Pointer vals
    rc = leftNode.SetKey(offset, keySpot);
    if (rc) { return rc;}
    rc = leftNode.SetPtr(offset, ptrSpot);
  }
      //Build Right interior node
  int spot=0;
  for(offset = midpoint; offset<b.info.numkeys; offset++){
    //std::cout<<":::: OFFSET (spot) for building new right interior node = "<<spot<<std::endl;
    //std::cout<<":::: Total Block OFFSET (offset), while rebuilding right interior node"<<offset<<std::endl;
    rightNode.info.numkeys++;
    //Get values from old node.
    rc = b.GetKey(offset, keySpot);
    if (rc) { return rc;}
    rc = b.GetPtr(offset, ptrSpot);
    if (rc) { return rc;}
    //set values in new right node.
    rc = rightNode.SetKey(spot, keySpot);
    if (rc) { return rc;}
    rc = rightNode.SetPtr(spot, ptrSpot);
    if (rc) { return rc;}
    spot++;
  }
  rc = b.GetPtr(offset, ptrSpot);
  if (rc) { return rc;}
  rc = rightNode.SetPtr(spot, ptrSpot);
  if (rc) { return rc;}
}
  //Serialize the new nodes
rc = leftNode.Serialize(buffercache, leftPtr);
if (rc) { return rc;}
rc = rightNode.Serialize(buffercache, rightPtr);
if (rc) { return rc;}
rc = b.Serialize(buffercache, node);

  //Find split key
KEY_T splitKey;
rc = b.GetKey(midpoint-1, splitKey);
if (rc) { return rc;}


  //If we're all the way up at the root, we need to make a new root.
  //  std::cout << ":::: NODE TYPE = " << b.info.nodetype << std::endl;
    
  //  std::cout<<"current node nodetype :::: "<<b.info.nodetype<<std::endl;
if (b.info.nodetype == BTREE_ROOT_NODE) {
  //std::cout<<":::: AT THE TOP, BUILDING A NEW ROOT ::::"<<std::endl;
  SIZE_T newRootPtr;
  BTreeNode newRootNode;
  AllocateNode(newRootPtr);
  newRootNode = BTreeNode(BTREE_ROOT_NODE, superblock.info.keysize, superblock.info.valuesize, superblock.info.blocksize);
  superblock.info.rootnode = newRootPtr;
    newRootNode.info.rootnode = newRootPtr;
    newRootNode.info.numkeys = 1;
    newRootNode.SetKey(0, splitKey);
    newRootNode.SetPtr(0, leftPtr);
    newRootNode.SetPtr(1, rightPtr);
  rc = newRootNode.Serialize(buffercache, newRootPtr);
  if(rc) {return rc;}
//std::cout<<"::: We made it here! Root node"<<std::endl;
}
else{
//Find the parent node
  SIZE_T parentPtr = ptrPath.back();
//  std::cout<<"WE BUILT THIS CITY ON ROCK AND ROLL COW ::: "<<parentPtr<<std::endl;
      //std::cout<<"ALSO THIS  IN OUR REBALANCE::: "<<ptrPath.size()<<std::endl;
//    for(int i =ptrPath.size()-1; i>=0; i--) {
//        std::cout<<"Little sumpin"<<ptrPath.at(i)<<std::endl;
//      }
  ptrPath.pop_back();
  BTreeNode parentNode;
  rc = parentNode.Unserialize(buffercache, parentPtr);
  if(rc) {return rc;}

    if (parentNode.info.nodetype == BTREE_SUPERBLOCK) {
        AllocateNode(parentPtr);
        
    }
//Increment the key count for the given node.
  //parentNode.info.numkeys++;
    
    BTreeNode newParentNode = BTreeNode(parentNode.info.nodetype, superblock.info.keysize, superblock.info.valuesize, superblock.info.blocksize);
    newParentNode.info.numkeys = parentNode.info.numkeys + 1;
    newParentNode.info.freelist = parentNode.info.freelist;
    
    bool newKeyInserted = false;
    for (offset = 0; offset < newParentNode.info.numkeys - 1; offset++) {
        rc = parentNode.GetKey(offset, testKey);
        //    if(rc){ return rc;}
        if (newKeyInserted) {
            rc = parentNode.GetKey(offset, keySpot);
            newParentNode.SetKey(offset + 1, keySpot);
            
            rc = parentNode.GetPtr(offset + 1, ptrSpot);
            newParentNode.SetPtr(offset + 2, ptrSpot);
        } else {
            if (splitKey < testKey) {
                newKeyInserted = true;
                newParentNode.SetPtr(offset, leftPtr);
                newParentNode.SetKey(offset, splitKey);
                newParentNode.SetPtr(offset+1, rightPtr);
                offset = offset - 1;
                
            } else {
                rc = parentNode.GetKey(offset, keySpot);
                if (rc) {return rc;}
                rc = newParentNode.SetKey(offset, keySpot);
                if (rc) {return rc;}
                
                rc = parentNode.GetPtr(offset, ptrSpot);
                if (rc) {return rc;}
                rc = newParentNode.SetPtr(offset, ptrSpot);
                if (rc) {return rc;}
            }
        }
    }
    if (newKeyInserted == false) {
        newKeyInserted = true;
        newParentNode.SetPtr(offset, leftPtr);
        newParentNode.SetKey(offset, splitKey);
        newParentNode.SetPtr(offset+1, rightPtr);
    }
    
    newParentNode.Serialize(buffercache, parentPtr);
    
    
//find split keys spot in parent (interior) node, insert it and update keys and pointers.
//  for(offset = 0; offset<parentNode.info.numkeys-1; offset++){
//    //std::cout<<":::: Searching Interior Nodes for splitKey Insertion ::::: offset = "<<offset<<std::endl;
//    rc = parentNode.GetKey(offset, testKey);
//    if(rc){ return rc;}
//    if(splitKey < testKey || splitKey == testKey){ // if testkey > splitkey
//      //std::cout<<":::: Moving through the parent node for rebalance insertion ::: Number of keys in parent = "<<parentNode.info.numkeys<<std::endl;
//      //std::cout<<":::: Moving through the parent node for rebalance insertion ::: parent nodetype = "<<parentNode.info.nodetype<<std::endl;
//          //Once you've found the insertion point for the new key, move all other keys & pointers over by 1
//      for(offset2= parentNode.info.numkeys-2 ; offset2 >= offset; offset2-- ){
//        //std::cout<<":::: Found INSERTION POINT, moving spots over :::: = offset"<<offset<<std::endl;
//            //Grab the old key and pointer
//        rc = parentNode.GetKey(offset2, keySpot);
//        if(rc){ return rc;}
//        rc = parentNode.GetPtr(offset2, ptrSpot);
//        if(rc){ return rc;}
//            //Move it up by 1
//        rc = parentNode.SetKey(offset2+1, keySpot);
//        if(rc){ return rc;}
//        rc = parentNode.SetPtr(offset2+2, ptrSpot);
//      }
//          //We now have moved every pointer over except for the  1 to the immediate right of where we will be inserting our splitKey
//          //Set our pointers and our new key
//      rc = parentNode.SetPtr(offset2+1, rightPtr);
//      if(rc){ return rc;}
//      rc = parentNode.SetPtr(offset,leftPtr);
//      if(rc){ return rc;}
//      rc = parentNode.SetKey(offset, splitKey);
//      if(rc){ return rc;}
//
//      break;
//    }
//  }


  //Check the length of the node and call rebalance if necessary
  //parentNode.Serialize(buffercache, parentPtr);

  if((int)newParentNode.info.numkeys > (int)(2*maxNumKeys/3)){
    rc = Rebalance(parentPtr, ptrPath);
    if(rc){ return rc;}
  }
}
  //Deallocate the old (too large) node
DeallocateNode(node);
return ERROR_NOERROR;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x1a8, %rsp            # imm = 0x1A8
movq %rdx, %r15
movq %rsi, %rbx
movq %rdi, %r14
leaq 0x68(%rsp), %rdi
callq 0x725a
leaq 0xf0(%rsp), %rdi
callq 0x725a
leaq 0xc8(%rsp), %rdi
callq 0x725a
movq 0x8(%r14), %rsi
movl (%rbx), %edx
leaq 0x68(%rsp), %rdi
callq 0x73fc
movl %eax, %ebp
testl %eax, %eax
jne 0x5ebf
leaq 0x8(%rsp), %rsi
movq %r14, %rdi
callq 0x4f90
xorl %ebp, %ebp
cmpl $0x4, 0x68(%rsp)
sete %bpl
addl $0x3, %ebp
movl 0x1c(%r14), %edx
movl 0x20(%r14), %ecx
movl 0x24(%r14), %r8d
leaq 0x40(%rsp), %rdi
movl %ebp, %esi
callq 0x7280
leaq 0xf0(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x732a
leaq 0x40(%rsp), %rdi
callq 0x7264
movq 0x8(%r14), %rsi
movl 0x8(%rsp), %edx
leaq 0xf0(%rsp), %rdi
callq 0x7338
leaq 0x4(%rsp), %rsi
movq %r14, %rdi
callq 0x4f90
movl 0x1c(%r14), %edx
movl 0x20(%r14), %ecx
movl 0x24(%r14), %r8d
leaq 0x40(%rsp), %rdi
movl %ebp, %esi
callq 0x7280
leaq 0xc8(%rsp), %rdi
leaq 0x40(%rsp), %rsi
callq 0x732a
leaq 0x40(%rsp), %rdi
callq 0x7264
movq 0x8(%r14), %rsi
movl 0x4(%rsp), %edx
leaq 0xc8(%rsp), %rdi
callq 0x7338
movq 0x8(%r14), %rsi
movl 0x8(%rsp), %edx
leaq 0xf0(%rsp), %rdi
callq 0x73fc
movl %eax, %ebp
testl %eax, %eax
jne 0x5ebf
movq 0x8(%r14), %rsi
movl 0x4(%rsp), %edx
leaq 0xc8(%rsp), %rdi
callq 0x73fc
movl %eax, %ebp
testl %eax, %eax
jne 0x5ebf
leaq 0x40(%rsp), %rdi
callq 0x2ac4
leaq 0x180(%rsp), %rdi
callq 0x2ac4
leaq 0x140(%rsp), %rdi
callq 0x2ac4
movq %r15, 0x90(%rsp)
movq %rbx, 0x10(%rsp)
movl 0x80(%rsp), %eax
cvtsi2sd %rax, %xmm0
movsd 0x28b5(%rip), %xmm1     # 0x86a0
addsd %xmm1, %xmm0
mulsd %xmm1, %xmm0
cvttsd2si %xmm0, %eax
xorl %r13d, %r13d
testl %eax, %eax
movl $0x0, %ebx
movq %rax, 0x98(%rsp)
cmovgl %eax, %ebx
cmpl $0x4, 0x68(%rsp)
jne 0x5ef7
xorl %r13d, %r13d
leaq 0x68(%rsp), %r12
leaq 0x40(%rsp), %r15
cmpl %r13d, %ebx
je 0x6012
incl 0x108(%rsp)
movq %r12, %rdi
movl %r13d, %esi
movq %r15, %rdx
callq 0x7622
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
movq %r12, %rdi
movl %r13d, %esi
leaq 0x140(%rsp), %rdx
callq 0x768a
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xf0(%rsp), %rdi
movl %r13d, %esi
movq %r15, %rdx
callq 0x770a
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xf0(%rsp), %rdi
movl %r13d, %esi
leaq 0x140(%rsp), %rdx
callq 0x775a
movl %eax, %ebp
incl %r13d
testl %eax, %eax
je 0x5e24
leaq 0x140(%rsp), %rdi
callq 0x2c6e
leaq 0x180(%rsp), %rdi
callq 0x2c6e
leaq 0x40(%rsp), %rdi
callq 0x2c6e
leaq 0xc8(%rsp), %rdi
callq 0x7264
leaq 0xf0(%rsp), %rdi
callq 0x7264
leaq 0x68(%rsp), %rdi
callq 0x7264
movl %ebp, %eax
addq $0x1a8, %rsp            # imm = 0x1A8
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x68(%rsp), %r12
leaq 0x40(%rsp), %r15
cmpl %r13d, %ebx
je 0x5f72
incl 0x108(%rsp)
movq %r12, %rdi
movl %r13d, %esi
movq %r15, %rdx
callq 0x7622
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
movq %r12, %rdi
movl %r13d, %esi
movq %rsp, %rdx
callq 0x766e
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xf0(%rsp), %rdi
movl %r13d, %esi
movq %r15, %rdx
callq 0x770a
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xf0(%rsp), %rdi
movl %r13d, %esi
movq %rsp, %rdx
callq 0x773e
incl %r13d
jmp 0x5f01
xorl %r13d, %r13d
movq 0x10(%rsp), %r15
movq 0x98(%rsp), %r12
leal (%r12,%r13), %ebx
cmpl 0x80(%rsp), %ebx
jae 0x60bc
incl 0xe0(%rsp)
leaq 0x68(%rsp), %rdi
movl %ebx, %esi
leaq 0x40(%rsp), %rdx
callq 0x7622
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0x68(%rsp), %rdi
movl %ebx, %esi
movq %rsp, %rdx
callq 0x766e
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xc8(%rsp), %rdi
movl %r13d, %esi
leaq 0x40(%rsp), %rdx
callq 0x770a
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xc8(%rsp), %rdi
movl %r13d, %esi
movq %rsp, %rdx
callq 0x773e
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
incl %r13d
jmp 0x5f82
xorl %r13d, %r13d
movq 0x10(%rsp), %r15
movq 0x98(%rsp), %r12
leal (%r12,%r13), %ebx
cmpl 0x80(%rsp), %ebx
jae 0x60f2
incl 0xe0(%rsp)
leaq 0x68(%rsp), %rdi
movl %ebx, %esi
leaq 0x40(%rsp), %rdx
callq 0x7622
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0x68(%rsp), %rdi
movl %ebx, %esi
leaq 0x140(%rsp), %rdx
callq 0x768a
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xc8(%rsp), %rdi
movl %r13d, %esi
leaq 0x40(%rsp), %rdx
callq 0x770a
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xc8(%rsp), %rdi
movl %r13d, %esi
leaq 0x140(%rsp), %rdx
callq 0x775a
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
incl %r13d
jmp 0x6022
leaq 0x68(%rsp), %rdi
movq %rsp, %rdx
movl %ebx, %esi
callq 0x766e
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
leaq 0xc8(%rsp), %rdi
movq %rsp, %rdx
movl %r13d, %esi
callq 0x773e
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
movq 0x8(%r14), %rsi
movl 0x8(%rsp), %edx
leaq 0xf0(%rsp), %rdi
callq 0x7338
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
movq 0x8(%r14), %rsi
movl 0x4(%rsp), %edx
leaq 0xc8(%rsp), %rdi
callq 0x7338
movl %eax, %ebp
testl %eax, %eax
jne 0x5e9b
movq 0x8(%r14), %rsi
movl (%r15), %edx
leaq 0x68(%rsp), %rdi
callq 0x7338
leaq 0x118(%rsp), %rdi
callq 0x2ac4
decl %r12d
leaq 0x68(%rsp), %rdi
leaq 0x118(%rsp), %rdx
movl %r12d, %esi
callq 0x7622
movl %eax, %ebp
testl %eax, %eax
jne 0x6512
cmpl $0x2, 0x68(%rsp)
jne 0x6250
leaq 0xa0(%rsp), %rdi
callq 0x725a
leaq 0xc(%rsp), %rsi
movq %r14, %rdi
callq 0x4f90
movl 0x1c(%r14), %edx
movl 0x20(%r14), %ecx
movl 0x24(%r14), %r8d
leaq 0x18(%rsp), %rdi
pushq $0x2
popq %rsi
callq 0x7280
leaq 0xa0(%rsp), %rdi
leaq 0x18(%rsp), %rsi
callq 0x732a
leaq 0x18(%rsp), %rdi
callq 0x7264
movl 0xc(%rsp), %ebx
movl %ebx, 0x28(%r14)
leaq 0xa0(%rsp), %rdi
movl %ebx, 0x10(%rdi)
movl $0x1, 0x18(%rdi)
leaq 0x118(%rsp), %rdx
xorl %esi, %esi
callq 0x770a
leaq 0xa0(%rsp), %rdi
leaq 0x8(%rsp), %rdx
xorl %esi, %esi
callq 0x773e
leaq 0xa0(%rsp), %rdi
pushq $0x1
popq %rsi
leaq 0x4(%rsp), %rdx
callq 0x773e
movq 0x8(%r14), %rsi
leaq 0xa0(%rsp), %rdi
movl %ebx, %edx
callq 0x7338
movl %eax, %ebp
leaq 0xa0(%rsp), %rdi
callq 0x7264
testl %ebp, %ebp
movq 0x10(%rsp), %rsi
jne 0x6512
jmp 0x6508
movq 0x90(%rsp), %rcx
movq 0x8(%rcx), %rax
movl -0x4(%rax), %ebx
addq $-0x4, %rax
movl %ebx, 0xc(%rsp)
movq %rax, 0x8(%rcx)
leaq 0xa0(%rsp), %rdi
callq 0x725a
movq 0x8(%r14), %rsi
leaq 0xa0(%rsp), %rdi
movl %ebx, %edx
callq 0x73fc
movl %eax, %ebp
testl %eax, %eax
je 0x6299
xorl %r15d, %r15d
jmp 0x64f1
movl 0xa0(%rsp), %esi
cmpl $0x1, %esi
jne 0x62b9
leaq 0xc(%rsp), %rsi
movq %r14, %rdi
callq 0x4f90
movl 0xa0(%rsp), %esi
movl 0x1c(%r14), %edx
movl 0x20(%r14), %ecx
movl 0x24(%r14), %r8d
leaq 0x18(%rsp), %rdi
callq 0x7280
leaq 0xa0(%rsp), %r13
movl 0x14(%r13), %ecx
movl 0x18(%r13), %eax
incl %eax
leaq 0x18(%rsp), %rdx
movl %eax, 0x18(%rdx)
movl %ecx, 0x14(%rdx)
xorl %r12d, %r12d
xorl %r15d, %r15d
decl %eax
cmpl %eax, %r12d
jae 0x6430
movq %r13, %rdi
movl %r12d, %esi
leaq 0x180(%rsp), %rdx
callq 0x7622
testb $0x1, %r15b
je 0x6360
movq %r13, %rdi
movl %r12d, %esi
leaq 0x40(%rsp), %rdx
callq 0x7622
leal 0x1(%r12), %ebx
leaq 0x18(%rsp), %rdi
movl %ebx, %esi
leaq 0x40(%rsp), %rdx
callq 0x770a
movq %r13, %rdi
movl %ebx, %esi
movq %rsp, %rdx
callq 0x766e
leal 0x2(%r12), %esi
leaq 0x18(%rsp), %rdi
movq %rsp, %rdx
callq 0x773e
jmp 0x6424
leaq 0x118(%rsp), %rdi
leaq 0x180(%rsp), %rsi
callq 0x2ccc
testb %al, %al
je 0x63bc
leaq 0x18(%rsp), %rdi
movl %r12d, %esi
leaq 0x8(%rsp), %rdx
callq 0x773e
leaq 0x18(%rsp), %rdi
movl %r12d, %esi
leaq 0x118(%rsp), %rdx
callq 0x770a
leal 0x1(%r12), %esi
leaq 0x18(%rsp), %rdi
leaq 0x4(%rsp), %rdx
callq 0x773e
decl %r12d
movb $0x1, %r15b
jmp 0x6424
movq %r13, %rdi
movl %r12d, %esi
leaq 0x40(%rsp), %rdx
callq 0x7622
movl %eax, %ebp
testl %eax, %eax
jne 0x64df
leaq 0x18(%rsp), %rdi
movl %r12d, %esi
leaq 0x40(%rsp), %rdx
callq 0x770a
movl %eax, %ebp
testl %eax, %eax
jne 0x64df
movq %r13, %rdi
movl %r12d, %esi
movq %rsp, %rdx
callq 0x766e
movl %eax, %ebp
testl %eax, %eax
jne 0x64df
leaq 0x18(%rsp), %rdi
movl %r12d, %esi
movq %rsp, %rdx
callq 0x773e
movl %eax, %ebp
testl %eax, %eax
jne 0x64df
incl %r12d
movl 0x30(%rsp), %eax
jmp 0x62f2
testb $0x1, %r15b
jne 0x6472
leaq 0x18(%rsp), %rdi
leaq 0x8(%rsp), %rdx
movl %r12d, %esi
callq 0x773e
leaq 0x18(%rsp), %rdi
leaq 0x118(%rsp), %rdx
movl %r12d, %esi
callq 0x770a
incl %r12d
leaq 0x18(%rsp), %rdi
leaq 0x4(%rsp), %rdx
movl %r12d, %esi
callq 0x773e
movq 0x8(%r14), %rsi
movl 0xc(%rsp), %edx
leaq 0x18(%rsp), %rdi
callq 0x7338
movl 0x30(%rsp), %ecx
movl 0x40(%r14), %eax
addl %eax, %eax
xorl %ebp, %ebp
pushq $0x3
popq %rsi
xorl %edx, %edx
divl %esi
cmpl %eax, %ecx
jle 0x64e4
leaq 0x168(%rsp), %rdi
movq 0x90(%rsp), %rsi
callq 0x6f2c
leaq 0xc(%rsp), %rsi
leaq 0x168(%rsp), %rdx
movq %r14, %rdi
callq 0x5c56
movl %eax, %ebx
leaq 0x168(%rsp), %rdi
callq 0x6f7a
testl %ebx, %ebx
je 0x64e4
xorl %r15d, %r15d
movl %ebx, %ebp
jmp 0x64e7
xorl %r15d, %r15d
jmp 0x64e7
movb $0x1, %r15b
leaq 0x18(%rsp), %rdi
callq 0x7264
leaq 0xa0(%rsp), %rdi
callq 0x7264
testb %r15b, %r15b
movq 0x10(%rsp), %rsi
je 0x6512
xorl %ebp, %ebp
movq %r14, %rdi
callq 0x503c
leaq 0x118(%rsp), %rdi
callq 0x2c6e
jmp 0x5e9b
movq %rax, %rbx
leaq 0x168(%rsp), %rdi
callq 0x6f7a
jmp 0x6553
jmp 0x6544
jmp 0x6550
jmp 0x6550
jmp 0x6544
jmp 0x654b
jmp 0x654b
jmp 0x6544
movq %rax, %rbx
jmp 0x655d
jmp 0x65a4
movq %rax, %rbx
jmp 0x656a
movq %rax, %rbx
leaq 0x18(%rsp), %rdi
callq 0x7264
leaq 0xa0(%rsp), %rdi
callq 0x7264
leaq 0x118(%rsp), %rdi
callq 0x2c6e
jmp 0x65a7
jmp 0x65a4
jmp 0x65a4
movq %rax, %rbx
jmp 0x65b4
movq %rax, %rbx
jmp 0x65c1
jmp 0x65d9
jmp 0x65a4
jmp 0x65a4
jmp 0x6591
jmp 0x65d9
movq %rax, %rbx
leaq 0x40(%rsp), %rdi
callq 0x7264
jmp 0x65dc
jmp 0x65d9
jmp 0x65a4
movq %rax, %rbx
leaq 0x140(%rsp), %rdi
callq 0x2c6e
leaq 0x180(%rsp), %rdi
callq 0x2c6e
leaq 0x40(%rsp), %rdi
callq 0x2c6e
jmp 0x65dc
jmp 0x65d9
movq %rax, %rbx
jmp 0x65e9
movq %rax, %rbx
jmp 0x65f6
movq %rax, %rbx
leaq 0xc8(%rsp), %rdi
callq 0x7264
leaq 0xf0(%rsp), %rdi
callq 0x7264
leaq 0x68(%rsp), %rdi
callq 0x7264
movq %rbx, %rdi
callq 0x2380