user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<coalesce>:
  endbr64
  push   %rbx
  mov    %rdi,%rax
  mov    -0x8(%rdi),%edx
  and    $0xfffffff8,%edx
  mov    %rdi,%rcx
  sub    %rdx,%rcx
  lea    -0x4(%rcx),%r10
  mov    (%r10),%esi
  and    $0xfffffff8,%esi
  mov    %rdi,%rcx
  sub    %rdx,%rcx
  mov    %esi,%edx
  mov    -0x8(%rcx,%rdx,1),%edi
  mov    -0x4(%rax),%ecx
  and    $0xfffffff8,%ecx
  mov    %ecx,%r8d
  mov    -0x4(%rax,%r8,1),%edx
  and    $0x1,%edi
  setne  %r9b
  mov    %rdx,%rbx
  and    $0x1,%ebx
  setne  %r11b
  test   %r9b,%r9b
  je     L30
  test   %r11b,%r11b
  je     L30
L25:
  pop    %rbx
  ret
L30:
  test   %rbx,%rbx
  jne    L31
  test   %r9b,%r9b
  je     L31
  and    $0xfffffff8,%edx
  add    %ecx,%edx
  mov    %edx,-0x4(%rax)
  mov    %edx,%ecx
  mov    %edx,-0x8(%rax,%rcx,1)
  jmp    L25
L31:
  test   %rdi,%rdi
  jne    L22
  test   %r11b,%r11b
  je     L22
  add    %esi,%ecx
  mov    %ecx,-0x8(%rax,%r8,1)
  mov    -0x8(%rax),%edx
  and    $0xfffffff8,%edx
  mov    %rax,%rsi
  sub    %rdx,%rsi
  mov    %ecx,-0x4(%rsi)
  mov    -0x8(%rax),%edx
  and    $0xfffffff8,%edx
  sub    %rdx,%rax
  jmp    L25
L22:
  and    $0xfffffff8,%edx
  add    %rax,%r8
  mov    -0x8(%rdx,%r8,1),%edx
  and    $0xfffffff8,%edx
  add    %ecx,%esi
  lea    (%rdx,%rsi,1),%ecx
  mov    %ecx,(%r10)
  mov    -0x4(%rax),%edx
  and    $0xfffffff8,%edx
  mov    -0x4(%rax,%rdx,1),%esi
  and    $0xfffffff8,%esi
  add    %rax,%rdx
  mov    %ecx,-0x8(%rsi,%rdx,1)
  mov    -0x8(%rax),%edx
  and    $0xfffffff8,%edx
  sub    %rdx,%rax
  jmp    L25
```

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