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

```asm
<my_hashword2>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %rcx,-0x30(%rbp)
  mov    -0x20(%rbp),%rax
  shl    $0x2,%rax
  mov    %eax,%edx
  mov    -0x28(%rbp),%rax
  mov    (%rax),%eax
  add    %edx,%eax
  sub    $0x21524111,%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x8(%rbp),%eax
  mov    %eax,-0xc(%rbp)
  mov    -0x30(%rbp),%rax
  mov    (%rax),%eax
  add    %eax,-0x4(%rbp)
  jmp    L12
L46:
  mov    -0x18(%rbp),%rax
  mov    (%rax),%eax
  add    %eax,-0xc(%rbp)
  mov    -0x18(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  add    %eax,-0x8(%rbp)
  mov    -0x18(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%eax
  add    %eax,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  sub    %eax,-0xc(%rbp)
  mov    -0x4(%rbp),%eax
  shl    $0x4,%eax
  mov    %eax,%edx
  mov    -0x4(%rbp),%eax
  sar    $0x1c,%eax
  or     %edx,%eax
  xor    %eax,-0xc(%rbp)
  mov    -0x8(%rbp),%eax
  add    %eax,-0x4(%rbp)
  mov    -0xc(%rbp),%eax
  sub    %eax,-0x8(%rbp)
  mov    -0xc(%rbp),%eax
  shl    $0x6,%eax
  mov    %eax,%edx
  mov    -0xc(%rbp),%eax
  sar    $0x1a,%eax
  or     %edx,%eax
  xor    %eax,-0x8(%rbp)
  mov    -0x4(%rbp),%eax
  add    %eax,-0xc(%rbp)
  mov    -0x8(%rbp),%eax
  sub    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  shl    $0x8,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%eax
  sar    $0x18,%eax
  or     %edx,%eax
  xor    %eax,-0x4(%rbp)
  mov    -0xc(%rbp),%eax
  add    %eax,-0x8(%rbp)
  mov    -0x4(%rbp),%eax
  sub    %eax,-0xc(%rbp)
  mov    -0x4(%rbp),%eax
  shl    $0x10,%eax
  mov    %eax,%edx
  mov    -0x4(%rbp),%eax
  sar    $0x10,%eax
  or     %edx,%eax
  xor    %eax,-0xc(%rbp)
  mov    -0x8(%rbp),%eax
  add    %eax,-0x4(%rbp)
  mov    -0xc(%rbp),%eax
  sub    %eax,-0x8(%rbp)
  mov    -0xc(%rbp),%eax
  shl    $0x13,%eax
  mov    %eax,%edx
  mov    -0xc(%rbp),%eax
  sar    $0xd,%eax
  or     %edx,%eax
  xor    %eax,-0x8(%rbp)
  mov    -0x4(%rbp),%eax
  add    %eax,-0xc(%rbp)
  mov    -0x8(%rbp),%eax
  sub    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  shl    $0x4,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%eax
  sar    $0x1c,%eax
  or     %edx,%eax
  xor    %eax,-0x4(%rbp)
  mov    -0xc(%rbp),%eax
  add    %eax,-0x8(%rbp)
  subq   $0x3,-0x20(%rbp)
  addq   $0xc,-0x18(%rbp)
L12:
  cmpq   $0x3,-0x20(%rbp)
  ja     L46
  cmpq   $0x3,-0x20(%rbp)
  je     L39
  cmpq   $0x3,-0x20(%rbp)
  ja     L28
  cmpq   $0x2,-0x20(%rbp)
  je     L85
  cmpq   $0x2,-0x20(%rbp)
  ja     L28
  cmpq   $0x0,-0x20(%rbp)
  je     L53
  cmpq   $0x1,-0x20(%rbp)
  je     L45
  jmp    L28
L39:
  mov    -0x18(%rbp),%rax
  add    $0x8,%rax
  mov    (%rax),%eax
  add    %eax,-0x4(%rbp)
L85:
  mov    -0x18(%rbp),%rax
  add    $0x4,%rax
  mov    (%rax),%eax
  add    %eax,-0x8(%rbp)
L45:
  mov    -0x18(%rbp),%rax
  mov    (%rax),%eax
  add    %eax,-0xc(%rbp)
  mov    -0x8(%rbp),%eax
  xor    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  shl    $0xe,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%eax
  sar    $0x12,%eax
  or     %edx,%eax
  sub    %eax,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  xor    %eax,-0xc(%rbp)
  mov    -0x4(%rbp),%eax
  shl    $0xb,%eax
  mov    %eax,%edx
  mov    -0x4(%rbp),%eax
  sar    $0x15,%eax
  or     %edx,%eax
  sub    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  xor    %eax,-0x8(%rbp)
  mov    -0xc(%rbp),%eax
  shl    $0x19,%eax
  mov    %eax,%edx
  mov    -0xc(%rbp),%eax
  sar    $0x7,%eax
  or     %edx,%eax
  sub    %eax,-0x8(%rbp)
  mov    -0x8(%rbp),%eax
  xor    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  shl    $0x10,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%eax
  sar    $0x10,%eax
  or     %edx,%eax
  sub    %eax,-0x4(%rbp)
  mov    -0x4(%rbp),%eax
  xor    %eax,-0xc(%rbp)
  mov    -0x4(%rbp),%eax
  shl    $0x4,%eax
  mov    %eax,%edx
  mov    -0x4(%rbp),%eax
  sar    $0x1c,%eax
  or     %edx,%eax
  sub    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  xor    %eax,-0x8(%rbp)
  mov    -0xc(%rbp),%eax
  shl    $0xe,%eax
  mov    %eax,%edx
  mov    -0xc(%rbp),%eax
  sar    $0x12,%eax
  or     %edx,%eax
  sub    %eax,-0x8(%rbp)
  mov    -0x8(%rbp),%eax
  xor    %eax,-0x4(%rbp)
  mov    -0x8(%rbp),%eax
  shl    $0x18,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%eax
  sar    $0x8,%eax
  or     %edx,%eax
  sub    %eax,-0x4(%rbp)
L53:
  nop
L28:
  mov    -0x28(%rbp),%rax
  mov    -0x4(%rbp),%edx
  mov    %edx,(%rax)
  mov    -0x30(%rbp),%rax
  mov    -0x8(%rbp),%edx
  mov    %edx,(%rax)
  nop
  pop    %rbp
  ret
```

assistant: ```c
void my_hashword2(const uint32_t *k, size_t length, uint32_t *pc, uint32_t *pb) {
  uint32_t a, b, c;
  a = b = c = 0xdeadbeef + ((uint32_t)(length << 2)) + *pc;
  c += *pb;
  while (length > 3) {
    a += k[0];
    b += k[1];
    c += k[2];
    {
      a -= c;
      a ^= (((c) << (4)) | ((c) >> (32 - (4))));
      c += b;
      b -= a;
      b ^= (((a) << (6)) | ((a) >> (32 - (6))));
      a += c;
      c -= b;
      c ^= (((b) << (8)) | ((b) >> (32 - (8))));
      b += a;
      a -= c;
      a ^= (((c) << (16)) | ((c) >> (32 - (16))));
      c += b;
      b -= a;
      b ^= (((a) << (19)) | ((a) >> (32 - (19))));
      a += c;
      c -= b;
      c ^= (((b) << (4)) | ((b) >> (32 - (4))));
      b += a;
    };
    length -= 3;
    k += 3;
  }
  switch (length) {
  case 3:
    c += k[2];
  case 2:
    b += k[1];
  case 1:
    a += k[0];
    {
      c ^= b;
      c -= (((b) << (14)) | ((b) >> (32 - (14))));
      a ^= c;
      a -= (((c) << (11)) | ((c) >> (32 - (11))));
      b ^= a;
      b -= (((a) << (25)) | ((a) >> (32 - (25))));
      c ^= b;
      c -= (((b) << (16)) | ((b) >> (32 - (16))));
      a ^= c;
      a -= (((c) << (4)) | ((c) >> (32 - (4))));
      b ^= a;
      b -= (((a) << (14)) | ((a) >> (32 - (14))));
      c ^= b;
      c -= (((b) << (24)) | ((b) >> (32 - (24))));
    };
  case 0:
    break;
  }
  *pc = c;
  *pb = b;
}
```