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

```asm
<arikkei_utf8_ucs2_strcpy>:
  endbr64
  mov    %rdi,%rcx
  mov    %rsi,%rdi
  movzbl (%rcx),%eax
  test   %al,%al
  je     L77
  mov    $0x1,%r8d
  jmp    L1
  nopl   (%rax)
L46:
  add    $0x1,%rcx
L61:
  mov    %ax,(%rsi)
  movzbl (%rcx),%eax
  lea    0x1(%r8),%edx
  test   %al,%al
  je     L149
L101:
  mov    %edx,%r8d
L1:
  lea    -0x1(%r8),%edx
  mov    %rdx,%r9
  lea    (%rdi,%rdx,2),%rsi
  test   %al,%al
  jns    L46
  mov    %eax,%r10d
  movzbl %al,%edx
  and    $0xffffffe0,%r10d
  cmp    $0xc0,%r10b
  je     L126
  mov    %eax,%r10d
  and    $0xfffffff0,%r10d
  cmp    $0xe0,%r10b
  je     L38
  mov    %eax,%edx
  and    $0xfffffff8,%edx
  cmp    $0xf0,%dl
  je     L131
  mov    %eax,%edx
  and    $0xfffffffc,%edx
  cmp    $0xf8,%dl
  je     L10
  and    $0xfffffffe,%eax
  cmp    $0xfc,%al
  jne    L4
  movzbl 0x3(%rcx),%edx
  movzbl 0x5(%rcx),%eax
  add    $0x6,%rcx
  shl    $0xc,%edx
  and    $0x3f,%eax
  or     %edx,%eax
  movzbl -0x2(%rcx),%edx
  shl    $0x6,%edx
  and    $0xfc0,%dx
  or     %edx,%eax
  lea    0x1(%r8),%edx
  mov    %ax,(%rsi)
  movzbl (%rcx),%eax
  test   %al,%al
  jne    L101
  nopl   0x0(%rax,%rax,1)
L149:
  mov    %r8d,%eax
  lea    (%rdi,%rax,2),%rsi
L51:
  xor    %eax,%eax
  mov    %ax,(%rsi)
  mov    %r8d,%eax
  ret
L126:
  mov    %edx,%eax
  movzbl 0x1(%rcx),%edx
  add    $0x2,%rcx
  shl    $0x6,%eax
  and    $0x7c0,%ax
  and    $0x3f,%edx
  or     %edx,%eax
  jmp    L61
  nopl   0x0(%rax,%rax,1)
L38:
  movzbl 0x2(%rcx),%eax
  shl    $0xc,%edx
  add    $0x3,%rcx
  and    $0x3f,%eax
  or     %eax,%edx
  movzbl -0x2(%rcx),%eax
  shl    $0x6,%eax
  and    $0xfc0,%ax
  or     %edx,%eax
  jmp    L61
  nopw   0x0(%rax,%rax,1)
L131:
  movzbl 0x1(%rcx),%edx
  movzbl 0x3(%rcx),%eax
  add    $0x4,%rcx
  shl    $0xc,%edx
  and    $0x3f,%eax
  or     %edx,%eax
  movzbl -0x2(%rcx),%edx
  shl    $0x6,%edx
  and    $0xfc0,%dx
  or     %edx,%eax
  jmp    L61
  nop
L10:
  movzbl 0x2(%rcx),%edx
  movzbl 0x4(%rcx),%eax
  add    $0x5,%rcx
  shl    $0xc,%edx
  and    $0x3f,%eax
  or     %edx,%eax
  movzbl -0x2(%rcx),%edx
  shl    $0x6,%edx
  and    $0xfc0,%dx
  or     %edx,%eax
  jmp    L61
L4:
  mov    %r9d,%r8d
  jmp    L51
L77:
  xor    %r8d,%r8d
  jmp    L51
```

assistant: ```c
unsigned int arikkei_utf8_ucs2_strcpy(const unsigned char *s, unsigned short *d) {
  unsigned int dp;
  dp = 0;
  while (*s) {
    if ((*s & 0x80) == 0x0) {
      d[dp++] = s[0];
      s += 1;
    } else if ((*s & 0xe0) == 0xc0) {
      d[dp++] = ((s[0] & 0x1f) << 6) | (s[1] & 0x3f);
      s += 2;
    } else if ((*s & 0xf0) == 0xe0) {
      d[dp++] = ((s[0] & 0x0f) << 12) | ((s[1] & 0x3f) << 6) | (s[2] & 0x3f);
      s += 3;
    } else if ((*s & 0xf8) == 0xf0) {
      d[dp++] = ((s[0] & 0x07) << 18) | ((s[1] & 0x3f) << 12) | ((s[2] & 0x3f) << 6) | (s[3] & 0x3f);
      s += 4;
    } else if ((*s & 0xfc) == 0xf8) {
      d[dp++] = ((s[0] & 0x03) << 24) | ((s[1] & 0x3f) << 18) | ((s[2] & 0x3f) << 12) | ((s[3] & 0x3f) << 6) | (s[4] & 0x3f);
      s += 5;
    } else if ((*s & 0xfe) == 0xfc) {
      d[dp++] = ((s[0] & 0x01) << 30) | ((s[1] & 0x3f) << 24) | ((s[2] & 0x3f) << 18) | ((s[3] & 0x3f) << 12) | ((s[4] & 0x3f) << 6) | (s[5] & 0x3f);
      s += 6;
    } else {
      break;
    }
  }
  d[dp] = 0;
  return dp;
}
```