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

```asm
<UTF2Lat>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  mov    %rdi,%r14
  mov    %rsi,0x8(%rsp)
  mov    %edx,%r13d
  movslq %edx,%r15
  mov    %rdi,%rbp
  mov    %rsi,%rbx
  mov    $0x0,%r12d
  test   %edx,%edx
  jg     L80
L108:
  movb   $0x0,0x0(%rbp)
  mov    %r12d,%eax
L203:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L410:
  movzbl 0x1(%rbx),%eax
  and    $0xffffffc0,%eax
  cmp    $0x80,%al
  je     L464
L38:
  add    $0x1,%rbx
  call   <tolower@plt>
  mov    %al,0x0(%rbp)
L84:
  movzbl 0x0(%rbp),%edi
  test   %dil,%dil
  je     L400
  movzbl %dil,%edi
  call   <filtre@plt>
  test   %rax,%rax
  je     L400
  add    $0x1,%rbp
  mov    %rbx,%r12
  sub    0x8(%rsp),%r12
  lea    0x0(%r13,%r14,1),%eax
  sub    %ebp,%eax
  test   %eax,%eax
  jle    L108
  cmp    %r15,%r12
  jge    L108
L80:
  movzbl (%rbx),%eax
  test   %al,%al
  je     L108
  movzbl %al,%edi
  mov    %eax,%edx
  and    $0xfffffff0,%edx
  cmp    $0xe0,%dl
  je     L410
  and    $0xffffffe0,%eax
  cmp    $0xc0,%al
  jne    L38
  movzbl 0x1(%rbx),%eax
  and    $0xffffffc0,%eax
  cmp    $0x80,%al
  jne    L38
  movb   $0x0,0x0(%rbp)
  movzbl (%rbx),%eax
  add    $0x3e,%eax
  cmp    $0x9,%al
  ja     L391
  movzbl %al,%eax
  lea    D18(%rip),%rcx
  movslq (%rcx,%rax,4),%rax
  add    %rcx,%rax
  notrack jmp *%rax
L464:
  movzbl 0x2(%rbx),%eax
  and    $0xffffffc0,%eax
  cmp    $0x80,%al
  jne    L38
  movb   $0x0,0x0(%rbp)
  cmpb   $0xe2,(%rbx)
  je     L261
L490:
  add    $0x3,%rbx
  jmp    L84
L261:
  movzbl 0x1(%rbx),%eax
  cmp    $0x82,%al
  je     L343
  cmp    $0x84,%al
  je     L366
  cmp    $0x80,%al
  jne    L490
  movzbl 0x2(%rbx),%eax
  add    $0x6d,%eax
  cmp    $0x27,%al
  ja     L490
  movzbl %al,%eax
  lea    D0(%rip),%rsi
  movslq (%rsi,%rax,4),%rax
  add    %rsi,%rax
  notrack jmp *%rax
  movb   $0x96,0x0(%rbp)
  jmp    L490
  movb   $0x97,0x0(%rbp)
  jmp    L490
  movb   $0x91,0x0(%rbp)
  jmp    L490
  movb   $0x27,0x0(%rbp)
  jmp    L490
  movb   $0x82,0x0(%rbp)
  jmp    L490
  movb   $0x93,0x0(%rbp)
  jmp    L490
  movb   $0x94,0x0(%rbp)
  jmp    L490
  movb   $0x84,0x0(%rbp)
  jmp    L490
  movb   $0x86,0x0(%rbp)
  jmp    L490
  movb   $0x87,0x0(%rbp)
  jmp    L490
  movb   $0x95,0x0(%rbp)
  jmp    L490
  movb   $0x85,0x0(%rbp)
  jmp    L490
  movb   $0x89,0x0(%rbp)
  jmp    L490
  movb   $0x8b,0x0(%rbp)
  jmp    L490
  movb   $0x9b,0x0(%rbp)
  jmp    L490
L343:
  cmpb   $0xac,0x2(%rbx)
  jne    L490
  movb   $0x80,0x0(%rbp)
  jmp    L490
L366:
  cmpb   $0xa2,0x2(%rbx)
  jne    L490
  movb   $0x99,0x0(%rbp)
  jmp    L490
  movzbl 0x1(%rbx),%eax
  and    $0x3f,%eax
  or     $0xffffff80,%eax
  cmp    $0xa0,%al
  mov    $0x20,%edx
  cmove  %edx,%eax
  mov    %al,0x0(%rbp)
L391:
  add    $0x2,%rbx
  jmp    L84
  movzbl 0x1(%rbx),%edx
  mov    %edx,%eax
  or     $0xffffffc0,%eax
  cmp    $0xb3,%dl
  mov    $0xffffffa2,%esi
  cmove  %esi,%eax
  mov    %al,0x0(%rbp)
  jmp    L391
  movzbl 0x1(%rbx),%eax
  add    $0x6e,%eax
  cmp    $0x2c,%al
  ja     L391
  movzbl %al,%eax
  lea    D26(%rip),%rsi
  movslq (%rsi,%rax,4),%rax
  add    %rsi,%rax
  notrack jmp *%rax
  movb   $0x8c,0x0(%rbp)
  jmp    L391
  movb   $0x9c,0x0(%rbp)
  jmp    L391
  movb   $0x8a,0x0(%rbp)
  jmp    L391
  movb   $0x9a,0x0(%rbp)
  jmp    L391
  movb   $0x8f,0x0(%rbp)
  jmp    L391
  movb   $0x8e,0x0(%rbp)
  jmp    L391
  movb   $0x9e,0x0(%rbp)
  jmp    L391
  cmpb   $0x92,0x1(%rbx)
  jne    L391
  movb   $0x83,0x0(%rbp)
  jmp    L391
  movzbl 0x1(%rbx),%eax
  cmp    $0x86,%al
  je     L179
  cmp    $0x9c,%al
  jne    L391
  movb   $0x98,0x0(%rbp)
  jmp    L391
L179:
  movb   $0x88,0x0(%rbp)
  jmp    L391
L400:
  movb   $0x0,0x0(%rbp)
  mov    %r12d,%eax
  jmp    L203
```

assistant: ```c
int UTF2Lat(unsigned char *buffer_lower, const unsigned char *buffer, const int buf_len) {
  const unsigned char *p;
  unsigned char *q;
  int i;
  for (i = buf_len, p = buffer, q = buffer_lower; p - buffer < buf_len && i > 0 && *p != '\0';) {
    const unsigned char *p_org = p;
    if ((*p & 0xf0) == 0xe0 && (*(p + 1) & 0xc0) == 0x80 && (*(p + 2) & 0xc0) == 0x80) {
      *q = '\0';
      switch (*p) {
      case 0xE2:
        switch (*(p + 1)) {
        case 0x80:
          switch (*(p + 2)) {
          case 0x93:
            (*q) = 150;
            break;
          case 0x94:
            (*q) = 151;
            break;
          case 0x98:
            (*q) = 145;
            break;
          case 0x99:
            (*q) = '\'';
            break;
          case 0x9A:
            (*q) = 130;
            break;
          case 0x9C:
            (*q) = 147;
            break;
          case 0x9D:
            (*q) = 148;
            break;
          case 0x9E:
            (*q) = 132;
            break;
          case 0xA0:
            (*q) = 134;
            break;
          case 0xA1:
            (*q) = 135;
            break;
          case 0xA2:
            (*q) = 149;
            break;
          case 0xA6:
            (*q) = 133;
            break;
          case 0xB0:
            (*q) = 137;
            break;
          case 0xB9:
            (*q) = 139;
            break;
          case 0xBA:
            (*q) = 155;
            break;
          }
          break;
        case 0x82:
          switch (*(p + 2)) {
          case 0xAC:
            (*q) = 128;
            break;
          }
          break;
        case 0x84:
          switch (*(p + 2)) {
          case 0xA2:
            (*q) = 153;
            break;
          }
          break;
        }
        break;
      }
      p += 3;
    } else if ((*p & 0xe0) == 0xc0 && (*(p + 1) & 0xc0) == 0x80) {
      *q = '\0';
      switch (*p) {
      case 0xC2:
        (*q) = ((*(p + 1)) | 0x80) & 0xBF;
        if ((*q) == 0xA0)
          (*q) = ' ';
        break;
      case 0xC3:
        switch (*(p + 1)) {
        case 0xB3:
          (*q) = 162;
          break;
        default:
          (*q) = (*(p + 1)) | 0xC0;
          break;
        }
        break;
      case 0xC5:
        switch (*(p + 1)) {
        case 0x92:
          (*q) = 140;
          break;
        case 0x93:
          (*q) = 156;
          break;
        case 0xA0:
          (*q) = 138;
          break;
        case 0xA1:
          (*q) = 154;
          break;
        case 0xB8:
          (*q) = 143;
          break;
        case 0xBD:
          (*q) = 142;
          break;
        case 0xBE:
          (*q) = 158;
          break;
        }
        break;
      case 0xC6:
        switch (*(p + 1)) {
        case 0x92:
          (*q) = 131;
          break;
        }
        break;
      case 0xCB:
        switch (*(p + 1)) {
        case 0x86:
          (*q) = 136;
          break;
        case 0x9C:
          (*q) = 152;
          break;
        }
        break;
      }
      p += 2;
    } else {
      *q = tolower(*p++);
    }
    if (*q == '\0' || filtre(*q) == 0) {
      *q = '\0';
      return (p_org - buffer);
    }
    q++;
    i--;
  }
  *q = '\0';
  return (p - buffer);
}
```