user: Translate the below assembly code into C programming language:

```asm
<decode64>:
  endbr64
  push   %rbp
  mov    %rdi,%r10
  push   %rbx
  sub    $0x18,%rsp
  mov    %fs:0x28,%rax
  mov    %rax,0x8(%rsp)
  xor    %eax,%eax
  movzbl (%rdi),%eax
  cmp    $0x20,%al
  jle    L42
  xor    %r9d,%r9d
  xor    %edi,%edi
  lea    0x4(%rsp),%r11
  cmp    $0x3d,%al
  je     L42
  nopw   0x0(%rax,%rax,1)
L133:
  movslq %edi,%rdx
  mov    %r11,%rcx
  xor    %ebx,%ebx
  add    %r10,%rdx
  mov    %rdx,%rsi
  cmp    $0x3d,%al
  je     L136
L117:
  movsbl %al,%esi
  add    $0x1,%edi
  lea    -0x41(%rsi),%r8d
  cmp    $0x19,%r8d
  ja     L202
  sub    $0x41,%eax
  mov    %al,(%rcx)
L160:
  add    $0x1,%ebx
  add    $0x1,%rdx
  add    $0x1,%rcx
  cmp    $0x4,%ebx
  je     L20
L105:
  movzbl (%rdx),%eax
  mov    %rdx,%rsi
  cmp    $0x3d,%al
  jne    L117
L136:
  movzbl 0x5(%rsp),%eax
  movsbl 0x4(%rsp),%ecx
  movslq %r9d,%rbp
  lea    0x1(%r9),%r8d
  mov    %eax,%edx
  shl    $0x2,%ecx
  sar    $0x4,%dl
  or     %ecx,%edx
  mov    %dl,(%r10,%rbp,1)
  cmp    $0x3,%ebx
  je     L18
  mov    %r8d,%r9d
L110:
  movzbl (%rsi),%eax
  cmp    $0x20,%al
  jle    L73
  cmp    $0x3d,%al
  jne    L133
L73:
  movslq %r9d,%rax
  add    %rax,%r10
L125:
  movb   $0x0,(%r10)
  mov    0x8(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L79
  add    $0x18,%rsp
  mov    %r9d,%eax
  pop    %rbx
  pop    %rbp
  ret
  nopw   0x0(%rax,%rax,1)
L202:
  lea    -0x61(%rsi),%r8d
  cmp    $0x19,%r8d
  ja     L44
  sub    $0x47,%eax
  add    $0x1,%ebx
  add    $0x1,%rdx
  add    $0x1,%rcx
  mov    %al,-0x1(%rcx)
  cmp    $0x4,%ebx
  jne    L105
L20:
  movzbl 0x5(%rsp),%edx
  movsbl 0x4(%rsp),%ecx
  movslq %r9d,%rsi
  mov    %edx,%eax
  shl    $0x2,%ecx
  sar    $0x4,%al
  shl    $0x4,%edx
  or     %ecx,%eax
  lea    0x2(%r9),%ecx
  mov    %al,(%r10,%rsi,1)
  movzbl 0x6(%rsp),%eax
  lea    0x1(%r9),%esi
  add    $0x3,%r9d
  movslq %esi,%rsi
  mov    %eax,%r8d
  shl    $0x6,%eax
  or     0x7(%rsp),%al
  sar    $0x2,%r8b
  or     %r8d,%edx
  mov    %dl,(%r10,%rsi,1)
  movslq %ecx,%rdx
  movslq %edi,%rsi
  mov    %al,(%r10,%rdx,1)
  add    %r10,%rsi
  jmp    L110
  nopl   (%rax)
L44:
  lea    -0x30(%rsi),%r8d
  cmp    $0x9,%r8d
  ja     L138
  add    $0x4,%eax
  mov    %al,(%rcx)
  jmp    L160
  nopl   0x0(%rax)
L138:
  cmp    $0x2b,%esi
  je     L131
  cmp    $0x2f,%esi
  jne    L160
  movb   $0x3f,(%rcx)
  jmp    L160
L18:
  movzbl 0x6(%rsp),%edx
  shl    $0x4,%eax
  movslq %r8d,%r8
  add    $0x2,%r9d
  sar    $0x2,%dl
  or     %edx,%eax
  mov    %al,(%r10,%r8,1)
  jmp    L110
  nopl   0x0(%rax,%rax,1)
L131:
  movb   $0x3e,(%rcx)
  jmp    L160
L42:
  xor    %r9d,%r9d
  jmp    L125
L79:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int decode64(char *buffer) {
  int car;
  char valcar[4];
  int i;
  int posorig;
  int posdest;
  posorig = 0;
  posdest = 0;
  while (buffer[posorig] > ' ' && buffer[posorig] != '=') {
    for (i = 0; i < 4 && buffer[posorig] != '='; i++) {
      car = buffer[posorig++];
      if ('A' <= car && car <= 'Z')
        valcar[i] = car - 'A';
      else if ('a' <= car && car <= 'z')
        valcar[i] = car + 26 - 'a';
      else if ('0' <= car && car <= '9')
        valcar[i] = car + 52 - '0';
      else if (car == '+')
        valcar[i] = 62;
      else if (car == '/')
        valcar[i] = 63;
    }
    buffer[posdest++] = (valcar[0] << 2) | (valcar[1] >> 4);
    if (i > 2) {
      buffer[posdest++] = (valcar[1] << 4) | (valcar[2] >> 2);
      if (i > 3)
        buffer[posdest++] = (valcar[2] << 6) | (valcar[3]);
    }
  }
  buffer[posdest] = '\0';
  return (posdest);
}
```