user: What would the C source look like for the assembly code provided here?

```asm
<mulpm>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    -0x40(%rbp),%rax
  movsd  (%rax),%xmm1
  mov    -0x48(%rbp),%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm0,%xmm1
  mov    -0x40(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm2
  mov    -0x48(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x40(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm2
  mov    -0x48(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x48(%rbp),%rax
  add    $0x18,%rax
  movsd  (%rax),%xmm0
  addsd  %xmm1,%xmm0
  movsd  %xmm0,-0x28(%rbp)
  mov    -0x40(%rbp),%rax
  movsd  (%rax),%xmm1
  mov    -0x48(%rbp),%rax
  add    $0x20,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm0,%xmm1
  mov    -0x40(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm2
  mov    -0x48(%rbp),%rax
  add    $0x28,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x40(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm2
  mov    -0x48(%rbp),%rax
  add    $0x30,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x48(%rbp),%rax
  add    $0x38,%rax
  movsd  (%rax),%xmm0
  addsd  %xmm1,%xmm0
  movsd  %xmm0,-0x20(%rbp)
  mov    -0x40(%rbp),%rax
  movsd  (%rax),%xmm1
  mov    -0x48(%rbp),%rax
  add    $0x40,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm0,%xmm1
  mov    -0x40(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm2
  mov    -0x48(%rbp),%rax
  add    $0x48,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x40(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm2
  mov    -0x48(%rbp),%rax
  add    $0x50,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x48(%rbp),%rax
  add    $0x58,%rax
  movsd  (%rax),%xmm0
  addsd  %xmm1,%xmm0
  movsd  %xmm0,-0x18(%rbp)
  mov    -0x40(%rbp),%rax
  movsd  (%rax),%xmm1
  mov    -0x48(%rbp),%rax
  add    $0x60,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm0,%xmm1
  mov    -0x40(%rbp),%rax
  add    $0x8,%rax
  movsd  (%rax),%xmm2
  mov    -0x48(%rbp),%rax
  add    $0x68,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x40(%rbp),%rax
  add    $0x10,%rax
  movsd  (%rax),%xmm2
  mov    -0x48(%rbp),%rax
  add    $0x70,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  addsd  %xmm0,%xmm1
  mov    -0x48(%rbp),%rax
  add    $0x78,%rax
  movsd  (%rax),%xmm0
  addsd  %xmm1,%xmm0
  movsd  %xmm0,-0x10(%rbp)
  movsd  D25(%rip),%xmm0
  ucomisd -0x10(%rbp),%xmm0
  jp     L0
  movsd  D25(%rip),%xmm0
  ucomisd -0x10(%rbp),%xmm0
  je     L7
L0:
  movsd  D25(%rip),%xmm0
  divsd  -0x10(%rbp),%xmm0
  movsd  %xmm0,-0x8(%rbp)
  movsd  -0x28(%rbp),%xmm0
  mulsd  -0x8(%rbp),%xmm0
  mov    -0x38(%rbp),%rax
  movsd  %xmm0,(%rax)
  mov    -0x38(%rbp),%rax
  add    $0x8,%rax
  movsd  -0x20(%rbp),%xmm0
  mulsd  -0x8(%rbp),%xmm0
  movsd  %xmm0,(%rax)
  mov    -0x38(%rbp),%rax
  add    $0x10,%rax
  movsd  -0x18(%rbp),%xmm0
  mulsd  -0x8(%rbp),%xmm0
  movsd  %xmm0,(%rax)
  jmp    L22
L7:
  mov    -0x38(%rbp),%rax
  movsd  -0x28(%rbp),%xmm0
  movsd  %xmm0,(%rax)
  mov    -0x38(%rbp),%rax
  add    $0x8,%rax
  movsd  -0x20(%rbp),%xmm0
  movsd  %xmm0,(%rax)
  mov    -0x38(%rbp),%rax
  add    $0x10,%rax
  movsd  -0x18(%rbp),%xmm0
  movsd  %xmm0,(%rax)
L22:
  nop
  pop    %rbp
  ret
```

tool_calls: name: retrieve_data
arguments: data_label: D25
type: byte[8]

tool: {"D25": [0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0x3f]}

assistant: ```c
void mulpm(double *result, const double *s1, const double *s2) {
  const double x = s1[0] * s2[(0 + (0 << 2))] + s1[1] * s2[(1 + (0 << 2))] + s1[2] * s2[(2 + (0 << 2))] + s2[(3 + (0 << 2))];
  const double y = s1[0] * s2[(0 + (1 << 2))] + s1[1] * s2[(1 + (1 << 2))] + s1[2] * s2[(2 + (1 << 2))] + s2[(3 + (1 << 2))];
  const double z = s1[0] * s2[(0 + (2 << 2))] + s1[1] * s2[(1 + (2 << 2))] + s1[2] * s2[(2 + (2 << 2))] + s2[(3 + (2 << 2))];
  const double w = s1[0] * s2[(0 + (3 << 2))] + s1[1] * s2[(1 + (3 << 2))] + s1[2] * s2[(2 + (3 << 2))] + s2[(3 + (3 << 2))];
  if (w != 1) {
    const double l = 1 / (double)w;
    result[0] = (double)(x * l);
    result[1] = (double)(y * l);
    result[2] = (double)(z * l);
  } else {
    result[0] = x;
    result[1] = y;
    result[2] = z;
  }
}
```