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

```asm
<utf8_to_wchar>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %rsi,-0x30(%rbp)
  movl   $0x0,-0x14(%rbp)
  movl   $0x0,-0x10(%rbp)
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  call   <strlen@plt>
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  add    $0x1,%eax
  mov    $0x1,%esi
  mov    %eax,%edi
  call   <xcalloc@plt>
  mov    %rax,-0x8(%rbp)
  jmp    L12
L29:
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  test   %al,%al
  js     L89
  mov    -0x14(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x14(%rbp)
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  lea    (%rdx,%rax,1),%rcx
  mov    -0x10(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x10(%rbp)
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rax,%rdx
  movzbl (%rcx),%eax
  mov    %al,(%rdx)
  jmp    L12
L89:
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0xdf,%al
  ja     L107
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xffffffc0,%eax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x1(%rax),%rcx
  mov    -0x28(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  and    $0x3f,%eax
  mov    %edx,%ecx
  or     %eax,%ecx
  mov    -0x10(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x10(%rbp)
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  addl   $0x2,-0x14(%rbp)
  jmp    L12
L107:
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0xef,%al
  ja     L9
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0xc,%eax
  mov    %eax,%ecx
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x1(%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xffffffc0,%eax
  or     %eax,%ecx
  mov    %ecx,%edx
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x2(%rax),%rcx
  mov    -0x28(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  and    $0x3f,%eax
  mov    %edx,%ecx
  or     %eax,%ecx
  mov    -0x10(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x10(%rbp)
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  addl   $0x3,-0x14(%rbp)
  jmp    L12
L9:
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0xf7,%al
  ja     L95
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x2(%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xffffffc0,%eax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x2(%rax),%rcx
  mov    -0x28(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  and    $0x3f,%eax
  mov    %edx,%ecx
  or     %eax,%ecx
  mov    -0x10(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x10(%rbp)
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  addl   $0x4,-0x14(%rbp)
  jmp    L12
L95:
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0xfb,%al
  ja     L33
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x3(%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xffffffc0,%eax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x4(%rax),%rcx
  mov    -0x28(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  and    $0x3f,%eax
  mov    %edx,%ecx
  or     %eax,%ecx
  mov    -0x10(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x10(%rbp)
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  addl   $0x5,-0x14(%rbp)
  jmp    L12
L33:
  mov    -0x14(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  cmp    $0xfb,%al
  jbe    L12
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x4(%rax),%rdx
  mov    -0x28(%rbp),%rax
  add    %rdx,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xffffffc0,%eax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  cltq
  lea    0x5(%rax),%rcx
  mov    -0x28(%rbp),%rax
  add    %rcx,%rax
  movzbl (%rax),%eax
  and    $0x3f,%eax
  mov    %edx,%ecx
  or     %eax,%ecx
  mov    -0x10(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    %edx,-0x10(%rbp)
  movslq %eax,%rdx
  mov    -0x8(%rbp),%rax
  add    %rdx,%rax
  mov    %ecx,%edx
  mov    %dl,(%rax)
  addl   $0x6,-0x14(%rbp)
L12:
  mov    -0x14(%rbp),%eax
  cmp    -0xc(%rbp),%eax
  jl     L29
  mov    -0x10(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    -0x8(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <xrealloc@plt>
  mov    %rax,-0x8(%rbp)
  mov    -0x10(%rbp),%eax
  movslq %eax,%rdx
  mov    -0x30(%rbp),%rax
  mov    %rdx,(%rax)
  mov    -0x8(%rbp),%rax
  leave
  ret
```

assistant: ```c
wchar_t *utf8_to_wchar(const unsigned char *utf, size_t *memsize) {
  int i = 0;
  int j = 0;
  int len = strlen((char *)utf);
  wchar_t *mem = xcalloc(len + 1, sizeof(wchar_t));
  while (i < len) {
    if (utf[i] < 0x80)
      mem[j++] = utf[i++];
    else if (utf[i] < 0xE0) {
      mem[j++] = ((utf[i] & 0x1F) << 6) | (utf[i + 1] & 0x3F);
      i += 2;
    } else if (utf[i] < 0xF0) {
      mem[j++] = ((utf[i] & 0x0F) << 12) | ((utf[i + 1] & 0x3F) << 6) | (utf[i + 2] & 0x3F);
      i += 3;
    } else if (utf[i] < 0xF8) {
      mem[j++] = ((utf[i] & 0x07) << 18) | ((utf[i + 1] & 0x3F) << 12) | ((utf[i + 2] & 0x3F) << 6) | (utf[i + 2] & 0x3F);
      i += 4;
    } else if (utf[i] < 0xFC) {
      mem[j++] = ((utf[i] & 0x03) << 24) | ((utf[i + 1] & 0x3F) << 18) | ((utf[i + 2] & 0x3F) << 12) | ((utf[i + 3] & 0x3F) << 6) | (utf[i + 4] & 0x3F);
      i += 5;
    } else if (utf[i] >= 0xFC) {
      mem[j++] = ((utf[i] & 0x01) << 30) | ((utf[i + 1] & 0x3F) << 24) | ((utf[i + 2] & 0x3F) << 18) | ((utf[i + 3] & 0x3F) << 12) | ((utf[i + 4] & 0x3F) << 6) | (utf[i + 5] & 0x3F);
      i += 6;
    }
  }
  mem = xrealloc(mem, sizeof(wchar_t) * (j + 1));
  *memsize = j;
  return mem;
}
```