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

```asm
<_js_decode_string>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x28,%rsp
  mov    %rdi,(%rsp)
  mov    %rsi,%r14
  mov    %fs:0x28,%rax
  mov    %rax,0x18(%rsp)
  xor    %eax,%eax
  mov    (%rsi),%rax
  lea    (%rdi,%rax,4),%r12
  movl   $0x0,0x10(%rsp)
  cmp    %rcx,%rdx
  jae    L409
  mov    %rdx,%rbx
  mov    %rcx,%rbp
  movabs $0x400000000002001,%r15
  jmp    L285
L493:
  mov    0x14(%rsp),%eax
  cmp    $0x5c,%eax
  je     L516
  cmp    $0xffff,%eax
  jg     L287
  mov    %eax,(%r12)
  lea    0x4(%r12),%r12
  mov    %r13,%rbx
L406:
  cmp    %rbx,%rbp
  jbe    L409
L285:
  lea    0x4(%rbx),%r13
  lea    0x14(%rsp),%rsi
  lea    0x10(%rsp),%rdi
  mov    (%rbx),%edx
  call   <decode@plt>
  test   %rax,%rax
  je     L493
  cmpl   $0xc,0x10(%rsp)
  je     L265
  mov    %r13,%rbx
  jmp    L406
L516:
  cmp    %r13,%rbp
  jbe    L132
  lea    0x8(%rbx),%rcx
  mov    0x4(%rbx),%eax
  mov    %eax,0x14(%rsp)
  cmp    $0x5c,%eax
  jle    L215
  lea    -0x62(%rax),%edx
  cmp    $0x13,%edx
  ja     L70
  sub    $0x62,%eax
  cmp    $0x13,%eax
  ja     L467
  mov    %eax,%eax
  lea    D8(%rip),%rsi
  movslq (%rsi,%rax,4),%rax
  add    %rsi,%rax
  notrack jmp *%rax
L215:
  cmp    $0x21,%eax
  jg     L365
  mov    $0xffffffff,%eax
  jmp    L457
L365:
  lea    -0x22(%rax),%edx
  bt     %rdx,%r15
  jb     L176
  mov    $0xffffffff,%eax
  jmp    L457
L287:
  mov    %eax,%edx
  sar    $0xa,%edx
  add    $0xd7c0,%edx
  mov    %edx,(%r12)
  and    $0x3ff,%eax
  add    $0xdc00,%eax
  mov    %eax,0x4(%r12)
  lea    0x8(%r12),%r12
  mov    %r13,%rbx
  jmp    L406
L409:
  sub    (%rsp),%r12
  sar    $0x2,%r12
  mov    %r12,(%r14)
  cmpl   $0x0,0x10(%rsp)
  setne  %al
  movzbl %al,%eax
  jmp    L457
L176:
  mov    %eax,(%r12)
  lea    0x4(%r12),%r12
  mov    %rcx,%rbx
  jmp    L406
  movl   $0x8,(%r12)
  lea    0x4(%r12),%r12
  mov    %rcx,%rbx
  jmp    L406
  movl   $0xc,(%r12)
  lea    0x4(%r12),%r12
  mov    %rcx,%rbx
  jmp    L406
  movl   $0xa,(%r12)
  lea    0x4(%r12),%r12
  mov    %rcx,%rbx
  jmp    L406
  movl   $0xd,(%r12)
  lea    0x4(%r12),%r12
  mov    %rcx,%rbx
  jmp    L406
  movl   $0x9,(%r12)
  lea    0x4(%r12),%r12
  mov    %rcx,%rbx
  jmp    L406
  cmp    %rcx,%rbp
  jbe    L61
  mov    0x8(%rbx),%edi
  lea    0x18(%rbx),%r13
  movl   $0x0,0xc(%rsp)
L460:
  mov    %edi,0x14(%rsp)
  call   <decode_hex@plt>
  cmp    $0xffff,%eax
  je     L291
  shl    $0xc,%eax
  mov    %eax,0x8(%rsp)
  lea    -0xc(%r13),%rax
  cmp    %rax,%rbp
  jbe    L198
  mov    %r13,%rbx
  mov    -0xc(%r13),%edi
  mov    %edi,0x14(%rsp)
  call   <decode_hex@plt>
  cmp    $0xffff,%eax
  je     L312
  shl    $0x8,%eax
  mov    %eax,%ecx
  or     0x8(%rsp),%ecx
  mov    %ecx,0x8(%rsp)
  lea    -0x8(%r13),%rax
  cmp    %rax,%rbp
  jbe    L3
  mov    -0x8(%r13),%edi
  mov    %edi,0x14(%rsp)
  call   <decode_hex@plt>
  cmp    $0xffff,%eax
  je     L548
  shl    $0x4,%eax
  or     0x8(%rsp),%eax
  mov    %eax,0x8(%rsp)
  lea    -0x4(%r13),%rax
  cmp    %rax,%rbp
  jbe    L397
  mov    -0x4(%r13),%edi
  mov    %edi,0x14(%rsp)
  call   <decode_hex@plt>
  cmp    $0xffff,%eax
  je     L443
  or     0x8(%rsp),%eax
  add    $0x4,%r12
  mov    %eax,-0x4(%r12)
  cmpl   $0x0,0xc(%rsp)
  jne    L227
  lea    -0xd800(%rax),%edx
  cmp    $0x3ff,%edx
  ja     L347
  cmp    %r13,%rbp
  jbe    L528
  lea    0x4(%r13),%rax
  cmp    %rax,%rbp
  jbe    L180
  cmpl   $0x5c,0x0(%r13)
  jne    L180
  lea    0x8(%r13),%rax
  cmp    %rax,%rbp
  setbe  %al
  cmpl   $0x75,0x4(%r13)
  setne  %dl
  add    $0x18,%r13
  or     %dl,%al
  je     L246
  mov    $0xffffffff,%eax
  jmp    L457
L227:
  sub    $0xdc00,%eax
  cmp    $0x3ff,%eax
  jbe    L406
  mov    $0xffffffff,%eax
  jmp    L457
L347:
  sub    $0xdc00,%eax
  cmp    $0x3ff,%eax
  ja     L406
  mov    $0xffffffff,%eax
  jmp    L457
L246:
  mov    -0x10(%r13),%edi
  movl   $0x1,0xc(%rsp)
  jmp    L460
L265:
  mov    $0xffffffff,%eax
L457:
  mov    0x18(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L26
  add    $0x28,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L132:
  mov    $0xffffffff,%eax
  jmp    L457
L467:
  mov    $0xffffffff,%eax
  jmp    L457
L70:
  mov    $0xffffffff,%eax
  jmp    L457
L61:
  mov    $0xffffffff,%eax
  jmp    L457
L291:
  mov    $0xffffffff,%eax
  jmp    L457
L198:
  mov    $0xffffffff,%eax
  jmp    L457
L312:
  mov    $0xffffffff,%eax
  jmp    L457
L3:
  mov    $0xffffffff,%eax
  jmp    L457
L548:
  mov    $0xffffffff,%eax
  jmp    L457
L397:
  mov    $0xffffffff,%eax
  jmp    L457
L443:
  mov    $0xffffffff,%eax
  jmp    L457
L528:
  mov    $0xffffffff,%eax
  jmp    L457
L180:
  mov    $0xffffffff,%eax
  jmp    L457
L26:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int _js_decode_string(uint16_t *const dest, size_t *destoff, const uint8_t *s, const uint8_t *const srcend) {
  uint16_t *d = dest + *destoff;
  uint32_t state = 0;
  uint32_t codepoint;
  uint8_t surrogate = 0;
  uint16_t temp_hex = 0;
  uint16_t unidata;
standard:
  while (s < srcend) {
    if (decode(&state, &codepoint, *s++) != 0) {
      if (state == 12) {
        return -1;
      }
      continue;
    }
    if (codepoint == '\\') {
      if (s >= srcend) {
        return -1;
      }
      codepoint = *s++;
      goto backslash;
    } else if (codepoint <= 0xffff)
      *d++ = (uint16_t)codepoint;
    else {
      *d++ = (uint16_t)(0xD7C0 + (codepoint >> 10));
      *d++ = (uint16_t)(0xDC00 + (codepoint & 0x3FF));
    }
  }
  *destoff = d - dest;
  return (state != 0);
backslash:
  switch (codepoint) {
  case '"':
  case '\\':
  case '/':
    *d++ = (uint16_t)codepoint;
    goto standard;
    break;
  case 'b':
    *d++ = '\b';
    goto standard;
  case 'f':
    *d++ = '\f';
    goto standard;
  case 'n':
    *d++ = '\n';
    goto standard;
  case 'r':
    *d++ = '\r';
    goto standard;
  case 't':
    *d++ = '\t';
    goto standard;
  case 'u': {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode1;
  };
    ;
    break;
  default:
    return -1;
  }
unicode1:
  temp_hex = decode_hex(codepoint);
  if (temp_hex == 0xFFFF) {
    return -1;
  } else
    unidata = temp_hex << 12;
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode2;
  };
unicode2:
  temp_hex = decode_hex(codepoint);
  if (temp_hex == 0xFFFF) {
    return -1;
  } else
    unidata |= temp_hex << 8;
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode3;
  };
unicode3:
  temp_hex = decode_hex(codepoint);
  if (temp_hex == 0xFFFF) {
    return -1;
  } else
    unidata |= temp_hex << 4;
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode4;
  };
unicode4:
  temp_hex = decode_hex(codepoint);
  if (temp_hex == 0xFFFF) {
    return -1;
  } else
    unidata |= temp_hex;
  *d++ = (uint16_t)unidata;
  if (surrogate) {
    if (unidata < 0xDC00 || unidata > 0xDFFF)
      return -1;
    surrogate = 0;
  } else if (unidata >= 0xD800 && unidata <= 0xDBFF) {
    surrogate = 1;
    {
      if (s >= srcend) {
        return -1;
      }
      codepoint = *s++;
      goto surrogate1;
    };
  } else if (unidata >= 0xDC00 && unidata <= 0xDFFF) {
    return -1;
  }
  goto standard;
surrogate1:
  if (codepoint != '\\') {
    return -1;
  }
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto surrogate2;
  }
surrogate2:
  if (codepoint != 'u') {
    return -1;
  }
  {
    if (s >= srcend) {
      return -1;
    }
    codepoint = *s++;
    goto unicode1;
  }
}
```