user: Please show me the C implementation that matches the assembly code listed below:

```asm
<Murmur3>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x68(%rbp)
  mov    %rsi,-0x70(%rbp)
  mov    $0xdeadbeef,%eax
  mov    %rax,-0x40(%rbp)
  movq   $0xacffe3d,-0x38(%rbp)
  movq   $0xe4ef5f3,-0x30(%rbp)
  mov    $0xa729a897,%eax
  mov    %rax,-0x28(%rbp)
  movq   $0xb,-0x20(%rbp)
  movq   $0x12,-0x18(%rbp)
  movq   $0x12,-0x10(%rbp)
  mov    -0x70(%rbp),%rdx
  mov    -0x40(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x58(%rbp)
  movq   $0x0,-0x50(%rbp)
  mov    -0x68(%rbp),%rax
  mov    %rax,-0x48(%rbp)
  jmp    L29
L36:
  mov    -0x48(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x48(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x50(%rbp),%rax
  imul   -0x38(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %eax,%ecx
  rolq   %cl,-0x50(%rbp)
  mov    -0x50(%rbp),%rax
  imul   -0x30(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x58(%rbp),%rdx
  mov    %rdx,%rax
  add    %rax,%rax
  add    %rdx,%rax
  mov    %rax,-0x58(%rbp)
  mov    -0x50(%rbp),%rax
  xor    %rax,-0x58(%rbp)
  subq   $0x8,-0x70(%rbp)
L29:
  cmpq   $0x7,-0x70(%rbp)
  ja     L36
  mov    -0x48(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  cmpq   $0x3,-0x70(%rbp)
  je     L57
  cmpq   $0x3,-0x70(%rbp)
  ja     L60
  cmpq   $0x1,-0x70(%rbp)
  je     L18
  cmpq   $0x2,-0x70(%rbp)
  je     L54
  jmp    L60
L57:
  mov    -0x8(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  shl    $0x10,%eax
  cltq
  xor    %rax,-0x50(%rbp)
L54:
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movsbl %al,%eax
  shl    $0x8,%eax
  cltq
  xor    %rax,-0x50(%rbp)
L18:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movsbq %al,%rax
  xor    %rax,-0x50(%rbp)
  mov    -0x50(%rbp),%rax
  imul   -0x38(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x20(%rbp),%rax
  mov    %eax,%ecx
  rolq   %cl,-0x50(%rbp)
  mov    -0x50(%rbp),%rax
  imul   -0x30(%rbp),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x58(%rbp),%rdx
  mov    %rdx,%rax
  add    %rax,%rax
  add    %rdx,%rax
  mov    %rax,-0x58(%rbp)
  mov    -0x50(%rbp),%rax
  xor    %rax,-0x58(%rbp)
L60:
  mov    -0x18(%rbp),%rax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  mov    %edx,%ecx
  shr    %cl,%rax
  xor    %rax,-0x58(%rbp)
  mov    -0x58(%rbp),%rax
  imul   -0x28(%rbp),%rax
  mov    %rax,-0x58(%rbp)
  mov    -0x10(%rbp),%rax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rax
  mov    %edx,%ecx
  shr    %cl,%rax
  xor    %rax,-0x58(%rbp)
  mov    -0x58(%rbp),%rax
  pop    %rbp
  ret
```

assistant: ```c
size_t Murmur3(const char *key, size_t len) {
  const size_t seed = 0xDEADBEEF;
  const size_t m1 = 0x0acffe3d, m2 = 0x0e4ef5f3, m3 = 0xa729a897;
  const size_t r1 = 11, r2 = 18, r3 = 18;
  size_t h = len + seed, k = 0;
  const size_t *dwords = (const size_t *)key;
  while (len >= sizeof(size_t)) {
    k = *dwords++;
    {
      k *= m1;
      k = (k << r1) | (k >> (sizeof(size_t) * 8 - r1));
      k *= m2;
      h *= 3;
      h ^= k;
    };
    len -= sizeof(size_t);
  }
  const char *tail = (const char *)dwords;
  switch (len) {
  case 3:
    k ^= tail[2] << 16;
  case 2:
    k ^= tail[1] << 8;
  case 1:
    k ^= tail[0];
    {
      k *= m1;
      k = (k << r1) | (k >> (sizeof(size_t) * 8 - r1));
      k *= m2;
      h *= 3;
      h ^= k;
    };
  }
  h ^= h >> r2;
  h *= m3;
  h ^= h >> r3;
  return h;
}
```