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

```asm
<__boyer_moore>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  mov    %r8d,%r13d
  push   %r12
  mov    %rdi,%r12
  push   %rbp
  mov    %rcx,%rbp
  push   %rbx
  sub    $0x848,%rsp
  mov    %rdx,0x20(%rsp)
  mov    %rsi,0x18(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x838(%rsp)
  xor    %eax,%eax
  lea    -0x1(%rcx),%rax
  add    %rax,%rdx
  mov    %rax,0x28(%rsp)
  lea    0x30(%rsp),%rax
  mov    %rdx,0x10(%rsp)
  lea    0x830(%rsp),%rdx
  nopl   0x0(%rax)
L204:
  mov    %rbp,(%rax)
  add    $0x8,%rax
  cmp    %rdx,%rax
  jne    L204
  mov    0x20(%rsp),%rax
  mov    0x10(%rsp),%rsi
  mov    %rax,%rbx
  cmp    %rsi,%rax
  jb     L74
  jmp    L314
L237:
  mov    %r14,0x30(%rsp,%rdi,8)
  add    $0x1,%rbx
  cmp    %rbx,0x10(%rsp)
  je     L314
L74:
  mov    0x10(%rsp),%r14
  movzbl (%rbx),%edi
  sub    %rbx,%r14
  test   %r13d,%r13d
  je     L237
  call   <isupper@plt>
  test   %rax,%rax
  je     L216
  movzbl (%rbx),%edi
  add    $0x1,%rbx
  call   <tolower@plt>
  movslq %eax,%rdi
  mov    %r14,0x30(%rsp,%rdi,8)
  cmp    %rbx,0x10(%rsp)
  jne    L74
L314:
  cmp    0x18(%rsp),%rbp
  ja     L67
  nopl   0x0(%rax)
L296:
  mov    0x28(%rsp),%rax
  lea    (%r12,%rax,1),%r15
  mov    0x10(%rsp),%rax
  cmp    %rax,0x20(%rsp)
  jae    L31
  mov    %rax,%r14
  xor    %ebx,%ebx
  jmp    L211
  nopl   0x0(%rax,%rax,1)
L250:
  cmp    %dil,(%r15)
  jne    L236
L338:
  sub    $0x1,%r15
  sub    $0x1,%r14
  add    $0x1,%ebx
  cmp    %r15,%r12
  je     L236
L211:
  movzbl (%r14),%edi
  test   %r13d,%r13d
  je     L250
  call   <isupper@plt>
  test   %rax,%rax
  je     L411
  movzbl (%r14),%edi
  call   <tolower@plt>
  mov    %eax,0xc(%rsp)
L199:
  movzbl (%r15),%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L256
  movzbl (%r15),%edi
  call   <tolower@plt>
L355:
  cmp    %eax,0xc(%rsp)
  je     L338
  nopw   0x0(%rax,%rax,1)
L236:
  movzbl (%r14),%edi
  test   %r13d,%r13d
  jne    L261
  movzbl (%r15),%eax
  cmp    %dil,%al
  je     L406
  mov    0x30(%rsp,%rax,8),%r14
  cmp    %r14,%rbp
  jne    L213
  test   %ebx,%ebx
  je     L213
  mov    0x20(%rsp),%rsi
  mov    0x10(%rsp),%rax
  movzbl (%rsi),%esi
  cmp    %sil,(%rax)
  jne    L213
L332:
  sub    $0x1,%r14
L213:
  sub    %r14,0x18(%rsp)
  mov    0x18(%rsp),%rax
  add    %r14,%r12
  cmp    %rax,%rbp
  jbe    L296
L67:
  xor    %eax,%eax
L0:
  mov    0x838(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L71
  add    $0x848,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nop
L216:
  movzbl (%rbx),%edi
  jmp    L237
  nopl   0x0(%rax,%rax,1)
L256:
  movzbl (%r15),%eax
  jmp    L355
  nopl   0x0(%rax)
L411:
  movzbl (%r14),%eax
  mov    %eax,0xc(%rsp)
  jmp    L199
  nopl   (%rax)
L261:
  call   <isupper@plt>
  test   %rax,%rax
  je     L318
  movzbl (%r14),%edi
  call   <tolower@plt>
  mov    %eax,%r14d
L99:
  movzbl (%r15),%edi
  call   <isupper@plt>
  movzbl (%r15),%edi
  test   %rax,%rax
  je     L356
  mov    %edi,0xc(%rsp)
  call   <tolower@plt>
  mov    0xc(%rsp),%edi
  cmp    %eax,%r14d
  je     L406
L174:
  call   <isupper@plt>
  test   %rax,%rax
  je     L17
  movzbl (%r15),%edi
  call   <tolower@plt>
L122:
  cltq
  mov    0x30(%rsp,%rax,8),%r14
  cmp    %r14,%rbp
  jne    L213
  test   %ebx,%ebx
  je     L213
  mov    0x10(%rsp),%rbx
  movzbl (%rbx),%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L245
  movzbl (%rbx),%edi
  call   <tolower@plt>
  mov    %eax,%ebx
L43:
  mov    0x20(%rsp),%r15
  movzbl (%r15),%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L371
  movzbl (%r15),%edi
  call   <tolower@plt>
L239:
  cmp    %eax,%ebx
  je     L332
  jmp    L213
  nopw   0x0(%rax,%rax,1)
L318:
  movzbl (%r14),%r14d
  jmp    L99
  nopl   0x0(%rax)
L356:
  mov    %edi,%eax
  cmp    %eax,%r14d
  jne    L174
L406:
  mov    %r12,%rax
  jmp    L0
  nopl   0x0(%rax,%rax,1)
L17:
  movzbl (%r15),%eax
  jmp    L122
L371:
  mov    0x20(%rsp),%rax
  movzbl (%rax),%eax
  jmp    L239
L245:
  mov    0x10(%rsp),%rax
  movzbl (%rax),%ebx
  jmp    L43
L31:
  mov    0x10(%rsp),%r14
  xor    %ebx,%ebx
  jmp    L236
L71:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
unsigned char *__boyer_moore(const unsigned char *haystack, size_t haystacklen, const unsigned char *needle, size_t needlelen, int icase) {
  register unsigned char *hc_ptr, *nc_ptr;
  unsigned char *he_ptr, *ne_ptr, *h_ptr;
  size_t skiptable[256], n;
  register int i;
  ne_ptr = (unsigned char *)needle + needlelen - 1;
  he_ptr = (unsigned char *)haystack + haystacklen - 1;
  for (i = 0; i < 256; i++)
    skiptable[i] = needlelen;
  for (nc_ptr = (unsigned char *)needle; nc_ptr < ne_ptr; nc_ptr++)
    skiptable[((icase) ? (isupper((int)(*nc_ptr)) ? tolower((int)(*nc_ptr)) : (int)(*nc_ptr)) : (int)(*nc_ptr))] = (size_t)(ne_ptr - nc_ptr);
  h_ptr = (unsigned char *)haystack;
  while (haystacklen >= needlelen) {
    hc_ptr = h_ptr + needlelen - 1;
    nc_ptr = ne_ptr;
    for (i = 0; nc_ptr > (unsigned char *)needle; nc_ptr--, hc_ptr--, i++)
      if (!((icase) ? (isupper((int)(*nc_ptr)) ? tolower((int)(*nc_ptr)) : (int)(*nc_ptr)) == (isupper((int)(*hc_ptr)) ? tolower((int)(*hc_ptr)) : (int)(*hc_ptr)) : (*nc_ptr) == (*hc_ptr)))
        break;
    if (!((icase) ? (isupper((int)(*nc_ptr)) ? tolower((int)(*nc_ptr)) : (int)(*nc_ptr)) == (isupper((int)(*hc_ptr)) ? tolower((int)(*hc_ptr)) : (int)(*hc_ptr)) : (*nc_ptr) == (*hc_ptr))) {
      n = skiptable[((icase) ? (isupper((int)(*hc_ptr)) ? tolower((int)(*hc_ptr)) : (int)(*hc_ptr)) : (int)(*hc_ptr))];
      if (n == needlelen && i)
        if (((icase) ? (isupper((int)(*ne_ptr)) ? tolower((int)(*ne_ptr)) : (int)(*ne_ptr)) == (isupper((int)(((unsigned char *)needle)[0])) ? tolower((int)(((unsigned char *)needle)[0])) : (int)(((unsigned char *)needle)[0])) : (*ne_ptr) == (((unsigned char *)needle)[0])))
          n--;
      h_ptr += n;
      haystacklen -= n;
    } else
      return (unsigned char *)h_ptr;
  }
  return NULL;
}
```