// File: /workspace/github_cpp_makefile_star2_O1/BU-DiSC[P]BF-Shared-Hashing/hash/city.cc
// Function: CityHash64(char const*, unsigned long)
uint64 CityHash64(const char *s, size_t len) {
  if (len <= 32) {
    if (len <= 16) {
      return HashLen0to16(s, len);
    } else {
      return HashLen17to32(s, len);
    }
  } else if (len <= 64) {
    return HashLen33to64(s, len);
  }

  // For strings over 64 bytes we hash the end first, and then as we
  // loop we keep 56 bytes of state: v, w, x, y, and z.
  uint64 x = Fetch64(s + len - 40);
  uint64 y = Fetch64(s + len - 16) + Fetch64(s + len - 56);
  uint64 z = HashLen16(Fetch64(s + len - 48) + len, Fetch64(s + len - 24));
  pair<uint64, uint64> v = WeakHashLen32WithSeeds(s + len - 64, len, z);
  pair<uint64, uint64> w = WeakHashLen32WithSeeds(s + len - 32, y + k1, x);
  x = x * k1 + Fetch64(s);

  // Decrease len to the nearest multiple of 64, and operate on 64-byte chunks.
  len = (len - 1) & ~static_cast<size_t>(63);
  do {
    x = Rotate(x + y + v.first + Fetch64(s + 8), 37) * k1;
    y = Rotate(y + v.second + Fetch64(s + 48), 42) * k1;
    x ^= w.second;
    y += v.first + Fetch64(s + 40);
    z = Rotate(z + w.first, 33) * k1;
    v = WeakHashLen32WithSeeds(s, v.second * k1, x + w.first);
    w = WeakHashLen32WithSeeds(s + 32, z + w.second, y + Fetch64(s + 16));
    std::swap(z, x);
    s += 64;
    len -= 64;
  } while (len != 0);
  return HashLen16(HashLen16(v.first, w.first) + ShiftMix(y) * k1 + z,
                   HashLen16(v.second, w.second) + x);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
cmpq $0x20, %rsi
ja 0x282bb
cmpq $0x10, %rsi
ja 0x2838c
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x28648
cmpq $0x40, %rsi
ja 0x28408
movabsq $-0x651e95c4d06fbfb1, %rax # imm = 0x9AE16A3B2F90404F
movq %rsi, %r14
leaq (%rax,%rsi,2), %rcx
movq (%rdi), %r10
imulq %rax, %r10
movq -0x20(%rdi,%rsi), %rdx
movq -0x18(%rdi,%rsi), %r9
imulq 0x10(%rdi), %rax
movq 0x8(%rdi), %rbx
movq 0x18(%rdi), %rsi
leaq (%rsi,%rsi,8), %r11
movq -0x8(%rdi,%r14), %r8
movq -0x10(%rdi,%r14), %rsi
imulq %rcx, %rsi
addq %r8, %r10
movq %r10, %r14
rolq $0x15, %r14
addq %r11, %rax
movq %rax, %rdi
addq %r9, %rax
addq %rax, %r8
addq %rbx, %rax
rolq $0x22, %rbx
addq %r9, %rbx
leaq (%rbx,%rbx,8), %rbx
addq %r14, %rbx
xorq %rdx, %r10
leaq (%r11,%r10), %r14
addq %r11, %r10
incq %r10
addq %rbx, %r10
imulq %rcx, %r10
bswapq %r10
rolq $0x16, %rdi
addq %r9, %rdi
leaq (%rsi,%r14), %r9
incq %r9
addq %r10, %r9
imulq %rcx, %r9
bswapq %r9
addq %rdi, %r8
addq %r9, %r8
imulq %rcx, %r8
bswapq %r8
addq %r8, %rax
imulq %rcx, %rax
addq %rdx, %rsi
addq %rax, %rsi
movq %rsi, %rax
shrq $0x2f, %rax
xorq %rsi, %rax
imulq %rcx, %rax
addq %rdi, %rax
jmp 0x2863d
movabsq $-0x651e95c4d06fbfb1, %rdx # imm = 0x9AE16A3B2F90404F
movq %rsi, %r9
leaq (%rdx,%rsi,2), %rcx
movabsq $-0x4b6d499041670d8d, %rsi # imm = 0xB492B66FBE98F273
imulq (%rdi), %rsi
movq 0x8(%rdi), %rax
movq -0x8(%rdi,%r9), %r8
imulq %rcx, %r8
movq -0x10(%rdi,%r9), %rdi
imulq %rdx, %rdi
leaq (%rsi,%rax), %r9
rolq $0x15, %r9
addq %rdx, %rax
rolq $0x2e, %rax
addq %rsi, %rax
addq %r8, %rax
rolq $0x22, %r8
addq %r9, %r8
addq %rdi, %r8
xorq %rax, %r8
imulq %rcx, %r8
xorq %r8, %rax
shrq $0x2f, %r8
xorq %rax, %r8
imulq %rcx, %r8
movq %r8, %rax
shrq $0x2f, %rax
xorq %r8, %rax
imulq %rcx, %rax
jmp 0x2863d
movabsq $-0x4b6d499041670d8d, %r12 # imm = 0xB492B66FBE98F273
movabsq $-0x622015f714c7d297, %rbx # imm = 0x9DDFEA08EB382D69
movq -0x28(%rdi,%rsi), %rax
movq -0x10(%rdi,%rsi), %r14
movq -0x38(%rdi,%rsi), %rcx
movq -0x30(%rdi,%rsi), %r9
leaq (%rcx,%r14), %r8
leaq (%r9,%rsi), %r11
movq -0x18(%rdi,%rsi), %r10
xorq %r10, %r11
imulq %rbx, %r11
movq %r10, %rdx
xorq %r11, %rdx
shrq $0x2f, %r11
xorq %rdx, %r11
imulq %rbx, %r11
movq %r11, %r13
shrq $0x2f, %r13
xorq %r11, %r13
imulq %rbx, %r13
movq -0x40(%rdi,%rsi), %r11
addq %rsi, %r11
leaq (%rax,%r11), %rbx
addq %r13, %rbx
rolq $0x2b, %rbx
addq %r9, %rcx
addq %r11, %rcx
movq %rcx, %r9
rolq $0x14, %r9
addq %rax, %rcx
addq %r11, %r9
addq %rbx, %r9
movq -0x20(%rdi,%rsi), %r11
addq %r8, %r11
movq -0x8(%rdi,%rsi), %rbx
addq %r12, %r11
leaq (%rax,%rbx), %r15
addq %r11, %r15
rolq $0x2b, %r15
addq %r14, %r10
addq %r11, %r10
movq %r10, %r14
rolq $0x14, %r14
addq %rbx, %r10
addq %r11, %r14
imulq %r12, %rax
addq (%rdi), %rax
addq %r15, %r14
decq %rsi
andq $-0x40, %rsi
movq %rsi, -0x10(%rsp)
xorl %r15d, %r15d
movq %r13, %rbx
addq %rcx, %rax
addq %r8, %rax
movq 0x8(%rdi,%r15), %r11
movq 0x10(%rdi,%r15), %r12
addq %r11, %rax
rolq $0x1b, %rax
addq %r9, %r8
movq 0x30(%rdi,%r15), %rdx
movq %rdx, -0x8(%rsp)
addq %rdx, %r8
rolq $0x16, %r8
movabsq $-0x4b6d499041670d8d, %rdx # imm = 0xB492B66FBE98F273
imulq %rdx, %rax
movq %r8, %rsi
imulq %rdx, %rsi
movq %rax, %r13
xorq %r14, %r13
movq 0x28(%rdi,%r15), %rbp
addq %rbp, %rcx
movq %rcx, %r8
addq %rsi, %r8
addq %r10, %rbx
rolq $0x1f, %rbx
movq %rbx, %rax
imulq %rdx, %rax
imulq %rdx, %r9
movq 0x18(%rdi,%r15), %rsi
addq (%rdi,%r15), %r9
addq %r9, %r10
addq %rsi, %r10
addq %r12, %r11
addq %r9, %r11
movq %r11, %rcx
rolq $0x14, %r11
addq %rsi, %rcx
addq %r11, %r9
addq %rax, %r14
addq %r8, %r12
addq 0x20(%rdi,%r15), %r14
movq 0x38(%rdi,%r15), %rsi
addq %r14, %r12
addq %rsi, %r12
addq %r13, %r10
rolq $0x2b, %r10
rolq $0x2b, %r12
addq %r10, %r9
addq -0x8(%rsp), %rbp
addq %r14, %rbp
movq %rbp, %r10
addq %rsi, %r10
rolq $0x14, %rbp
addq %rbp, %r14
addq %r12, %r14
addq $0x40, %r15
cmpq %r15, -0x10(%rsp)
jne 0x284d3
xorq %r10, %rcx
movabsq $-0x622015f714c7d297, %rdi # imm = 0x9DDFEA08EB382D69
imulq %rdi, %rcx
xorq %rcx, %r10
shrq $0x2f, %rcx
xorq %r10, %rcx
imulq %rdi, %rcx
movq %rcx, %rsi
shrq $0x2f, %rsi
xorq %rcx, %rsi
imulq %rdi, %rsi
movq %r8, %rcx
shrq $0x2f, %rcx
xorq %r8, %rcx
movabsq $-0x4b6d499041670d8d, %r8 # imm = 0xB492B66FBE98F273
imulq %r8, %rcx
addq %r13, %rcx
addq %rsi, %rcx
xorq %r14, %r9
imulq %rdi, %r9
xorq %r9, %r14
shrq $0x2f, %r9
xorq %r14, %r9
imulq %rdi, %r9
movq %r9, %rdx
shrq $0x2f, %rdx
xorq %r9, %rdx
imulq %rdi, %rdx
addq %rax, %rdx
xorq %rdx, %rcx
imulq %rdi, %rcx
xorq %rcx, %rdx
shrq $0x2f, %rcx
xorq %rdx, %rcx
imulq %rdi, %rcx
movq %rcx, %rax
shrq $0x2f, %rax
xorq %rcx, %rax
imulq %rdi, %rax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq