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

```asm
<linear_expansion_sum>:
  endbr64
  push   %r13
  mov    %edx,%r11d
  mov    %rcx,%r9
  movq   D0(%rip),%xmm8
  push   %r12
  push   %rbp
  push   %rbx
  movsd  (%rsi),%xmm6
  mov    %rsi,%rbx
  movsd  (%rcx),%xmm0
  movapd %xmm6,%xmm1
  comisd %xmm6,%xmm0
  xorpd  %xmm8,%xmm1
  seta   %dl
  comisd %xmm1,%xmm0
  seta   %al
  cmp    %al,%dl
  je     L90
  movsd  0x8(%rcx),%xmm5
  mov    $0x1,%edx
  xor    %ecx,%ecx
L114:
  cmp    %edi,%ecx
  jge    L10
  cmp    %r11d,%edx
  jl     L64
L8:
  movapd %xmm6,%xmm2
  add    $0x1,%ecx
  addsd  %xmm0,%xmm2
  movslq %ecx,%rax
  movapd %xmm2,%xmm1
  subsd  %xmm6,%xmm1
  movsd  (%rbx,%rax,8),%xmm6
  subsd  %xmm1,%xmm0
  jmp    L46
  nopl   0x0(%rax)
L64:
  comisd %xmm6,%xmm5
  movapd %xmm6,%xmm1
  xorpd  %xmm8,%xmm1
  seta   %sil
  comisd %xmm1,%xmm5
  seta   %al
  cmp    %al,%sil
  je     L8
L10:
  movapd %xmm5,%xmm2
  add    $0x1,%edx
  addsd  %xmm0,%xmm2
  movslq %edx,%rax
  movapd %xmm2,%xmm1
  subsd  %xmm5,%xmm1
  movsd  (%r9,%rax,8),%xmm5
  subsd  %xmm1,%xmm0
L46:
  lea    (%rdi,%r11,1),%r12d
  mov    %r8,%rax
  lea    -0x2(%r12),%r10d
  test   %r10d,%r10d
  jle    L110
  lea    -0x3(%r12),%esi
  lea    0x8(%r8,%rsi,8),%rbp
  jmp    L40
  xchg   %ax,%ax
L38:
  comisd %xmm6,%xmm5
  movapd %xmm6,%xmm1
  xorpd  %xmm8,%xmm1
  seta   %r13b
  comisd %xmm1,%xmm5
  seta   %sil
  cmp    %sil,%r13b
  je     L45
L109:
  movapd %xmm0,%xmm1
  add    $0x1,%edx
  addsd  %xmm5,%xmm1
  movslq %edx,%rsi
  movapd %xmm1,%xmm3
  subsd  %xmm5,%xmm3
  subsd  %xmm3,%xmm0
  movsd  %xmm0,(%rax)
  movsd  (%r9,%rsi,8),%xmm5
L49:
  movapd %xmm1,%xmm3
  add    $0x8,%rax
  addsd  %xmm2,%xmm3
  movapd %xmm3,%xmm4
  movapd %xmm3,%xmm7
  subsd  %xmm2,%xmm4
  subsd  %xmm4,%xmm7
  subsd  %xmm4,%xmm1
  subsd  %xmm7,%xmm2
  movapd %xmm2,%xmm0
  addsd  %xmm1,%xmm0
  cmp    %rax,%rbp
  je     L55
  movapd %xmm3,%xmm2
L40:
  cmp    %ecx,%edi
  jle    L109
  cmp    %edx,%r11d
  jg     L38
L45:
  movapd %xmm6,%xmm1
  add    $0x1,%ecx
  addsd  %xmm0,%xmm1
  movslq %ecx,%rsi
  movapd %xmm1,%xmm3
  subsd  %xmm6,%xmm3
  subsd  %xmm3,%xmm0
  movsd  %xmm0,(%rax)
  movsd  (%rbx,%rsi,8),%xmm6
  jmp    L49
  nopl   (%rax)
L55:
  movslq %r10d,%r10
  shl    $0x3,%r10
  lea    (%r8,%r10,1),%rax
  add    $0x8,%r10
L73:
  movsd  %xmm0,(%rax)
  mov    %r12d,%eax
  pop    %rbx
  pop    %rbp
  movsd  %xmm3,(%r8,%r10,1)
  pop    %r12
  pop    %r13
  ret
  nopl   0x0(%rax,%rax,1)
L90:
  movapd %xmm0,%xmm5
  xor    %edx,%edx
  movapd %xmm6,%xmm0
  mov    $0x1,%ecx
  movsd  0x8(%rsi),%xmm6
  jmp    L114
  nopl   0x0(%rax)
L110:
  movapd %xmm2,%xmm3
  mov    $0x2,%r12d
  mov    $0x8,%r10d
  jmp    L73
```

tool_calls: name: retrieve_data
arguments: label: D0
type: byte[8]

tool: {"D0": [0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80]}

assistant: ```c
int linear_expansion_sum(elen, e, flen, f, h)
int elen;
double *e;
int flen;
double *f;
double *h;
{
  double Q, q;
  double Qnew;
  double R;
  double bvirt;
  double avirt, bround, around;
  int eindex, findex, hindex;
  double enow, fnow;
  double g0;
  enow = e[0];
  fnow = f[0];
  eindex = findex = 0;
  if ((fnow > enow) == (fnow > -enow)) {
    g0 = enow;
    enow = e[++eindex];
  } else {
    g0 = fnow;
    fnow = f[++findex];
  }
  if ((eindex < elen) && ((findex >= flen) || ((fnow > enow) == (fnow > -enow)))) {
    Qnew = (double)(enow + g0);
    bvirt = Qnew - enow;
    q = g0 - bvirt;
    enow = e[++eindex];
  } else {
    Qnew = (double)(fnow + g0);
    bvirt = Qnew - fnow;
    q = g0 - bvirt;
    fnow = f[++findex];
  }
  Q = Qnew;
  for (hindex = 0; hindex < elen + flen - 2; hindex++) {
    if ((eindex < elen) && ((findex >= flen) || ((fnow > enow) == (fnow > -enow)))) {
      R = (double)(enow + q);
      bvirt = R - enow;
      h[hindex] = q - bvirt;
      enow = e[++eindex];
    } else {
      R = (double)(fnow + q);
      bvirt = R - fnow;
      h[hindex] = q - bvirt;
      fnow = f[++findex];
    }
    Qnew = (double)(Q + R);
    bvirt = (double)(Qnew - Q);
    avirt = Qnew - bvirt;
    bround = R - bvirt;
    around = Q - avirt;
    q = around + bround;
    Q = Qnew;
  }
  h[hindex] = q;
  h[hindex + 1] = Q;
  return hindex + 2;
}
```