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

```asm
<libc_double_to_string>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  movsd  %xmm0,-0x48(%rbp)
  mov    %rdi,-0x50(%rbp)
  mov    %esi,-0x54(%rbp)
  mov    %edx,-0x58(%rbp)
  lea    -0x48(%rbp),%rax
  mov    %rax,-0x20(%rbp)
  movq   $0x0,-0x38(%rbp)
  movq   $0x0,-0x30(%rbp)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%rax
  shr    $0x3f,%rax
  mov    %rax,-0x18(%rbp)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%rax
  shr    $0x34,%rax
  and    $0x7ff,%eax
  mov    %rax,-0x28(%rbp)
  mov    -0x20(%rbp),%rax
  mov    (%rax),%rax
  movabs $0xfffffffffffff,%rdx
  and    %rdx,%rax
  mov    %rax,-0x10(%rbp)
  movl   $0x0,-0x3c(%rbp)
  jmp    L66
L39:
  mov    $0x34,%eax
  sub    -0x3c(%rbp),%eax
  mov    -0x10(%rbp),%rdx
  mov    %eax,%ecx
  shr    %cl,%rdx
  mov    %rdx,%rax
  and    $0x1,%eax
  test   %rax,%rax
  je     L64
  mov    $0x31,%edi
  call   <putchar@plt>
  jmp    L133
L64:
  mov    $0x30,%edi
  call   <putchar@plt>
L133:
  addl   $0x1,-0x3c(%rbp)
L66:
  cmpl   $0x33,-0x3c(%rbp)
  jle    L39
  cmpq   $0xff,-0x28(%rbp)
  jne    L228
  cmpq   $0x0,-0x10(%rbp)
  jne    L228
  cmpq   $0x0,-0x18(%rbp)
  je     L114
  mov    -0x54(%rbp),%edx
  mov    -0x50(%rbp),%rax
  lea    D16(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
  jmp    L214
L114:
  mov    -0x54(%rbp),%edx
  mov    -0x50(%rbp),%rax
  lea    D29(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
  jmp    L214
L228:
  cmpq   $0xff,-0x28(%rbp)
  jne    L196
  cmpq   $0x0,-0x10(%rbp)
  je     L196
  mov    -0x54(%rbp),%edx
  mov    -0x50(%rbp),%rax
  lea    D12(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <strncpy@plt>
  jmp    L214
L196:
  subq   $0x3ff,-0x28(%rbp)
  movabs $0x10000000000000,%rax
  or     %rax,-0x10(%rbp)
  movl   $0x34,-0x3c(%rbp)
  jmp    L164
L207:
  mov    -0x3c(%rbp),%eax
  mov    -0x10(%rbp),%rdx
  mov    %eax,%ecx
  shr    %cl,%rdx
  mov    %rdx,%rax
  and    $0x1,%eax
  test   %rax,%rax
  je     L28
  cmpq   $0x0,-0x28(%rbp)
  js     L54
  mov    -0x28(%rbp),%rax
  mov    $0x1,%edx
  mov    %eax,%ecx
  shl    %cl,%rdx
  mov    %rdx,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  add    %rax,-0x38(%rbp)
  jmp    L28
L54:
  movabs $0x4563918244f40000,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x28(%rbp),%rax
  not    %eax
  mov    %eax,%ecx
  shrq   %cl,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  add    %rax,-0x30(%rbp)
L28:
  subq   $0x1,-0x28(%rbp)
  subl   $0x1,-0x3c(%rbp)
L164:
  cmpl   $0x0,-0x3c(%rbp)
  jns    L207
  cmpq   $0x0,-0x18(%rbp)
  je     L52
  cmpl   $0x0,-0x54(%rbp)
  jle    L52
  mov    -0x50(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x50(%rbp)
  movb   $0x2d,(%rax)
  subl   $0x1,-0x54(%rbp)
L52:
  mov    -0x54(%rbp),%edx
  mov    -0x50(%rbp),%rsi
  mov    -0x38(%rbp),%rax
  mov    $0x0,%ecx
  mov    %rax,%rdi
  call   <libc_ulltoa@plt>
  mov    %eax,-0x3c(%rbp)
  mov    -0x3c(%rbp),%eax
  add    $0x1,%eax
  sub    %eax,-0x54(%rbp)
  mov    -0x3c(%rbp),%eax
  cltq
  add    %rax,-0x50(%rbp)
  mov    -0x54(%rbp),%eax
  mov    %eax,%esi
  lea    D15(%rip),%rax
  mov    %rax,%rdi
  call   <dprintf@plt>
  cmpl   $0x0,-0x54(%rbp)
  jle    L214
  mov    -0x50(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x50(%rbp)
  movb   $0x2e,(%rax)
  cmpl   $0x0,-0x54(%rbp)
  jle    L214
  mov    -0x58(%rbp),%eax
  cmp    -0x54(%rbp),%eax
  jge    L103
  mov    -0x58(%rbp),%eax
  add    $0x1,%eax
  jmp    L130
L103:
  mov    -0x54(%rbp),%eax
L130:
  mov    -0x50(%rbp),%rsi
  mov    -0x30(%rbp),%rdi
  mov    $0x1,%ecx
  mov    %eax,%edx
  call   <libc_ulltoa@plt>
  jmp    L214
L214:
  nop
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: tag: D16
data_type: string
name: retrieve_data
arguments: tag: D29
data_type: string
name: retrieve_data
arguments: tag: D12
data_type: string
name: retrieve_data
arguments: tag: D15
data_type: string

tool: D16: -inf

tool: D29: inf

tool: D12: nan

tool: D15: N = %d


assistant: ```c
void libc_double_to_string(double fl, char *dst, int n, int prec) {
  unsigned long long *p = (unsigned long long *)&fl;
  unsigned long long i = 0;
  unsigned long long f = 0;
  unsigned long long m, s;
  long long e;
  int x;
  unsigned long long z;
  s = *p >> 63;
  e = (*p >> 52) & 0x7ff;
  m = *p & 0xfffffffffffff;
  for (x = 0; x < 52; x++)
    if (m & ((unsigned long long)1 << (52 - x)))
      putchar('1');
    else
      putchar('0');
  if (e == 255 && m == 0) {
    if (s)
      strncpy(dst, "-inf", n);
    else
      strncpy(dst, "inf", n);
  } else if (e == 255 && m != 0) {
    strncpy(dst, "nan", n);
  } else {
    e -= 1023;
    m |= (unsigned long long)1 << 52;
    for (x = 52; x >= 0; x--) {
      if (m & ((unsigned long long)1 << x)) {
        if (e >= 0) {
          z = (long long)1 << e;
          i += z;
        } else {
          z = 5000000000000000000;
          z >>= -(e + 1);
          f += z;
        }
      }
      e--;
    }
    if (s && (n > 0)) {
      *(dst++) = '-';
      n--;
    }
    x = libc_ulltoa(i, dst, n, 0);
    n -= x + 1;
    dst += x;
    dprintf("N = %d\n", n);
    if (n > 0) {
      *(dst++) = '.';
      if (n > 0)
        libc_ulltoa(f, dst, (n < (prec + 1)) ? n : (prec + 1), 1);
    }
  }
}
```