user: Please show me the C implementation that matches the assembly code listed below:

```asm
<solve_quartic_2>:
  endbr64
  movaps %xmm0,%xmm6
  push   %r13
  movaps %xmm0,%xmm4
  movaps %xmm1,%xmm7
  mulss  %xmm0,%xmm6
  push   %r12
  movaps %xmm4,%xmm8
  cvtss2sd %xmm3,%xmm3
  push   %rbp
  mulss  %xmm1,%xmm8
  push   %rbx
  mov    %rdi,%rbx
  sub    $0x48,%rsp
  movss  D0(%rip),%xmm0
  movss  D169(%rip),%xmm5
  mulss  D121(%rip),%xmm8
  mov    %fs:0x28,%rax
  mov    %rax,0x38(%rsp)
  xor    %eax,%eax
  mulss  %xmm6,%xmm0
  mulss  %xmm5,%xmm0
  subss  %xmm0,%xmm7
  movaps %xmm6,%xmm0
  mulss  %xmm4,%xmm0
  mulss  %xmm1,%xmm6
  pxor   %xmm1,%xmm1
  mulss  D110(%rip),%xmm6
  mulss  %xmm0,%xmm5
  mulss  %xmm4,%xmm0
  cvtss2sd %xmm6,%xmm6
  subss  %xmm8,%xmm5
  cvtss2sd %xmm0,%xmm0
  mulsd  D90(%rip),%xmm0
  addss  %xmm2,%xmm5
  mulss  %xmm4,%xmm2
  mulss  D57(%rip),%xmm2
  addsd  %xmm6,%xmm0
  cvtss2sd %xmm2,%xmm2
  subsd  %xmm2,%xmm0
  addsd  %xmm3,%xmm0
  pxor   %xmm3,%xmm3
  ucomiss %xmm3,%xmm5
  cvtsd2ss %xmm0,%xmm1
  jp     L76
  jne    L76
  lea    0x20(%rsp),%rsi
  movaps %xmm7,%xmm0
  mov    $0x1,%edi
  movss  %xmm4,(%rsp)
  call   <solve_quadratic_2@plt>
  test   %eax,%eax
  jne    L67
L48:
  mov    0x38(%rsp),%rdx
  sub    %fs:0x28,%rdx
  jne    L63
  add    $0x48,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  ret
  nopl   0x0(%rax)
L76:
  movaps %xmm7,%xmm0
  movss  D50(%rip),%xmm3
  movaps %xmm5,%xmm2
  movss  %xmm4,0xc(%rsp)
  mulss  %xmm7,%xmm0
  xorps  %xmm3,%xmm2
  lea    0x20(%rsp),%rsi
  movss  %xmm7,0x8(%rsp)
  mulss  D11(%rip),%xmm1
  movss  %xmm2,0x4(%rsp)
  mulss  %xmm2,%xmm5
  subss  %xmm1,%xmm0
  movaps %xmm7,%xmm1
  addss  %xmm7,%xmm1
  cvttss2si %xmm1,%edi
  movaps %xmm5,%xmm1
  call   <solve_cubic@plt>
  movss  0x20(%rsp),%xmm1
  movaps %xmm1,%xmm0
  movss  %xmm1,(%rsp)
  call   <sqrt@plt>
  movss  0x4(%rsp),%xmm2
  movss  (%rsp),%xmm1
  lea    0x10(%rsp),%rsi
  movss  0x8(%rsp),%xmm7
  mov    $0x1,%edi
  movss  %xmm0,(%rsp)
  mov    D48(%rip),%rax
  divss  %xmm0,%xmm2
  addss  %xmm1,%xmm7
  mov    %rax,0x10(%rsp)
  mov    %rax,0x18(%rsp)
  movaps %xmm7,%xmm1
  movss  %xmm7,0x8(%rsp)
  addss  %xmm2,%xmm1
  mulss  D121(%rip),%xmm1
  movss  %xmm2,0x4(%rsp)
  call   <solve_quadratic_2@plt>
  movss  0x4(%rsp),%xmm2
  movss  0x8(%rsp),%xmm7
  movss  D50(%rip),%xmm3
  movss  D121(%rip),%xmm1
  movss  (%rsp),%xmm0
  lea    0x18(%rsp),%rsi
  mov    %eax,%ebp
  subss  %xmm2,%xmm7
  mov    $0x1,%edi
  xorps  %xmm3,%xmm0
  mulss  %xmm7,%xmm1
  call   <solve_quadratic_2@plt>
  movss  0xc(%rsp),%xmm4
  mulss  D57(%rip),%xmm4
  movslq %ebp,%rdx
  movq   0x10(%rsp),%xmm0
  add    %ebp,%eax
  shufps $0xe0,%xmm4,%xmm4
  subps  %xmm4,%xmm0
  movlps %xmm0,(%rbx)
  movq   0x18(%rsp),%xmm0
  subps  %xmm4,%xmm0
  movlps %xmm0,(%rbx,%rdx,4)
  jmp    L48
  nopl   (%rax)
L67:
  xor    %edi,%edi
  cmp    $0x2,%eax
  sete   %dil
  call   <assert@plt>
  movss  0x20(%rsp),%xmm0
  pxor   %xmm3,%xmm3
  movss  (%rsp),%xmm4
  comiss %xmm3,%xmm0
  jae    L20
  mov    $0x2,%ebp
  mov    $0x4,%r12d
  xor    %r13d,%r13d
  xor    %eax,%eax
L6:
  movss  0x24(%rsp),%xmm0
  pxor   %xmm3,%xmm3
  movss  %xmm4,(%rsp)
  comiss %xmm3,%xmm0
  jb     L48
  call   <sqrt@plt>
  movss  (%rsp),%xmm4
  mov    %ebp,%eax
  mulss  D57(%rip),%xmm4
  movaps %xmm0,%xmm1
  xorps  D50(%rip),%xmm0
  subss  %xmm4,%xmm1
  subss  %xmm4,%xmm0
  movss  %xmm1,(%rbx,%r13,1)
  movss  %xmm0,(%rbx,%r12,1)
  jmp    L48
  nopl   0x0(%rax)
L20:
  call   <sqrt@plt>
  movss  (%rsp),%xmm4
  mov    $0x4,%ebp
  mov    $0xc,%r12d
  movaps %xmm0,%xmm1
  xorps  D50(%rip),%xmm1
  mov    $0x8,%r13d
  mov    $0x2,%eax
  unpcklps %xmm1,%xmm0
  movss  D57(%rip),%xmm1
  mulss  %xmm4,%xmm1
  shufps $0xe0,%xmm1,%xmm1
  subps  %xmm1,%xmm0
  movlps %xmm0,(%rbx)
  jmp    L6
L63:
  call   <__stack_chk_fail@plt>
```

tool_calls: name: retrieve_data
arguments: tag: D0
datatype: f32
name: retrieve_data
arguments: tag: D169
datatype: byte[4]
name: retrieve_data
arguments: tag: D121
datatype: byte[4]
name: retrieve_data
arguments: tag: D110
datatype: byte[4]
name: retrieve_data
arguments: tag: D90
datatype: f32[2]
name: retrieve_data
arguments: tag: D57
datatype: byte[4]
name: retrieve_data
arguments: tag: D50
datatype: byte[16]
name: retrieve_data
arguments: tag: D11
datatype: f32
name: retrieve_data
arguments: tag: D48
datatype: byte[8]

tool: D0: 3

tool: {"D169": [0x00,0x00,0x00,0x3e]}

tool: {"D121": [0x00,0x00,0x00,0x3f]}

tool: {"D110": [0x00,0x00,0x80,0x3d]}

tool: {"D90": [0.0,-1.0625]}

tool: {"D57": [0x00,0x00,0x80,0x3e]}

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

tool: D11: 4

tool: {"D48": [0x00,0x00,0x80,0xbf,0x00,0x00,0x80,0xbf]}

assistant: ```c
int solve_quartic_2(float p, float q, float r, float s, float t[4]) {
  float a = q - p * p * 3 / 8;
  float b = p * p * p / 8 - p * q / 2 + r;
  float c = p * p * p * p * (-3.0 / 256.0) + p * p * q / 16 - p * r / 4 + s;
  if (b == 0.0) {
    float z[2];
    int count = solve_quadratic_2(1, a, c, z);
    if (count == 0)
      return 0;
    assert(count == 2);
    int solutions = 0;
    if (z[0] >= 0) {
      float x1 = sqrt(z[0]);
      float x2 = -x1;
      t[0] = x1 - p / 4;
      t[1] = x2 - p / 4;
      solutions += 2;
    }
    if (z[1] >= 0) {
      float x1 = sqrt(z[1]);
      float x2 = -x1;
      t[solutions + 0] = x1 - p / 4;
      t[solutions + 1] = x2 - p / 4;
      solutions += 2;
    }
    return solutions;
  }
  float t3[4];
  solve_cubic(2 * a, a * a - 4 * c, -b * b, t3);
  float z = t3[0];
  float alpha = sqrt(z);
  float rho = -b / alpha;
  float beta = (a + z + rho) / 2;
  float delta = (a + z - rho) / 2;
  float t1[2] = {-1, -1}, t2[2] = {-1, -1};
  int n1 = solve_quadratic_2(1, alpha, beta, t1);
  int n2 = solve_quadratic_2(1, -alpha, delta, t2);
  t[0] = t1[0] - p / 4;
  t[1] = t1[1] - p / 4;
  t[n1 + 0] = t2[0] - p / 4;
  t[n1 + 1] = t2[1] - p / 4;
  return n1 + n2;
}
```