user: What would the C source look like for the assembly code provided here:

```asm
<fnmatch>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rsi,0x20(%rsp)
  mov    %edx,0x18(%rsp)
  movzbl (%rdi),%ebp
  test   %bpl,%bpl
  je     L108
  mov    %rdi,%r13
  lea    0x1(%rdi),%rbx
  mov    %rsi,%r14
  mov    %edx,%esi
  mov    %edx,%r15d
  and    $0x10,%r15d
  mov    %edx,%eax
  and    $0x2,%eax
  mov    %eax,0x28(%rsp)
  mov    %edx,%eax
  shr    $0x2,%eax
  and    $0x1,%eax
  mov    %al,0x2e(%rsp)
  mov    %edx,%eax
  shr    %eax
  xor    $0x1,%eax
  and    $0x1,%eax
  mov    %al,0x2d(%rsp)
  mov    %edx,%eax
  and    $0x1,%eax
  mov    %al,(%rsp)
  and    $0x1,%esi
  mov    %esi,0x1c(%rsp)
  mov    %r14,0x10(%rsp)
  jmp    L383
L533:
  mov    0x10(%rsp),%rcx
  cmp    %rcx,0x20(%rsp)
  je     L841
  cmpl   $0x0,0x1c(%rsp)
  je     L453
  cmpb   $0x2f,-0x1(%rcx)
  je     L1158
  mov    %rbx,%r13
  jmp    L1297
L470:
  mov    %rbx,%r13
  mov    $0x5c,%ebp
  jmp    L1114
L146:
  mov    %rbx,%r13
L1114:
  mov    0x10(%rsp),%rax
  movsbl (%rax),%eax
L1019:
  movsbl %bpl,%ebp
  cmp    %eax,%ebp
  jne    L25
L1297:
  addq   $0x1,0x10(%rsp)
  lea    0x1(%r13),%rbx
  movzbl 0x0(%r13),%ebp
  test   %bpl,%bpl
  je     L1221
L383:
  test   %r15d,%r15d
  je     L474
  movsbl %bpl,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L758
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%ebp
L758:
  cmp    $0x5b,%bpl
  je     L432
  jg     L307
  cmp    $0x2a,%bpl
  je     L1177
  cmp    $0x3f,%bpl
  jne    L242
L996:
  mov    0x10(%rsp),%rax
  movzbl (%rax),%edx
  test   %dl,%dl
  je     L1048
  mov    0x1c(%rsp),%ecx
  mov    %ecx,%eax
  test   %ecx,%ecx
  je     L655
  cmp    $0x2f,%dl
  je     L357
L655:
  cmpb   $0x0,0x2e(%rsp)
  je     L41
  cmp    $0x2e,%dl
  je     L533
L41:
  mov    %rbx,%r13
  jmp    L1297
L1177:
  mov    0x10(%rsp),%r14
  testb  $0x4,0x18(%rsp)
  je     L64
  cmpb   $0x2e,(%r14)
  je     L923
L64:
  lea    0x2(%r13),%rbp
  movzbl 0x1(%r13),%ebx
  cmp    $0x3f,%bl
  je     L581
  cmp    $0x2a,%bl
  jne    L799
L581:
  mov    0x18(%rsp),%edx
  and    $0x1,%edx
L991:
  mov    %edx,%eax
  test   %edx,%edx
  je     L1002
  cmpb   $0x2f,(%r14)
  je     L1158
L1002:
  cmp    $0x3f,%bl
  je     L475
L1188:
  add    $0x1,%rbp
  movzbl -0x1(%rbp),%ebx
  add    $0x1,%r14
  cmp    $0x3f,%bl
  je     L991
  cmp    $0x2a,%bl
  je     L991
L799:
  mov    $0x0,%eax
  test   %bl,%bl
  je     L1158
  testb  $0x2,0x18(%rsp)
  jne    L612
  cmp    $0x5c,%bl
  je     L540
L612:
  mov    %ebx,%r13d
L1200:
  test   %r15d,%r15d
  je     L1055
  movsbl %r13b,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1055
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%r13d
L1055:
  lea    -0x1(%rbp),%rax
  mov    %rax,(%rsp)
  movzbl (%r14),%r12d
  test   %r12b,%r12b
  je     L860
  mov    0x18(%rsp),%eax
  and    $0xfffffffb,%eax
  mov    %eax,0x8(%rsp)
  jmp    L1052
L923:
  cmp    %r14,0x20(%rsp)
  je     L622
  mov    0x18(%rsp),%eax
  and    $0x1,%eax
  je     L64
  cmpb   $0x2f,-0x1(%r14)
  jne    L64
  jmp    L1158
L475:
  cmpb   $0x0,(%r14)
  jne    L1188
  mov    $0x1,%eax
  jmp    L1158
L540:
  movzbl 0x0(%rbp),%r13d
  jmp    L1200
L1401:
  movsbl %r12b,%r12d
L578:
  movsbl %r13b,%eax
  cmp    %r12d,%eax
  je     L828
L106:
  add    $0x1,%r14
  movzbl (%r14),%r12d
  test   %r12b,%r12b
  je     L88
L1052:
  cmp    $0x5b,%bl
  je     L828
  test   %r15d,%r15d
  je     L1401
  movsbl %r12b,%ebp
  mov    %ebp,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L1401
  mov    %ebp,%edi
  call   <tolower@plt>
  mov    %eax,%r12d
  jmp    L578
L828:
  mov    0x8(%rsp),%edx
  mov    %r14,%rsi
  mov    (%rsp),%rdi
  mov    $0x0,%eax
  call   <fnmatch>
  test   %eax,%eax
  jne    L106
  jmp    L1158
L88:
  mov    $0x1,%eax
L1158:
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L432:
  mov    0x10(%rsp),%rcx
  movzbl (%rcx),%eax
  mov    %al,0x2c(%rsp)
  test   %al,%al
  je     L1348
  cmpb   $0x0,0x2e(%rsp)
  je     L253
  cmp    $0x2e,%al
  jne    L253
  cmp    %rcx,0x20(%rsp)
  je     L518
  mov    0x1c(%rsp),%esi
  mov    %esi,%eax
  test   %esi,%esi
  je     L253
  cmpb   $0x2f,-0x1(%rcx)
  je     L1158
L253:
  movzbl 0x1(%r13),%eax
  cmp    $0x21,%al
  sete   %dl
  cmp    $0x5e,%al
  sete   %al
  add    $0x2,%r13
  or     %al,%dl
  mov    %dl,0x2f(%rsp)
  cmovne %r13,%rbx
  lea    0x1(%rbx),%r13
  movzbl (%rbx),%ebx
  movsbl 0x2c(%rsp),%r14d
  jmp    L654
L484:
  lea    0x1(%r13),%rax
  movzbl 0x0(%r13),%ebp
  test   %r15d,%r15d
  jne    L1242
  mov    %ebp,%ebx
  mov    %rax,%r13
  jmp    L378
L1242:
  mov    %rax,%r13
L1197:
  movsbl %bpl,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L102
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%ebp
L102:
  test   %bl,%bl
  je     L738
  lea    0x1(%r13),%rax
  mov    %rax,0x8(%rsp)
  movzbl 0x0(%r13),%ebx
  movsbl %bl,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  jne    L1303
  mov    %r13,%rax
  mov    0x8(%rsp),%r13
  jmp    L1193
L1303:
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%ebx
  mov    %r13,%rax
  mov    0x8(%rsp),%r13
  jmp    L1193
L762:
  movzbl 0x1(%rax),%r12d
  cmp    $0x5d,%r12b
  je     L714
  lea    0x2(%rax),%rbx
  cmp    $0x5c,%r12b
  jne    L883
  cmpb   $0x0,0x2d(%rsp)
  jne    L407
L883:
  test   %r12b,%r12b
  je     L1152
  test   %r15d,%r15d
  je     L71
  movsbl %r12b,%r13d
  mov    %r13d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L71
  mov    %r13d,%edi
  call   <tolower@plt>
  mov    %eax,%r12d
L71:
  lea    0x1(%rbx),%r13
  movzbl (%rbx),%ebx
  jmp    L333
L407:
  lea    0x3(%rax),%rbx
  movzbl 0x2(%rax),%r12d
  jmp    L883
L714:
  mov    %ebp,%r12d
  jmp    L333
L328:
  cmp    $0x5d,%bl
  je     L1064
  test   %bl,%bl
  je     L665
  movzbl 0x2d(%rsp),%ecx
  jmp    L1071
L381:
  cmpb   $0x0,0x2f(%rsp)
  jne    L1297
  mov    $0x1,%eax
  jmp    L1158
L405:
  cmp    $0x5d,%al
  je     L1144
  test   %al,%al
  je     L750
L1145:
  mov    %rdx,%r13
L1071:
  lea    0x1(%r13),%rdx
  movzbl 0x0(%r13),%eax
  cmp    $0x5c,%al
  jne    L405
  test   %cl,%cl
  je     L405
  lea    0x2(%r13),%rdx
  jmp    L1145
L1144:
  mov    %rdx,%r13
L1064:
  cmpb   $0x0,0x2f(%rsp)
  je     L1297
  mov    $0x1,%eax
  jmp    L1158
L242:
  movsbl %bpl,%ebp
  mov    0x10(%rsp),%rax
  movsbl (%rax),%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L396
  mov    %r12d,%edi
  call   <tolower@plt>
  jmp    L597
L453:
  mov    %rbx,%r13
  jmp    L1297
L1221:
  mov    0x10(%rsp),%r14
L248:
  movzbl (%r14),%ecx
  mov    $0x0,%eax
  test   %cl,%cl
  je     L1158
  mov    0x18(%rsp),%edx
  shr    $0x3,%edx
  cmp    $0x2f,%cl
  sete   %al
  and    %edx,%eax
  xor    $0x1,%eax
  movzbl %al,%eax
  jmp    L1158
L108:
  mov    0x20(%rsp),%r14
  jmp    L248
L1048:
  mov    $0x1,%eax
  jmp    L1158
L357:
  mov    $0x1,%eax
  jmp    L1158
L841:
  mov    $0x1,%eax
  jmp    L1158
L25:
  mov    $0x1,%eax
  jmp    L1158
L622:
  mov    $0x1,%eax
  jmp    L1158
L860:
  mov    $0x1,%eax
  jmp    L1158
L1348:
  mov    $0x1,%eax
  jmp    L1158
L518:
  mov    $0x1,%eax
  jmp    L1158
L1192:
  mov    $0x1,%eax
  jmp    L1158
L1152:
  mov    $0x1,%eax
  jmp    L1158
L665:
  mov    $0x1,%eax
  jmp    L1158
L750:
  mov    $0x1,%eax
  jmp    L1158
L986:
  mov    $0x1,%eax
  jmp    L1158
L738:
  mov    $0x1,%eax
  jmp    L1158
L287:
  mov    $0x1,%eax
  jmp    L1158
L307:
  cmp    $0x5c,%bpl
  jne    L242
  cmpl   $0x0,0x28(%rsp)
  jne    L206
  lea    0x2(%r13),%rbx
  movzbl 0x1(%r13),%ebp
  movsbl %bpl,%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L601
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %eax,%ebp
  jmp    L601
L474:
  cmp    $0x5b,%bpl
  je     L432
  jg     L815
  cmp    $0x2a,%bpl
  je     L1177
  cmp    $0x3f,%bpl
  je     L996
L29:
  movsbl %bpl,%ebp
L396:
  mov    0x10(%rsp),%rax
  movsbl (%rax),%eax
L597:
  cmp    %ebp,%eax
  jne    L986
  mov    %rbx,%r13
  jmp    L1297
L815:
  cmp    $0x5c,%bpl
  jne    L29
  cmpl   $0x0,0x28(%rsp)
  je     L969
L206:
  test   %r15d,%r15d
  je     L470
  mov    $0x5c,%ebp
L601:
  mov    0x10(%rsp),%rax
  movsbl (%rax),%r12d
  mov    %r12d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L146
  mov    %r12d,%edi
  call   <tolower@plt>
  mov    %rbx,%r13
  jmp    L1019
L969:
  movzbl 0x1(%r13),%ebp
  lea    0x2(%r13),%r13
  jmp    L1114
L1010:
  cmp    %bpl,0x2c(%rsp)
  jl     L48
L805:
  mov    %r14d,%eax
L554:
  movsbl %r12b,%r12d
  cmp    %eax,%r12d
  jge    L328
L48:
  cmp    $0x5d,%bl
  je     L381
L654:
  cmp    $0x5c,%bl
  jne    L1018
  cmpb   $0x0,0x2d(%rsp)
  jne    L484
L1018:
  mov    %ebx,%ebp
  test   %r15d,%r15d
  jne    L1197
  test   %bl,%bl
  je     L287
L378:
  movzbl 0x0(%r13),%edx
  mov    %r13,%rax
  lea    0x1(%r13),%r13
  mov    %ebx,%ebp
  mov    %edx,%ebx
L1193:
  cmpb   $0x0,(%rsp)
  je     L335
  cmp    $0x2f,%bl
  je     L1192
L335:
  mov    %ebp,%r12d
  cmp    $0x2d,%bl
  je     L762
L333:
  test   %r15d,%r15d
  je     L1010
  mov    %r14d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L173
  mov    %r14d,%edi
  call   <tolower@plt>
  movsbl %bpl,%ebp
  cmp    %eax,%ebp
  jg     L48
  mov    %r14d,%ebp
L600:
  mov    %ebp,%edi
  call   <tolower@plt>
  jmp    L554
L173:
  cmp    %bpl,0x2c(%rsp)
  jl     L48
  mov    %r14d,%ebp
  mov    %r14d,%edi
  call   <isupper@plt>
  test   %eax,%eax
  je     L805
  jmp    L600
```

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