user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<trackball>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0xc0,%rsp
  mov    %rdi,-0x98(%rbp)
  movsd  %xmm0,-0xa0(%rbp)
  movsd  %xmm1,-0xa8(%rbp)
  movsd  %xmm2,-0xb0(%rbp)
  movsd  %xmm3,-0xb8(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  movsd  -0xa0(%rbp),%xmm0
  ucomisd -0xb0(%rbp),%xmm0
  jp     L64
  movsd  -0xa0(%rbp),%xmm0
  ucomisd -0xb0(%rbp),%xmm0
  jne    L64
  movsd  -0xa8(%rbp),%xmm0
  ucomisd -0xb8(%rbp),%xmm0
  jp     L64
  movsd  -0xa8(%rbp),%xmm0
  ucomisd -0xb8(%rbp),%xmm0
  jne    L64
  mov    -0x98(%rbp),%rax
  pxor   %xmm2,%xmm2
  pxor   %xmm1,%xmm1
  mov    D73(%rip),%rdx
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <vset@plt>
  mov    -0x98(%rbp),%rax
  add    $0x18,%rax
  movsd  D25(%rip),%xmm0
  movsd  %xmm0,(%rax)
  jmp    L41
L64:
  movsd  -0xa0(%rbp),%xmm0
  movsd  %xmm0,-0x60(%rbp)
  movsd  -0xa8(%rbp),%xmm0
  movsd  %xmm0,-0x58(%rbp)
  movsd  -0xa8(%rbp),%xmm1
  movsd  -0xa0(%rbp),%xmm0
  mov    D25(%rip),%rax
  movapd %xmm1,%xmm2
  movapd %xmm0,%xmm1
  movq   %rax,%xmm0
  call   <tb_project_to_sphere@plt>
  movq   %xmm0,%rax
  mov    %rax,-0x50(%rbp)
  movsd  -0xb0(%rbp),%xmm0
  movsd  %xmm0,-0x40(%rbp)
  movsd  -0xb8(%rbp),%xmm0
  movsd  %xmm0,-0x38(%rbp)
  movsd  -0xb8(%rbp),%xmm1
  movsd  -0xb0(%rbp),%xmm0
  mov    D25(%rip),%rax
  movapd %xmm1,%xmm2
  movapd %xmm0,%xmm1
  movq   %rax,%xmm0
  call   <tb_project_to_sphere@plt>
  movq   %xmm0,%rax
  mov    %rax,-0x30(%rbp)
  lea    -0x60(%rbp),%rdx
  lea    -0x40(%rbp),%rcx
  lea    -0x80(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <vcross@plt>
  lea    -0x40(%rbp),%rdx
  lea    -0x60(%rbp),%rcx
  lea    -0x20(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <vsub@plt>
  lea    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <vlength@plt>
  movq   %xmm0,%rax
  movsd  D33(%rip),%xmm1
  movq   %rax,%xmm0
  divsd  %xmm1,%xmm0
  movsd  %xmm0,-0x90(%rbp)
  movsd  -0x90(%rbp),%xmm0
  movsd  D25(%rip),%xmm1
  comisd %xmm1,%xmm0
  jbe    L79
  movsd  D25(%rip),%xmm0
  movsd  %xmm0,-0x90(%rbp)
L79:
  movsd  D29(%rip),%xmm0
  comisd -0x90(%rbp),%xmm0
  jbe    L33
  movsd  D29(%rip),%xmm0
  movsd  %xmm0,-0x90(%rbp)
L33:
  mov    -0x90(%rbp),%rax
  movq   %rax,%xmm0
  call   <asin@plt>
  addsd  %xmm0,%xmm0
  movsd  %xmm0,-0x88(%rbp)
  mov    -0x98(%rbp),%rcx
  mov    -0x88(%rbp),%rdx
  lea    -0x80(%rbp),%rax
  mov    %rcx,%rsi
  movq   %rdx,%xmm0
  mov    %rax,%rdi
  call   <axis_to_quat@plt>
L41:
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L28
  call   <__stack_chk_fail@plt>
L28:
  leave
  ret
```

tool_calls: name: disassemble_data
arguments: label: D73
data_type: f64
name: disassemble_data
arguments: label: D25
data_type: f64
name: disassemble_data
arguments: label: D33
data_type: f64
name: disassemble_data
arguments: label: D29
data_type: byte[8]

tool: D73: 0

tool: D25: 1

tool: D33: 2

tool: {"D29": [0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xbf]}

assistant: ```c
void trackball(double q[4], double p1x, double p1y, double p2x, double p2y) {
  double axis[3];
  double phi;
  double p1[3], p2[3], d[3];
  double t;
  if (p1x == p2x && p1y == p2y) {
    vset(q, 0.0, 0.0, 0.0);
    q[3] = 1.0;
    return;
  }
  p1[0] = p1x;
  p1[1] = p1y;
  p1[2] = tb_project_to_sphere((1.0), p1x, p1y);
  p2[0] = p2x;
  p2[1] = p2y;
  p2[2] = tb_project_to_sphere((1.0), p2x, p2y);
  vcross(axis, p2, p1);
  vsub(d, p1, p2);
  t = vlength(d) / (2.0 * (1.0));
  if (t > 1.0) {
    t = 1.0;
  }
  if (t < -1.0) {
    t = -1.0;
  }
  phi = 2.0 * asin(t);
  axis_to_quat(axis, phi, q);
}
```