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

```asm
<coalesce>:
  endbr64
  mov    -0x8(%rdi),%edx
  mov    $0xfffffffffffffffc,%r10
  mov    %rdi,%rcx
  mov    %rdi,%rax
  mov    %r10,%r8
  and    $0xfffffff8,%edx
  sub    %rdx,%r8
  sub    %rdx,%rcx
  add    %rdi,%r8
  mov    (%r8),%esi
  and    $0xfffffff8,%esi
  mov    %esi,%edx
  mov    -0x8(%rcx,%rdx,1),%edi
  mov    -0x4(%rax),%ecx
  and    $0xfffffff8,%ecx
  mov    %edi,%r9d
  mov    %ecx,%r11d
  mov    -0x4(%rax,%r11,1),%edx
  and    %edx,%r9d
  and    $0x1,%r9d
  jne    L21
  mov    %edx,%r9d
  not    %r9d
  and    %edi,%r9d
  and    $0x1,%r9d
  je     L13
  and    $0xfffffff8,%edx
  add    %edx,%ecx
  mov    %ecx,-0x4(%rax)
  mov    %ecx,-0x8(%rax,%rcx,1)
  ret
  nopl   (%rax)
L13:
  not    %edi
  add    %ecx,%esi
  lea    -0x8(%r11),%r9
  and    %edx,%edi
  and    $0x1,%edi
  jne    L4
  and    $0xfffffff8,%edx
  add    %rax,%r9
  mov    (%r9,%rdx,1),%ecx
  and    $0xfffffff8,%ecx
  add    %esi,%ecx
  mov    %ecx,(%r8)
  mov    -0x4(%rax),%edx
  and    $0xfffffff8,%edx
  mov    -0x4(%rax,%rdx,1),%esi
  add    %rax,%rdx
  and    $0xfffffff8,%esi
  mov    %ecx,-0x8(%rsi,%rdx,1)
  mov    -0x8(%rax),%edx
  and    $0xfffffff8,%edx
  sub    %rdx,%rax
L21:
  ret
  nopw   0x0(%rax,%rax,1)
L4:
  mov    %esi,-0x8(%rax,%r11,1)
  mov    -0x8(%rax),%edx
  and    $0xfffffff8,%edx
  sub    %rdx,%r10
  mov    %esi,(%rax,%r10,1)
  mov    -0x8(%rax),%edx
  and    $0xfffffff8,%edx
  sub    %rdx,%rax
  ret
```

assistant: ```c
void *coalesce(void *bp) {
  size_t prev_alloc = ((*(unsigned int *)(((char *)(((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7))) + ((*(unsigned int *)(((char *)(((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7))) - 4))) & ~0x7) - 8))) & 0x1);
  size_t next_alloc = ((*(unsigned int *)(((char *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7))) - 4))) & 0x1);
  size_t size = ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7);
  if (prev_alloc && next_alloc)
    return bp;
  else if (prev_alloc && !next_alloc) {
    size += ((*(unsigned int *)(((char *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7))) - 4))) & ~0x7);
    (*(unsigned int *)(((char *)(bp)-4)) = (((size) | (0))));
    (*(unsigned int *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7) - 8)) = (((size) | (0))));
  } else if (!prev_alloc && next_alloc) {
    size += ((*(unsigned int *)(((char *)(((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7))) - 4))) & ~0x7);
    (*(unsigned int *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7) - 8)) = (((size) | (0))));
    (*(unsigned int *)(((char *)(((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7))) - 4)) = (((size) | (0))));
    bp = ((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7));
  } else {
    size += ((*(unsigned int *)(((char *)(((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7))) - 4))) & ~0x7) + ((*(unsigned int *)(((char *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7))) + ((*(unsigned int *)(((char *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7))) - 4))) & ~0x7) - 8))) & ~0x7);
    (*(unsigned int *)(((char *)(((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7))) - 4)) = (((size) | (0))));
    (*(unsigned int *)(((char *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7))) + ((*(unsigned int *)(((char *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7))) - 4))) & ~0x7) - 8)) = (((size) | (0))));
    bp = ((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7));
  }
  return bp;
}
```