user: What is the c source code of the assembly code below?

```asm
<utf8char>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  js     L105
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  jmp    L99
L105:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0xbf,%al
  ja     L74
  mov    $0xffffffff,%eax
  jmp    L99
L74:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0xdf,%al
  ja     L86
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0x7c0,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x3f,%eax
  or     %edx,%eax
  jmp    L99
L86:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0xef,%al
  ja     L68
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0xc,%eax
  movzwl %ax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xfc0,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x3f,%eax
  or     %edx,%eax
  jmp    L99
L68:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0xf7,%al
  ja     L82
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x12,%eax
  and    $0x1c0000,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0xc,%eax
  and    $0x3f000,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xfc0,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x3f,%eax
  or     %edx,%eax
  jmp    L99
L82:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  cmp    $0xfb,%al
  ja     L50
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x18,%eax
  and    $0x3000000,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x12,%eax
  and    $0xfc0000,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0xc,%eax
  and    $0x3f000,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xfc0,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x4,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x3f,%eax
  or     %edx,%eax
  jmp    L99
L50:
  mov    -0x8(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x1e,%eax
  and    $0x40000000,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x18,%eax
  and    $0x3f000000,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x2,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x12,%eax
  and    $0xfc0000,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x3,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0xc,%eax
  and    $0x3f000,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x4,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  shl    $0x6,%eax
  and    $0xfc0,%eax
  or     %eax,%edx
  mov    -0x8(%rbp),%rax
  add    $0x5,%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  and    $0x3f,%eax
  or     %edx,%eax
L99:
  pop    %rbp
  ret
```

assistant: ```c
int utf8char(const char *const ss) {
  const unsigned char *const s = (const unsigned char *)ss;
  if (s[0] < 0x80)
    return s[0];
  if (s[0] < 0xC0)
    return -1;
  if (s[0] < 0xE0)
    return (s[0] & 0x1F) << 6 | s[1] & 0x3F;
  if (s[0] < 0xF0)
    return (s[0] & 0xF) << 12 | (s[1] & 0x3F) << 6 | (s[2] & 0x3F);
  if (s[0] < 0xF8)
    return (s[0] & 0x7) << 18 | (s[1] & 0x3F) << 12 | (s[2] & 0x3F) << 6 | (s[3] & 0x3F);
  if (s[0] < 0xFC)
    return (s[0] & 0x3) << 24 | (s[1] & 0x3F) << 18 | (s[2] & 0x3F) << 12 | (s[3] & 0x3F) << 6 | (s[4] & 0x3F);
  return (s[0] & 0x1) << 30 | (s[1] & 0x3F) << 24 | (s[2] & 0x3F) << 18 | (s[3] & 0x3F) << 12 | (s[4] & 0x3F) << 6 | (s[5] & 0x3F);
}
```