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

```asm
<__memcpy>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0xb0,%rsp
  mov    %rdi,-0x98(%rbp)
  mov    %rsi,-0xa0(%rbp)
  mov    %rdx,-0xa8(%rbp)
  mov    -0x98(%rbp),%rax
  mov    %rax,-0x88(%rbp)
  mov    -0xa0(%rbp),%rax
  mov    %rax,-0x80(%rbp)
  mov    -0x88(%rbp),%rdx
  mov    -0xa8(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x68(%rbp)
  movq   $0x7,-0x60(%rbp)
  mov    -0x88(%rbp),%rdx
  mov    -0x80(%rbp),%rax
  xor    %rdx,%rax
  and    -0x60(%rbp),%rax
  test   %rax,%rax
  jne    L54
  cmpq   $0x7,-0xa8(%rbp)
  ja     L143
L54:
  mov    $0x1,%eax
  jmp    L121
L143:
  mov    $0x0,%eax
L121:
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L31
  nop
  jmp    L12
L119:
  nop
L12:
  mov    -0x88(%rbp),%rax
  cmp    -0x68(%rbp),%rax
  setb   %al
  movzbl %al,%eax
  mov    $0x1,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L144
  jmp    L83
L32:
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x89(%rbp)
  addq   $0x1,-0x88(%rbp)
  addq   $0x1,-0x80(%rbp)
  mov    -0x88(%rbp),%rax
  lea    -0x1(%rax),%rdx
  movzbl -0x89(%rbp),%eax
  mov    %al,(%rdx)
L83:
  mov    -0x88(%rbp),%rax
  cmp    -0x68(%rbp),%rax
  jb     L32
L144:
  mov    -0x98(%rbp),%rax
  jmp    L21
L31:
  mov    -0x88(%rbp),%rax
  and    -0x60(%rbp),%rax
  test   %rax,%rax
  setne  %al
  movzbl %al,%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L52
  jmp    L141
L174:
  mov    -0x80(%rbp),%rax
  movzbl (%rax),%eax
  mov    %al,-0x8a(%rbp)
  addq   $0x1,-0x88(%rbp)
  addq   $0x1,-0x80(%rbp)
  mov    -0x88(%rbp),%rax
  lea    -0x1(%rax),%rdx
  movzbl -0x8a(%rbp),%eax
  mov    %al,(%rdx)
L141:
  mov    -0x88(%rbp),%rax
  and    -0x60(%rbp),%rax
  test   %rax,%rax
  jne    L174
L52:
  mov    -0x88(%rbp),%rax
  mov    %rax,-0x78(%rbp)
  mov    -0x80(%rbp),%rax
  mov    %rax,-0x70(%rbp)
  mov    -0x60(%rbp),%rax
  not    %rax
  mov    %rax,%rdx
  mov    -0x68(%rbp),%rax
  and    %rdx,%rax
  mov    %rax,-0x58(%rbp)
  mov    -0x58(%rbp),%rax
  sub    $0x40,%rax
  cmp    %rax,-0x78(%rbp)
  setb   %al
  movzbl %al,%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  je     L80
  jmp    L51
L115:
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x50(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x48(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x40(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x38(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x30(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x28(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x20(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x70(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x70(%rbp)
  mov    (%rax),%rax
  mov    %rax,-0x10(%rbp)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x50(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x48(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x40(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x38(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x30(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x28(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x20(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x18(%rbp),%rdx
  mov    %rdx,(%rax)
  mov    -0x78(%rbp),%rax
  lea    0x8(%rax),%rdx
  mov    %rdx,-0x78(%rbp)
  mov    -0x10(%rbp),%rdx
  mov    %rdx,(%rax)
L51:
  mov    -0x58(%rbp),%rax
  sub    $0x40,%rax
  cmp    %rax,-0x78(%rbp)
  jb     L115
  jmp    L80
L137:
  mov    -0x70(%rbp),%rax
  mov    (%rax),%rax
  mov    %rax,-0x8(%rbp)
  addq   $0x8,-0x78(%rbp)
  addq   $0x8,-0x70(%rbp)
  mov    -0x78(%rbp),%rax
  lea    -0x8(%rax),%rdx
  mov    -0x8(%rbp),%rax
  mov    %rax,(%rdx)
L80:
  mov    -0x78(%rbp),%rax
  cmp    -0x58(%rbp),%rax
  jb     L137
  mov    -0x78(%rbp),%rax
  mov    %rax,-0x88(%rbp)
  mov    -0x70(%rbp),%rax
  mov    %rax,-0x80(%rbp)
  mov    -0x88(%rbp),%rax
  cmp    -0x68(%rbp),%rax
  setb   %al
  movzbl %al,%eax
  mov    $0x0,%esi
  mov    %eax,%edi
  call   <__builtin_expect@plt>
  test   %rax,%rax
  jne    L119
  mov    -0x98(%rbp),%rax
L21:
  leave
  ret
```

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;
}
```