user: Please show me the C implementation that matches the assembly code listed below:

```asm
<utf32_to_utf8>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    %esi,-0x1c(%rbp)
  movl   $0x0,-0x4(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0xffffff80,%eax
  test   %eax,%eax
  jne    L69
  mov    -0x1c(%rbp),%eax
  and    $0x7f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %edx,(%rax)
  movl   $0x1,-0x4(%rbp)
  jmp    L94
L69:
  mov    -0x1c(%rbp),%eax
  and    $0xfffff800,%eax
  test   %eax,%eax
  jne    L22
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x4,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  movzbl %al,%eax
  or     $0xc0,%al
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %edx,(%rax)
  movl   $0x2,-0x4(%rbp)
  jmp    L94
L22:
  mov    -0x1c(%rbp),%eax
  mov    $0x0,%ax
  test   %eax,%eax
  jne    L97
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x8,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x4,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  movzbl %al,%eax
  or     $0xe0,%al
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %edx,(%rax)
  movl   $0x3,-0x4(%rbp)
  jmp    L94
L97:
  mov    -0x1c(%rbp),%eax
  and    $0xffe00000,%eax
  test   %eax,%eax
  jne    L0
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0xc,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x8,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x4,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  movzbl %al,%eax
  or     $0xf0,%al
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %edx,(%rax)
  movl   $0x4,-0x4(%rbp)
  jmp    L94
L0:
  mov    -0x1c(%rbp),%eax
  and    $0xfc000000,%eax
  test   %eax,%eax
  jne    L34
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x10,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0xc,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x8,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x4,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  movzbl %al,%eax
  or     $0xf8,%al
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %edx,(%rax)
  movl   $0x5,-0x4(%rbp)
  jmp    L94
L34:
  cmpl   $0x0,-0x1c(%rbp)
  js     L94
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x14,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x10,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0xc,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x8,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x3f,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  add    $0x4,%rax
  or     $0x80,%dl
  mov    %edx,(%rax)
  sarl   $0x6,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  movzbl %al,%eax
  or     $0xfc,%al
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %edx,(%rax)
  movl   $0x6,-0x4(%rbp)
L94:
  mov    -0x4(%rbp),%eax
  pop    %rbp
  ret
```

assistant: ```c
uint32_t utf32_to_utf8(uint8_t utf8[6], uint32_t utf32) {
  uint32_t utf8_len = 0;
  if ((utf32 & (~0x0000007F)) == 0) {
    utf8[0] = 0x0000007F & utf32;
    utf8_len = 1;
  } else if ((utf32 & (~0x000007FF)) == 0) {
    utf8[1] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[0] = (0x0000003F & utf32) | 0xC0;
    utf8_len = 2;
  } else if ((utf32 & (~0x0000FFFF)) == 0) {
    utf8[2] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[1] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[0] = (0x0000003F & utf32) | 0xE0;
    utf8_len = 3;
  } else if ((utf32 & (~0x001FFFFF)) == 0) {
    utf8[3] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[2] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[1] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[0] = (0x0000003F & utf32) | 0xF0;
    utf8_len = 4;
  } else if ((utf32 & (~0x03FFFFFF)) == 0) {
    utf8[4] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[3] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[2] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[1] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[0] = (0x0000003F & utf32) | 0xF8;
    utf8_len = 5;
  } else if ((utf32 & (~0x7FFFFFFF)) == 0) {
    utf8[5] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[4] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[3] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[2] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[1] = (0x0000003F & utf32) | 0x80;
    utf32 >>= 6;
    utf8[0] = (0x0000003F & utf32) | 0xFC;
    utf8_len = 6;
  }
  return utf8_len;
}
```