user: What is the c source code of the assembly code below:

```asm
<fnmatch>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  movzbl (%rdi),%ebp
  mov    %rsi,0x20(%rsp)
  mov    %edx,0x28(%rsp)
  test   %bpl,%bpl
  je     L96
  mov    %edx,%eax
  mov    %edx,%r12d
  and    $0x2,%edx
  mov    %rsi,0x10(%rsp)
  mov    %edx,0x1c(%rsp)
  mov    %eax,%edx
  shr    $0x2,%eax
  lea    0x1(%rdi),%r14
  and    $0x1,%edx
  and    $0x1,%eax
  and    $0x10,%r12d
  mov    %rdi,%r15
  mov    %edx,0x18(%rsp)
  mov    %al,0x2e(%rsp)
  mov    %dl,0x2d(%rsp)
L615:
  test   %r12d,%r12d
  je     L592
  movzbl %bpl,%r13d
  mov    %r13d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L32
  mov    %r13d,%edi
  call   <tolower@plt>
  mov    %eax,%ebp
L32:
  cmp    $0x5b,%bpl
  je     L617
  jg     L791
  cmp    $0x2a,%bpl
  je     L230
  cmp    $0x3f,%bpl
  jne    L842
L1174:
  mov    0x10(%rsp),%rax
  movzbl (%rax),%eax
  test   %al,%al
  je     L805
  cmp    $0x2f,%al
  jne    L113
  cmpb   $0x0,0x2d(%rsp)
  jne    L805
L113:
  cmpb   $0x0,0x2e(%rsp)
  je     L1363
  cmp    $0x2e,%al
  je     L183
L1363:
  mov    %r14,%r15
L1004:
  movzbl (%r15),%ebp
  addq   $0x1,0x10(%rsp)
  lea    0x1(%r15),%r14
  test   %bpl,%bpl
  jne    L615
  mov    0x10(%rsp),%rbx
L1276:
  movzbl (%rbx),%eax
  movl   $0x0,0x18(%rsp)
  test   %al,%al
  je     L423
  mov    0x28(%rsp),%edx
  shr    $0x3,%edx
  cmp    $0x2f,%al
  sete   %r13b
  and    %edx,%r13d
  xor    $0x1,%r13d
  movzbl %r13b,%eax
  mov    %eax,0x18(%rsp)
  jmp    L423
  nopw   0x0(%rax,%rax,1)
L791:
  cmp    $0x5c,%bpl
  jne    L842
  cmpl   $0x0,0x1c(%rsp)
  jne    L987
  movsbl 0x1(%r15),%r13d
  lea    0x2(%r15),%rbp
  movzbl %r13b,%r14d
  mov    %r14d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1128
  mov    %r14d,%edi
  call   <tolower@plt>
  movsbl %al,%r13d
L1128:
  mov    %rbp,%r15
L355:
  mov    0x10(%rsp),%rax
  movzbl (%rax),%ebp
  mov    %ebp,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1230
  mov    %ebp,%edi
  call   <tolower@plt>
  mov    %eax,%ebp
  jmp    L1230
  nopw   0x0(%rax,%rax,1)
L592:
  cmp    $0x5b,%bpl
  je     L617
  jg     L616
  cmp    $0x2a,%bpl
  je     L230
  cmp    $0x3f,%bpl
  je     L1174
L741:
  mov    0x10(%rsp),%rax
  movsbl %bpl,%ebp
  movzbl (%rax),%r13d
L1207:
  cmp    %ebp,%r13d
  je     L1363
  cs nopw 0x0(%rax,%rax,1)
L805:
  movl   $0x1,0x18(%rsp)
L423:
  mov    0x18(%rsp),%eax
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L616:
  cmp    $0x5c,%bpl
  jne    L741
  mov    0x1c(%rsp),%eax
  test   %eax,%eax
  je     L576
  mov    0x10(%rsp),%rax
  mov    %r14,%r15
  mov    $0x5c,%r13d
  movzbl (%rax),%ebp
L1230:
  cmp    %r13d,%ebp
  je     L1004
  jmp    L805
  xchg   %ax,%ax
L617:
  mov    0x10(%rsp),%rax
  movzbl (%rax),%ebp
  test   %bpl,%bpl
  je     L805
  cmpb   $0x0,0x2e(%rsp)
  je     L964
  cmp    $0x2e,%bpl
  jne    L964
  cmp    %rax,0x20(%rsp)
  je     L805
  mov    0x18(%rsp),%ecx
  test   %ecx,%ecx
  jne    L149
L964:
  movzbl 0x1(%r15),%eax
  lea    0x2(%r15),%rcx
  cmp    $0x21,%al
  sete   %dl
  cmp    $0x5e,%al
  sete   %al
  or     %al,%dl
  mov    %dl,0x2f(%rsp)
  mov    0x1c(%rsp),%edx
  cmovne %rcx,%r14
  test   %edx,%edx
  movzbl (%r14),%r13d
  lea    0x1(%r14),%r15
  sete   0x2c(%rsp)
  jmp    L648
  nop
L304:
  mov    %ebp,%edi
  mov    %cl,0xc(%rsp)
  call   <isupper@plt>
  movzbl 0xc(%rsp),%ecx
  test   %eax,%eax
  je     L318
  mov    %ebp,%edi
  call   <tolower@plt>
  movzbl 0xc(%rsp),%ecx
  cmp    %r14d,%eax
  mov    %eax,%ebx
  jl     L1049
L1338:
  movsbl %cl,%ecx
  cmp    %ebx,%ecx
  jge    L1131
L1049:
  cmp    $0x5d,%r13b
  je     L1327
L648:
  cmp    $0x5c,%r13b
  jne    L176
  cmpb   $0x0,0x2c(%rsp)
  jne    L520
L176:
  test   %r12d,%r12d
  je     L152
  movzbl %r13b,%edi
  mov    %edi,0xc(%rsp)
  call   <isupper@plt>
  test   %eax,%eax
  je     L680
  mov    0xc(%rsp),%edi
L255:
  call   <tolower@plt>
  mov    %r15,%rbx
  movsbl %al,%r14d
L264:
  test   %r13b,%r13b
  je     L805
L1280:
  movzbl (%rbx),%edi
  lea    0x1(%rbx),%r15
  mov    %edi,0xc(%rsp)
  mov    %edi,%r13d
  call   <isupper@plt>
  mov    0xc(%rsp),%edi
  test   %eax,%eax
  je     L1176
  call   <tolower@plt>
  mov    %eax,%r13d
L1176:
  cmp    $0x2f,%r13b
  jne    L233
  cmpb   $0x0,0x2d(%rsp)
  jne    L805
L233:
  mov    %r14d,%ecx
  cmp    $0x2d,%r13b
  je     L1154
L331:
  mov    %ebp,%ebx
  test   %r12d,%r12d
  jne    L304
L318:
  cmp    %r14d,%ebp
  jge    L1338
  cmp    $0x5d,%r13b
  jne    L648
L1327:
  cmpb   $0x0,0x2f(%rsp)
  jne    L1004
  jmp    L805
  nopl   0x0(%rax,%rax,1)
L152:
  test   %r13b,%r13b
  je     L805
L631:
  movzbl (%r15),%eax
  mov    %r15,%rbx
  movsbl %r13b,%r14d
  add    $0x1,%r15
  mov    %eax,%r13d
  jmp    L1176
  nopl   (%rax)
L1154:
  movzbl 0x1(%rbx),%ecx
  cmp    $0x5d,%cl
  je     L131
  lea    0x2(%rbx),%r13
  cmp    $0x5c,%cl
  jne    L619
  cmpb   $0x0,0x2c(%rsp)
  jne    L1014
L619:
  test   %cl,%cl
  je     L805
  test   %r12d,%r12d
  je     L1236
  movzbl %cl,%r15d
  mov    %cl,0xc(%rsp)
  mov    %r15d,%edi
  call   <isupper@plt>
  movzbl 0xc(%rsp),%ecx
  test   %eax,%eax
  je     L1236
  mov    %r15d,%edi
  call   <tolower@plt>
  mov    %eax,%ecx
L1236:
  lea    0x1(%r13),%r15
  movzbl 0x0(%r13),%r13d
  jmp    L331
  nopl   0x0(%rax,%rax,1)
L680:
  mov    %r15,%rbx
  movsbl %r13b,%r14d
  jmp    L264
  nopl   0x0(%rax)
L520:
  movsbl (%r15),%r14d
  lea    0x1(%r15),%rbx
  test   %r12d,%r12d
  jne    L1241
  mov    %r14d,%r13d
  mov    %rbx,%r15
  jmp    L631
L131:
  mov    %r14d,%ecx
  jmp    L331
  nopl   0x0(%rax,%rax,1)
L1241:
  movzbl %r14b,%edi
  mov    %edi,0xc(%rsp)
  call   <isupper@plt>
  mov    0xc(%rsp),%edi
  test   %eax,%eax
  je     L1280
  mov    %rbx,%r15
  jmp    L255
  nopl   0x0(%rax)
L230:
  mov    0x10(%rsp),%rbx
  mov    %r15,%r13
  testb  $0x4,0x28(%rsp)
  jne    L960
L923:
  movzbl 0x1(%r13),%ebp
  lea    0x2(%r13),%r14
  cmp    $0x3f,%bpl
  je     L978
  cmp    $0x2a,%bpl
  jne    L534
L978:
  mov    0x18(%rsp),%edi
  test   %edi,%edi
  jne    L17
  nopl   0x0(%rax,%rax,1)
L394:
  cmp    $0x3f,%bpl
  je     L693
L665:
  movzbl (%r14),%ebp
  add    $0x1,%r14
  add    $0x1,%rbx
  cmp    $0x2a,%bpl
  je     L394
L118:
  cmp    $0x3f,%bpl
  jne    L534
L693:
  cmpb   $0x0,(%rbx)
  jne    L665
  jmp    L805
  nopl   0x0(%rax,%rax,1)
L960:
  cmpb   $0x2e,(%rbx)
  jne    L923
  cmp    %rbx,0x20(%rsp)
  je     L805
  mov    0x18(%rsp),%r8d
  test   %r8d,%r8d
  je     L524
  cmpb   $0x2f,-0x1(%rbx)
  je     L423
  movzbl 0x1(%r15),%ebp
  lea    0x2(%r15),%r14
  cmp    $0x3f,%bpl
  jne    L637
  nopw   0x0(%rax,%rax,1)
L17:
  movzbl (%rbx),%eax
  cmp    $0x2f,%al
  je     L805
  cmp    $0x3f,%bpl
  je     L867
L652:
  movzbl (%r14),%ebp
  add    $0x1,%r14
  add    $0x1,%rbx
  cmp    $0x3f,%bpl
  je     L17
L637:
  cmp    $0x2a,%bpl
  je     L17
L534:
  movl   $0x0,0x18(%rsp)
  test   %bpl,%bpl
  je     L423
  mov    0x1c(%rsp),%esi
  test   %esi,%esi
  jne    L1264
  cmp    $0x5c,%bpl
  je     L942
L1264:
  mov    %ebp,%r13d
L78:
  test   %r12d,%r12d
  je     L1190
  movzbl %r13b,%r15d
  mov    %r15d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  jne    L169
L1190:
  movzbl (%rbx),%eax
  sub    $0x1,%r14
  test   %al,%al
  je     L805
  cmp    $0x5b,%bpl
  je     L141
  test   %r12d,%r12d
  movsbl %r13b,%ebp
  mov    0x28(%rsp),%r12d
  je     L752
  and    $0xfffffffb,%r12d
  jmp    L1376
  nopl   (%rax)
L1095:
  movzbl 0x1(%rbx),%eax
  add    $0x1,%rbx
  test   %al,%al
  je     L805
L1376:
  movzbl %al,%r13d
  mov    %r13d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L661
  mov    %r13d,%edi
  call   <tolower@plt>
  mov    %eax,%r13d
L661:
  cmp    %r13d,%ebp
  jne    L1095
  xor    %eax,%eax
  mov    %r12d,%edx
  mov    %rbx,%rsi
  mov    %r14,%rdi
  call   <fnmatch>
  test   %eax,%eax
  jne    L1095
L986:
  mov    %eax,0x18(%rsp)
  jmp    L423
  nopl   (%rax)
L867:
  test   %al,%al
  jne    L652
  jmp    L805
  nopl   (%rax)
L1014:
  movzbl 0x2(%rbx),%ecx
  lea    0x3(%rbx),%r13
  jmp    L619
  nopl   (%rax)
L842:
  mov    0x10(%rsp),%rax
  movsbl %bpl,%ebp
  movzbl (%rax),%r13d
  mov    %r13d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1207
  mov    %r13d,%edi
  call   <tolower@plt>
  mov    %eax,%r13d
  cmp    %ebp,%r13d
  je     L1363
  jmp    L805
  cs nopw 0x0(%rax,%rax,1)
L576:
  mov    0x10(%rsp),%rax
  movsbl 0x1(%r15),%r13d
  add    $0x2,%r15
  movzbl (%rax),%ebp
  jmp    L1230
  cs nopw 0x0(%rax,%rax,1)
L149:
  cmpb   $0x2f,-0x1(%rax)
  jne    L964
  jmp    L423
  nop
L183:
  mov    0x10(%rsp),%rax
  cmp    %rax,0x20(%rsp)
  je     L805
  mov    0x18(%rsp),%r9d
  test   %r9d,%r9d
  je     L1363
  cmpb   $0x2f,-0x1(%rax)
  jne    L1363
  jmp    L423
  nopl   (%rax)
L1131:
  cmp    $0x5d,%r13b
  je     L192
  test   %r13b,%r13b
  je     L805
  movzbl 0x2c(%rsp),%ecx
  jmp    L1341
  nopw   0x0(%rax,%rax,1)
L60:
  mov    %rdx,%r15
L328:
  cmp    $0x5d,%al
  je     L192
  test   %al,%al
  je     L805
L1341:
  movzbl (%r15),%eax
  lea    0x1(%r15),%rdx
  cmp    $0x5c,%al
  jne    L60
  test   %cl,%cl
  je     L60
L516:
  movzbl 0x2(%r15),%eax
  lea    0x2(%r15),%rdx
  cmp    $0x5c,%al
  je     L1231
  add    $0x3,%r15
  jmp    L328
L752:
  and    $0xfffffffb,%r12d
  jmp    L1380
L178:
  movzbl 0x1(%rbx),%eax
  add    $0x1,%rbx
  test   %al,%al
  je     L805
L1380:
  cmp    %eax,%ebp
  jne    L178
  xor    %eax,%eax
  mov    %r12d,%edx
  mov    %rbx,%rsi
  mov    %r14,%rdi
  call   <fnmatch>
  test   %eax,%eax
  jne    L178
  jmp    L986
L169:
  mov    %r15d,%edi
  call   <tolower@plt>
  mov    %eax,%r13d
  jmp    L1190
L524:
  movzbl 0x1(%r15),%ebp
  lea    0x2(%r15),%r14
  cmp    $0x2a,%bpl
  jne    L118
  jmp    L394
L192:
  cmpb   $0x0,0x2f(%rsp)
  je     L1004
  jmp    L805
  nopl   (%rax)
L141:
  mov    0x28(%rsp),%ebp
  and    $0xfffffffb,%ebp
  jmp    L33
  nopl   0x0(%rax)
L71:
  add    $0x1,%rbx
  cmpb   $0x0,(%rbx)
  je     L805
L33:
  xor    %eax,%eax
  mov    %ebp,%edx
  mov    %rbx,%rsi
  mov    %r14,%rdi
  call   <fnmatch>
  test   %eax,%eax
  jne    L71
  jmp    L986
L942:
  movzbl (%r14),%r13d
  jmp    L78
L96:
  mov    %rsi,%rbx
  jmp    L1276
L1231:
  mov    %rdx,%r15
  jmp    L516
L987:
  mov    %r14,%r15
  mov    $0x5c,%r13d
  jmp    L355
```

assistant: ```c
int fnmatch(pattern, string, flags) 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) : ((unsigned char)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++;
        c = ((flags & (1 << 4)) && (1 && isupper((unsigned char)c)) ? tolower((unsigned char)c) : ((unsigned char)c));
      }
      if (((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*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++, ++n)
        if (((flags & (1 << 0)) && *n == '/') || (c == '?' && *n == '\0'))
          return 1;
      if (c == '\0')
        return 0;
      {
        char c1 = (!(flags & (1 << 1)) && c == '\\') ? *p : c;
        c1 = ((flags & (1 << 4)) && (1 && isupper((unsigned char)c1)) ? tolower((unsigned char)c1) : ((unsigned char)c1));
        for (--p; *n != '\0'; ++n)
          if ((c == '[' || ((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*n)) == c1) && fnmatch(p, n, flags & ~(1 << 2)) == 0)
            return 0;
        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 == '\\')
          cstart = cend = *p++;
        cstart = cend = ((flags & (1 << 4)) && (1 && isupper((unsigned char)cstart)) ? tolower((unsigned char)cstart) : ((unsigned char)cstart));
        if (c == '\0')
          return 1;
        c = *p++;
        c = ((flags & (1 << 4)) && (1 && isupper((unsigned char)c)) ? tolower((unsigned char)c) : ((unsigned char)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) : ((unsigned char)cend));
          c = *p++;
        }
        if (((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*n)) >= cstart && ((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*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 == '\\')
          ++p;
      }
      if (not )
        return 1;
    } break;
    default:
      if (c != ((flags & (1 << 4)) && (1 && isupper((unsigned char)*n)) ? tolower((unsigned char)*n) : ((unsigned char)*n)))
        return 1;
    }
    ++n;
  }
  if (*n == '\0')
    return 0;
  if ((flags & (1 << 3)) && *n == '/')
    return 0;
  return 1;
}
```