user: Please show me the C implementation that matches the assembly code listed below:

```asm
<fnmatch>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x48,%rsp
  mov    %rsi,0x30(%rsp)
  mov    %edx,0x28(%rsp)
  movzbl (%rdi),%ebp
  test   %bpl,%bpl
  je     L1302
  mov    %rdi,%r15
  lea    0x1(%rdi),%rbx
  mov    %rsi,%r13
  mov    %edx,%esi
  mov    %edx,%r14d
  and    $0x10,%r14d
  mov    %edx,%eax
  and    $0x2,%eax
  mov    %eax,0x38(%rsp)
  mov    %edx,%eax
  shr    $0x2,%eax
  and    $0x1,%eax
  mov    %al,0x3e(%rsp)
  mov    %edx,%eax
  shr    %eax
  xor    $0x1,%eax
  and    $0x1,%eax
  mov    %al,0x3d(%rsp)
  mov    %edx,%eax
  and    $0x1,%eax
  mov    %al,0x8(%rsp)
  and    $0x1,%esi
  mov    %esi,0x2c(%rsp)
  mov    %r13,0x18(%rsp)
  jmp    L1126
L1299:
  mov    0x18(%rsp),%rcx
  cmp    %rcx,0x30(%rsp)
  je     L1405
  cmpl   $0x0,0x2c(%rsp)
  je     L1539
  cmpb   $0x2f,-0x1(%rcx)
  je     L951
  mov    %rbx,%r15
  jmp    L471
L428:
  mov    %rbx,%r15
  jmp    L125
L1215:
  mov    0x18(%rsp),%r13
  testb  $0x4,0x28(%rsp)
  je     L602
  cmpb   $0x2e,0x0(%r13)
  je     L117
L602:
  lea    0x2(%r15),%rbp
  movzbl 0x1(%r15),%ebx
  cmp    $0x3f,%bl
  je     L197
  cmp    $0x2a,%bl
  jne    L273
L197:
  mov    0x28(%rsp),%edx
  and    $0x1,%edx
L978:
  cmp    $0x3f,%bl
  je     L420
L280:
  add    $0x1,%rbp
  movzbl -0x1(%rbp),%ebx
  cmp    $0x3f,%bl
  je     L978
  cmp    $0x2a,%bl
  je     L978
L273:
  test   %bl,%bl
  jne    L1456
  mov    0x28(%rsp),%eax
  and    $0x9,%eax
  cmp    $0x1,%eax
  jne    L131
  movzbl 0x0(%r13),%edx
  test   %dl,%dl
  je     L1323
L1004:
  cmp    $0x2f,%dl
  je     L951
  add    $0x1,%r13
  movzbl 0x0(%r13),%edx
  test   %dl,%dl
  jne    L1004
  mov    $0x0,%eax
  jmp    L951
L117:
  cmp    %r13,0x30(%rsp)
  je     L1263
  mov    0x28(%rsp),%eax
  and    $0x1,%eax
  je     L602
  cmpb   $0x2f,-0x1(%r13)
  jne    L602
  jmp    L951
L420:
  movzbl 0x0(%r13),%eax
  test   %al,%al
  je     L617
  cmp    $0x2f,%al
  je     L1292
L564:
  add    $0x1,%r13
  jmp    L280
L1292:
  mov    %edx,%eax
  test   %edx,%edx
  je     L564
  jmp    L951
L1456:
  testb  $0x2,0x28(%rsp)
  jne    L925
  cmp    $0x5c,%bl
  je     L1035
L925:
  mov    %ebx,%r15d
L487:
  test   %r14d,%r14d
  je     L1225
  movzbl %r15b,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1225
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%r15d
L1225:
  lea    -0x1(%rbp),%rax
  mov    %rax,0x8(%rsp)
  movzbl 0x0(%r13),%r12d
  test   %r12b,%r12b
  je     L33
  mov    0x28(%rsp),%eax
  and    $0xfffffffb,%eax
  mov    %eax,0x14(%rsp)
  jmp    L1425
L1035:
  movzbl 0x0(%rbp),%r15d
  jmp    L487
L551:
  movsbl %r12b,%eax
L1145:
  movsbl %r15b,%edx
  cmp    %eax,%edx
  je     L1275
L880:
  cmp    $0x2f,%r12b
  je     L921
L892:
  add    $0x1,%r13
  movzbl 0x0(%r13),%r12d
  test   %r12b,%r12b
  je     L856
L1425:
  cmp    $0x5b,%bl
  je     L1275
  test   %r14d,%r14d
  je     L551
  movzbl %r12b,%ebp
  mov    %ebp,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L551
  mov    %ebp,%edi
  call   <tolower@plt>
  jmp    L1145
L1275:
  mov    0x14(%rsp),%edx
  mov    %r13,%rsi
  mov    0x8(%rsp),%rdi
  call   <fnmatch>
  test   %eax,%eax
  jne    L880
  jmp    L951
L921:
  mov    0x28(%rsp),%eax
  and    $0x1,%eax
  je     L892
  jmp    L951
L856:
  mov    $0x1,%eax
  jmp    L951
L241:
  mov    0x18(%rsp),%rcx
  movzbl (%rcx),%eax
  mov    %al,0x14(%rsp)
  test   %al,%al
  je     L913
  cmpb   $0x0,0x3e(%rsp)
  je     L1136
  cmp    $0x2e,%al
  jne    L1136
  cmp    %rcx,0x30(%rsp)
  je     L1223
  mov    0x2c(%rsp),%esi
  mov    %esi,%eax
  test   %esi,%esi
  je     L1136
  cmpb   $0x2f,-0x1(%rcx)
  je     L951
L1136:
  movzbl 0x1(%r15),%eax
  cmp    $0x21,%al
  sete   %dl
  cmp    $0x5e,%al
  sete   %al
  add    $0x2,%r15
  or     %al,%dl
  mov    %dl,0x3f(%rsp)
  cmovne %r15,%rbx
  lea    0x1(%rbx),%r15
  movzbl (%rbx),%ebx
  movzbl 0x14(%rsp),%eax
  movsbl %al,%ecx
  mov    %ecx,0x24(%rsp)
  movzbl %al,%eax
  mov    %eax,0x20(%rsp)
  jmp    L1390
L1052:
  movzbl (%r15),%ebp
  test   %bpl,%bpl
  je     L626
  add    $0x1,%r15
  test   %r14d,%r14d
  jne    L891
  mov    %ebp,%ebx
  jmp    L301
L116:
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  mov    %r15,%rax
  mov    %r13,%r15
  jmp    L1110
L724:
  movzbl 0x1(%rax),%r12d
  cmp    $0x5d,%r12b
  je     L52
  lea    0x2(%rax),%rbx
  cmp    $0x5c,%r12b
  jne    L934
  cmpb   $0x0,0x3d(%rsp)
  jne    L689
L934:
  test   %r12b,%r12b
  je     L967
  test   %r14d,%r14d
  je     L1318
  movzbl %r12b,%r13d
  mov    %r13d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1318
  mov    %r13d,%edi
  call   <tolower@plt>
  mov    %eax,%r12d
L1318:
  lea    0x1(%rbx),%r15
  movzbl (%rbx),%ebx
  jmp    L1271
L689:
  lea    0x3(%rax),%rbx
  movzbl 0x2(%rax),%r12d
  jmp    L934
L52:
  mov    %ebp,%r12d
  jmp    L1271
L1434:
  cmp    $0x5d,%bl
  je     L765
  test   %bl,%bl
  je     L186
  movzbl 0x3d(%rsp),%ecx
  jmp    L589
L365:
  cmpb   $0x0,0x3f(%rsp)
  jne    L471
  mov    $0x1,%eax
  jmp    L951
L827:
  cmp    $0x5d,%al
  je     L356
  test   %al,%al
  je     L675
L1566:
  mov    %rdx,%r15
L589:
  lea    0x1(%r15),%rdx
  movzbl (%r15),%eax
  cmp    $0x5c,%al
  jne    L827
  test   %cl,%cl
  je     L827
  cmpb   $0x0,0x1(%r15)
  je     L941
  lea    0x2(%r15),%rdx
  jmp    L1566
L356:
  mov    %rdx,%r15
L765:
  cmpb   $0x0,0x3f(%rsp)
  je     L471
  mov    $0x1,%eax
  jmp    L951
L1539:
  mov    %rbx,%r15
  jmp    L471
L343:
  mov    0x18(%rsp),%r13
L262:
  movzbl 0x0(%r13),%edx
  mov    $0x0,%eax
  test   %dl,%dl
  je     L951
  mov    0x28(%rsp),%eax
  shr    $0x3,%eax
  cmp    $0x2f,%dl
  sete   %dl
  and    %edx,%eax
  xor    $0x1,%eax
  movzbl %al,%eax
  jmp    L951
L1302:
  mov    0x30(%rsp),%r13
  jmp    L262
L1428:
  mov    $0x1,%eax
  jmp    L951
L145:
  mov    $0x1,%eax
  jmp    L951
L1405:
  mov    $0x1,%eax
  jmp    L951
L120:
  mov    $0x1,%eax
  jmp    L951
L1263:
  mov    $0x1,%eax
  jmp    L951
L617:
  mov    $0x1,%eax
L951:
  add    $0x48,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L131:
  mov    $0x0,%eax
  jmp    L951
L1323:
  mov    $0x0,%eax
  jmp    L951
L33:
  mov    $0x1,%eax
  jmp    L951
L913:
  mov    $0x1,%eax
  jmp    L951
L1223:
  mov    $0x1,%eax
  jmp    L951
L626:
  mov    $0x1,%eax
  jmp    L951
L1071:
  mov    $0x1,%eax
  jmp    L951
L967:
  mov    $0x1,%eax
  jmp    L951
L186:
  mov    $0x1,%eax
  jmp    L951
L675:
  mov    $0x1,%eax
  jmp    L951
L941:
  mov    $0x1,%eax
  jmp    L951
L144:
  mov    $0x1,%eax
  jmp    L951
L747:
  mov    $0x1,%eax
  jmp    L951
L1384:
  mov    $0x1,%eax
  jmp    L951
L2:
  test   %bl,%bl
  je     L1384
L301:
  movzbl (%r15),%edx
  mov    %r15,%rax
  lea    0x1(%r15),%r15
  mov    %ebx,%ebp
  mov    %edx,%ebx
L1110:
  cmpb   $0x0,0x8(%rsp)
  je     L1409
  cmp    $0x2f,%bl
  je     L1071
L1409:
  mov    %ebp,%r12d
  cmp    $0x2d,%bl
  je     L724
L1271:
  test   %r14d,%r14d
  je     L423
  mov    0x20(%rsp),%r13d
  mov    %r13d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L27
  mov    %r13d,%edi
  call   <tolower@plt>
  movsbl %bpl,%ebp
  cmp    %eax,%ebp
  jg     L600
  mov    0x20(%rsp),%ebp
L488:
  mov    %ebp,%edi
  call   <tolower@plt>
  jmp    L829
L132:
  cmp    $0x5c,%bpl
  jne    L1363
  cmpl   $0x0,0x38(%rsp)
  je     L85
  mov    %rbx,%r15
  jmp    L371
L433:
  cmp    $0x5b,%bpl
  je     L241
  jg     L211
  cmp    $0x2a,%bpl
  je     L1215
  cmp    $0x3f,%bpl
  jne    L89
L1158:
  mov    0x18(%rsp),%rax
  movzbl (%rax),%edx
  test   %dl,%dl
  je     L1428
  mov    0x2c(%rsp),%ecx
  mov    %ecx,%eax
  test   %ecx,%ecx
  je     L948
  cmp    $0x2f,%dl
  je     L145
L948:
  cmpb   $0x0,0x3e(%rsp)
  je     L1493
  cmp    $0x2e,%dl
  je     L1299
L1493:
  mov    %rbx,%r15
  jmp    L471
L211:
  cmp    $0x5c,%bpl
  jne    L89
  cmpl   $0x0,0x38(%rsp)
  jne    L416
L85:
  lea    0x2(%r15),%rbx
  movzbl 0x1(%r15),%ebp
  test   %bpl,%bpl
  je     L120
  test   %r14d,%r14d
  je     L428
  movzbl %bpl,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1192
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%ebp
L1192:
  mov    %rbx,%r15
L371:
  mov    0x18(%rsp),%rax
  movzbl (%rax),%ebx
  mov    %ebx,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L125
  mov    %ebx,%edi
  call   <tolower@plt>
  jmp    L372
L89:
  movsbl %bpl,%ebp
L947:
  mov    0x18(%rsp),%rax
  movsbl (%rax),%eax
L685:
  cmp    %ebp,%eax
  jne    L144
  mov    %rbx,%r15
L471:
  addq   $0x1,0x18(%rsp)
  lea    0x1(%r15),%rbx
  movzbl (%r15),%ebp
  test   %bpl,%bpl
  je     L343
L1126:
  test   %r14d,%r14d
  je     L433
  movzbl %bpl,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1447
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%ebp
L1447:
  cmp    $0x5b,%bpl
  je     L241
  jg     L132
  cmp    $0x2a,%bpl
  je     L1215
  cmp    $0x3f,%bpl
  je     L1158
L1363:
  movsbl %bpl,%ebp
  mov    0x18(%rsp),%rax
  movzbl (%rax),%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L947
  mov    %r12d,%edi
  call   <tolower@plt>
  jmp    L685
L416:
  mov    %rbx,%r15
L125:
  mov    0x18(%rsp),%rax
  movsbl (%rax),%eax
L372:
  movsbl %bpl,%ebp
  cmp    %eax,%ebp
  je     L471
  mov    $0x1,%eax
  jmp    L951
L27:
  cmp    %bpl,0x14(%rsp)
  jl     L600
  mov    0x20(%rsp),%edi
  mov    %edi,%ebp
  call   <isupper@plt>
  test   %eax,%eax
  je     L437
  jmp    L488
L423:
  cmp    %bpl,0x14(%rsp)
  jl     L600
L437:
  mov    0x24(%rsp),%eax
L829:
  movsbl %r12b,%r12d
  cmp    %eax,%r12d
  jge    L1434
L600:
  cmp    $0x5d,%bl
  je     L365
L1390:
  cmp    $0x5c,%bl
  jne    L1269
  cmpb   $0x0,0x3d(%rsp)
  jne    L1052
L1269:
  test   %r14d,%r14d
  je     L2
  mov    %ebx,%ebp
L891:
  movzbl %bpl,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L492
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%ebp
L492:
  test   %bl,%bl
  je     L747
  lea    0x1(%r15),%r13
  movzbl (%r15),%ebx
  movzbl %bl,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  jne    L116
  mov    %r15,%rax
  mov    %r13,%r15
  jmp    L1110
```

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