user: 请从给定的汇编指令推导出C源代码：

```asm
<siphash>:
  endbr64
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdi,%r10
  mov    %rsi,%r8
  mov    %edx,%r11d
  mov    0x8(%rcx),%r13d
  shl    $0x8,%r13d
  mov    0x10(%rcx),%eax
  shl    $0x10,%eax
  or     %eax,%r13d
  or     (%rcx),%r13d
  mov    0x18(%rcx),%eax
  shl    $0x18,%eax
  or     %eax,%r13d
  mov    0x48(%rcx),%eax
  shl    $0x8,%eax
  mov    0x50(%rcx),%edx
  shl    $0x10,%edx
  or     %edx,%eax
  or     0x40(%rcx),%eax
  mov    0x58(%rcx),%rdx
  shl    $0x18,%edx
  or     %edx,%eax
  movslq %r11d,%rdx
  and    $0xfffffffffffffffc,%rdx
  lea    (%rsi,%rdx,8),%rbx
  mov    %r11d,%ebp
  and    $0x7,%ebp
  mov    %eax,%edx
  xor    $0x79746573,%edx
  mov    %r13d,%ecx
  xor    $0x6e657261,%ecx
  mov    %ecx,%r14d
  xor    $0x6e646f6d,%eax
  xor    $0x70736575,%r13d
  cmp    %rbx,%rsi
  jne    L112
L99:
  cmp    $0x3,%ebp
  je     L91
  and    $0x4,%r11d
  jne    L8
  cmp    $0x1,%ebp
  je     L77
  cmp    $0x2,%ebp
  jne    L13
L102:
  mov    0x8(%rbx),%esi
  shl    $0x8,%esi
  or     %esi,%r11d
L77:
  or     (%rbx),%r11d
L13:
  xor    %r11d,%edx
  mov    $0x2,%esi
L105:
  add    %eax,%r13d
  mov    %eax,%edi
  shl    $0xd,%edi
  mov    $0x33,%ecx
  sar    %cl,%eax
  or     %eax,%edi
  xor    %r13d,%edi
  mov    $0x20,%ecx
  sar    %cl,%r13d
  lea    (%r14,%rdx,1),%ebx
  mov    %edx,%eax
  shl    $0x10,%eax
  mov    $0x30,%ecx
  sar    %cl,%edx
  or     %edx,%eax
  xor    %ebx,%eax
  add    %eax,%r13d
  mov    %eax,%edx
  shl    $0x15,%edx
  mov    $0x2b,%ecx
  sar    %cl,%eax
  or     %eax,%edx
  xor    %r13d,%edx
  add    %edi,%ebx
  mov    %edi,%eax
  shl    $0x11,%eax
  mov    $0x2f,%ecx
  sar    %cl,%edi
  or     %edi,%eax
  xor    %ebx,%eax
  mov    $0x20,%ecx
  sar    %cl,%ebx
  mov    %ebx,%r14d
  sub    $0x1,%esi
  jne    L105
  xor    %r13d,%r11d
  xor    $0xff,%bl
  mov    $0x4,%edi
L93:
  add    %eax,%r11d
  mov    %eax,%esi
  shl    $0xd,%esi
  mov    $0x33,%ecx
  sar    %cl,%eax
  or     %eax,%esi
  xor    %r11d,%esi
  mov    %esi,%r8d
  mov    $0x20,%ecx
  sar    %cl,%r11d
  lea    (%rbx,%rdx,1),%eax
  mov    %edx,%esi
  shl    $0x10,%esi
  mov    $0x30,%ecx
  sar    %cl,%edx
  or     %esi,%edx
  xor    %eax,%edx
  add    %edx,%r11d
  mov    %edx,%r9d
  shl    $0x15,%r9d
  mov    $0x2b,%ecx
  sar    %cl,%edx
  or     %edx,%r9d
  mov    %r11d,%edx
  xor    %r9d,%edx
  lea    (%rax,%r8,1),%ebx
  mov    %r8d,%eax
  shl    $0x11,%eax
  mov    %r8d,%esi
  mov    $0x2f,%ecx
  sar    %cl,%esi
  or     %esi,%eax
  xor    %ebx,%eax
  mov    $0x20,%ecx
  sar    %cl,%ebx
  sub    $0x1,%edi
  jne    L93
  xor    %r9d,%ebx
  xor    %eax,%ebx
  movslq %ebx,%rax
  mov    %rax,(%r10)
  mov    %ebx,%eax
  sar    $0x8,%eax
  cltq
  mov    %rax,0x8(%r10)
  mov    %ebx,%eax
  sar    $0x10,%eax
  cltq
  mov    %rax,0x10(%r10)
  mov    %ebx,%eax
  sar    $0x18,%eax
  cltq
  mov    %rax,0x18(%r10)
  mov    $0x20,%ecx
  sar    %cl,%ebx
  mov    %ebx,%ecx
  movslq %ebx,%rax
  mov    %rax,0x20(%r10)
  mov    %ebx,%eax
  sar    $0x8,%eax
  cltq
  mov    %rax,0x28(%r10)
  mov    %ebx,%eax
  sar    $0x10,%eax
  cltq
  mov    %rax,0x30(%r10)
  sar    $0x18,%ecx
  movslq %ecx,%rcx
  mov    %rcx,0x38(%r10)
  mov    $0x0,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  ret
L33:
  xor    %edi,%r13d
  add    $0x40,%r8
  cmp    %r8,%rbx
  je     L99
L112:
  mov    0x8(%r8),%edi
  shl    $0x8,%edi
  mov    0x10(%r8),%esi
  shl    $0x10,%esi
  or     %esi,%edi
  or     (%r8),%edi
  mov    0x18(%r8),%esi
  shl    $0x18,%esi
  or     %esi,%edi
  xor    %edi,%edx
  mov    $0x2,%r9d
L2:
  add    %eax,%r13d
  mov    %eax,%r12d
  shl    $0xd,%r12d
  mov    $0x33,%ecx
  sar    %cl,%eax
  or     %eax,%r12d
  xor    %r13d,%r12d
  mov    $0x20,%ecx
  sar    %cl,%r13d
  lea    (%r14,%rdx,1),%esi
  mov    %edx,%eax
  shl    $0x10,%eax
  mov    $0x30,%ecx
  sar    %cl,%edx
  or     %edx,%eax
  xor    %esi,%eax
  add    %eax,%r13d
  mov    %eax,%edx
  shl    $0x15,%edx
  mov    $0x2b,%ecx
  sar    %cl,%eax
  or     %eax,%edx
  xor    %r13d,%edx
  add    %r12d,%esi
  mov    %r12d,%eax
  shl    $0x11,%eax
  mov    $0x2f,%ecx
  sar    %cl,%r12d
  or     %r12d,%eax
  xor    %esi,%eax
  mov    $0x20,%ecx
  sar    %cl,%esi
  mov    %esi,%r14d
  sub    $0x1,%r9d
  jne    L2
  jmp    L33
L8:
  mov    0x18(%rbx),%esi
  shl    $0x18,%esi
L30:
  mov    0x10(%rbx),%r11d
  shl    $0x10,%r11d
  or     %esi,%r11d
  jmp    L102
L91:
  mov    $0x0,%esi
  jmp    L30
```

assistant: ```c
int siphash(uint8_t *out, const uint8_t *in, uint64_t inlen, const uint8_t *k) {
  uint64_t v0 = 0x736f6d6570736575ULL;
  uint64_t v1 = 0x646f72616e646f6dULL;
  uint64_t v2 = 0x6c7967656e657261ULL;
  uint64_t v3 = 0x7465646279746573ULL;
  uint64_t b;
  uint64_t k0 = (((uint64_t)((k)[0])) | ((uint64_t)((k)[1]) << 8) | ((uint64_t)((k)[2]) << 16) | ((uint64_t)((k)[3]) << 24) | ((uint64_t)((k)[4]) << 32) | ((uint64_t)((k)[5]) << 40) | ((uint64_t)((k)[6]) << 48) | ((uint64_t)((k)[7]) << 56));
  uint64_t k1 = (((uint64_t)((k + 8)[0])) | ((uint64_t)((k + 8)[1]) << 8) | ((uint64_t)((k + 8)[2]) << 16) | ((uint64_t)((k + 8)[3]) << 24) | ((uint64_t)((k + 8)[4]) << 32) | ((uint64_t)((k + 8)[5]) << 40) | ((uint64_t)((k + 8)[6]) << 48) | ((uint64_t)((k + 8)[7]) << 56));
  uint64_t m;
  int i;
  const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
  const int left = inlen & 7;
  b = ((uint64_t)inlen) << 56;
  v3 ^= k1;
  v2 ^= k0;
  v1 ^= k1;
  v0 ^= k0;
  for (; in != end; in += 8) {
    m = (((uint64_t)((in)[0])) | ((uint64_t)((in)[1]) << 8) | ((uint64_t)((in)[2]) << 16) | ((uint64_t)((in)[3]) << 24) | ((uint64_t)((in)[4]) << 32) | ((uint64_t)((in)[5]) << 40) | ((uint64_t)((in)[6]) << 48) | ((uint64_t)((in)[7]) << 56));
    v3 ^= m;
    ;
    for (i = 0; i < 2; ++i)
      do {
        v0 += v1;
        v1 = (uint64_t)(((v1) << (13)) | ((v1) >> (64 - (13))));
        v1 ^= v0;
        v0 = (uint64_t)(((v0) << (32)) | ((v0) >> (64 - (32))));
        v2 += v3;
        v3 = (uint64_t)(((v3) << (16)) | ((v3) >> (64 - (16))));
        v3 ^= v2;
        v0 += v3;
        v3 = (uint64_t)(((v3) << (21)) | ((v3) >> (64 - (21))));
        v3 ^= v0;
        v2 += v1;
        v1 = (uint64_t)(((v1) << (17)) | ((v1) >> (64 - (17))));
        v1 ^= v2;
        v2 = (uint64_t)(((v2) << (32)) | ((v2) >> (64 - (32))));
      } while (0);
    v0 ^= m;
  }
  switch (left) {
  case 7:
    b |= ((uint64_t)in[6]) << 48;
  case 6:
    b |= ((uint64_t)in[5]) << 40;
  case 5:
    b |= ((uint64_t)in[4]) << 32;
  case 4:
    b |= ((uint64_t)in[3]) << 24;
  case 3:
    b |= ((uint64_t)in[2]) << 16;
  case 2:
    b |= ((uint64_t)in[1]) << 8;
  case 1:
    b |= ((uint64_t)in[0]);
    break;
  case 0:
    break;
  }
  v3 ^= b;
  ;
  for (i = 0; i < 2; ++i)
    do {
      v0 += v1;
      v1 = (uint64_t)(((v1) << (13)) | ((v1) >> (64 - (13))));
      v1 ^= v0;
      v0 = (uint64_t)(((v0) << (32)) | ((v0) >> (64 - (32))));
      v2 += v3;
      v3 = (uint64_t)(((v3) << (16)) | ((v3) >> (64 - (16))));
      v3 ^= v2;
      v0 += v3;
      v3 = (uint64_t)(((v3) << (21)) | ((v3) >> (64 - (21))));
      v3 ^= v0;
      v2 += v1;
      v1 = (uint64_t)(((v1) << (17)) | ((v1) >> (64 - (17))));
      v1 ^= v2;
      v2 = (uint64_t)(((v2) << (32)) | ((v2) >> (64 - (32))));
    } while (0);
  v0 ^= b;
  v2 ^= 0xff;
  ;
  for (i = 0; i < 4; ++i)
    do {
      v0 += v1;
      v1 = (uint64_t)(((v1) << (13)) | ((v1) >> (64 - (13))));
      v1 ^= v0;
      v0 = (uint64_t)(((v0) << (32)) | ((v0) >> (64 - (32))));
      v2 += v3;
      v3 = (uint64_t)(((v3) << (16)) | ((v3) >> (64 - (16))));
      v3 ^= v2;
      v0 += v3;
      v3 = (uint64_t)(((v3) << (21)) | ((v3) >> (64 - (21))));
      v3 ^= v0;
      v2 += v1;
      v1 = (uint64_t)(((v1) << (17)) | ((v1) >> (64 - (17))));
      v1 ^= v2;
      v2 = (uint64_t)(((v2) << (32)) | ((v2) >> (64 - (32))));
    } while (0);
  b = v0 ^ v1 ^ v2 ^ v3;
  ((out))[0] = (uint8_t)(((uint32_t)((b))));
  ((out))[1] = (uint8_t)(((uint32_t)((b))) >> 8);
  ((out))[2] = (uint8_t)(((uint32_t)((b))) >> 16);
  ((out))[3] = (uint8_t)(((uint32_t)((b))) >> 24);
  ;
  ((out) + 4)[0] = (uint8_t)(((uint32_t)((b) >> 32)));
  ((out) + 4)[1] = (uint8_t)(((uint32_t)((b) >> 32)) >> 8);
  ((out) + 4)[2] = (uint8_t)(((uint32_t)((b) >> 32)) >> 16);
  ((out) + 4)[3] = (uint8_t)(((uint32_t)((b) >> 32)) >> 24);
  ;
  ;
  return 0;
}
```