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

```asm
<sqlite3Fts5UnicodeFold>:
  endbr64
  push   %r13
  xor    %eax,%eax
  push   %r12
  push   %rbp
  mov    %edi,%ebp
  mov    $0x1,%edi
  push   %rbx
  mov    %esi,%ebx
  sub    $0x8,%rsp
  call   <assert@plt>
  cmp    $0x7f,%ebp
  jg     L98
  lea    -0x41(%rbp),%edx
  lea    0x20(%rbp),%eax
  cmp    $0x1a,%edx
  cmovae %ebp,%eax
L67:
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
  nopw   0x0(%rax,%rax,1)
L98:
  cmp    $0xffff,%ebp
  jle    L12
  lea    -0x10400(%rbp),%edx
  lea    0x28(%rbp),%eax
  cmp    $0x28,%edx
  cmovae %ebp,%eax
  add    $0x8,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
  nopw   0x0(%rax,%rax,1)
L12:
  mov    $0x1,%edi
  xor    %eax,%eax
  lea    D12(%rip),%r13
  call   <assert@plt>
  mov    $0x3f1,%edx
  mov    $0xffffffff,%edi
  xor    %ecx,%ecx
  mov    $0xa2,%esi
  mov    $0xa2,%eax
  jmp    L59
  nopl   0x0(%rax,%rax,1)
L49:
  lea    0x1(%rax),%ecx
  mov    %eax,%edi
  cmp    %ecx,%esi
  jl     L30
L17:
  lea    (%rsi,%rcx,1),%eax
  mov    %eax,%edx
  sar    %edx
  movslq %edx,%rdx
  movzwl 0x0(%r13,%rdx,4),%edx
L59:
  sar    %eax
  cmp    %edx,%ebp
  jge    L49
  lea    -0x1(%rax),%esi
  cmp    %ecx,%esi
  jge    L17
L30:
  cmp    $0xffffffff,%edi
  je     L7
  movslq %edi,%r12
  xor    %edi,%edi
  movzwl 0x0(%r13,%r12,4),%eax
  cmp    %ebp,%eax
  setle  %dil
L103:
  xor    %eax,%eax
  call   <assert@plt>
  movzwl 0x0(%r13,%r12,4),%edx
  movzbl 0x3(%r13,%r12,4),%eax
  add    %edx,%eax
  cmp    %ebp,%eax
  jle    L14
  movzbl 0x2(%r13,%r12,4),%eax
  xor    %ebp,%edx
  mov    %eax,%ecx
  and    $0x1,%ecx
  test   %edx,%ecx
  je     L69
L14:
  mov    %ebp,%eax
  test   %ebx,%ebx
  je     L67
  xor    %esi,%esi
  cmp    $0x2,%ebx
  mov    %ebp,%edi
  sete   %sil
  add    $0x8,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  jmp    1070 <fts5_remove_diacritic@plt>
  nopl   0x0(%rax)
L7:
  xor    %edi,%edi
  mov    $0xffffffffffffffff,%r12
  jmp    L103
  nopl   0x0(%rax,%rax,1)
L69:
  shr    %al
  lea    D18(%rip),%rdx
  xor    %edi,%edi
  and    $0x7f,%eax
  add    (%rdx,%rax,2),%bp
  movzwl %bp,%ebp
  test   %ebp,%ebp
  setg   %dil
  xor    %eax,%eax
  call   <assert@plt>
  jmp    L14
```

tool_calls: name: extract_symbolic_data
arguments: data_tag: D12
data_type: string
name: extract_symbolic_data
arguments: data_tag: D18
data_type: string

tool: D12: A

tool: D18: 

assistant: ```c
int sqlite3Fts5UnicodeFold(int c, int eRemoveDiacritic) {
  static const struct TableEntry {
    unsigned short iCode;
    unsigned char flags;
    unsigned char nRange;
  } aEntry[] = {
      {65, 14, 26}, {181, 64, 1}, {192, 14, 23}, {216, 14, 7}, {256, 1, 48}, {306, 1, 6}, {313, 1, 16}, {330, 1, 46}, {376, 116, 1}, {377, 1, 6}, {383, 104, 1}, {385, 50, 1}, {386, 1, 4}, {390, 44, 1}, {391, 0, 1}, {393, 42, 2}, {395, 0, 1}, {398, 32, 1}, {399, 38, 1}, {400, 40, 1}, {401, 0, 1}, {403, 42, 1}, {404, 46, 1}, {406, 52, 1}, {407, 48, 1}, {408, 0, 1}, {412, 52, 1}, {413, 54, 1}, {415, 56, 1}, {416, 1, 6}, {422, 60, 1}, {423, 0, 1}, {425, 60, 1}, {428, 0, 1}, {430, 60, 1}, {431, 0, 1}, {433, 58, 2}, {435, 1, 4}, {439, 62, 1}, {440, 0, 1}, {444, 0, 1}, {452, 2, 1}, {453, 0, 1}, {455, 2, 1}, {456, 0, 1}, {458, 2, 1}, {459, 1, 18}, {478, 1, 18}, {497, 2, 1}, {498, 1, 4}, {502, 122, 1}, {503, 134, 1}, {504, 1, 40}, {544, 110, 1}, {546, 1, 18}, {570, 70, 1}, {571, 0, 1}, {573, 108, 1}, {574, 68, 1}, {577, 0, 1}, {579, 106, 1}, {580, 28, 1}, {581, 30, 1}, {582, 1, 10}, {837, 36, 1}, {880, 1, 4}, {886, 0, 1}, {902, 18, 1}, {904, 16, 3}, {908, 26, 1}, {910, 24, 2}, {913, 14, 17}, {931, 14, 9}, {962, 0, 1}, {975, 4, 1}, {976, 140, 1}, {977, 142, 1}, {981, 146, 1}, {982, 144, 1}, {984, 1, 24}, {1008, 136, 1}, {1009, 138, 1}, {1012, 130, 1}, {1013, 128, 1}, {1015, 0, 1}, {1017, 152, 1}, {1018, 0, 1}, {1021, 110, 3}, {1024, 34, 16}, {1040, 14, 32}, {1120, 1, 34}, {1162, 1, 54}, {1216, 6, 1}, {1217, 1, 14}, {1232, 1, 88}, {1329, 22, 38}, {4256, 66, 38}, {4295, 66, 1}, {4301, 66, 1}, {7680, 1, 150}, {7835, 132, 1}, {7838, 96, 1}, {7840, 1, 96}, {7944, 150, 8}, {7960, 150, 6}, {7976, 150, 8}, {7992, 150, 8}, {8008, 150, 6}, {8025, 151, 8}, {8040, 150, 8}, {8072, 150, 8}, {8088, 150, 8}, {8104, 150, 8}, {8120, 150, 2}, {8122, 126, 2}, {8124, 148, 1}, {8126, 100, 1}, {8136, 124, 4}, {8140, 148, 1}, {8152, 150, 2}, {8154, 120, 2}, {8168, 150, 2}, {8170, 118, 2}, {8172, 152, 1}, {8184, 112, 2}, {8186, 114, 2}, {8188, 148, 1}, {8486, 98, 1}, {8490, 92, 1}, {8491, 94, 1}, {8498, 12, 1}, {8544, 8, 16}, {8579, 0, 1}, {9398, 10, 26}, {11264, 22, 47}, {11360, 0, 1}, {11362, 88, 1}, {11363, 102, 1}, {11364, 90, 1}, {11367, 1, 6}, {11373, 84, 1}, {11374, 86, 1}, {11375, 80, 1}, {11376, 82, 1}, {11378, 0, 1}, {11381, 0, 1}, {11390, 78, 2}, {11392, 1, 100}, {11499, 1, 4}, {11506, 0, 1}, {42560, 1, 46}, {42624, 1, 24}, {42786, 1, 14}, {42802, 1, 62}, {42873, 1, 4}, {42877, 76, 1}, {42878, 1, 10}, {42891, 0, 1}, {42893, 74, 1}, {42896, 1, 4}, {42912, 1, 10}, {42922, 72, 1}, {65313, 14, 26},
  };
  static const unsigned short aiOff[] = {
      1, 2, 8, 15, 16, 26, 28, 32, 37, 38, 40, 48, 63, 64, 69, 71, 79, 80, 116, 202, 203, 205, 206, 207, 209, 210, 211, 213, 214, 217, 218, 219, 775, 7264, 10792, 10795, 23228, 23256, 30204, 54721, 54753, 54754, 54756, 54787, 54793, 54809, 57153, 57274, 57921, 58019, 58363, 61722, 65268, 65341, 65373, 65406, 65408, 65410, 65415, 65424, 65436, 65439, 65450, 65462, 65472, 65476, 65478, 65480, 65482, 65488, 65506, 65511, 65514, 65521, 65527, 65528, 65529,
  };
  int ret = c;
  assert(sizeof(unsigned short) == 2 && sizeof(unsigned char) == 1);
  if (c < 128) {
    if (c >= 'A' && c <= 'Z')
      ret = c + ('a' - 'A');
  } else if (c < 65536) {
    const struct TableEntry *p;
    int iHi = sizeof(aEntry) / sizeof(aEntry[0]) - 1;
    int iLo = 0;
    int iRes = -1;
    assert(c > aEntry[0].iCode);
    while (iHi >= iLo) {
      int iTest = (iHi + iLo) / 2;
      int cmp = (c - aEntry[iTest].iCode);
      if (cmp >= 0) {
        iRes = iTest;
        iLo = iTest + 1;
      } else {
        iHi = iTest - 1;
      }
    }
    assert(iRes >= 0 && c >= aEntry[iRes].iCode);
    p = &aEntry[iRes];
    if (c < (p->iCode + p->nRange) && 0 == (0x01 & p->flags & (p->iCode ^ c))) {
      ret = (c + (aiOff[p->flags >> 1])) & 0x0000FFFF;
      assert(ret > 0);
    }
    if (eRemoveDiacritic) {
      ret = fts5_remove_diacritic(ret, eRemoveDiacritic == 2);
    }
  } else if (c >= 66560 && c < 66600) {
    ret = c + 40;
  }
  return ret;
}
```