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

```asm
<parse_timespec>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  cmpq   $0x0,-0x28(%rbp)
  jne    L105
  mov    D88(%rip),%rax
  jmp    L34
L105:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D107(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L23
  lea    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <parse_npt@plt>
  movq   %xmm0,%rax
  jmp    L34
L23:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D40(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L157
  mov    D32(%rip),%rdx
  lea    -0x20(%rbp),%rax
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <parse_smpte@plt>
  movq   %xmm0,%rax
  jmp    L34
L157:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D1(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L111
  mov    D162(%rip),%rdx
  lea    -0x20(%rbp),%rax
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <parse_smpte@plt>
  movq   %xmm0,%rax
  jmp    L34
L111:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D39(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L56
  mov    D55(%rip),%rdx
  lea    -0x20(%rbp),%rax
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <parse_smpte@plt>
  movq   %xmm0,%rax
  jmp    L34
L56:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D152(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L200
  mov    D138(%rip),%rdx
  lea    -0x20(%rbp),%rax
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <parse_smpte@plt>
  movq   %xmm0,%rax
  jmp    L34
L200:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D66(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L140
  mov    D169(%rip),%rdx
  lea    -0x20(%rbp),%rax
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <parse_smpte@plt>
  movq   %xmm0,%rax
  jmp    L34
L140:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D170(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L98
  mov    D109(%rip),%rdx
  lea    -0x20(%rbp),%rax
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <parse_smpte@plt>
  movq   %xmm0,%rax
  jmp    L34
L98:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D44(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L84
  mov    D29(%rip),%rdx
  lea    -0x20(%rbp),%rax
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <parse_smpte@plt>
  movq   %xmm0,%rax
  jmp    L34
L84:
  lea    -0x20(%rbp),%rdx
  mov    -0x28(%rbp),%rax
  lea    D149(%rip),%rcx
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <sscanf@plt>
  cmp    $0x1,%eax
  jne    L24
  mov    D146(%rip),%rdx
  lea    -0x20(%rbp),%rax
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <parse_smpte@plt>
  movq   %xmm0,%rax
  jmp    L34
L24:
  mov    -0x28(%rbp),%rax
  mov    %rax,%rdi
  call   <parse_npt@plt>
  movq   %xmm0,%rax
L34:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L189
  call   <__stack_chk_fail@plt>
L189:
  movq   %rax,%xmm0
  leave
  ret
```

tool_calls: name: unpack_data
arguments: tag: D88
data_type: byte[8]
name: unpack_data
arguments: tag: D107
data_type: string
name: unpack_data
arguments: tag: D40
data_type: string
name: unpack_data
arguments: tag: D32
data_type: f64
name: unpack_data
arguments: tag: D1
data_type: string
name: unpack_data
arguments: tag: D162
data_type: f64
name: unpack_data
arguments: tag: D39
data_type: string
name: unpack_data
arguments: tag: D55
data_type: f64
name: unpack_data
arguments: tag: D152
data_type: string
name: unpack_data
arguments: tag: D138
data_type: f64
name: unpack_data
arguments: tag: D66
data_type: string
name: unpack_data
arguments: tag: D169
data_type: f64
name: unpack_data
arguments: tag: D170
data_type: string
name: unpack_data
arguments: tag: D109
data_type: f64
name: unpack_data
arguments: tag: D44
data_type: string
name: unpack_data
arguments: tag: D29
data_type: byte[8]
name: unpack_data
arguments: tag: D149
data_type: string
name: unpack_data
arguments: tag: D146
data_type: f64

tool: {"D88": [0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xbf]}

tool: D107: npt:%16s

tool: D40: smpte-24:%16s

tool: D32: 24

tool: D1: smpte-24-drop:%16s

tool: D162: 23.976

tool: D39: smpte-25:%16s

tool: D55: 25

tool: D152: smpte-30:%16s

tool: D138: 30

tool: D66: smpte-30-drop:%16s

tool: D169: 29.97

tool: D170: smpte-50:%16s

tool: D109: 50

tool: D44: smpte-60:%16s

tool: {"D29": [0x00,0x00,0x00,0x00,0x00,0x00,0x4e,0x40]}

tool: D149: smpte-60-drop:%16s

tool: D146: 59.94

assistant: ```c
double parse_timespec(const char *str) {
  char timespec[16];
  if (str == NULL)
    return -1.0;
  if (sscanf(str, "npt:%16s", timespec) == 1) {
    return parse_npt(timespec);
  }
  if (sscanf(str, "smpte-24:%16s", timespec) == 1) {
    return parse_smpte(timespec, 24.0);
  }
  if (sscanf(str, "smpte-24-drop:%16s", timespec) == 1) {
    return parse_smpte(timespec, 23.976);
  }
  if (sscanf(str, "smpte-25:%16s", timespec) == 1) {
    return parse_smpte(timespec, 25.0);
  }
  if (sscanf(str, "smpte-30:%16s", timespec) == 1) {
    return parse_smpte(timespec, 30.0);
  }
  if (sscanf(str, "smpte-30-drop:%16s", timespec) == 1) {
    return parse_smpte(timespec, 29.97);
  }
  if (sscanf(str, "smpte-50:%16s", timespec) == 1) {
    return parse_smpte(timespec, 50.0);
  }
  if (sscanf(str, "smpte-60:%16s", timespec) == 1) {
    return parse_smpte(timespec, 60);
  }
  if (sscanf(str, "smpte-60-drop:%16s", timespec) == 1) {
    return parse_smpte(timespec, 59.94);
  }
  return parse_npt(str);
}
```