user: 请将以下的汇编代码转换成C语言代码：

```asm
<metrohash64_1>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdi,%r14
  movslq %esi,%rax
  lea    (%rdi,%rax,4),%r15
  add    $0x7bdec03b,%edx
  imul   $0xc83a91e1,%edx,%edx
  lea    (%rdx,%rsi,1),%eax
  mov    %eax,0x4(%rsp)
  cmp    $0x1f,%esi
  jle    L12
  mov    %eax,%r12d
  mov    %eax,%r13d
  mov    %eax,(%rsp)
  mov    %eax,%ebp
  mov    %rdi,%rbx
  lea    -0x80(%r15),%rax
  mov    %rax,0x8(%rsp)
L79:
  mov    %rbx,%rdi
  call   <read_u64@plt>
  imul   $0xc83a91e1,%eax,%edi
  add    %r12d,%edi
  mov    $0x1d,%esi
  call   <rotate_right@plt>
  mov    (%rsp),%ecx
  lea    (%rax,%rcx,1),%r12d
  lea    0x20(%rbx),%rdi
  call   <read_u64@plt>
  imul   $0x8648dbdb,%eax,%edi
  add    %ebp,%edi
  mov    $0x1d,%esi
  call   <rotate_right@plt>
  lea    (%rax,%r13,1),%ebp
  lea    0x40(%rbx),%rdi
  call   <read_u64@plt>
  imul   $0x7bdec03b,%eax,%edi
  add    (%rsp),%edi
  mov    $0x1d,%esi
  call   <rotate_right@plt>
  add    %r12d,%eax
  mov    %eax,(%rsp)
  lea    0x60(%rbx),%rdi
  call   <read_u64@plt>
  sub    $0xffffffffffffff80,%rbx
  imul   $0x2f5870a5,%eax,%edi
  add    %r13d,%edi
  mov    $0x1d,%esi
  call   <rotate_right@plt>
  lea    0x0(%rbp,%rax,1),%r13d
  cmp    0x8(%rsp),%rbx
  jbe    L79
  mov    %r15,%rax
  sub    %r14,%rax
  lea    -0x80(%rax),%rax
  and    $0xffffffffffffff80,%rax
  lea    0x80(%rax),%rax
  lea    0x1(%r14),%rcx
  lea    -0x7f(%r15),%rdx
  cmp    %rdx,%rcx
  mov    $0x80,%edx
  cmova  %rdx,%rax
  add    %rax,%r14
  lea    (%r12,%r13,1),%edi
  imul   $0xc83a91e1,%edi,%edi
  add    %ebp,%edi
  mov    $0x21,%esi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  mov    (%rsp),%ebx
  xor    %eax,%ebx
  lea    0x0(%rbp,%rbx,1),%edi
  imul   $0x8648dbdb,%edi,%edi
  add    %r12d,%edi
  mov    $0x21,%esi
  call   <rotate_right@plt>
  imul   $0xc83a91e1,%eax,%eax
  xor    %eax,%r13d
  lea    (%r12,%rbx,1),%edi
  imul   $0xc83a91e1,%edi,%edi
  add    %r13d,%edi
  mov    $0x21,%esi
  call   <rotate_right@plt>
  mov    %eax,(%rsp)
  xor    %ebp,%r12d
  lea    0x0(%rbp,%r13,1),%edi
  imul   $0x8648dbdb,%edi,%edi
  add    %ebx,%edi
  mov    $0x21,%esi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,(%rsp),%edx
  xor    %r12d,%edx
  imul   $0xc83a91e1,%eax,%eax
  xor    %eax,%edx
  add    %edx,0x4(%rsp)
L12:
  mov    %r15,%rax
  sub    %r14,%rax
  cmp    $0x3c,%rax
  jg     L92
L66:
  mov    %r15,%rax
  sub    %r14,%rax
  cmp    $0x1c,%rax
  jg     L37
L49:
  mov    %r15,%rax
  sub    %r14,%rax
  cmp    $0xc,%rax
  jg     L70
L90:
  mov    %r15,%rax
  sub    %r14,%rax
  cmp    $0x4,%rax
  jg     L15
L91:
  sub    %r14,%r15
  test   %r15,%r15
  jg     L73
L16:
  mov    $0x21,%esi
  mov    0x4(%rsp),%ebx
  mov    %ebx,%edi
  call   <rotate_right@plt>
  xor    %eax,%ebx
  imul   $0xc83a91e1,%ebx,%ebx
  mov    $0x21,%esi
  mov    %ebx,%edi
  call   <rotate_right@plt>
  xor    %ebx,%eax
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L92:
  mov    %r14,%rdi
  call   <read_u64@plt>
  imul   $0xc83a91e1,%eax,%edi
  mov    0x4(%rsp),%ebx
  add    %ebx,%edi
  mov    $0x21,%esi
  call   <rotate_right@plt>
  mov    %eax,%ebp
  imul   $0x8648dbdb,%eax,%r13d
  lea    0x20(%r14),%rdi
  call   <read_u64@plt>
  add    $0x40,%r14
  imul   $0x8648dbdb,%eax,%edi
  mov    %ebx,0x4(%rsp)
  add    %ebx,%edi
  mov    $0x21,%esi
  call   <rotate_right@plt>
  mov    %eax,%ebx
  imul   $0x7bdec03b,%eax,%r12d
  imul   $0x322e467b,%ebp,%edi
  mov    $0x23,%esi
  call   <rotate_right@plt>
  lea    (%rax,%r12,1),%ebp
  xor    %r13d,%ebp
  imul   $0x33f3b607,%ebx,%edi
  mov    $0x23,%esi
  call   <rotate_right@plt>
  add    %ebp,%eax
  xor    %r12d,%eax
  add    %eax,0x4(%rsp)
  jmp    L66
L37:
  mov    %r14,%rdi
  call   <read_u64@plt>
  imul   $0x2f5870a5,%eax,%ebx
  add    0x4(%rsp),%ebx
  add    $0x20,%r14
  mov    $0x21,%esi
  mov    %ebx,%edi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  xor    %ebx,%eax
  mov    %eax,0x4(%rsp)
  jmp    L49
L70:
  mov    %r14,%rdi
  call   <read_u32@plt>
  imul   $0x2f5870a5,%eax,%ebx
  add    0x4(%rsp),%ebx
  add    $0x10,%r14
  mov    $0xf,%esi
  mov    %ebx,%edi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  xor    %ebx,%eax
  mov    %eax,0x4(%rsp)
  jmp    L90
L15:
  mov    %r14,%rdi
  call   <read_u16@plt>
  imul   $0x2f5870a5,%eax,%ebx
  add    0x4(%rsp),%ebx
  add    $0x8,%r14
  mov    $0xd,%esi
  mov    %ebx,%edi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  xor    %ebx,%eax
  mov    %eax,0x4(%rsp)
  jmp    L91
L73:
  mov    %r14,%rdi
  call   <read_u8@plt>
  imul   $0x2f5870a5,%eax,%ebx
  add    0x4(%rsp),%ebx
  mov    $0x19,%esi
  mov    %ebx,%edi
  call   <rotate_right@plt>
  imul   $0x8648dbdb,%eax,%eax
  xor    %ebx,%eax
  mov    %eax,0x4(%rsp)
  jmp    L16
```

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;
}
```