user: What is the c source code of the assembly code below?

```asm
<upb_murmur_hash2>:
  endbr64
  mov    %rdi,%r9
  push   %r12
  mov    %rdx,%rax
  mov    %rsi,%rdi
  push   %rbp
  xor    %rsi,%rax
  push   %rbx
  mov    %r9d,%ebx
  and    $0x3,%ebx
  je     L206
  cmp    $0x3,%rsi
  jbe    L206
  cmp    $0x2,%ebx
  je     L157
  xor    %edx,%edx
  cmp    $0x3,%ebx
  je     L207
  mov    0x8(%r9),%ecx
  shl    $0x10,%ecx
  movslq %ecx,%rcx
L116:
  mov    0x4(%r9),%edx
  shl    $0x8,%edx
  movslq %edx,%rdx
  or     %rcx,%rdx
L207:
  movslq (%r9),%rsi
  mov    $0x4,%r10d
  lea    0x0(,%rbx,8),%r11d
  sub    %ebx,%r10d
  mov    %r11d,%ecx
  or     %rdx,%rsi
  movslq %r10d,%rdx
  shl    $0x3,%r10d
  sub    %rdx,%rdi
  shl    %cl,%rsi
  lea    (%r9,%rdx,4),%rbp
  cmp    $0x3,%rdi
  jbe    L46
  mov    %rbp,%r9
  mov    %rdi,%r8
  nopl   0x0(%rax)
L224:
  mov    %rsi,%r12
  mov    (%r9),%rsi
  mov    %r11d,%ecx
  sub    $0x4,%r8
  shr    %cl,%r12
  mov    %r10d,%ecx
  add    $0x10,%r9
  mov    %rsi,%rdx
  imul   $0x5bd1e995,%rax,%rax
  shl    %cl,%rdx
  or     %r12,%rdx
  imul   $0x5bd1e995,%rdx,%rdx
  mov    %rdx,%rcx
  shr    $0x18,%rcx
  xor    %rcx,%rdx
  imul   $0x5bd1e995,%rdx,%rdx
  xor    %rdx,%rax
  cmp    $0x3,%r8
  ja     L224
  mov    %rdi,%r8
  sub    $0x4,%rdi
  shr    $0x2,%rdi
  and    $0x3,%r8d
  add    $0x1,%rdi
  shl    $0x4,%rdi
  add    %rdi,%rbp
L115:
  movslq %ebx,%rdi
  cmp    %r8,%rdi
  ja     L29
  cmp    $0x2,%ebx
  je     L4
  xor    %ecx,%ecx
  cmp    $0x3,%ebx
  jne    L10
  mov    0x8(%rbp),%edx
  shl    $0x10,%edx
  movslq %edx,%rdx
L148:
  mov    0x4(%rbp),%ecx
  shl    $0x8,%ecx
  movslq %ecx,%rcx
  or     %rdx,%rcx
L10:
  movslq 0x0(%rbp),%rdx
  sub    %rdi,%r8
  or     %rcx,%rdx
  mov    %r10d,%ecx
  shl    %cl,%rdx
  mov    %r11d,%ecx
  shr    %cl,%rsi
  imul   $0x5bd1e995,%rax,%rcx
  or     %rsi,%rdx
  imul   $0x5bd1e995,%rdx,%rsi
  mov    %rsi,%rdx
  shr    $0x18,%rdx
  xor    %rsi,%rdx
  imul   $0x5bd1e995,%rdx,%rax
  lea    0x0(%rbp,%rdi,4),%rdx
  xor    %rcx,%rax
  cmp    $0x1,%r8
  je     L199
  cmp    $0x2,%r8
  jne    L188
  mov    0x4(%rdx),%ecx
  shl    $0x8,%ecx
  movslq %ecx,%rcx
  xor    %rcx,%rax
L199:
  movslq (%rdx),%rdx
  xor    %rdx,%rax
  imul   $0x5bd1e995,%rax,%rax
L188:
  mov    %rax,%rdx
  pop    %rbx
  pop    %rbp
  shr    $0xd,%rdx
  pop    %r12
  xor    %rax,%rdx
  imul   $0x5bd1e995,%rdx,%rdx
  mov    %rdx,%rax
  shr    $0xf,%rax
  xor    %rdx,%rax
  ret
  nopl   0x0(%rax,%rax,1)
L206:
  mov    %r9,%rsi
  mov    %rdi,%rcx
  mov    %rdi,%rdx
  cmp    $0x3,%rdi
  jbe    L57
  nop
L113:
  imul   $0x5bd1e995,(%rsi),%r8
  sub    $0x4,%rcx
  add    $0x10,%rsi
  imul   $0x5bd1e995,%rax,%rax
  mov    %r8,%rdx
  shr    $0x18,%rdx
  xor    %r8,%rdx
  imul   $0x5bd1e995,%rdx,%rdx
  xor    %rdx,%rax
  cmp    $0x3,%rcx
  ja     L113
  mov    %rdi,%rdx
  sub    $0x4,%rdi
  shr    $0x2,%rdi
  and    $0x3,%edx
  add    $0x1,%rdi
  shl    $0x4,%rdi
  add    %rdi,%r9
L57:
  cmp    $0x2,%rdx
  je     L13
  cmp    $0x3,%rdx
  je     L214
  cmp    $0x1,%rdx
  jne    L188
  movslq (%r9),%rdx
  xor    %rdx,%rax
  imul   $0x5bd1e995,%rax,%rax
  jmp    L188
  nopl   0x0(%rax)
L214:
  mov    0x8(%r9),%edx
  shl    $0x10,%edx
  movslq %edx,%rdx
  xor    %rdx,%rax
L13:
  mov    0x4(%r9),%edx
  shl    $0x8,%edx
  movslq %edx,%rdx
  xor    %rdx,%rax
  movslq (%r9),%rdx
  xor    %rdx,%rax
  imul   $0x5bd1e995,%rax,%rax
  jmp    L188
  nopl   0x0(%rax)
L29:
  cmp    $0x1,%r8
  je     L198
  xor    %edx,%edx
  cmp    $0x2,%r8
  jne    L132
  mov    0x4(%rbp),%ecx
  shl    $0x8,%ecx
  movslq %ecx,%rcx
L164:
  movslq 0x0(%rbp),%rdx
  or     %rcx,%rdx
  mov    %r10d,%ecx
  shl    %cl,%rdx
L132:
  mov    %r11d,%ecx
  shr    %cl,%rsi
  or     %rdx,%rsi
  xor    %rsi,%rax
  imul   $0x5bd1e995,%rax,%rax
  jmp    L188
  nopl   0x0(%rax)
L157:
  xor    %ecx,%ecx
  jmp    L116
  nop
L4:
  xor    %edx,%edx
  jmp    L148
  nopw   0x0(%rax,%rax,1)
L198:
  xor    %ecx,%ecx
  jmp    L164
  nopl   0x0(%rax)
L46:
  mov    %rdi,%r8
  jmp    L115
```

assistant: ```c
uint32_t upb_murmur_hash2(const void *key, size_t len, uint32_t seed) {
  const uint32_t m = 0x5bd1e995;
  const int32_t r = 24;
  const uint8_t *data = (const uint8_t *)key;
  uint32_t h = (uint32_t)(seed ^ len);
  uint8_t align = (uintptr_t)data & 3;
  if (align && (len >= 4)) {
    uint32_t t = 0, d = 0;
    int32_t sl;
    int32_t sr;
    switch (align) {
    case 1:
      t |= data[2] << 16;
    case 2:
      t |= data[1] << 8;
    case 3:
      t |= data[0];
    }
    t <<= (8 * align);
    data += 4 - align;
    len -= 4 - align;
    sl = 8 * (4 - align);
    sr = 8 * align;
    while (len >= 4) {
      uint32_t k;
      d = *(uint32_t *)data;
      t = (t >> sr) | (d << sl);
      k = t;
      {
        k *= m;
        k ^= k >> r;
        k *= m;
        h *= m;
        h ^= k;
      };
      t = d;
      data += 4;
      len -= 4;
    }
    d = 0;
    if (len >= align) {
      uint32_t k;
      switch (align) {
      case 3:
        d |= data[2] << 16;
      case 2:
        d |= data[1] << 8;
      case 1:
        d |= data[0];
      }
      k = (t >> sr) | (d << sl);
      {
        k *= m;
        k ^= k >> r;
        k *= m;
        h *= m;
        h ^= k;
      };
      data += align;
      len -= align;
      switch (len) {
      case 3:
        h ^= data[2] << 16;
      case 2:
        h ^= data[1] << 8;
      case 1:
        h ^= data[0];
        h *= m;
      };
    } else {
      switch (len) {
      case 3:
        d |= data[2] << 16;
      case 2:
        d |= data[1] << 8;
      case 1:
        d |= data[0];
      case 0:
        h ^= (t >> sr) | (d << sl);
        h *= m;
      }
    }
    h ^= h >> 13;
    h *= m;
    h ^= h >> 15;
    return h;
  } else {
    while (len >= 4) {
      uint32_t k = *(uint32_t *)data;
      {
        k *= m;
        k ^= k >> r;
        k *= m;
        h *= m;
        h ^= k;
      };
      data += 4;
      len -= 4;
    }
    switch (len) {
    case 3:
      h ^= data[2] << 16;
    case 2:
      h ^= data[1] << 8;
    case 1:
      h ^= data[0];
      h *= m;
    };
    h ^= h >> 13;
    h *= m;
    h ^= h >> 15;
    return h;
  }
}
```