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

```asm
<printi>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x38,%rsp
  mov    %rdi,%rbp
  mov    %esi,%r10d
  mov    %edx,%edi
  mov    %ecx,0x4(%rsp)
  mov    %r8d,0xc(%rsp)
  mov    %r9d,%r12d
  mov    %fs:0x28,%rax
  mov    %rax,0x28(%rsp)
  xor    %eax,%eax
  mov    %esi,%ecx
  mov    %r9d,%eax
  and    $0xfffffffd,%eax
  test   %r8d,%r8d
  cmovns %eax,%r12d
  mov    %r12d,%r14d
  and    $0x4,%r14d
  je     L89
  test   %esi,%esi
  js     L299
  mov    %r12d,%r14d
  and    $0x18,%r14d
  je     L89
  mov    %r12d,%eax
  and    $0x8,%eax
  cmp    $0x1,%eax
  sbb    %eax,%eax
  and    $0xfffffff5,%eax
  add    $0x2b,%eax
  mov    %al,0x1a(%rsp)
  mov    $0x1,%r14d
L89:
  test   %r10d,%r10d
  jne    L6
L151:
  lea    0x1(%r10),%ebx
  movslq %r10d,%r10
  movb   $0x30,0x1c(%rsp,%r10,1)
L252:
  mov    0xc(%rsp),%eax
  cmp    %eax,%ebx
  cmovge %ebx,%eax
  add    %r14d,%eax
  mov    %eax,0x8(%rsp)
  mov    %r12d,%r13d
  and    $0x3,%r13d
  jne    L239
  mov    0x4(%rsp),%r15d
  sub    %eax,%r15d
  test   %r15d,%r15d
  jle    L239
L158:
  mov    %rbp,%rsi
  mov    $0x20,%edi
  call   <putc@plt>
  add    $0x1,%r13d
  cmp    %r15d,%r13d
  jne    L158
L239:
  test   %r14d,%r14d
  jle    L291
  movsbl 0x1a(%rsp),%edi
  mov    %rbp,%rsi
  call   <putc@plt>
  cmp    $0x1,%r14d
  jle    L291
  movsbl 0x1b(%rsp),%edi
  mov    %rbp,%rsi
  call   <putc@plt>
L291:
  test   $0x2,%r12b
  je     L186
  mov    0x4(%rsp),%r14d
  sub    0x8(%rsp),%r14d
  test   %r14d,%r14d
  jle    L186
  mov    $0x0,%r13d
L114:
  mov    %rbp,%rsi
  mov    $0x30,%edi
  call   <putc@plt>
  add    $0x1,%r13d
  cmp    %r14d,%r13d
  jne    L114
L186:
  mov    0xc(%rsp),%r14d
  sub    %ebx,%r14d
  test   %r14d,%r14d
  jle    L246
  mov    $0x0,%r13d
L45:
  mov    %rbp,%rsi
  mov    $0x30,%edi
  call   <putc@plt>
  add    $0x1,%r13d
  cmp    %r14d,%r13d
  jne    L45
L246:
  sub    $0x1,%ebx
  js     L150
  movslq %ebx,%rbx
  lea    0x1c(%rsp),%r13
L163:
  movsbl (%rbx,%r13,1),%edi
  mov    %rbp,%rsi
  call   <putc@plt>
  sub    $0x1,%rbx
  test   %ebx,%ebx
  jns    L163
L150:
  test   $0x1,%r12b
  je     L85
  mov    0x4(%rsp),%r12d
  sub    0x8(%rsp),%r12d
  test   %r12d,%r12d
  jle    L85
  mov    $0x0,%ebx
L287:
  mov    %rbp,%rsi
  mov    $0x20,%edi
  call   <putc@plt>
  add    $0x1,%ebx
  cmp    %r12d,%ebx
  jne    L287
L85:
  mov    0x8(%rsp),%ecx
  mov    0x4(%rsp),%eax
  cmp    %eax,%ecx
  cmovge %ecx,%eax
  mov    0x28(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L68
  add    $0x38,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L299:
  neg    %ecx
  movb   $0x2d,0x1a(%rsp)
  mov    $0x1,%r14d
  test   $0x40,%r12b
  je     L95
  mov    $0x1,%r14d
  jmp    L116
L6:
  test   $0x40,%r12b
  je     L298
L116:
  lea    0x1(%r14),%edx
  movslq %r14d,%rax
  movb   $0x30,0x1a(%rsp,%rax,1)
  mov    %r12d,%eax
  and    $0x80,%eax
  cmp    $0x1,%eax
  sbb    %eax,%eax
  and    $0x20,%eax
  add    $0x58,%eax
  add    $0x2,%r14d
  movslq %edx,%rdx
  mov    %al,0x1a(%rsp,%rdx,1)
L298:
  mov    $0x0,%ebx
  test   %ecx,%ecx
  je     L37
L95:
  mov    %r12d,%eax
  and    $0x80,%eax
  cmp    $0x1,%eax
  sbb    %r9d,%r9d
  and    $0x20,%r9d
  mov    $0x1,%esi
  mov    %edi,%r8d
  add    $0x37,%r9d
  lea    0x1b(%rsp),%r11
  jmp    L156
L81:
  mov    %eax,%ecx
L156:
  mov    %ecx,%eax
  mov    $0x0,%edx
  div    %edi
  lea    0x30(%rdx),%ebx
  lea    (%r9,%rdx,1),%eax
  cmp    $0x9,%edx
  cmovle %ebx,%eax
  mov    %esi,%ebx
  mov    %al,(%r11,%rsi,1)
  mov    %ecx,%eax
  mov    $0x0,%edx
  div    %r8d
  add    $0x1,%rsi
  cmp    %ecx,%edi
  jbe    L81
  test   %r10d,%r10d
  je     L180
L37:
  mov    %ebx,%r10d
  test   $0x20,%r12b
  jne    L151
  jmp    L252
L180:
  mov    %ebx,%r10d
  jmp    L151
L68:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int printi(FILE *fp, int x, int base, int w, int prec, int flag) {
  char buf[12], pbuf[2];
  int i, n, len = 0, plen = 0;
  unsigned u = x;
  if (prec >= 0)
    flag &= ~(1 << 1);
  if (flag & (1 << 2)) {
    if (x < 0) {
      u = -x;
      pbuf[plen++] = '-';
    } else if (flag & ((1 << 3) | (1 << 4))) {
      pbuf[plen++] = flag & (1 << 3) ? '+' : ' ';
    }
  }
  if (x && flag & (1 << 6)) {
    pbuf[plen++] = '0';
    pbuf[plen++] = flag & (1 << 7) ? 'X' : 'x';
  }
  while (u > 0) {
    int t = u % base;
    buf[len++] = (t < 10) ? (t + '0') : (t - 10 + (flag & (1 << 7) ? 'A' : 'a'));
    u /= base;
  }
  if (x == 0 || flag & (1 << 5))
    buf[len++] = '0';
  n = ((len) > (prec) ? (len) : (prec)) + plen;
  if (!(flag & ((1 << 0) | (1 << 1))))
    for (i = 0; i < w - n; ++i)
      putc(' ', fp);
  for (i = 0; i < plen; ++i)
    putc(pbuf[i], fp);
  if (flag & (1 << 1))
    for (i = 0; i < w - n; ++i)
      putc('0', fp);
  for (i = 0; i < prec - len; ++i)
    putc('0', fp);
  for (i = len - 1; i >= 0; --i)
    putc(buf[i], fp);
  if (flag & (1 << 0))
    for (i = 0; i < w - n; ++i)
      putc(' ', fp);
  return ((w) > (n) ? (w) : (n));
}
```