// File: /workspace/github_cpp_makefile_star2_O2/attractivechaos[P]udb2/libcuckoo/./cuckoohash_map.hh
// Function: bool cuckoohash_map<unsigned int, unsigned int, Hash32, std::equal_to<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int>>, 4ul>::cuckoopath_move<std::integral_constant<bool, false>>(unsigned long, std::array<cuckoohash_map<unsigned int, unsigned int, Hash32, std::equal_to<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int>>, 4ul>::CuckooRecord, 5ul>&, unsigned long, cuckoohash_map<unsigned int, unsigned int, Hash32, std::equal_to<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int>>, 4ul>::TwoBuckets&)
bool cuckoopath_move(const size_type hp, CuckooRecords &cuckoo_path,
                       size_type depth, TwoBuckets &b) {
    if (depth == 0) {
      // There is a chance that depth == 0, when try_add_to_bucket sees
      // both buckets as full and cuckoopath_search finds one empty. In
      // this case, we lock both buckets. If the slot that
      // cuckoopath_search found empty isn't empty anymore, we unlock them
      // and return false. Otherwise, the bucket is empty and insertable,
      // so we hold the locks and return true.
      const size_type bucket = cuckoo_path[0].bucket;
      assert(bucket == b.i1 || bucket == b.i2);
      b = lock_two(hp, b.i1, b.i2, TABLE_MODE());
      if (!buckets_[bucket].occupied(cuckoo_path[0].slot)) {
        return true;
      } else {
        b.unlock();
        return false;
      }
    }

    while (depth > 0) {
      CuckooRecord &from = cuckoo_path[depth - 1];
      CuckooRecord &to = cuckoo_path[depth];
      const size_type fs = from.slot;
      const size_type ts = to.slot;
      TwoBuckets twob;
      LockManager extra_manager;
      if (depth == 1) {
        // Even though we are only swapping out of one of the original
        // buckets, we have to lock both of them along with the slot we
        // are swapping to, since at the end of this function, they both
        // must be locked. We store tb inside the extrab container so it
        // is unlocked at the end of the loop.
        std::tie(twob, extra_manager) =
            lock_three(hp, b.i1, b.i2, to.bucket, TABLE_MODE());
      } else {
        twob = lock_two(hp, from.bucket, to.bucket, TABLE_MODE());
      }

      bucket &fb = buckets_[from.bucket];
      bucket &tb = buckets_[to.bucket];

      // We plan to kick out fs, but let's check if it is still there;
      // there's a small chance we've gotten scooped by a later cuckoo. If
      // that happened, just... try again. Also the slot we are filling in
      // may have already been filled in by another thread, or the slot we
      // are moving from may be empty, both of which invalidate the swap.
      // We only need to check that the hash value is the same, because,
      // even if the keys are different and have the same hash value, then
      // the cuckoopath is still valid.
      if (tb.occupied(ts) || !fb.occupied(fs) ||
          hashed_key_only_hash(fb.key(fs)) != from.hv.hash) {
        return false;
      }

      buckets_.setKV(to.bucket, ts, fb.partial(fs), fb.movable_key(fs),
                     std::move(fb.mapped(fs)));
      buckets_.eraseKV(from.bucket, fs);
      if (depth == 1) {
        // Hold onto the locks contained in twob
        b = std::move(twob);
      }
      depth--;
    }
    return true;
  }

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdx, %r13
movq %rsi, 0x20(%rsp)
movq %rdi, %r10
testq %rcx, %rcx
movq %r8, 0x18(%rsp)
movq %rdi, 0x8(%rsp)
je 0x3a7f
movq %rcx, %rbx
leaq 0x8(%r10), %rax
leaq 0x50(%rsp), %r15
movq %rax, 0x78(%rsp)
movq %r13, 0x10(%rsp)
testq %rbx, %rbx
sete 0x7(%rsp)
je 0x3b0b
leaq -0x1(%rbx), %rax
movq %rax, 0x80(%rsp)
shlq $0x5, %rax
leaq (%rax,%r13), %r14
movq %rbx, %rcx
shlq $0x5, %rcx
leaq (%rcx,%r13), %rbp
movq 0x8(%r13,%rax), %r12
movq 0x8(%r13,%rcx), %r13
leaq 0x40(%rsp), %rax
xorps %xmm0, %xmm0
movups %xmm0, (%rax)
andq $0x0, 0x28(%rsp)
cmpq $0x1, %rbx
jne 0x3919
movq 0x18(%rsp), %rax
movq (%rax), %rcx
movq 0x8(%rax), %r8
movq (%rbp), %r9
movq %r15, %rdi
movq %r10, %rsi
movq 0x20(%rsp), %rdx
callq 0x3e9c
leaq 0x28(%rsp), %rax
movq %rax, 0x88(%rsp)
leaq 0x30(%rsp), %rax
movq %rax, 0x90(%rsp)
leaq 0x88(%rsp), %rdi
movq %r15, %rsi
callq 0x3fd2
movq %r15, %rdi
callq 0x400a
movq 0x8(%rsp), %r10
jmp 0x399e
movq (%r14), %rcx
movq (%rbp), %r8
movq %r15, %rdi
movq %r10, %rsi
movq 0x20(%rsp), %rdx
callq 0x2e9c
movups 0x50(%rsp), %xmm0
movq 0x60(%rsp), %rcx
andq $0x0, 0x60(%rsp)
movaps %xmm0, 0x30(%rsp)
movq 0x40(%rsp), %rax
movq %rcx, 0x40(%rsp)
testq %rax, %rax
je 0x3957
movb $0x0, (%rax)
movq 0x68(%rsp), %rcx
andq $0x0, 0x68(%rsp)
movq 0x48(%rsp), %rax
movq %rcx, 0x48(%rsp)
testq %rax, %rax
movq 0x8(%rsp), %r10
leaq 0x50(%rsp), %r15
je 0x398b
movb $0x0, (%rax)
movq 0x68(%rsp), %rax
testq %rax, %rax
je 0x398b
movb $0x0, (%rax)
andq $0x0, 0x68(%rsp)
movq 0x60(%rsp), %rax
testq %rax, %rax
je 0x399e
movb $0x0, (%rax)
movq 0x18(%r10), %rax
movq (%rbp), %rsi
imulq $0x28, %rsi, %rcx
addq %rax, %rcx
cmpb $0x0, 0x24(%r13,%rcx)
jne 0x3a20
imulq $0x28, (%r14), %rcx
addq %rcx, %rax
cmpb $0x1, 0x24(%rax,%r12)
jne 0x3a20
movl (%rax,%r12,8), %ecx
cmpq %rcx, 0x10(%r14)
jne 0x3a20
leaq (%rax,%r12,8), %r8
movzbl 0x20(%rax,%r12), %ecx
leaq (%rax,%r12,8), %r9
addq $0x4, %r9
movq 0x78(%rsp), %rbp
movq %rbp, %rdi
movq %r13, %rdx
callq 0x4020
movq (%r14), %rsi
movq %rbp, %rdi
movq %r12, %rdx
callq 0x29bc
movb $0x1, %bpl
cmpq $0x1, %rbx
movq 0x8(%rsp), %r10
leaq 0x50(%rsp), %r15
movq 0x10(%rsp), %r13
je 0x3a62
movq 0x80(%rsp), %rbx
jmp 0x3a27
xorl %ebp, %ebp
movq 0x10(%rsp), %r13
movq 0x28(%rsp), %rax
testq %rax, %rax
je 0x3a34
movb $0x0, (%rax)
movq 0x48(%rsp), %rax
testq %rax, %rax
je 0x3a41
movb $0x0, (%rax)
andq $0x0, 0x48(%rsp)
movq 0x40(%rsp), %rax
testq %rax, %rax
je 0x3a54
movb $0x0, (%rax)
testb %bpl, %bpl
jne 0x386f
jmp 0x3b0b
movq 0x18(%rsp), %rdi
leaq 0x30(%rsp), %rsi
callq 0x3382
leaq 0x50(%rsp), %r15
movq 0x8(%rsp), %r10
xorl %ebx, %ebx
jmp 0x3a27
movq %r8, %r12
movq (%r13), %r14
movq (%r8), %rcx
movq 0x8(%r8), %r8
cmpq %rcx, %r14
sete %al
cmpq %r8, %r14
sete %dl
orb %al, %dl
je 0x3b21
leaq 0x50(%rsp), %rbx
movq %rbx, %rdi
movq %r10, %rsi
movq 0x20(%rsp), %rdx
callq 0x2e9c
movq %r12, %rdi
movq %rbx, %rsi
callq 0x3382
movq 0x18(%rbx), %rax
testq %rax, %rax
je 0x3acd
movb $0x0, (%rax)
andq $0x0, 0x68(%rsp)
movq 0x60(%rsp), %rax
testq %rax, %rax
je 0x3ae0
movb $0x0, (%rax)
movq 0x8(%r13), %rax
imulq $0x28, %r14, %rcx
movq 0x8(%rsp), %rdx
addq 0x18(%rdx), %rcx
movb 0x24(%rax,%rcx), %bl
cmpb $0x1, %bl
movq 0x18(%rsp), %rdi
jne 0x3b04
callq 0x35fc
xorb $0x1, %bl
movb %bl, 0x7(%rsp)
movb 0x7(%rsp), %al
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x25c1(%rip), %rdi      # 0x60e9
leaq 0x175f(%rip), %rsi      # 0x528e
leaq 0x25d4(%rip), %rcx      # 0x610a
movl $0x55a, %edx            # imm = 0x55A
callq 0x20f0
jmp 0x3b44
jmp 0x3b44
movq 0x28(%rsp), %rcx
testq %rcx, %rcx
je 0x3b51
movb $0x0, (%rcx)
movq 0x48(%rsp), %rcx
testq %rcx, %rcx
je 0x3b5e
movb $0x0, (%rcx)
andq $0x0, 0x48(%rsp)
movq 0x40(%rsp), %rcx
testq %rcx, %rcx
je 0x3b71
movb $0x0, (%rcx)
movq %rax, %rdi
callq 0x2210
nop