user: 请从给定的汇编指令推导出C源代码:

```asm
<metrohash64_1>:
  endbr64
  add    $0x7bdec03b,%edx
  push   %r15
  movslq %esi,%rax
  mov    %rdi,%r15
  push   %r14
  imul   $0xc83a91e1,%edx,%edx
  lea    (%rdi,%rax,4),%rcx
  push   %r13
  push   %r12
  push   %rbp
  lea    (%rdx,%rsi,1),%eax
  push   %rbx
  sub    $0x28,%rsp
  mov    %rcx,0x18(%rsp)
  mov    %eax,0xc(%rsp)
  cmp    $0x1f,%esi
  jle    L19
  add    $0xffffffffffffff80,%rcx
  mov    %eax,%r12d
  mov    %eax,%r13d
  mov    %eax,%r14d
  mov    %rcx,0x10(%rsp)
  mov    %eax,%ebp
  mov    %rdi,%rbx
  nopl   0x0(%rax)
L56:
  mov    %rbx,%rdi
  call   <read_u64@plt>
  mov    $0x1d,%esi
  imul   $0xc83a91e1,%eax,%edi
  add    %r12d,%edi
  call   <rotate_right@plt>
  lea    0x20(%rbx),%rdi
  lea    (%rax,%r14,1),%r12d
  call   <read_u64@plt>
  mov    $0x1d,%esi
  imul   $0x8648dbdb,%eax,%edi
  add    %ebp,%edi
  call   <rotate_right@plt>
  lea    0x40(%rbx),%rdi
  lea    (%rax,%r13,1),%ebp
  call   <read_u64@plt>
  mov    $0x1d,%esi
  imul   $0x7bdec03b,%eax,%edi
  add    %r14d,%edi
  call   <rotate_right@plt>
  lea    0x60(%rbx),%rdi
  sub    $0xffffffffffffff80,%rbx
  lea    (%r12,%rax,1),%r14d
  call   <read_u64@plt>
  mov    $0x1d,%esi
  imul   $0x2f5870a5,%eax,%edi
  add    %r13d,%edi
  call   <rotate_right@plt>
  lea    0x0(%rbp,%rax,1),%r13d
  cmp    %rbx,0x10(%rsp)
  jae    L56
  mov    0x18(%rsp),%rdx
  lea    0x1(%r15),%rcx
  lea    (%r12,%r13,1),%edi
  mov    $0x21,%esi
  mov    %rdx,%rax
  sub    $0x7f,%rdx
  sub    %r15,%rax
  add    $0xffffffffffffff80,%rax
  and    $0xffffffffffffff80,%rax
  sub    $0xffffffffffffff80,%rax
  cmp    %rdx,%rcx
  mov    $0x80,%edx
  cmova  %rdx,%rax
  imul   $0xc83a91e1,%edi,%edi
  add    %rax,%r15
  add    %ebp,%edi
  call   <rotate_right@plt>
  mov    $0x21,%esi
  imul   $0x8648dbdb,%eax,%eax
  xor    %r14d,%eax
  lea    0x0(%rbp,%rax,1),%edi
  mov    %eax,%ebx
  imul   $0x8648dbdb,%edi,%edi
  add    %r12d,%edi
  call   <rotate_right@plt>
  lea    (%r12,%rbx,1),%edi
  mov    $0x21,%esi
  xor    %ebp,%r12d
  imul   $0xc83a91e1,%eax,%r14d
  imul   $0xc83a91e1,%edi,%edi
  xor    %r13d,%r14d
  add    %r14d,%edi
  call   <rotate_right@plt>
  lea    0x0(%rbp,%r14,1),%edi
  mov    $0x21,%esi
  imul   $0x8648dbdb,%edi,%edi
  mov    %eax,%r13d
  imul   $0x8648dbdb,%r13d,%r13d
  add    %ebx,%edi
  call   <rotate_right@plt>
  xor    %r12d,%r13d
  imul   $0xc83a91e1,%eax,%eax
  xor    %eax,%r13d
  add    %r13d,0xc(%rsp)
L19:
  mov    0x18(%rsp),%rax
  sub    %r15,%rax
  cmp    $0x3c,%rax
  jg     L13
L108:
  cmp    $0x1c,%rax
  jg     L34
L18:
  cmp    $0xc,%rax
  jg     L68
L91:
  cmp    $0x4,%rax
  jg     L5
L80:
  test   %rax,%rax
  jle    L77
  mov    %r15,%rdi
  call   <read_u8@plt>
  mov    $0x19,%esi
  imul   $0x2f5870a5,%eax,%ebx
  add    0xc(%rsp),%ebx
  mov    %ebx,%edi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  xor    %ebx,%eax
  mov    %eax,0xc(%rsp)
L77:
  mov    0xc(%rsp),%ebx
  mov    $0x21,%esi
  mov    %ebx,%edi
  call   <rotate_right@plt>
  mov    $0x21,%esi
  xor    %eax,%ebx
  imul   $0xc83a91e1,%ebx,%ebx
  mov    %ebx,%edi
  call   <rotate_right@plt>
  add    $0x28,%rsp
  xor    %ebx,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L5:
  mov    %r15,%rdi
  add    $0x8,%r15
  call   <read_u16@plt>
  mov    $0xd,%esi
  imul   $0x2f5870a5,%eax,%ebx
  add    0xc(%rsp),%ebx
  mov    %ebx,%edi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  xor    %ebx,%eax
  mov    %eax,0xc(%rsp)
  mov    0x18(%rsp),%rax
  sub    %r15,%rax
  jmp    L80
  nopl   0x0(%rax,%rax,1)
L68:
  mov    %r15,%rdi
  add    $0x10,%r15
  call   <read_u32@plt>
  mov    $0xf,%esi
  imul   $0x2f5870a5,%eax,%ebx
  add    0xc(%rsp),%ebx
  mov    %ebx,%edi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  xor    %ebx,%eax
  mov    %eax,0xc(%rsp)
  mov    0x18(%rsp),%rax
  sub    %r15,%rax
  jmp    L91
  nopl   0x0(%rax,%rax,1)
L34:
  mov    %r15,%rdi
  add    $0x20,%r15
  call   <read_u64@plt>
  mov    $0x21,%esi
  imul   $0x2f5870a5,%eax,%ebx
  add    0xc(%rsp),%ebx
  mov    %ebx,%edi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  xor    %ebx,%eax
  mov    %eax,0xc(%rsp)
  mov    0x18(%rsp),%rax
  sub    %r15,%rax
  jmp    L18
  nopl   0x0(%rax,%rax,1)
L13:
  mov    %r15,%rdi
  call   <read_u64@plt>
  mov    0xc(%rsp),%r14d
  mov    $0x21,%esi
  imul   $0xc83a91e1,%eax,%edi
  add    %r14d,%edi
  call   <rotate_right@plt>
  lea    0x20(%r15),%rdi
  add    $0x40,%r15
  mov    %eax,%ebp
  imul   $0x8648dbdb,%eax,%r13d
  call   <read_u64@plt>
  mov    $0x21,%esi
  imul   $0x8648dbdb,%eax,%edi
  add    %r14d,%edi
  call   <rotate_right@plt>
  imul   $0x322e467b,%ebp,%edi
  mov    $0x23,%esi
  imul   $0x7bdec03b,%eax,%r12d
  mov    %eax,%ebx
  call   <rotate_right@plt>
  imul   $0x33f3b607,%ebx,%edi
  mov    $0x23,%esi
  lea    (%rax,%r12,1),%ebp
  xor    %r13d,%ebp
  call   <rotate_right@plt>
  add    %ebp,%eax
  xor    %r12d,%eax
  add    %eax,%r14d
  mov    0x18(%rsp),%rax
  mov    %r14d,0xc(%rsp)
  sub    %r15,%rax
  jmp    L108
```

assistant: ```c
uint64_t metrohash64_1(const uint8_t *key, uint64_t len, uint64_t seed) {
  static const uint64_t k0 = 0xC83A91E1;
  static const uint64_t k1 = 0x8648DBDB;
  static const uint64_t k2 = 0x7BDEC03B;
  static const uint64_t k3 = 0x2F5870A5;
  const uint8_t *ptr = key;
  const uint8_t *const end = ptr + len;
  uint64_t hash = ((((uint64_t)seed) + k2) * k0) + len;
  if (len >= 32) {
    uint64_t v[4];
    v[0] = hash;
    v[1] = hash;
    v[2] = hash;
    v[3] = hash;
    do {
      v[0] += read_u64(ptr) * k0;
      ptr += 8;
      v[0] = rotate_right(v[0], 29) + v[2];
      v[1] += read_u64(ptr) * k1;
      ptr += 8;
      v[1] = rotate_right(v[1], 29) + v[3];
      v[2] += read_u64(ptr) * k2;
      ptr += 8;
      v[2] = rotate_right(v[2], 29) + v[0];
      v[3] += read_u64(ptr) * k3;
      ptr += 8;
      v[3] = rotate_right(v[3], 29) + v[1];
    } while (ptr <= (end - 32));
    v[2] ^= rotate_right(((v[0] + v[3]) * k0) + v[1], 33) * k1;
    v[3] ^= rotate_right(((v[1] + v[2]) * k1) + v[0], 33) * k0;
    v[0] ^= rotate_right(((v[0] + v[2]) * k0) + v[3], 33) * k1;
    v[1] ^= rotate_right(((v[1] + v[3]) * k1) + v[2], 33) * k0;
    hash += v[0] ^ v[1];
  }
  if ((end - ptr) >= 16) {
    uint64_t v0 = hash + (read_u64(ptr) * k0);
    ptr += 8;
    v0 = rotate_right(v0, 33) * k1;
    uint64_t v1 = hash + (read_u64(ptr) * k1);
    ptr += 8;
    v1 = rotate_right(v1, 33) * k2;
    v0 ^= rotate_right(v0 * k0, 35) + v1;
    v1 ^= rotate_right(v1 * k3, 35) + v0;
    hash += v1;
  }
  if ((end - ptr) >= 8) {
    hash += read_u64(ptr) * k3;
    ptr += 8;
    hash ^= rotate_right(hash, 33) * k1;
  }
  if ((end - ptr) >= 4) {
    hash += read_u32(ptr) * k3;
    ptr += 4;
    hash ^= rotate_right(hash, 15) * k1;
  }
  if ((end - ptr) >= 2) {
    hash += read_u16(ptr) * k3;
    ptr += 2;
    hash ^= rotate_right(hash, 13) * k1;
  }
  if ((end - ptr) >= 1) {
    hash += read_u8(ptr) * k3;
    hash ^= rotate_right(hash, 25) * k1;
  }
  hash ^= rotate_right(hash, 33);
  hash *= k0;
  hash ^= rotate_right(hash, 33);
  return hash;
}
```