user: Translate the below assembly code into C programming language:

```asm
<ieee_80_to_double>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x28(%rbp)
  movw   $0x0,-0x12(%rbp)
  movl   $0x0,-0x10(%rbp)
  movl   $0x0,-0xc(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %ax,-0x12(%rbp)
  movswl -0x12(%rbp),%eax
  shl    $0x8,%eax
  mov    %ax,-0x12(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %ax,-0x12(%rbp)
  movzwl -0x12(%rbp),%eax
  sar    $0xf,%ax
  and    $0x1,%eax
  mov    %al,-0x13(%rbp)
  andw   $0x7fff,-0x12(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,-0x10(%rbp)
  shll   $0x8,-0x10(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %eax,-0x10(%rbp)
  shll   $0x8,-0x10(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %eax,-0x10(%rbp)
  shll   $0x8,-0x10(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %eax,-0x10(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  mov    %eax,-0xc(%rbp)
  shll   $0x8,-0xc(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %eax,-0xc(%rbp)
  shll   $0x8,-0xc(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %eax,-0xc(%rbp)
  shll   $0x8,-0xc(%rbp)
  mov    -0x28(%rbp),%rax
  lea    0x1(%rax),%rdx
  mov    %rdx,-0x28(%rbp)
  movzbl (%rax),%eax
  movzbl %al,%eax
  or     %eax,-0xc(%rbp)
  cmpl   $0x0,-0x10(%rbp)
  jne    L58
  cmpl   $0x0,-0xc(%rbp)
  jne    L58
  cmpw   $0x0,-0x12(%rbp)
  jne    L58
  cmpb   $0x0,-0x13(%rbp)
  jne    L58
  pxor   %xmm0,%xmm0
  jmp    L68
L58:
  mov    -0xc(%rbp),%eax
  mov    %eax,%edi
  call   <myUlongToDouble@plt>
  movsd  D23(%rip),%xmm1
  mulsd  %xmm1,%xmm0
  movsd  %xmm0,-0x8(%rbp)
  mov    -0x10(%rbp),%eax
  mov    %eax,%edi
  call   <myUlongToDouble@plt>
  movsd  D8(%rip),%xmm1
  mulsd  %xmm1,%xmm0
  movsd  -0x8(%rbp),%xmm1
  addsd  %xmm1,%xmm0
  movsd  %xmm0,-0x8(%rbp)
  movswl -0x12(%rbp),%eax
  pxor   %xmm0,%xmm0
  cvtsi2sd %eax,%xmm0
  movsd  D15(%rip),%xmm1
  subsd  %xmm1,%xmm0
  mov    D40(%rip),%rax
  movapd %xmm0,%xmm1
  movq   %rax,%xmm0
  call   <pow@plt>
  movsd  -0x8(%rbp),%xmm1
  mulsd  %xmm1,%xmm0
  movsd  %xmm0,-0x8(%rbp)
  cmpb   $0x0,-0x13(%rbp)
  je     L0
  movsd  -0x8(%rbp),%xmm0
  movq   D3(%rip),%xmm1
  xorpd  %xmm1,%xmm0
  jmp    L68
L0:
  movsd  -0x8(%rbp),%xmm0
L68:
  movq   %xmm0,%rax
  movq   %rax,%xmm0
  leave
  ret
```

tool_calls: name: parse_data
arguments: tag: D23
type_infered: f32[2]
name: parse_data
arguments: tag: D8
type_infered: f32[2]
name: parse_data
arguments: tag: D15
type_infered: f64
name: parse_data
arguments: tag: D40
type_infered: f64
name: parse_data
arguments: tag: D3
type_infered: f32[2]

tool: {"D23": [0.0,0.0078125]}

tool: {"D8": [0.0,0.125]}

tool: D15: 16383

tool: D40: 2

tool: {"D3": [0.0,-0.0]}

assistant: ```c
double ieee_80_to_double(unsigned char *p) {
  unsigned char sign;
  short lexp = 0;
  unsigned int mant1 = 0;
  unsigned int mant0 = 0;
  double val;
  lexp = *p++;
  lexp <<= 8;
  lexp |= *p++;
  sign = (lexp & 0x8000) ? 1 : 0;
  lexp &= 0x7FFF;
  mant1 = *p++;
  mant1 <<= 8;
  mant1 |= *p++;
  mant1 <<= 8;
  mant1 |= *p++;
  mant1 <<= 8;
  mant1 |= *p++;
  mant0 = *p++;
  mant0 <<= 8;
  mant0 |= *p++;
  mant0 <<= 8;
  mant0 |= *p++;
  mant0 <<= 8;
  mant0 |= *p++;
  if (mant1 == 0 && mant0 == 0 && lexp == 0 && sign == 0)
    return 0.0;
  else {
    val = myUlongToDouble(mant0) * pow(2.0, -63.0);
    val += myUlongToDouble(mant1) * pow(2.0, -31.0);
    val *= pow(2.0, ((double)lexp) - 16383.0);
    return sign ? -val : val;
  }
}
```