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

```asm
<__boyer_moore>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %r14
  push   %r13
  push   %r12
  push   %rbx
  sub    $0x860,%rsp
  mov    %rdi,-0x858(%rbp)
  mov    %rsi,-0x860(%rbp)
  mov    %rdx,-0x868(%rbp)
  mov    %rcx,-0x870(%rbp)
  mov    %r8d,-0x874(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x28(%rbp)
  xor    %eax,%eax
  mov    -0x870(%rbp),%rax
  lea    -0x1(%rax),%rdx
  mov    -0x868(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x840(%rbp)
  mov    -0x860(%rbp),%rax
  lea    -0x1(%rax),%rdx
  mov    -0x858(%rbp),%rax
  add    %rdx,%rax
  mov    %rax,-0x838(%rbp)
  mov    $0x0,%r13d
  jmp    L56
L115:
  movslq %r13d,%rax
  mov    -0x870(%rbp),%rdx
  mov    %rdx,-0x830(%rbp,%rax,8)
  add    $0x1,%r13d
L56:
  cmp    $0xff,%r13d
  jle    L115
  mov    -0x868(%rbp),%rbx
  jmp    L315
L288:
  mov    -0x840(%rbp),%rax
  sub    %rbx,%rax
  mov    %rax,%r12
  cmpl   $0x0,-0x874(%rbp)
  je     L328
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L353
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L276
L353:
  movzbl (%rbx),%eax
  movzbl %al,%eax
  jmp    L276
L328:
  movzbl (%rbx),%eax
  movzbl %al,%eax
L276:
  mov    %r12,%rdx
  cltq
  mov    %rdx,-0x830(%rbp,%rax,8)
  add    $0x1,%rbx
L315:
  cmp    -0x840(%rbp),%rbx
  jb     L288
  mov    -0x858(%rbp),%rax
  mov    %rax,-0x850(%rbp)
  jmp    L384
L242:
  mov    -0x870(%rbp),%rax
  lea    -0x1(%rax),%rdx
  mov    -0x850(%rbp),%rax
  lea    (%rdx,%rax,1),%r12
  mov    -0x840(%rbp),%rbx
  mov    $0x0,%r13d
  jmp    L159
L205:
  cmpl   $0x0,-0x874(%rbp)
  je     L181
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L229
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  mov    %eax,%r14d
  jmp    L12
L229:
  movzbl (%rbx),%eax
  movzbl %al,%r14d
L12:
  movzbl (%r12),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L297
  movzbl (%r12),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L53
L297:
  movzbl (%r12),%eax
  movzbl %al,%eax
L53:
  cmp    %eax,%r14d
  setne  %al
  jmp    L75
L181:
  movzbl (%rbx),%edx
  movzbl (%r12),%eax
  cmp    %al,%dl
  setne  %al
L75:
  test   %al,%al
  jne    L0
  sub    $0x1,%rbx
  sub    $0x1,%r12
  add    $0x1,%r13d
L159:
  cmp    -0x868(%rbp),%rbx
  ja     L205
  jmp    L176
L0:
  nop
L176:
  cmpl   $0x0,-0x874(%rbp)
  je     L87
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L400
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  jmp    L399
L400:
  movzbl (%rbx),%eax
  movzbl %al,%ebx
L399:
  movzbl (%r12),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L419
  movzbl (%r12),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L266
L419:
  movzbl (%r12),%eax
  movzbl %al,%eax
L266:
  cmp    %eax,%ebx
  setne  %al
  jmp    L164
L87:
  movzbl (%rbx),%edx
  movzbl (%r12),%eax
  cmp    %al,%dl
  setne  %al
L164:
  test   %al,%al
  je     L357
  cmpl   $0x0,-0x874(%rbp)
  je     L39
  movzbl (%r12),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L208
  movzbl (%r12),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L409
L208:
  movzbl (%r12),%eax
  movzbl %al,%eax
  jmp    L409
L39:
  movzbl (%r12),%eax
  movzbl %al,%eax
L409:
  cltq
  mov    -0x830(%rbp,%rax,8),%rax
  mov    %rax,-0x848(%rbp)
  mov    -0x848(%rbp),%rax
  cmp    -0x870(%rbp),%rax
  jne    L146
  test   %r13d,%r13d
  je     L146
  cmpl   $0x0,-0x874(%rbp)
  je     L55
  mov    -0x840(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L346
  mov    -0x840(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  jmp    L289
L346:
  mov    -0x840(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%ebx
L289:
  mov    -0x868(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %rax,%rax
  je     L342
  mov    -0x868(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L326
L342:
  mov    -0x868(%rbp),%rax
  movzbl (%rax),%eax
  movzbl %al,%eax
L326:
  cmp    %eax,%ebx
  sete   %al
  jmp    L350
L55:
  mov    -0x840(%rbp),%rax
  movzbl (%rax),%edx
  mov    -0x868(%rbp),%rax
  movzbl (%rax),%eax
  cmp    %al,%dl
  sete   %al
L350:
  test   %al,%al
  je     L146
  subq   $0x1,-0x848(%rbp)
L146:
  mov    -0x848(%rbp),%rax
  add    %rax,-0x850(%rbp)
  mov    -0x848(%rbp),%rax
  sub    %rax,-0x860(%rbp)
  jmp    L384
L357:
  mov    -0x850(%rbp),%rax
  jmp    L172
L384:
  mov    -0x860(%rbp),%rax
  cmp    -0x870(%rbp),%rax
  jae    L242
  mov    $0x0,%eax
L172:
  mov    -0x28(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L37
  call   <__stack_chk_fail@plt>
L37:
  add    $0x860,%rsp
  pop    %rbx
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %rbp
  ret
```

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;
}
```