// File: attractivechaos[P]udb2/libcuckoo/./cuckoohash_map.hh
// Function: cuckoohash_map<unsigned int, unsigned int, Hash32, std::equal_to<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int>>, 4ul>::move_buckets(libcuckoo_bucket_container<unsigned int, unsigned int, std::allocator<std::pair<unsigned int const, unsigned int>>, unsigned char, 4ul>&, unsigned long, unsigned long, unsigned long, unsigned long)
void move_buckets(buckets_t &new_buckets, size_type current_hp,
                    size_type new_hp, size_type start_ind, size_type end_ind) {
    for (size_type old_bucket_ind = start_ind; old_bucket_ind < end_ind;
         ++old_bucket_ind) {
      // By doubling the table size, the index_hash and alt_index of
      // each key got one bit added to the top, at position
      // current_hp, which means anything we have to move will either
      // be at the same bucket position, or exactly
      // hashsize(current_hp) later than the current bucket
      bucket &old_bucket = buckets_[old_bucket_ind];
      const size_type new_bucket_ind = old_bucket_ind + hashsize(current_hp);
      size_type new_bucket_slot = 0;

      // For each occupied slot, either move it into its same position in the
      // new buckets container, or to the first available spot in the new
      // bucket in the new buckets container.
      for (size_type old_bucket_slot = 0; old_bucket_slot < slot_per_bucket();
           ++old_bucket_slot) {
        if (!old_bucket.occupied(old_bucket_slot)) {
          continue;
        }
        const hash_value hv = hashed_key(old_bucket.key(old_bucket_slot));
        const size_type old_ihash = index_hash(current_hp, hv.hash);
        const size_type old_ahash =
            alt_index(current_hp, hv.partial, old_ihash);
        const size_type new_ihash = index_hash(new_hp, hv.hash);
        const size_type new_ahash = alt_index(new_hp, hv.partial, new_ihash);
        size_type dst_bucket_ind, dst_bucket_slot;
        if ((old_bucket_ind == old_ihash && new_ihash == new_bucket_ind) ||
            (old_bucket_ind == old_ahash && new_ahash == new_bucket_ind)) {
          // We're moving the key to the new bucket
          dst_bucket_ind = new_bucket_ind;
          dst_bucket_slot = new_bucket_slot++;
        } else {
          // We're moving the key to the old bucket
          assert((old_bucket_ind == old_ihash && new_ihash == old_ihash) ||
                 (old_bucket_ind == old_ahash && new_ahash == old_ahash));
          dst_bucket_ind = old_bucket_ind;
          dst_bucket_slot = old_bucket_slot;
        }
        new_buckets.setKV(dst_bucket_ind, dst_bucket_slot++,
                          old_bucket.partial(old_bucket_slot),
                          old_bucket.movable_key(old_bucket_slot),
                          std::move(old_bucket.mapped(old_bucket_slot)));
      }
    }
  }

// Assembly:
subq $0xd8, %rsp
movq %rdi, 0xd0(%rsp)
movq %rsi, 0xc8(%rsp)
movq %rdx, 0xc0(%rsp)
movq %rcx, 0xb8(%rsp)
movq %r8, 0xb0(%rsp)
movq %r9, 0xa8(%rsp)
movq 0xd0(%rsp), %rax
movq %rax, 0x38(%rsp)
movq 0xb0(%rsp), %rax
movq %rax, 0xa0(%rsp)
movq 0xa0(%rsp), %rax
cmpq 0xa8(%rsp), %rax
jae 0xbcdb
movq 0x38(%rsp), %rdi
addq $0x8, %rdi
movq 0xa0(%rsp), %rsi
callq 0x4db0
movq %rax, 0x98(%rsp)
movq 0xa0(%rsp), %rax
movq %rax, 0x30(%rsp)
movq 0xc0(%rsp), %rdi
callq 0x3cf0
movq %rax, %rcx
movq 0x30(%rsp), %rax
addq %rcx, %rax
movq %rax, 0x90(%rsp)
movq $0x0, 0x88(%rsp)
movq $0x0, 0x80(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x28(%rsp)
callq 0x3ce0
movq %rax, %rcx
movq 0x28(%rsp), %rax
cmpq %rcx, %rax
jae 0xbcc0
movq 0x98(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x3590
testb $0x1, (%rax)
jne 0xba7f
jmp 0xbca7
movq 0x98(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x6370
movq 0x38(%rsp), %rdi
movq %rax, %rsi
callq 0x4a60
movq %rax, 0x70(%rsp)
movb %dl, 0x78(%rsp)
movq 0xc0(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x4f50
movq %rax, 0x68(%rsp)
movq 0xc0(%rsp), %rdi
movb 0x78(%rsp), %al
movq 0x68(%rsp), %rdx
movzbl %al, %esi
callq 0x4f80
movq %rax, 0x60(%rsp)
movq 0xb8(%rsp), %rdi
movq 0x70(%rsp), %rsi
callq 0x4f50
movq %rax, 0x58(%rsp)
movq 0xb8(%rsp), %rdi
movb 0x78(%rsp), %al
movq 0x58(%rsp), %rdx
movzbl %al, %esi
callq 0x4f80
movq %rax, 0x50(%rsp)
movq 0xa0(%rsp), %rax
cmpq 0x68(%rsp), %rax
jne 0xbb32
movq 0x58(%rsp), %rax
cmpq 0x90(%rsp), %rax
je 0xbb50
movq 0xa0(%rsp), %rax
cmpq 0x60(%rsp), %rax
jne 0xbb7e
movq 0x50(%rsp), %rax
cmpq 0x90(%rsp), %rax
jne 0xbb7e
movq 0x90(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x88(%rsp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, 0x88(%rsp)
movq %rax, 0x40(%rsp)
jmp 0xbc12
movq 0xa0(%rsp), %rax
cmpq 0x68(%rsp), %rax
jne 0xbb9f
movq 0x58(%rsp), %rcx
movb $0x1, %al
cmpq 0x68(%rsp), %rcx
movb %al, 0x27(%rsp)
je 0xbbcd
movq 0xa0(%rsp), %rcx
xorl %eax, %eax
cmpq 0x60(%rsp), %rcx
movb %al, 0x26(%rsp)
jne 0xbbc5
movq 0x50(%rsp), %rax
cmpq 0x60(%rsp), %rax
sete %al
movb %al, 0x26(%rsp)
movb 0x26(%rsp), %al
movb %al, 0x27(%rsp)
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0xbbd7
jmp 0xbbd9
jmp 0xbbf8
leaq 0x3a0f(%rip), %rdi      # 0xf5ef
leaq 0x26c7(%rip), %rsi      # 0xe2ae
movl $0x669, %edx            # imm = 0x669
leaq 0x3a6f(%rip), %rcx      # 0xf662
callq 0x2110
movq 0xa0(%rsp), %rax
movq %rax, 0x48(%rsp)
movq 0x80(%rsp), %rax
movq %rax, 0x40(%rsp)
movq 0xc8(%rsp), %rax
movq %rax, (%rsp)
movq 0x48(%rsp), %rax
movq %rax, 0x8(%rsp)
movq 0x40(%rsp), %rax
movq %rax, 0x10(%rsp)
addq $0x1, %rax
movq %rax, 0x40(%rsp)
movq 0x98(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x7840
movb (%rax), %al
movb %al, 0x25(%rsp)
movq 0x98(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x8020
movq %rax, 0x18(%rsp)
movq 0x98(%rsp), %rdi
movq 0x80(%rsp), %rsi
callq 0x4dd0
movq (%rsp), %rdi
movq 0x8(%rsp), %rsi
movq 0x10(%rsp), %rdx
movq 0x18(%rsp), %r8
movq %rax, %r9
movb 0x25(%rsp), %al
movzbl %al, %ecx
callq 0x7f20
movq 0x80(%rsp), %rax
addq $0x1, %rax
movq %rax, 0x80(%rsp)
jmp 0xba3d
jmp 0xbcc2
movq 0xa0(%rsp), %rax
addq $0x1, %rax
movq %rax, 0xa0(%rsp)
jmp 0xb9c4
addq $0xd8, %rsp
retq
nopw %cs:(%rax,%rax)
nopl (%rax)