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

```asm
<cubic_spline_sp>:
  endbr64
  push   %r15
  mov    %rdx,%r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  mov    %edi,%ebp
  push   %rbx
  mov    %rcx,%rbx
  sub    $0x58,%rsp
  mov    %esi,0x18(%rsp)
  mov    %r8,0x28(%rsp)
  mov    %r9,0x30(%rsp)
  cmp    $0x1,%edi
  jle    L210
  lea    -0x2(%rdi),%eax
  mov    %rdx,%r13
  lea    D29(%rip),%r12
  lea    0x8(%rdx,%rax,8),%r14
  jmp    L72
  nopl   (%rax)
L135:
  add    $0x8,%r13
  cmp    %r13,%r14
  je     L11
L72:
  movsd  0x0(%r13),%xmm0
  comisd 0x8(%r13),%xmm0
  jb     L135
  mov    %r12,%rdi
  add    $0x8,%r13
  call   <error_handler@plt>
  cmp    %r13,%r14
  jne    L72
L11:
  mov    0x18(%rsp),%eax
  test   %eax,%eax
  jle    L305
L171:
  movslq %ebp,%rax
  mov    %ebp,0x8(%rsp)
  xor    %r14d,%r14d
  lea    D34(%rip),%r13
  lea    -0x8(%r15,%rax,8),%r12
  mov    %r12,%rbp
  mov    0x18(%rsp),%r12d
  nopw   0x0(%rax,%rax,1)
L265:
  movsd  (%rbx,%r14,8),%xmm0
  movsd  (%r15),%xmm1
  comisd %xmm0,%xmm1
  ja     L281
  comisd 0x0(%rbp),%xmm0
  jbe    L18
L281:
  mov    %r13,%rdi
  call   <error_handler@plt>
L18:
  add    $0x1,%r14
  cmp    %r14d,%r12d
  jg     L265
  mov    0x8(%rsp),%ebp
  cmp    $0x1,%ebp
  jle    L199
  cmp    $0x2,%ebp
  je     L270
L95:
  lea    -0x1(%rbp),%ecx
  lea    0x0(,%rcx,8),%r8d
  mov    %ecx,0x10(%rsp)
  movslq %ecx,%r14
  mov    %r8d,%edi
  mov    %r8d,0x8(%rsp)
  call   <malloc@plt>
  mov    0x8(%rsp),%edi
  mov    %rax,0x20(%rsp)
  call   <malloc@plt>
  mov    0x8(%rsp),%r8d
  mov    %rax,%r13
  lea    0x8(%r8),%edi
  call   <malloc@plt>
  mov    0x10(%rsp),%ecx
  mov    0x8(%rsp),%r8d
  mov    %rax,%r12
  test   %ecx,%ecx
  jle    L242
  mov    0x28(%rsp),%rdx
  mov    0x20(%rsp),%rdi
  lea    -0x2(%rbp),%eax
  mov    %r15,%rsi
  lea    0x8(%r13,%rax,8),%r9
  sub    %r13,%rsi
  mov    %r13,%rax
  sub    %r13,%rdx
  sub    %r13,%rdi
  nopw   0x0(%rax,%rax,1)
L347:
  movsd  0x8(%rsi,%rax,1),%xmm1
  subsd  (%rsi,%rax,1),%xmm1
  movsd  %xmm1,(%rax)
  movsd  0x8(%rdx,%rax,1),%xmm0
  subsd  (%rdx,%rax,1),%xmm0
  divsd  %xmm1,%xmm0
  movsd  %xmm0,(%rdi,%rax,1)
  add    $0x8,%rax
  cmp    %rax,%r9
  jne    L347
  cmp    $0x1,%ecx
  jle    L242
  mov    0x20(%rsp),%r11
  lea    -0x3(%rbp),%edx
  mov    %r12,%rsi
  mov    %r13,%r10
  lea    -0x8(%r13),%r9
  pxor   %xmm5,%xmm5
  lea    0x8(%r11),%rax
  lea    0x10(%r11,%rdx,8),%rdi
  sub    %r11,%rsi
  sub    %r11,%r10
  sub    %r11,%r9
  nopl   (%rax)
L358:
  movsd  (%rax),%xmm3
  movsd  -0x8(%rax),%xmm4
  lea    (%rsi,%rax,1),%rdx
  movapd %xmm5,%xmm2
  movapd %xmm3,%xmm0
  mulsd  %xmm4,%xmm0
  comisd %xmm5,%xmm0
  jbe    L58
  movsd  (%r10,%rax,1),%xmm2
  movsd  (%r9,%rax,1),%xmm0
  movapd %xmm2,%xmm1
  addsd  %xmm2,%xmm1
  addsd  %xmm0,%xmm1
  addsd  %xmm0,%xmm0
  addsd  %xmm2,%xmm0
  movapd %xmm1,%xmm2
  divsd  %xmm4,%xmm1
  addsd  %xmm0,%xmm2
  divsd  %xmm3,%xmm0
  addsd  %xmm0,%xmm1
  divsd  %xmm1,%xmm2
L58:
  add    $0x8,%rax
  movsd  %xmm2,(%rdx)
  cmp    %rax,%rdi
  jne    L358
L231:
  movsd  0x0(%r13),%xmm1
  mov    0x20(%rsp),%rax
  movsd  0x8(%r13),%xmm2
  movapd %xmm1,%xmm0
  movsd  0x8(%rax),%xmm3
  addsd  %xmm1,%xmm0
  mulsd  %xmm1,%xmm3
  addsd  %xmm2,%xmm1
  addsd  %xmm2,%xmm0
  mulsd  (%rax),%xmm0
  subsd  %xmm3,%xmm0
  divsd  %xmm1,%xmm0
  movsd  %xmm0,(%r12)
  movsd  (%rax),%xmm1
  movapd %xmm0,%xmm2
  mulsd  %xmm1,%xmm2
  comisd %xmm2,%xmm5
  ja     L221
  mov    0x20(%rsp),%rax
  mulsd  0x8(%rax),%xmm1
  comisd %xmm1,%xmm5
  ja     L79
L213:
  shl    $0x3,%r14
  mov    0x20(%rsp),%rax
  movsd  -0x8(%r13,%r14,1),%xmm1
  movsd  -0x10(%r13,%r14,1),%xmm2
  lea    -0x8(%rax,%r14,1),%rdx
  lea    -0x10(%rax,%r14,1),%rax
  add    %r12,%r14
  movapd %xmm1,%xmm0
  movsd  (%rax),%xmm3
  addsd  %xmm1,%xmm0
  mulsd  %xmm1,%xmm3
  addsd  %xmm2,%xmm1
  addsd  %xmm2,%xmm0
  mulsd  (%rdx),%xmm0
  subsd  %xmm3,%xmm0
  divsd  %xmm1,%xmm0
  movsd  %xmm0,(%r14)
  movsd  (%rdx),%xmm1
  movapd %xmm0,%xmm2
  mulsd  %xmm1,%xmm2
  comisd %xmm2,%xmm5
  ja     L319
  mulsd  (%rax),%xmm1
  comisd %xmm1,%xmm5
  ja     L50
L124:
  mov    %r8d,%edi
  mov    %ecx,0x3c(%rsp)
  mov    %r8d,0x10(%rsp)
  call   <malloc@plt>
  mov    0x10(%rsp),%edi
  mov    %rax,0x8(%rsp)
  call   <malloc@plt>
  mov    0x3c(%rsp),%ecx
  mov    %rax,0x10(%rsp)
  test   %ecx,%ecx
  jle    L314
  mov    0x20(%rsp),%r10
  mov    0x10(%rsp),%r8
  lea    -0x2(%rbp),%eax
  mov    %r13,%r9
  mov    0x8(%rsp),%rdi
  movsd  D28(%rip),%xmm3
  lea    0x8(%r12,%rax,8),%r11
  sub    %r12,%r9
  mov    %r12,%rax
  sub    %r12,%r10
  sub    %r12,%r8
  sub    %r12,%rdi
  nopl   0x0(%rax)
L256:
  lea    (%r10,%rax,1),%rcx
  mov    %rax,%rdx
  add    $0x8,%rax
  movsd  (%rcx),%xmm0
  movsd  (%rdx),%xmm1
  lea    (%r9,%rdx,1),%rsi
  mulsd  %xmm3,%xmm0
  addsd  %xmm1,%xmm1
  subsd  %xmm1,%xmm0
  subsd  (%rax),%xmm0
  divsd  (%rsi),%xmm0
  movsd  %xmm0,(%r8,%rdx,1)
  movsd  (%rcx),%xmm0
  movsd  (%rsi),%xmm1
  mulsd  %xmm1,%xmm1
  movapd %xmm0,%xmm2
  addsd  %xmm0,%xmm2
  movsd  (%rdx),%xmm0
  subsd  %xmm2,%xmm0
  addsd  (%rax),%xmm0
  divsd  %xmm1,%xmm0
  movsd  %xmm0,(%rdi,%rdx,1)
  cmp    %rax,%r11
  jne    L256
L314:
  mov    0x18(%rsp),%ecx
  test   %ecx,%ecx
  jle    L339
  mov    0x18(%rsp),%eax
  mov    0x30(%rsp),%r14
  mov    %r13,0x30(%rsp)
  sub    $0x1,%eax
  mov    %r14,%r13
  mov    %r15,%r14
  mov    0x28(%rsp),%r15
  lea    0x8(%rbx,%rax,8),%rax
  mov    %rax,0x18(%rsp)
  jmp    L335
  nopl   0x0(%rax,%rax,1)
L93:
  mov    0x10(%rsp),%rcx
  lea    (%r15,%rsi,1),%rax
  lea    (%r12,%rsi,1),%r8
  lea    (%rcx,%rsi,1),%r9
  add    0x8(%rsp),%rsi
L216:
  subsd  %xmm0,%xmm1
  movsd  (%rsi),%xmm0
  add    $0x8,%rbx
  add    $0x8,%r13
  mulsd  %xmm1,%xmm0
  addsd  (%r9),%xmm0
  mulsd  %xmm1,%xmm0
  addsd  (%r8),%xmm0
  mulsd  %xmm1,%xmm0
  addsd  (%rax),%xmm0
  movsd  %xmm0,-0x8(%r13)
  cmp    0x18(%rsp),%rbx
  je     L190
L335:
  movsd  (%rbx),%xmm0
  mov    %ebp,%esi
  mov    %r14,%rdi
  call   <nearest_index@plt>
  movsd  (%rbx),%xmm1
  movslq %eax,%r8
  movsd  (%r14,%r8,8),%xmm0
  lea    0x0(,%r8,8),%rsi
  comisd %xmm0,%xmm1
  ja     L93
  test   %eax,%eax
  jne    L5
  movsd  (%r14),%xmm0
  mov    0x8(%rsp),%rsi
  mov    %r12,%r8
  mov    %r15,%rax
  mov    0x10(%rsp),%r9
  jmp    L216
  nopl   0x0(%rax)
L270:
  mov    0x28(%rsp),%rsi
  movsd  (%r15),%xmm2
  movsd  0x8(%r15),%xmm1
  mov    0x18(%rsp),%eax
  movsd  (%rsi),%xmm0
  movsd  0x8(%rsi),%xmm3
  subsd  %xmm2,%xmm1
  lea    -0x1(%rax),%edx
  mov    0x30(%rsp),%rcx
  xor    %eax,%eax
  subsd  %xmm0,%xmm3
  shl    $0x3,%rdx
  divsd  %xmm1,%xmm3
  jmp    L47
  nopl   0x0(%rax)
L43:
  movsd  (%r15),%xmm2
  movsd  (%rsi),%xmm0
  add    $0x8,%rax
L47:
  movsd  (%rbx,%rax,1),%xmm1
  subsd  %xmm2,%xmm1
  mulsd  %xmm3,%xmm1
  addsd  %xmm1,%xmm0
  movsd  %xmm0,(%rcx,%rax,1)
  cmp    %rax,%rdx
  jne    L43
L285:
  add    $0x58,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopw   0x0(%rax,%rax,1)
L221:
  movq   $0x0,(%r12)
  jmp    L213
  nopl   (%rax)
L5:
  mov    0x10(%rsp),%rcx
  lea    -0x8(%rsi),%r10
  movsd  -0x8(%r14,%rsi,1),%xmm0
  lea    (%r15,%r10,1),%rax
  lea    (%r12,%r10,1),%r8
  lea    (%rcx,%r10,1),%r9
  mov    0x8(%rsp),%rcx
  lea    (%rcx,%r10,1),%rsi
  jmp    L216
  nopw   0x0(%rax,%rax,1)
L190:
  mov    0x30(%rsp),%r13
L339:
  mov    0x10(%rsp),%rdi
  call   <free@plt>
  mov    0x8(%rsp),%rdi
  call   <free@plt>
  mov    %r12,%rdi
  call   <free@plt>
  mov    %r13,%rdi
  call   <free@plt>
  mov    0x20(%rsp),%rdi
  add    $0x58,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1090 <free@plt>
  nopl   0x0(%rax)
L319:
  movq   $0x0,(%r14)
  jmp    L124
  nopl   0x0(%rax)
L210:
  mov    0x18(%rsp),%edx
  test   %edx,%edx
  jg     L171
  nopl   0x0(%rax)
L199:
  lea    D15(%rip),%rdi
  call   <error_handler@plt>
  jmp    L95
  nopl   0x0(%rax)
L50:
  mov    %r8d,0x3c(%rsp)
  mov    %ecx,0x10(%rsp)
  mov    %rdx,0x40(%rsp)
  call   <fabs@plt>
  movsd  D28(%rip),%xmm3
  mov    0x40(%rsp),%rdx
  mov    %rax,0x8(%rsp)
  movapd %xmm3,%xmm0
  movsd  %xmm3,0x48(%rsp)
  mulsd  (%rdx),%xmm0
  call   <fabs@plt>
  cmp    %rax,0x8(%rsp)
  mov    0x10(%rsp),%ecx
  mov    0x3c(%rsp),%r8d
  jle    L124
  mov    0x40(%rsp),%rdx
  movsd  0x48(%rsp),%xmm3
  mulsd  (%rdx),%xmm3
  movsd  %xmm3,(%r14)
  jmp    L124
  nopl   (%rax)
L79:
  mov    %r8d,0x3c(%rsp)
  movsd  %xmm5,0x40(%rsp)
  mov    %ecx,0x10(%rsp)
  call   <fabs@plt>
  movsd  D28(%rip),%xmm3
  mov    0x20(%rsp),%rcx
  mov    %rax,0x8(%rsp)
  movapd %xmm3,%xmm0
  movsd  %xmm3,0x48(%rsp)
  mulsd  (%rcx),%xmm0
  call   <fabs@plt>
  cmp    %rax,0x8(%rsp)
  mov    0x10(%rsp),%ecx
  mov    0x3c(%rsp),%r8d
  movsd  0x40(%rsp),%xmm5
  jle    L213
  mov    0x20(%rsp),%rax
  movsd  0x48(%rsp),%xmm3
  mulsd  (%rax),%xmm3
  movsd  %xmm3,(%r12)
  jmp    L213
  nopl   (%rax)
L305:
  cmp    $0x2,%ebp
  jne    L95
  jmp    L285
L242:
  pxor   %xmm5,%xmm5
  jmp    L231
```

tool_calls: name: read_data
arguments: label: D29
data_type: string
name: read_data
arguments: label: D34
data_type: string
name: read_data
arguments: label: D28
data_type: f64
name: read_data
arguments: label: D15
data_type: string

tool: D29: cubic_spline_sp: grid1 is not monotonic increasing

tool: D34: cubic_spline_sp: grid2 lies outside grid1

tool: D28: 3

tool: D15: cubic_spline_sp: the size of input grid should be at least 2

assistant: ```c
void cubic_spline_sp(int size1, int size2, const double *grid1, const double *grid2, const double *data1, double *data2) {
  double *delta = NULL, *d = NULL, *dh = NULL, *b = NULL, *c = NULL;
  double s, w1, w2, p;
  int i, k, n, klo, khi, kmax;
  for (i = 1; i < size1; i++) {
    if (grid1[i] <= grid1[i - 1])
      error_handler("cubic_spline_sp: grid1 is not monotonic increasing");
  }
  for (i = 0; i < size2; i++) {
    if (grid2[i] < grid1[0] || grid2[i] > grid1[size1 - 1])
      error_handler("cubic_spline_sp: grid2 lies outside grid1");
  }
  if (size1 < 2)
    error_handler("cubic_spline_sp: the size of input grid should be at least 2");
  if (size1 == 2) {
    p = (data1[1] - data1[0]) / (grid1[1] - grid1[0]);
    for (i = 0; i < size2; i++)
      data2[i] = p * (grid2[i] - grid1[0]) + data1[0];
    return;
  }
  delta = (double *)malloc((size1 - 1) * sizeof(double));
  dh = (double *)malloc((size1 - 1) * sizeof(double));
  d = (double *)malloc(size1 * sizeof(double));
  for (k = 0; k < size1 - 1; k++) {
    dh[k] = grid1[k + 1] - grid1[k];
    delta[k] = (data1[k + 1] - data1[k]) / (dh[k]);
  }
  for (k = 1; k < size1 - 1; k++) {
    if (delta[k] * delta[k - 1] > 0.0) {
      w1 = 2.0 * dh[k] + dh[k - 1];
      w2 = dh[k] + 2.0 * dh[k - 1];
      d[k] = (w1 + w2) / (w1 / delta[k - 1] + w2 / delta[k]);
    } else {
      d[k] = 0.0;
    }
  }
  kmax = size1 - 1;
  d[0] = ((2.0 * dh[0] + dh[1]) * delta[0] - dh[0] * delta[1]) / (dh[0] + dh[1]);
  if (d[0] * delta[0] < 0.0) {
    d[0] = 0.0;
  } else {
    if (delta[0] * delta[1] < 0.0 && fabs(d[0]) > fabs(3.0 * delta[0])) {
      d[0] = 3.0 * delta[0];
    }
  }
  d[kmax] = ((2.0 * dh[kmax - 1] + dh[kmax - 2]) * delta[kmax - 1] - dh[kmax - 1] * delta[kmax - 2]) / (dh[kmax - 1] + dh[kmax - 2]);
  if (d[kmax] * delta[kmax - 1] < 0.0) {
    d[kmax] = 0.0;
  } else {
    if (delta[kmax - 1] * delta[kmax - 2] < 0.0 && fabs(d[kmax]) > fabs(3.0 * delta[kmax - 1])) {
      d[kmax] = 3.0 * delta[kmax - 1];
    }
  }
  b = (double *)malloc((size1 - 1) * sizeof(double));
  c = (double *)malloc((size1 - 1) * sizeof(double));
  for (k = 0; k < size1 - 1; k++) {
    c[k] = (3.0 * delta[k] - 2.0 * d[k] - d[k + 1]) / dh[k];
    b[k] = (d[k] - 2.0 * delta[k] + d[k + 1]) / (dh[k] * dh[k]);
  }
  for (k = 0; k < size2; k++) {
    n = nearest_index(grid2[k], grid1, size1);
    if (grid1[n] < grid2[k]) {
      klo = n;
    } else {
      if (n == 0) {
        klo = n;
      } else {
        klo = n - 1;
      }
    }
    khi = klo + 1;
    s = grid2[k] - grid1[klo];
    data2[k] = data1[klo] + s * (d[klo] + s * (c[klo] + s * b[klo]));
  }
  free(c);
  free(b);
  free(d);
  free(dh);
  free(delta);
}
```