user: Translate the below assembly code into C programming language:

```asm
<coalesce>:
  endbr64
  mov    %rdi,%rax
  mov    -0x4(%rdi),%edx
  mov    %edx,%r8d
  and    $0x2,%r8d
  mov    %r8d,%edi
  mov    %edx,%ecx
  and    $0xfffffff8,%ecx
  mov    %ecx,%edx
  mov    -0x4(%rax,%rdx,1),%edx
  test   %rdi,%rdi
  setne  %sil
  mov    %rdx,%r10
  and    $0x1,%r10d
  setne  %r9b
  test   %sil,%sil
  je     L44
  test   %r9b,%r9b
  je     L44
L46:
  ret
L44:
  test   %r10,%r10
  jne    L63
  test   %sil,%sil
  je     L63
  and    $0xfffffff8,%edx
  add    %ecx,%edx
  or     %r8d,%edx
  mov    %edx,-0x4(%rax)
  mov    %edx,%ecx
  and    $0xfffffff8,%ecx
  mov    %edx,-0x8(%rax,%rcx,1)
  ret
L63:
  test   %rdi,%rdi
  jne    L45
  test   %r9b,%r9b
  je     L45
  mov    -0x8(%rax),%edx
  and    $0xfffffff8,%edx
  sub    %rdx,%rax
  mov    -0x4(%rax),%esi
  mov    %esi,%edx
  and    $0xfffffff8,%edx
  add    %ecx,%edx
  and    $0x2,%esi
  or     %esi,%edx
  mov    %edx,-0x4(%rax)
  mov    %edx,%ecx
  and    $0xfffffff8,%ecx
  mov    %edx,-0x8(%rax,%rcx,1)
  ret
L45:
  mov    -0x8(%rax),%edi
  and    $0xfffffff8,%edi
  mov    %rax,%rsi
  sub    %rdi,%rsi
  mov    -0x4(%rsi),%esi
  and    $0xfffffff8,%esi
  and    $0xfffffff8,%edx
  add    %edx,%esi
  sub    %rdi,%rax
  mov    -0x4(%rax),%edx
  and    $0x2,%edx
  add    %esi,%ecx
  or     %ecx,%edx
  mov    %edx,-0x4(%rax)
  mov    %edx,%ecx
  and    $0xfffffff8,%ecx
  mov    %edx,-0x8(%rax,%rcx,1)
  jmp    L46
```

assistant: ```c
void *coalesce(void *bp) {
  size_t prev_alloc = ((*(unsigned int *)(((char *)(bp)-4))) & 0x2);
  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);
  char *next_block;
  size_t next_size;
  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) | (prev_alloc))));
    (*(unsigned int *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7) - 8)) = (((size) | (prev_alloc))));
  } else if (!prev_alloc && next_alloc) {
    bp = ((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7));
    size += ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7);
    prev_alloc = ((*(unsigned int *)(((char *)(bp)-4))) & 0x2);
    (*(unsigned int *)(((char *)(bp)-4)) = (((size) | (prev_alloc))));
    (*(unsigned int *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7) - 8)) = (((size) | (prev_alloc))));
  } 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))) - 4))) & ~0x7);
    bp = ((char *)(bp) - ((*(unsigned int *)(((char *)(bp)-8))) & ~0x7));
    prev_alloc = ((*(unsigned int *)(((char *)(bp)-4))) & 0x2);
    (*(unsigned int *)(((char *)(bp)-4)) = (((size) | (prev_alloc))));
    (*(unsigned int *)(((char *)(bp) + ((*(unsigned int *)(((char *)(bp)-4))) & ~0x7) - 8)) = (((size) | (prev_alloc))));
  }
  return bp;
}
```