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

```asm
<utf8_wctomb>:
  endbr64
  mov    %esi,%eax
  test   %rdi,%rdi
  je     L63
  cmp    $0x7f,%esi
  jbe    L66
  cmp    $0x7ff,%esi
  jbe    L22
  cmp    $0xffff,%esi
  jbe    L35
  cmp    $0x1fffff,%esi
  jbe    L69
  cmp    $0x3ffffff,%esi
  jbe    L38
  test   %esi,%esi
  js     L16
  mov    %esi,%ecx
  shr    $0x1e,%ecx
  or     $0xfffffffc,%ecx
  mov    %cl,(%rdi)
  mov    %esi,%ecx
  shr    $0x18,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x1(%rdi)
  mov    %esi,%ecx
  shr    $0x12,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x2(%rdi)
  mov    %esi,%ecx
  shr    $0xc,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x3(%rdi)
  mov    %esi,%ecx
  shr    $0x6,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x4(%rdi)
  and    $0x3f,%eax
  or     $0xffffff80,%eax
  mov    %al,0x5(%rdi)
  mov    $0x6,%eax
  ret
L66:
  mov    %sil,(%rdi)
  mov    $0x1,%eax
  ret
L22:
  mov    %esi,%ecx
  shr    $0x6,%ecx
  or     $0xffffffc0,%ecx
  mov    %cl,(%rdi)
  and    $0x3f,%eax
  or     $0xffffff80,%eax
  mov    %al,0x1(%rdi)
  mov    $0x2,%eax
  ret
L35:
  mov    %esi,%ecx
  shr    $0xc,%ecx
  or     $0xffffffe0,%ecx
  mov    %cl,(%rdi)
  mov    %esi,%ecx
  shr    $0x6,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x1(%rdi)
  and    $0x3f,%eax
  or     $0xffffff80,%eax
  mov    %al,0x2(%rdi)
  mov    $0x3,%eax
  ret
L69:
  mov    %esi,%ecx
  shr    $0x12,%ecx
  or     $0xfffffff0,%ecx
  mov    %cl,(%rdi)
  mov    %esi,%ecx
  shr    $0xc,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x1(%rdi)
  mov    %esi,%ecx
  shr    $0x6,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x2(%rdi)
  and    $0x3f,%eax
  or     $0xffffff80,%eax
  mov    %al,0x3(%rdi)
  mov    $0x4,%eax
  ret
L38:
  mov    %esi,%ecx
  shr    $0x18,%ecx
  or     $0xfffffff8,%ecx
  mov    %cl,(%rdi)
  mov    %esi,%ecx
  shr    $0x12,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x1(%rdi)
  mov    %esi,%ecx
  shr    $0xc,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x2(%rdi)
  mov    %esi,%ecx
  shr    $0x6,%ecx
  and    $0x3f,%ecx
  or     $0xffffff80,%ecx
  mov    %cl,0x3(%rdi)
  and    $0x3f,%eax
  or     $0xffffff80,%eax
  mov    %al,0x4(%rdi)
  mov    $0x5,%eax
  ret
L63:
  mov    $0x0,%eax
  ret
L16:
  mov    $0xffffffff,%eax
  ret
```

assistant: ```c
int utf8_wctomb(char *s, int wc1) {
  unsigned int wc = wc1;
  if (!s)
    return 0;
  if (wc < (1 << 7)) {
    *s++ = wc;
    return 1;
  } else if (wc < (1 << 11)) {
    *s++ = 0xc0 | (wc >> 6);
    *s++ = 0x80 | (wc & 0x3f);
    return 2;
  } else if (wc < (1 << 16)) {
    *s++ = 0xe0 | (wc >> 12);
    *s++ = 0x80 | ((wc >> 6) & 0x3f);
    *s++ = 0x80 | (wc & 0x3f);
    return 3;
  } else if (wc < (1 << 21)) {
    *s++ = 0xf0 | (wc >> 18);
    *s++ = 0x80 | ((wc >> 12) & 0x3f);
    *s++ = 0x80 | ((wc >> 6) & 0x3f);
    *s++ = 0x80 | (wc & 0x3f);
    return 4;
  } else if (wc < (1 << 26)) {
    *s++ = 0xf8 | (wc >> 24);
    *s++ = 0x80 | ((wc >> 18) & 0x3f);
    *s++ = 0x80 | ((wc >> 12) & 0x3f);
    *s++ = 0x80 | ((wc >> 6) & 0x3f);
    *s++ = 0x80 | (wc & 0x3f);
    return 5;
  } else if (wc < (1 << 31)) {
    *s++ = 0xfc | (wc >> 30);
    *s++ = 0x80 | ((wc >> 24) & 0x3f);
    *s++ = 0x80 | ((wc >> 18) & 0x3f);
    *s++ = 0x80 | ((wc >> 12) & 0x3f);
    *s++ = 0x80 | ((wc >> 6) & 0x3f);
    *s++ = 0x80 | (wc & 0x3f);
    return 6;
  } else
    return -1;
}
```