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

```asm
<hashlittle2>:
  endbr64
  mov    (%rdx),%eax
  mov    %rcx,%r9
  mov    (%rcx),%ecx
  mov    %rdx,%r8
  lea    -0x21524111(%rax,%rsi,1),%eax
  add    %eax,%ecx
  mov    %eax,%edx
  test   $0x3,%dil
  je     L118
  test   $0x1,%dil
  jne    L192
  cmp    $0xc,%rsi
  jbe    L137
  nopw   0x0(%rax,%rax,1)
L62:
  mov    0x8(%rdi),%r10d
  add    (%rdi),%eax
  add    0x10(%rdi),%edx
  add    0x20(%rdi),%ecx
  shl    $0x10,%r10d
  add    %r10d,%eax
  mov    0x18(%rdi),%r10d
  shl    $0x10,%r10d
  add    %r10d,%edx
  mov    0x28(%rdi),%r10d
  shl    $0x10,%r10d
  add    %r10d,%ecx
  sub    %ecx,%eax
  mov    %ecx,%r11d
  mov    %eax,%r10d
  mov    %ecx,%eax
  sar    $0x1c,%r11d
  add    %edx,%ecx
  shl    $0x4,%eax
  or     %r11d,%eax
  xor    %r10d,%eax
  sub    %eax,%edx
  mov    %eax,%r11d
  mov    %edx,%r10d
  mov    %eax,%edx
  sar    $0x1a,%r11d
  add    %ecx,%eax
  shl    $0x6,%edx
  or     %r11d,%edx
  xor    %r10d,%edx
  sub    %edx,%ecx
  mov    %edx,%r11d
  mov    %ecx,%r10d
  mov    %edx,%ecx
  sar    $0x18,%r11d
  add    %eax,%edx
  shl    $0x8,%ecx
  or     %r11d,%ecx
  xor    %r10d,%ecx
  mov    %ecx,%r10d
  mov    %ecx,%r11d
  sub    %ecx,%eax
  sar    $0x10,%r11d
  shl    $0x10,%r10d
  or     %r11d,%r10d
  xor    %r10d,%eax
  add    %edx,%ecx
  sub    $0xc,%rsi
  add    $0x30,%rdi
  mov    %eax,%r10d
  mov    %eax,%r11d
  sub    %eax,%edx
  add    %ecx,%eax
  sar    $0xd,%r11d
  shl    $0x13,%r10d
  or     %r11d,%r10d
  xor    %r10d,%edx
  sub    %edx,%ecx
  mov    %edx,%r11d
  mov    %ecx,%r10d
  mov    %edx,%ecx
  sar    $0x1c,%r11d
  add    %eax,%edx
  shl    $0x4,%ecx
  or     %r11d,%ecx
  xor    %r10d,%ecx
  cmp    $0xc,%rsi
  ja     L62
L137:
  lea    D15(%rip),%r10
  movslq (%r10,%rsi,4),%rsi
  add    %r10,%rsi
  notrack jmp *%rsi
L37:
  add    0x8(%rdi),%ecx
  add    (%rdi),%eax
  sub    %ecx,%eax
  mov    %ecx,%r11d
  add    0x4(%rdi),%edx
  mov    %eax,%r10d
  mov    %ecx,%eax
  sar    $0x1c,%r11d
  add    %edx,%ecx
  shl    $0x4,%eax
  or     %r11d,%eax
  xor    %r10d,%eax
  sub    %eax,%edx
  mov    %eax,%r11d
  mov    %edx,%r10d
  mov    %eax,%edx
  sar    $0x1a,%r11d
  add    %ecx,%eax
  shl    $0x6,%edx
  or     %r11d,%edx
  xor    %r10d,%edx
  sub    %edx,%ecx
  mov    %edx,%r11d
  mov    %ecx,%r10d
  mov    %edx,%ecx
  sar    $0x18,%r11d
  add    %eax,%edx
  shl    $0x8,%ecx
  or     %r11d,%ecx
  xor    %r10d,%ecx
  mov    %ecx,%r10d
  mov    %ecx,%r11d
  sub    %ecx,%eax
  add    %edx,%ecx
  sar    $0x10,%r11d
  shl    $0x10,%r10d
  or     %r11d,%r10d
  xor    %r10d,%eax
  mov    %eax,%r10d
  mov    %eax,%r11d
  sub    %eax,%edx
  sar    $0xd,%r11d
  shl    $0x13,%r10d
  or     %r11d,%r10d
  xor    %r10d,%edx
  add    %ecx,%eax
  sub    $0xc,%rsi
  add    $0xc,%rdi
  mov    %edx,%r10d
  mov    %edx,%r11d
  sub    %edx,%ecx
  add    %eax,%edx
  shl    $0x4,%r10d
  sar    $0x1c,%r11d
  or     %r11d,%r10d
  xor    %r10d,%ecx
L118:
  cmp    $0xc,%rsi
  ja     L37
  lea    D0(%rip),%r10
  movslq (%r10,%rsi,4),%rsi
  add    %r10,%rsi
  notrack jmp *%rsi
  xchg   %ax,%ax
L36:
  mov    0x4(%rdi),%r10d
  add    (%rdi),%eax
  add    0x10(%rdi),%edx
  add    0x20(%rdi),%ecx
  shl    $0x8,%r10d
  add    %r10d,%eax
  mov    0x8(%rdi),%r10d
  shl    $0x10,%r10d
  add    %eax,%r10d
  mov    0xc(%rdi),%eax
  shl    $0x18,%eax
  add    %r10d,%eax
  mov    0x14(%rdi),%r10d
  shl    $0x8,%r10d
  add    %r10d,%edx
  mov    0x18(%rdi),%r10d
  shl    $0x10,%r10d
  add    %edx,%r10d
  mov    0x1c(%rdi),%edx
  shl    $0x18,%edx
  add    %r10d,%edx
  mov    0x24(%rdi),%r10d
  shl    $0x8,%r10d
  add    %r10d,%ecx
  mov    0x28(%rdi),%r10d
  shl    $0x10,%r10d
  add    %ecx,%r10d
  mov    0x2c(%rdi),%ecx
  shl    $0x18,%ecx
  add    %r10d,%ecx
  sub    %ecx,%eax
  mov    %ecx,%r11d
  mov    %eax,%r10d
  mov    %ecx,%eax
  sar    $0x1c,%r11d
  add    %edx,%ecx
  shl    $0x4,%eax
  or     %r11d,%eax
  xor    %r10d,%eax
  sub    %eax,%edx
  mov    %eax,%r11d
  mov    %edx,%r10d
  mov    %eax,%edx
  sar    $0x1a,%r11d
  shl    $0x6,%edx
  or     %r11d,%edx
  xor    %r10d,%edx
  add    %ecx,%eax
  sub    $0xc,%rsi
  add    $0x30,%rdi
  sub    %edx,%ecx
  mov    %edx,%r11d
  mov    %ecx,%r10d
  mov    %edx,%ecx
  sar    $0x18,%r11d
  add    %eax,%edx
  shl    $0x8,%ecx
  or     %r11d,%ecx
  xor    %r10d,%ecx
  mov    %ecx,%r10d
  mov    %ecx,%r11d
  sub    %ecx,%eax
  add    %edx,%ecx
  sar    $0x10,%r11d
  shl    $0x10,%r10d
  or     %r11d,%r10d
  xor    %r10d,%eax
  mov    %eax,%r10d
  mov    %eax,%r11d
  sub    %eax,%edx
  add    %ecx,%eax
  sar    $0xd,%r11d
  shl    $0x13,%r10d
  or     %r11d,%r10d
  xor    %r10d,%edx
  sub    %edx,%ecx
  mov    %edx,%r11d
  mov    %ecx,%r10d
  mov    %edx,%ecx
  sar    $0x1c,%r11d
  add    %eax,%edx
  shl    $0x4,%ecx
  or     %r11d,%ecx
  xor    %r10d,%ecx
L192:
  cmp    $0xc,%rsi
  ja     L36
  lea    D4(%rip),%r10
  movslq (%r10,%rsi,4),%rsi
  add    %r10,%rsi
  notrack jmp *%rsi
  mov    0x2c(%rdi),%esi
  shl    $0x18,%esi
  add    %esi,%ecx
  mov    0x28(%rdi),%esi
  shl    $0x10,%esi
  add    %esi,%ecx
  mov    0x24(%rdi),%esi
  shl    $0x8,%esi
  add    %esi,%ecx
  add    0x20(%rdi),%ecx
  mov    0x1c(%rdi),%esi
  shl    $0x18,%esi
  add    %esi,%edx
  mov    0x18(%rdi),%esi
  shl    $0x10,%esi
  add    %esi,%edx
  mov    0x14(%rdi),%esi
  shl    $0x8,%esi
  add    %esi,%edx
  add    0x10(%rdi),%edx
  mov    0xc(%rdi),%esi
  shl    $0x18,%esi
  add    %esi,%eax
  mov    0x8(%rdi),%esi
  shl    $0x10,%esi
  add    %esi,%eax
  mov    0x4(%rdi),%esi
  shl    $0x8,%esi
  add    %esi,%eax
L172:
  add    (%rdi),%eax
L33:
  mov    %edx,%esi
  mov    %edx,%edi
  xor    %edx,%ecx
  sar    $0x12,%edi
  shl    $0xe,%esi
  or     %edi,%esi
  sub    %esi,%ecx
  mov    %ecx,%esi
  mov    %ecx,%edi
  xor    %ecx,%eax
  sar    $0x15,%edi
  shl    $0xb,%esi
  or     %edi,%esi
  sub    %esi,%eax
  mov    %eax,%esi
  mov    %eax,%edi
  xor    %eax,%edx
  sar    $0x7,%edi
  shl    $0x19,%esi
  or     %edi,%esi
  sub    %esi,%edx
  mov    %edx,%esi
  mov    %edx,%edi
  xor    %edx,%ecx
  sar    $0x10,%edi
  shl    $0x10,%esi
  or     %edi,%esi
  sub    %esi,%ecx
  mov    %ecx,%esi
  mov    %ecx,%edi
  xor    %ecx,%eax
  shl    $0x4,%esi
  sar    $0x1c,%edi
  or     %edi,%esi
  sub    %esi,%eax
  mov    %eax,%esi
  xor    %eax,%edx
  sar    $0x12,%eax
  shl    $0xe,%esi
  or     %esi,%eax
  sub    %eax,%edx
  mov    %edx,%eax
  mov    %edx,%esi
  xor    %edx,%ecx
  shl    $0x18,%eax
  sar    $0x8,%esi
  or     %esi,%eax
  sub    %eax,%ecx
  mov    %ecx,(%r8)
  mov    %edx,(%r9)
  ret
  mov    0x18(%rdi),%esi
  shl    $0x10,%esi
  add    %esi,%edx
  add    0x10(%rdi),%edx
L94:
  mov    0x8(%rdi),%rsi
  add    (%rdi),%eax
  shl    $0x10,%esi
  add    %esi,%eax
  jmp    L33
  mov    (%rdi),%esi
  and    $0xffffff,%esi
  add    %esi,%eax
  jmp    L33
  add    0x8(%rdi),%ecx
  add    0x4(%rdi),%edx
  add    (%rdi),%eax
  jmp    L33
  mov    0x8(%rdi),%esi
  add    0x4(%rdi),%edx
  add    (%rdi),%eax
  and    $0xffffff,%esi
  add    %esi,%ecx
  jmp    L33
  movzwl 0x8(%rdi),%esi
  add    0x4(%rdi),%edx
  add    (%rdi),%eax
  add    %esi,%ecx
  jmp    L33
  movzbl 0x8(%rdi),%esi
  add    0x4(%rdi),%edx
  add    (%rdi),%eax
  add    %esi,%ecx
  jmp    L33
  add    0x4(%rdi),%edx
  add    (%rdi),%eax
  jmp    L33
  mov    0x4(%rdi),%esi
  add    (%rdi),%eax
  and    $0xffffff,%esi
  add    %esi,%edx
  jmp    L33
  movzwl 0x4(%rdi),%esi
  add    (%rdi),%eax
  add    %esi,%edx
  jmp    L33
  movzbl 0x4(%rdi),%esi
  add    (%rdi),%eax
  add    %esi,%edx
  jmp    L33
  movzwl (%rdi),%esi
  add    %esi,%eax
  jmp    L33
  movzbl (%rdi),%esi
  add    %esi,%eax
  jmp    L33
  mov    0x28(%rdi),%esi
  shl    $0x10,%esi
  add    %esi,%ecx
  mov    0x18(%rdi),%esi
  add    0x10(%rdi),%edx
  add    0x20(%rdi),%ecx
  shl    $0x10,%esi
  add    %esi,%edx
  jmp    L94
  add    0x20(%rdi),%ecx
  mov    0x18(%rdi),%esi
  add    0x10(%rdi),%edx
  shl    $0x10,%esi
  add    %esi,%edx
  jmp    L94
  mov    0x8(%rdi),%esi
  shl    $0x10,%esi
  add    %esi,%eax
  jmp    L172
  mov    0x28(%rdi),%esi
  add    0x20(%rdi),%ecx
  add    0x10(%rdi),%edx
  add    (%rdi),%eax
  shl    $0x10,%esi
  add    %esi,%ecx
  mov    0x18(%rdi),%esi
  shl    $0x10,%esi
  add    %esi,%edx
  mov    0x8(%rdi),%esi
  shl    $0x10,%esi
  add    %esi,%eax
  jmp    L33
```

assistant: ```c
void hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb) {
  uint32_t a, b, c;
  union {
    const void *ptr;
    size_t i;
  } u;
  a = b = c = 0xdeadbeef + ((uint32_t)length) + *pc;
  c += *pb;
  u.ptr = key;
  if (1 && ((u.i & 0x3) == 0)) {
    const uint32_t *k = (const uint32_t *)key;
    while (length > 12) {
      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 -= 12;
      k += 3;
    }
    switch (length) {
    case 12:
      c += k[2];
      b += k[1];
      a += k[0];
      break;
    case 11:
      c += k[2] & 0xffffff;
      b += k[1];
      a += k[0];
      break;
    case 10:
      c += k[2] & 0xffff;
      b += k[1];
      a += k[0];
      break;
    case 9:
      c += k[2] & 0xff;
      b += k[1];
      a += k[0];
      break;
    case 8:
      b += k[1];
      a += k[0];
      break;
    case 7:
      b += k[1] & 0xffffff;
      a += k[0];
      break;
    case 6:
      b += k[1] & 0xffff;
      a += k[0];
      break;
    case 5:
      b += k[1] & 0xff;
      a += k[0];
      break;
    case 4:
      a += k[0];
      break;
    case 3:
      a += k[0] & 0xffffff;
      break;
    case 2:
      a += k[0] & 0xffff;
      break;
    case 1:
      a += k[0] & 0xff;
      break;
    case 0:
      *pc = c;
      *pb = b;
      return;
    }
  } else if (1 && ((u.i & 0x1) == 0)) {
    const uint16_t *k = (const uint16_t *)key;
    const uint8_t *k8;
    while (length > 12) {
      a += k[0] + (((uint32_t)k[1]) << 16);
      b += k[2] + (((uint32_t)k[3]) << 16);
      c += k[4] + (((uint32_t)k[5]) << 16);
      {
        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 -= 12;
      k += 6;
    }
    k8 = (const uint8_t *)k;
    switch (length) {
    case 12:
      c += k[4] + (((uint32_t)k[5]) << 16);
      b += k[2] + (((uint32_t)k[3]) << 16);
      a += k[0] + (((uint32_t)k[1]) << 16);
      break;
    case 11:
      c += ((uint32_t)k8[10]) << 16;
    case 10:
      c += k[4];
      b += k[2] + (((uint32_t)k[3]) << 16);
      a += k[0] + (((uint32_t)k[1]) << 16);
      break;
    case 9:
      c += k8[8];
    case 8:
      b += k[2] + (((uint32_t)k[3]) << 16);
      a += k[0] + (((uint32_t)k[1]) << 16);
      break;
    case 7:
      b += ((uint32_t)k8[6]) << 16;
    case 6:
      b += k[2];
      a += k[0] + (((uint32_t)k[1]) << 16);
      break;
    case 5:
      b += k8[4];
    case 4:
      a += k[0] + (((uint32_t)k[1]) << 16);
      break;
    case 3:
      a += ((uint32_t)k8[2]) << 16;
    case 2:
      a += k[0];
      break;
    case 1:
      a += k8[0];
      break;
    case 0:
      *pc = c;
      *pb = b;
      return;
    }
  } else {
    const uint8_t *k = (const uint8_t *)key;
    while (length > 12) {
      a += k[0];
      a += ((uint32_t)k[1]) << 8;
      a += ((uint32_t)k[2]) << 16;
      a += ((uint32_t)k[3]) << 24;
      b += k[4];
      b += ((uint32_t)k[5]) << 8;
      b += ((uint32_t)k[6]) << 16;
      b += ((uint32_t)k[7]) << 24;
      c += k[8];
      c += ((uint32_t)k[9]) << 8;
      c += ((uint32_t)k[10]) << 16;
      c += ((uint32_t)k[11]) << 24;
      {
        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 -= 12;
      k += 12;
    }
    switch (length) {
    case 12:
      c += ((uint32_t)k[11]) << 24;
    case 11:
      c += ((uint32_t)k[10]) << 16;
    case 10:
      c += ((uint32_t)k[9]) << 8;
    case 9:
      c += k[8];
    case 8:
      b += ((uint32_t)k[7]) << 24;
    case 7:
      b += ((uint32_t)k[6]) << 16;
    case 6:
      b += ((uint32_t)k[5]) << 8;
    case 5:
      b += k[4];
    case 4:
      a += ((uint32_t)k[3]) << 24;
    case 3:
      a += ((uint32_t)k[2]) << 16;
    case 2:
      a += ((uint32_t)k[1]) << 8;
    case 1:
      a += k[0];
      break;
    case 0:
      *pc = c;
      *pb = b;
      return;
    }
  }
  {
    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))));
  };
  *pc = c;
  *pb = b;
}
```