user: What is the c source code of the assembly code below?

```asm
<decode_args>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x58,%rsp
  mov    %edi,%r13d
  mov    %esi,%edi
  mov    %esi,0x1c(%rsp)
  mov    %rcx,%rsi
  mov    %r8,0x8(%rsp)
  movzbl (%rdx),%eax
  test   %al,%al
  je     L353
  mov    %rdx,%rbp
  mov    %r13d,%edx
  shr    $0x8,%edx
  mov    %edx,%ecx
  and    $0x7f,%ecx
  mov    %ecx,0x34(%rsp)
  mov    %edx,%ebx
  and    $0x20,%ebx
  mov    %ebx,0x44(%rsp)
  or     $0x20,%ecx
  mov    %ecx,0x48(%rsp)
  and    $0x5f,%edx
  mov    %edx,0x4c(%rsp)
  mov    %r13d,%edx
  shr    $0x10,%edx
  mov    %edx,%ecx
  and    $0x7f,%ecx
  mov    %ecx,0x38(%rsp)
  mov    %edx,%ebx
  and    $0x1f,%ebx
  mov    %ebx,0x10(%rsp)
  mov    %r13d,%edx
  shr    $0x15,%edx
  and    $0x1f,%edx
  mov    %edx,0x4(%rsp)
  mov    %r13d,%r15d
  shr    $0xb,%r15d
  and    $0x1f,%r15d
  lea    0x1(%r15),%ecx
  mov    %ecx,0x24(%rsp)
  lea    0x0(,%r13,4),%edx
  and    $0xffffffc,%edx
  and    $0xf0000000,%edi
  or     %edi,%edx
  mov    %edx,0x20(%rsp)
  mov    %r13d,%edx
  shr    $0x6,%edx
  mov    %edx,%edi
  and    $0xfffff,%edi
  mov    %edi,0x18(%rsp)
  and    $0x1f,%edx
  mov    %edx,0x14(%rsp)
  mov    %r13d,%edx
  shr    $0x12,%edx
  and    $0x7,%edx
  mov    %edx,0x28(%rsp)
  mov    %r13d,%edx
  shl    $0x5,%edx
  and    $0x60,%edx
  or     %ebx,%edx
  mov    %edx,0x3c(%rsp)
  movl   $0x0,0x30(%rsp)
  mov    $0x0,%ebx
  lea    D9(%rip),%r14
  mov    %r13d,%edx
  and    $0xfffffffc,%edx
  movswl %dx,%edi
  mov    %edi,0x2c(%rsp)
  mov    %r13d,%ecx
  and    $0x7f,%ecx
  mov    %ecx,0x40(%rsp)
  jmp    L100
L70:
  lea    0x1(%rbx),%r12d
  movslq %r12d,%rax
  cmpb   $0x7a,0x0(%rbp,%rax,1)
  ja     L245
  movzbl 0x0(%rbp,%rax,1),%edx
  movslq (%r14,%rdx,4),%rdx
  add    %r14,%rdx
  notrack jmp *%rdx
  movl   $0x1,0x30(%rsp)
  jmp    L245
  mov    %r15d,%edi
  call   <print_cpureg@plt>
  mov    %rax,%rsi
L245:
  lea    0x1(%r12),%ebx
L293:
  movslq %ebx,%rax
  movzbl 0x0(%rbp,%rax,1),%eax
  test   %al,%al
  je     L353
L100:
  cmp    $0x25,%al
  je     L70
  add    $0x1,%ebx
  mov    %al,(%rsi)
  lea    0x1(%rsi),%rsi
  jmp    L293
  mov    0x10(%rsp),%edi
  call   <print_cpureg@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x4(%rsp),%edi
  call   <print_cpureg@plt>
  mov    %rax,%rsi
  jmp    L245
  movswl %r13w,%edi
  call   <print_imm@plt>
  mov    %rax,%rsi
  jmp    L245
  movzwl %r13w,%edi
  call   <print_hex@plt>
  mov    %rax,%rsi
  jmp    L245
  movswl %r13w,%edi
  mov    0x8(%rsp),%rcx
  mov    %rsi,%rdx
  mov    0x4(%rsp),%esi
  call   <print_ofs@plt>
  mov    %rax,%rsi
  jmp    L245
  movswl %r13w,%edi
  mov    %rsi,%rdx
  mov    0x1c(%rsp),%esi
  call   <print_pcofs@plt>
  mov    %rax,%rsi
  jmp    L245
  movswl %r13w,%edi
  mov    0x8(%rsp),%rcx
  mov    %rsi,%rdx
  mov    0x4(%rsp),%esi
  call   <print_ofs@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x20(%rsp),%edi
  call   <print_jump@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x8(%rsp),%rdx
  mov    0x4(%rsp),%edi
  call   <print_jumpr@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x14(%rsp),%edi
  call   <print_int@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    %r15d,%edi
  call   <print_cop0@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    %r15d,%edi
  call   <print_cop1@plt>
  mov    %rax,%rsi
  jmp    L245
  lea    0x1(%rsi),%rax
  movb   $0x24,(%rsi)
  mov    %rax,%rsi
  mov    %r15d,%edi
  call   <print_int@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x10(%rsp),%edi
  call   <print_hex@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x14(%rsp),%edi
  call   <print_fpureg@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x10(%rsp),%edi
  call   <print_fpureg@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    %r15d,%edi
  call   <print_fpureg@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    %r15d,%edi
  call   <print_debugreg@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x24(%rsp),%edi
  call   <print_int@plt>
  mov    %rax,%rsi
  jmp    L245
  movzbl 0x1(%rbp,%rax,1),%eax
  test   %al,%al
  je     L245
  movsbl %al,%eax
  mov    %rsi,%rdx
  mov    %eax,%esi
  mov    0x38(%rsp),%edi
  call   <print_vfpureg@plt>
  mov    %rax,%rsi
  lea    0x2(%rbx),%r12d
  jmp    L245
  movzbl 0x1(%rbp,%rax,1),%eax
  test   %al,%al
  je     L245
  mov    0x34(%rsp),%edi
  cmpl   $0x0,0x30(%rsp)
  je     L243
  cmpl   $0x0,0x44(%rsp)
  mov    0x4c(%rsp),%edi
  cmove  0x48(%rsp),%edi
L243:
  movsbl %al,%eax
  mov    %rsi,%rdx
  mov    %eax,%esi
  call   <print_vfpureg@plt>
  mov    %rax,%rsi
  lea    0x2(%rbx),%r12d
  jmp    L245
  movzbl 0x1(%rbp,%rax,1),%eax
  test   %al,%al
  je     L245
  movsbl %al,%eax
  mov    %rsi,%rdx
  mov    %eax,%esi
  mov    0x40(%rsp),%edi
  call   <print_vfpureg@plt>
  mov    %rax,%rsi
  lea    0x2(%rbx),%r12d
  jmp    L245
  movzbl 0x1(%rbp,%rax,1),%eax
  test   %al,%al
  je     L245
  movsbl %al,%eax
  mov    %rsi,%rdx
  mov    %eax,%esi
  mov    0x3c(%rsp),%edi
  call   <print_vfpureg@plt>
  mov    %rax,%rsi
  lea    0x2(%rbx),%r12d
  jmp    L245
  mov    0x28(%rsp),%edi
  call   <print_imm@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x18(%rsp),%edi
  call   <print_hex@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x18(%rsp),%edi
  call   <print_syscall@plt>
  mov    %rax,%rsi
  jmp    L245
  mov    0x8(%rsp),%rcx
  mov    %rsi,%rdx
  mov    0x4(%rsp),%esi
  mov    0x2c(%rsp),%edi
  call   <print_ofs@plt>
  mov    %rax,%rsi
  jmp    L245
L353:
  movb   $0x0,(%rsi)
  add    $0x58,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

assistant: ```c
void decode_args(unsigned int opcode, unsigned int PC, const char *fmt, char *output, unsigned int *realregs) {
  int i = 0;
  int vmmul = 0;
  while (fmt[i]) {
    if (fmt[i] == '%') {
      i++;
      switch (fmt[i]) {
      case 'd':
        output = print_cpureg(((opcode >> 11) & 0x1F), output);
        break;
      case 't':
        output = print_cpureg(((opcode >> 16) & 0x1F), output);
        break;
      case 's':
        output = print_cpureg(((opcode >> 21) & 0x1F), output);
        break;
      case 'i':
        output = print_imm(((signed short)(opcode & 0xFFFF)), output);
        break;
      case 'I':
        output = print_hex(((unsigned short)(opcode & 0xFFFF)), output);
        break;
      case 'o':
        output = print_ofs(((signed short)(opcode & 0xFFFF)), ((opcode >> 21) & 0x1F), output, realregs);
        break;
      case 'O':
        output = print_pcofs(((signed short)(opcode & 0xFFFF)), PC, output);
        break;
      case 'V':
        output = print_ofs(((signed short)(opcode & 0xFFFF)), ((opcode >> 21) & 0x1F), output, realregs);
        break;
      case 'j':
        output = print_jump(((PC & 0xF0000000) | ((opcode & 0x3FFFFFF) << 2)), output);
        break;
      case 'J':
        output = print_jumpr(((opcode >> 21) & 0x1F), output, realregs);
        break;
      case 'a':
        output = print_int(((opcode >> 6) & 0x1F), output);
        break;
      case '0':
        output = print_cop0(((opcode >> 11) & 0x1F), output);
        break;
      case '1':
        output = print_cop1(((opcode >> 11) & 0x1F), output);
        break;
      case 'p':
        *output++ = '$';
        output = print_int(((opcode >> 11) & 0x1F), output);
        break;
      case 'k':
        output = print_hex(((opcode >> 16) & 0x1F), output);
        break;
      case 'D':
        output = print_fpureg(((opcode >> 6) & 0x1F), output);
        break;
      case 'T':
        output = print_fpureg(((opcode >> 16) & 0x1F), output);
        break;
      case 'S':
        output = print_fpureg(((opcode >> 11) & 0x1F), output);
        break;
      case 'r':
        output = print_debugreg(((opcode >> 11) & 0x1F), output);
        break;
      case 'n':
        output = print_int(((opcode >> 11) & 0x1F) + 1, output);
        break;
      case 'x':
        if (fmt[i + 1]) {
          output = print_vfpureg(((opcode >> 16) & 0x7F), fmt[i + 1], output);
          i++;
        }
        break;
      case 'y':
        if (fmt[i + 1]) {
          int reg = ((opcode >> 8) & 0x7F);
          if (vmmul) {
            if (reg & 0x20) {
              reg &= 0x5F;
            } else {
              reg |= 0x20;
            }
          }
          output = print_vfpureg(reg, fmt[i + 1], output);
          i++;
        }
        break;
      case 'z':
        if (fmt[i + 1]) {
          output = print_vfpureg((opcode & 0x7F), fmt[i + 1], output);
          i++;
        }
        break;
      case 'v':
        break;
      case 'X':
        if (fmt[i + 1]) {
          output = print_vfpureg((((opcode & 3) << 5) | ((opcode >> 16) & 0x1F)), fmt[i + 1], output);
          i++;
        }
        break;
      case 'Z':
        output = print_imm(((opcode >> 18) & 7), output);
        break;
      case 'c':
        output = print_hex(((opcode >> 6) & 0xFFFFF), output);
        break;
      case 'C':
        output = print_syscall(((opcode >> 6) & 0xFFFFF), output);
        break;
      case 'Y':
        output = print_ofs(((signed short)(opcode & 0xFFFF)) & ~3, ((opcode >> 21) & 0x1F), output, realregs);
        break;
      case '?':
        vmmul = 1;
        break;
      case 0:
        goto end;
      default:
        break;
      };
      i++;
    } else {
      *output++ = fmt[i++];
    }
  }
end:
  *output = 0;
}
```