user: 请从给定的汇编指令推导出C源代码:

```asm
<fromuutobits>:
  endbr64
  movsbl (%rsi),%eax
  xor    %r9d,%r9d
  cmp    $0x60,%al
  je     L129
  lea    -0x20(%rax),%r9d
  lea    0x1(%rsi),%rdx
  cmp    $0x2d,%r9d
  ja     L177
  test   %r9d,%r9d
  je     L129
  mov    $0xaaaaaaab,%eax
  lea    0x2(,%r9,4),%ecx
  xor    %esi,%esi
  imul   %rax,%rcx
  shr    $0x21,%rcx
  lea    -0x1(%rcx),%eax
  lea    -0x4(%rcx),%r8d
  and    $0xfffffffc,%eax
  sub    %eax,%r8d
  movzbl (%rdx),%eax
  cmp    $0x60,%al
  je     L71
  sub    $0x20,%eax
  movzbl %al,%r10d
  test   $0xc0,%al
  jne    L119
L102:
  movzbl 0x1(%rdx),%eax
  cmp    $0x60,%al
  je     L151
  sub    $0x20,%eax
  movzbl %al,%r11d
  test   $0xc0,%al
  jne    L119
  shr    $0x4,%al
L133:
  push   %rbp
  push   %rbx
  nopl   0x0(%rax,%rax,1)
L261:
  shl    $0x2,%r10d
  movslq %esi,%rbp
  lea    0x1(%rsi),%ebx
  or     %r10d,%eax
  mov    %al,(%rdi,%rbp,1)
  cmp    $0x2,%ecx
  jle    L226
  movzbl 0x2(%rdx),%eax
  cmp    $0x60,%al
  je     L118
  sub    $0x20,%eax
  movzbl %al,%r10d
  test   $0xc0,%al
  jne    L84
  shr    $0x2,%al
L95:
  shl    $0x4,%r11d
  movslq %ebx,%rbx
  lea    0x2(%rsi),%ebp
  or     %r11d,%eax
  mov    %al,(%rdi,%rbx,1)
  cmp    $0x3,%ecx
  je     L49
  movzbl 0x3(%rdx),%eax
  cmp    $0x60,%al
  je     L83
  sub    $0x20,%eax
  test   $0xc0,%al
  jne    L84
L150:
  shl    $0x6,%r10d
  movslq %ebp,%rbp
  add    $0x3,%esi
  or     %r10d,%eax
  mov    %al,(%rdi,%rbp,1)
L127:
  sub    $0x4,%ecx
  add    $0x4,%rdx
  cmp    %r8d,%ecx
  je     L72
  movzbl (%rdx),%eax
  cmp    $0x60,%al
  je     L163
  sub    $0x20,%eax
  movzbl %al,%r10d
  test   $0xc0,%al
  jne    L84
  movzbl 0x1(%rdx),%eax
  cmp    $0x60,%al
  je     L109
L77:
  sub    $0x20,%eax
  movzbl %al,%r11d
  test   $0xc0,%al
  jne    L84
  shr    $0x4,%al
  jmp    L261
L71:
  xor    %r10d,%r10d
  jmp    L102
  nopl   0x0(%rax)
L177:
  mov    $0xfffffffe,%r9d
L129:
  mov    %r9d,%eax
  ret
  nopw   0x0(%rax,%rax,1)
L226:
  mov    %ebx,%esi
  jmp    L127
  nopl   0x0(%rax)
L163:
  movzbl 0x1(%rdx),%eax
  xor    %r10d,%r10d
  cmp    $0x60,%al
  jne    L77
L109:
  xor    %eax,%eax
  xor    %r11d,%r11d
  jmp    L261
  nopl   (%rax)
L118:
  xor    %eax,%eax
  xor    %r10d,%r10d
  jmp    L95
  nopw   0x0(%rax,%rax,1)
L83:
  xor    %eax,%eax
  jmp    L150
  nopw   0x0(%rax,%rax,1)
L84:
  mov    $0xffffffff,%r9d
  pop    %rbx
  pop    %rbp
  mov    %r9d,%eax
  ret
L72:
  mov    %esi,%ebp
L49:
  cmp    %r9d,%ebp
  mov    $0xfffffffd,%eax
  pop    %rbx
  pop    %rbp
  cmovne %eax,%r9d
  mov    %r9d,%eax
  ret
L151:
  xor    %eax,%eax
  xor    %r11d,%r11d
  jmp    L133
L119:
  or     $0xffffffff,%r9d
  jmp    L129
```

assistant: ```c
int fromuutobits(char *out, const char *in) {
  int len, outlen, inlen;
  register unsigned char digit1, digit2;
  outlen = (in[0] == '`' ? 0 : in[0] - ' ');
  in += 1;
  if (outlen < 0 || outlen > 45)
    return -2;
  if (outlen == 0)
    return 0;
  inlen = (outlen * 4 + 2) / 3;
  len = 0;
  for (; inlen > 0; inlen -= 4) {
    digit1 = (in[0] == '`' ? 0 : in[0] - ' ');
    if ((digit1 & ~63))
      return -1;
    digit2 = (in[1] == '`' ? 0 : in[1] - ' ');
    if ((digit2 & ~63))
      return -1;
    out[len++] = (digit1 << 2) | (digit2 >> 4);
    if (inlen > 2) {
      digit1 = (in[2] == '`' ? 0 : in[2] - ' ');
      if ((digit1 & ~63))
        return -1;
      out[len++] = (digit2 << 4) | (digit1 >> 2);
      if (inlen > 3) {
        digit2 = (in[3] == '`' ? 0 : in[3] - ' ');
        if ((digit2 & ~63))
          return -1;
        out[len++] = (digit1 << 6) | digit2;
      }
    }
    in += 4;
  }
  return len == outlen ? len : -3;
}
```