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

```asm
<fnmatch>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,-0x48(%rbp)
  mov    %rsi,-0x50(%rbp)
  mov    %edx,-0x54(%rbp)
  mov    -0x48(%rbp),%r12
  mov    -0x50(%rbp),%rbx
  jmp    L966
L1298:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L1220
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1220
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L1324
L1220:
  mov    %r13d,%eax
L1324:
  mov    %eax,%r13d
  movsbl %r13b,%eax
  cmp    $0x5c,%eax
  je     L866
  cmp    $0x5c,%eax
  jg     L1261
  cmp    $0x5b,%eax
  je     L94
  cmp    $0x5b,%eax
  jg     L1261
  cmp    $0x2a,%eax
  je     L119
  cmp    $0x3f,%eax
  jne    L1261
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L1240
  mov    $0x1,%eax
  jmp    L649
L1240:
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L345
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  jne    L345
  mov    $0x1,%eax
  jmp    L649
L345:
  mov    -0x54(%rbp),%eax
  and    $0x4,%eax
  test   %eax,%eax
  je     L301
  movzbl (%rbx),%eax
  cmp    $0x2e,%al
  jne    L301
  cmp    -0x50(%rbp),%rbx
  je     L582
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L301
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jne    L301
L582:
  mov    $0x1,%eax
  jmp    L649
L866:
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L729
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  test   %r13b,%r13b
  jne    L265
  mov    $0x1,%eax
  jmp    L649
L265:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L55
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L55
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L1046
L55:
  mov    %r13d,%eax
L1046:
  mov    %eax,%r13d
L729:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L293
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L293
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L629
L293:
  movzbl (%rbx),%eax
  movsbl %al,%eax
L629:
  movsbl %r13b,%edx
  cmp    %edx,%eax
  je     L234
  mov    $0x1,%eax
  jmp    L649
L119:
  mov    -0x54(%rbp),%eax
  and    $0x4,%eax
  test   %eax,%eax
  je     L1083
  movzbl (%rbx),%eax
  cmp    $0x2e,%al
  jne    L1083
  cmp    -0x50(%rbp),%rbx
  je     L693
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L1083
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jne    L1083
L693:
  mov    $0x1,%eax
  jmp    L649
L1083:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  jmp    L1041
L597:
  cmp    $0x3f,%r13b
  jne    L432
  movzbl (%rbx),%eax
  test   %al,%al
  je     L604
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  jne    L717
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L717
L604:
  mov    $0x1,%eax
  jmp    L649
L717:
  add    $0x1,%rbx
L432:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
L1041:
  cmp    $0x3f,%r13b
  je     L597
  cmp    $0x2a,%r13b
  je     L597
  test   %r13b,%r13b
  jne    L615
  mov    -0x54(%rbp),%eax
  and    $0x9,%eax
  cmp    $0x1,%eax
  jne    L107
  jmp    L858
L1439:
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  jne    L186
  mov    $0x1,%eax
  jmp    L649
L186:
  add    $0x1,%rbx
L858:
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L1439
L107:
  mov    $0x0,%eax
  jmp    L649
L615:
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L1224
  cmp    $0x5c,%r13b
  jne    L1224
  movzbl (%r12),%eax
  jmp    L254
L1224:
  mov    %r13d,%eax
L254:
  mov    %al,-0x31(%rbp)
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L908
  movzbl -0x31(%rbp),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L908
  movzbl -0x31(%rbp),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L247
L908:
  movzbl -0x31(%rbp),%eax
L247:
  mov    %al,-0x31(%rbp)
  sub    $0x1,%r12
  jmp    L576
L1126:
  cmp    $0x5b,%r13b
  je     L910
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L60
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L60
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L200
L60:
  movzbl (%rbx),%eax
  movsbl %al,%eax
L200:
  movsbl -0x31(%rbp),%edx
  cmp    %edx,%eax
  jne    L1147
L910:
  mov    -0x54(%rbp),%eax
  and    $0xfffffffb,%eax
  mov    %eax,%edx
  mov    %rbx,%rsi
  mov    %r12,%rdi
  call   <fnmatch>
  test   %eax,%eax
  jne    L1147
  mov    $0x0,%eax
  jmp    L649
L1147:
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  jne    L116
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  jne    L1307
L116:
  add    $0x1,%rbx
L576:
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L1126
  jmp    L408
L1307:
  nop
L408:
  mov    $0x1,%eax
  jmp    L649
L94:
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L1416
  mov    $0x1,%eax
  jmp    L649
L1416:
  mov    -0x54(%rbp),%eax
  and    $0x4,%eax
  test   %eax,%eax
  je     L414
  movzbl (%rbx),%eax
  cmp    $0x2e,%al
  jne    L414
  cmp    -0x50(%rbp),%rbx
  je     L259
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L414
  lea    -0x1(%rbx),%rax
  movzbl (%rax),%eax
  cmp    $0x2f,%al
  jne    L414
L259:
  mov    $0x1,%eax
  jmp    L649
L414:
  movzbl (%r12),%eax
  cmp    $0x21,%al
  je     L1269
  movzbl (%r12),%eax
  cmp    $0x5e,%al
  jne    L603
L1269:
  mov    $0x1,%eax
  jmp    L1266
L603:
  mov    $0x0,%eax
L1266:
  mov    %eax,%r15d
  test   %r15d,%r15d
  je     L1379
  add    $0x1,%r12
L1379:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
L548:
  mov    %r13b,-0x55(%rbp)
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L933
  cmp    $0x5c,%r13b
  jne    L933
  movzbl (%r12),%eax
  test   %al,%al
  jne    L707
  mov    $0x1,%eax
  jmp    L649
L707:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r14d
  mov    %r14b,-0x55(%rbp)
L933:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L155
  movzbl -0x55(%rbp),%r14d
  mov    %r14d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L155
  mov    %r14d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L1242
L155:
  movzbl -0x55(%rbp),%eax
L1242:
  mov    %eax,%r14d
  mov    %r14b,-0x55(%rbp)
  test   %r13b,%r13b
  jne    L560
  mov    $0x1,%eax
  jmp    L649
L560:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L925
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L925
  mov    %r13d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L1237
L925:
  mov    %r13d,%eax
L1237:
  mov    %eax,%r13d
  mov    -0x54(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  je     L1173
  cmp    $0x2f,%r13b
  jne    L1173
  mov    $0x1,%eax
  jmp    L649
L1173:
  cmp    $0x2d,%r13b
  jne    L320
  movzbl (%r12),%eax
  cmp    $0x5d,%al
  je     L320
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r14d
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L640
  cmp    $0x5c,%r14b
  jne    L640
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r14d
L640:
  test   %r14b,%r14b
  jne    L584
  mov    $0x1,%eax
  jmp    L649
L584:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L221
  mov    %r14d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L221
  mov    %r14d,%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L6
L221:
  mov    %r14d,%eax
L6:
  mov    %eax,%r14d
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
L320:
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L1339
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1339
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L175
L1339:
  movzbl (%rbx),%eax
  movsbl %al,%eax
L175:
  movsbl -0x55(%rbp),%edx
  cmp    %edx,%eax
  jl     L1314
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L1139
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1139
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L327
L1139:
  movzbl (%rbx),%eax
  movsbl %al,%eax
L327:
  movsbl %r14b,%edx
  cmp    %edx,%eax
  jle    L714
L1314:
  cmp    $0x5d,%r13b
  je     L1109
  jmp    L548
L1109:
  nop
  test   %r15d,%r15d
  jne    L607
  mov    $0x1,%eax
  jmp    L649
L714:
  nop
  jmp    L36
L123:
  test   %r13b,%r13b
  jne    L1366
  mov    $0x1,%eax
  jmp    L649
L1366:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  mov    -0x54(%rbp),%eax
  and    $0x2,%eax
  test   %eax,%eax
  jne    L36
  cmp    $0x5c,%r13b
  jne    L36
  movzbl (%r12),%eax
  test   %al,%al
  jne    L1316
  mov    $0x1,%eax
  jmp    L649
L1316:
  add    $0x1,%r12
L36:
  cmp    $0x5d,%r13b
  jne    L123
  test   %r15d,%r15d
  je     L269
  mov    $0x1,%eax
  jmp    L649
L1261:
  movsbl %r13b,%r13d
  mov    -0x54(%rbp),%eax
  and    $0x10,%eax
  test   %eax,%eax
  je     L326
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L326
  movzbl (%rbx),%eax
  movzbl %al,%eax
  mov    %eax,%edi
  call   <tolower@plt>
  jmp    L668
L326:
  movzbl (%rbx),%eax
  movsbl %al,%eax
L668:
  cmp    %r13d,%eax
  je     L391
  mov    $0x1,%eax
  jmp    L649
L301:
  nop
  jmp    L391
L234:
  nop
  jmp    L391
L607:
  nop
  jmp    L391
L269:
  nop
L391:
  add    $0x1,%rbx
L966:
  mov    %r12,%rax
  lea    0x1(%rax),%r12
  movzbl (%rax),%r13d
  test   %r13b,%r13b
  jne    L1298
  movzbl (%rbx),%eax
  test   %al,%al
  jne    L1133
  mov    $0x0,%eax
  jmp    L649
L1133:
  mov    -0x54(%rbp),%eax
  and    $0x8,%eax
  test   %eax,%eax
  je     L294
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  jne    L294
  mov    $0x0,%eax
  jmp    L649
L294:
  mov    $0x1,%eax
L649:
  add    $0x38,%rsp
  pop    %rbx
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  pop    %rbp
  ret
```

assistant: ```c
int fnmatch(const char *pattern, const char *string, int flags) {
  register const char *p = pattern, *n = string;
  register char c;
  while ((c = *p++) != '\0') {
    c = ((flags & (1 << 4)) && (1 && isupper((unsigned char)(c))) ? tolower((unsigned char)(c)) : (c));
    switch (c) {
    case '?':
      if (*n == '\0')
        return 1;
      else if ((flags & (1 << 0)) && *n == '/')
        return 1;
      else if ((flags & (1 << 2)) && *n == '.' && (n == string || ((flags & (1 << 0)) && n[-1] == '/')))
        return 1;
      break;
    case '\\':
      if (!(flags & (1 << 1))) {
        c = *p++;
        if (c == '\0')
          return 1;
        c = ((flags & (1 << 4)) && (1 && isupper((unsigned char)(c))) ? tolower((unsigned char)(c)) : (c));
      }
      if (((flags & (1 << 4)) && (1 && isupper((unsigned char)(*n))) ? tolower((unsigned char)(*n)) : (*n)) != c)
        return 1;
      break;
    case '*':
      if ((flags & (1 << 2)) && *n == '.' && (n == string || ((flags & (1 << 0)) && n[-1] == '/')))
        return 1;
      for (c = *p++; c == '?' || c == '*'; c = *p++) {
        if (c == '?') {
          if (*n == '\0' || (*n == '/' && (flags & (1 << 0))))
            return 1;
          else
            ++n;
        }
      }
      if (c == '\0') {
        if ((flags & ((1 << 0) | (1 << 3))) == (1 << 0))
          for (; *n != '\0'; n++)
            if (*n == '/')
              return 1;
        return 0;
      }
      {
        char c1 = (!(flags & (1 << 1)) && c == '\\') ? *p : c;
        c1 = ((flags & (1 << 4)) && (1 && isupper((unsigned char)(c1))) ? tolower((unsigned char)(c1)) : (c1));
        for (--p; *n != '\0'; ++n)
          if ((c == '[' || ((flags & (1 << 4)) && (1 && isupper((unsigned char)(*n))) ? tolower((unsigned char)(*n)) : (*n)) == c1) && fnmatch(p, n, flags & ~(1 << 2)) == 0)
            return 0;
          else if (*n == '/' && (flags & (1 << 0)))
            break;
        return 1;
      }
    case '[': {
      register int not ;
      if (*n == '\0')
        return 1;
      if ((flags & (1 << 2)) && *n == '.' && (n == string || ((flags & (1 << 0)) && n[-1] == '/')))
        return 1;
      not = (*p == '!' || *p == '^');
      if (not )
        ++p;
      c = *p++;
      for (;;) {
        register char cstart = c, cend = c;
        if (!(flags & (1 << 1)) && c == '\\') {
          if (*p == '\0')
            return 1;
          cstart = cend = *p++;
        }
        cstart = cend = ((flags & (1 << 4)) && (1 && isupper((unsigned char)(cstart))) ? tolower((unsigned char)(cstart)) : (cstart));
        if (c == '\0')
          return 1;
        c = *p++;
        c = ((flags & (1 << 4)) && (1 && isupper((unsigned char)(c))) ? tolower((unsigned char)(c)) : (c));
        if ((flags & (1 << 0)) && c == '/')
          return 1;
        if (c == '-' && *p != ']') {
          cend = *p++;
          if (!(flags & (1 << 1)) && cend == '\\')
            cend = *p++;
          if (cend == '\0')
            return 1;
          cend = ((flags & (1 << 4)) && (1 && isupper((unsigned char)(cend))) ? tolower((unsigned char)(cend)) : (cend));
          c = *p++;
        }
        if (((flags & (1 << 4)) && (1 && isupper((unsigned char)(*n))) ? tolower((unsigned char)(*n)) : (*n)) >= cstart && ((flags & (1 << 4)) && (1 && isupper((unsigned char)(*n))) ? tolower((unsigned char)(*n)) : (*n)) <= cend)
          goto matched;
        if (c == ']')
          break;
      }
      if (!not )
        return 1;
      break;
    matched:;
      while (c != ']') {
        if (c == '\0')
          return 1;
        c = *p++;
        if (!(flags & (1 << 1)) && c == '\\') {
          if (*p == '\0')
            return 1;
          ++p;
        }
      }
      if (not )
        return 1;
    } break;
    default:
      if (c != ((flags & (1 << 4)) && (1 && isupper((unsigned char)(*n))) ? tolower((unsigned char)(*n)) : (*n)))
        return 1;
    }
    ++n;
  }
  if (*n == '\0')
    return 0;
  if ((flags & (1 << 3)) && *n == '/')
    return 0;
  return 1;
}
```