user: Converte this assembly snippet into its equivalent C code:

```asm
<__memcpy>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x8,%rsp
  mov    %rdi,%r13
  mov    %rsi,%rbp
  lea    (%rdi,%rdx,1),%r14
  mov    %rdi,%rax
  xor    %rsi,%rax
  test   $0x7,%al
  setne  %dil
  cmp    $0x7,%rdx
  setbe  %al
  or     %eax,%edi
  movzbl %dil,%edi
  mov    $0x0,%esi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  jne    L88
  mov    %r13,%r12
  and    $0x7,%r12d
  setne  %dil
  movzbl %dil,%edi
  mov    $0x0,%esi
  call   <__builtin_expect@plt>
  mov    %r13,%rbx
  test   %rax,%rax
  je     L42
  test   %r12,%r12
  je     L42
L133:
  movzbl 0x0(%rbp),%eax
  add    $0x1,%rbx
  add    $0x1,%rbp
  mov    %al,-0x1(%rbx)
  test   $0x7,%bl
  jne    L133
L42:
  mov    %r14,%r12
  and    $0xfffffffffffffff8,%r12
  lea    -0x40(%r12),%r15
  cmp    %rbx,%r15
  seta   %dil
  movzbl %dil,%edi
  mov    $0x0,%esi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L72
  cmp    %rbx,%r15
  jbe    L72
L45:
  mov    0x0(%rbp),%r11
  mov    0x8(%rbp),%r10
  mov    0x10(%rbp),%r9
  mov    0x18(%rbp),%r8
  mov    0x20(%rbp),%rdi
  mov    0x28(%rbp),%rsi
  mov    0x30(%rbp),%rcx
  mov    0x38(%rbp),%rdx
  add    $0x48,%rbp
  mov    -0x8(%rbp),%rax
  mov    %r11,(%rbx)
  mov    %r10,0x8(%rbx)
  mov    %r9,0x10(%rbx)
  mov    %r8,0x18(%rbx)
  mov    %rdi,0x20(%rbx)
  mov    %rsi,0x28(%rbx)
  mov    %rcx,0x30(%rbx)
  mov    %rdx,0x38(%rbx)
  add    $0x48,%rbx
  mov    %rax,-0x8(%rbx)
  cmp    %rbx,%r15
  ja     L45
L72:
  mov    %rbp,%rdx
  mov    %rbx,%rax
  cmp    %rbx,%r12
  jbe    L63
L100:
  mov    (%rdx),%rcx
  add    $0x8,%rax
  add    $0x8,%rdx
  mov    %rcx,-0x8(%rax)
  cmp    %rax,%r12
  ja     L100
  sub    $0x1,%r12
  sub    %rbx,%r12
  shr    $0x3,%r12
  lea    0x8(,%r12,8),%rax
  add    %rax,%rbx
  add    %rax,%rbp
L63:
  cmp    %rbx,%r14
  seta   %dil
  movzbl %dil,%edi
  mov    $0x0,%esi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  jne    L24
L52:
  mov    %r13,%rax
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L88:
  mov    %r13,%rbx
L24:
  cmp    %r14,%rbx
  setb   %dil
  movzbl %dil,%edi
  mov    $0x1,%esi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L52
  cmp    %r14,%rbx
  jae    L52
  sub    %rbx,%r14
  mov    $0x0,%eax
L111:
  movzbl 0x0(%rbp,%rax,1),%edx
  mov    %dl,(%rbx,%rax,1)
  add    $0x1,%rax
  cmp    %rax,%r14
  jne    L111
  jmp    L52
```

assistant: ```c
void *__memcpy(void *aa, const void *bb, size_t n) {
  char *a = (char *)aa;
  const char *b = (const char *)bb;
  char *end = a + n;
  uintptr_t msk = sizeof(long) - 1;
  if (__builtin_expect(((uintptr_t)a & msk) != ((uintptr_t)b & msk) || n < sizeof(long), 0)) {
  small:
    if (__builtin_expect(a < end, 1))
      while (a < end) {
        char tt = *b;
        a++, b++;
        *(a - 1) = tt;
      };
    return aa;
  }
  if (__builtin_expect(((uintptr_t)a & msk) != 0, 0))
    while ((uintptr_t)a & msk) {
      char tt = *b;
      a++, b++;
      *(a - 1) = tt;
    };
  long *la = (long *)a;
  const long *lb = (const long *)b;
  long *lend = (long *)((uintptr_t)end & ~msk);
  if (__builtin_expect(la < lend - 8, 0)) {
    while (la < lend - 8) {
      long b0 = *lb++;
      long b1 = *lb++;
      long b2 = *lb++;
      long b3 = *lb++;
      long b4 = *lb++;
      long b5 = *lb++;
      long b6 = *lb++;
      long b7 = *lb++;
      long b8 = *lb++;
      *la++ = b0;
      *la++ = b1;
      *la++ = b2;
      *la++ = b3;
      *la++ = b4;
      *la++ = b5;
      *la++ = b6;
      *la++ = b7;
      *la++ = b8;
    }
  }
  while (la < lend) {
    long tt = *lb;
    la++, lb++;
    *(la - 1) = tt;
  };
  a = (char *)la;
  b = (const char *)lb;
  if (__builtin_expect(a < end, 0))
    goto small;
  return aa;
}
```