user: Converte this assembly snippet into its equivalent C code:

```asm
<form_flat_clusters_maxclust_monocrit>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x48,%rsp
  mov    %rdi,%r15
  mov    %rsi,%r13
  mov    %rdx,0x38(%rsp)
  mov    %ecx,0x14(%rsp)
  mov    %r8d,0x28(%rsp)
  movslq %ecx,%rdi
  mov    %rdi,%rax
  shr    $0x3,%rax
  pxor   %xmm0,%xmm0
  cvtsi2sd %ecx,%xmm0
  mulsd  D8(%rip),%xmm0
  pxor   %xmm1,%xmm1
  cvtsi2sd %rax,%xmm1
  ucomisd %xmm1,%xmm0
  jp     L68
  mov    %eax,%ebx
  jne    L68
L3:
  movsd  -0x10(%r13,%rdi,8),%xmm7
  movsd  %xmm7,0x8(%rsp)
  shl    $0x2,%rdi
  call   <malloc@plt>
  mov    %rax,%r14
  movslq %ebx,%r12
  mov    %r12,0x18(%rsp)
  mov    %r12,%rdi
  call   <malloc@plt>
  mov    %rax,%rbp
  mov    %r12,%rdi
  call   <malloc@plt>
  mov    %rax,%rbx
  mov    0x14(%rsp),%eax
  lea    -0x2(%rax,%rax,1),%edi
  mov    %edi,0x2c(%rsp)
  mov    %edi,(%r14)
  mov    %r12,%rdx
  mov    $0x0,%esi
  mov    %rbp,%rdi
  call   <memset@plt>
  mov    %r12,%rdx
  mov    $0x0,%esi
  mov    %rbx,%rdi
  call   <memset@plt>
  mov    0x14(%rsp),%r12d
  sub    $0x2,%r12d
  js     L52
  movslq %r12d,%r12
  movsd  D4(%rip),%xmm7
  movsd  %xmm7,0x30(%rsp)
  jmp    L202
L68:
  lea    0x1(%rax),%ebx
  jmp    L3
L211:
  add    $0x1,%edi
  sub    $0x1,%edx
  shr    $0x3,%rax
  not    %ecx
  and    $0x7,%ecx
  mov    $0x1,%esi
  shl    %cl,%esi
  or     %sil,0x0(%rbp,%rax,1)
  or     %sil,(%rbx,%rax,1)
  jmp    L188
L51:
  mov    %r10d,0x4(%r14,%r9,1)
  add    $0x1,%edx
  jmp    L188
L123:
  mov    $0x1,%r10d
  shl    %cl,%r10d
  or     %r10d,%esi
  mov    %sil,(%rax)
  mov    %r8d,0x4(%r14,%r9,1)
  add    $0x1,%edx
  jmp    L188
L158:
  sub    $0x1,%edx
L188:
  test   %edx,%edx
  js     L142
L21:
  movslq %edx,%rax
  lea    0x0(,%rax,4),%r9
  mov    (%r14,%rax,4),%ecx
  sub    %r12d,%ecx
  lea    0x0(,%rcx,4),%eax
  cltq
  lea    (%r15,%rax,8),%rax
  movsd  (%rax),%xmm0
  movsd  0x8(%rax),%xmm1
  movslq %ecx,%rax
  comisd 0x0(%r13,%rax,8),%xmm2
  jae    L211
  shr    $0x3,%rax
  lea    0x0(%rbp,%rax,1),%rsi
  movzbl (%rsi),%r8d
  not    %ecx
  and    $0x7,%ecx
  movzbl %r8b,%r10d
  bt     %ecx,%r10d
  jb     L119
  cvttsd2si %xmm0,%r10d
  mov    $0x1,%r11d
  shl    %cl,%r11d
  or     %r8d,%r11d
  mov    %r11b,(%rsi)
  cmp    %r10d,%r12d
  jle    L51
  add    $0x1,%edi
L119:
  add    %rbx,%rax
  movzbl (%rax),%esi
  movzbl %sil,%r8d
  bt     %ecx,%r8d
  jb     L158
  cvttsd2si %xmm1,%r8d
  cmp    %r8d,%r12d
  jle    L123
  add    $0x1,%edi
  jmp    L158
L142:
  mov    0x20(%rsp),%r12
  cmp    0x28(%rsp),%edi
  jle    L136
  movsd  (%rsp),%xmm7
  comisd 0x30(%rsp),%xmm7
  ja     L195
L136:
  cmp    0x28(%rsp),%edi
  jg     L120
  movsd  0x8(%rsp),%xmm6
  movsd  (%rsp),%xmm5
  minsd  %xmm6,%xmm5
  movsd  %xmm5,0x8(%rsp)
L120:
  sub    $0x1,%r12
  test   %r12d,%r12d
  js     L52
L202:
  movsd  0x0(%r13,%r12,8),%xmm3
  movsd  %xmm3,(%rsp)
  comisd 0x8(%rsp),%xmm3
  ja     L120
  mov    0x2c(%rsp),%eax
  mov    %eax,(%r14)
  mov    0x18(%rsp),%rdx
  mov    $0x0,%esi
  mov    %rbp,%rdi
  call   <memset@plt>
  mov    0x18(%rsp),%rdx
  mov    $0x0,%esi
  mov    %rbx,%rdi
  call   <memset@plt>
  mov    $0x0,%edi
  mov    $0x0,%edx
  mov    %r12,0x20(%rsp)
  movsd  (%rsp),%xmm2
  mov    0x14(%rsp),%r12d
  jmp    L21
L195:
  movsd  (%rsp),%xmm7
  movsd  %xmm7,0x30(%rsp)
  jmp    L120
L52:
  mov    0x14(%rsp),%ecx
  movsd  0x8(%rsp),%xmm0
  mov    0x38(%rsp),%rdx
  mov    %r13,%rsi
  mov    %r15,%rdi
  mov    $0x1,%eax
  call   <form_flat_clusters_from_monotonic_criterion@plt>
  mov    %r14,%rdi
  call   <free@plt>
  mov    %rbp,%rdi
  call   <free@plt>
  mov    %rbx,%rdi
  call   <free@plt>
  add    $0x48,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
```

tool_calls: name: parse_data
arguments: tag: D8
datatype: f32[2]
name: parse_data
arguments: tag: D4
datatype: f32[2]

tool: {"D8": [0.0,1.5]}

tool: {"D4": [0.0,-1.875]}

assistant: ```c
void form_flat_clusters_maxclust_monocrit(const double *Z, const double *mono_crit, int *T, int n, int mc) {
  int *curNode;
  int ndid, lid, rid, k, nc, g, ms;
  unsigned char *lvisited, *rvisited;
  const double *Zrow;
  double thresh, maxmono_crit;
  double max_illegal = -1.0;
  double min_legal = 0.0;
  int min_legal_nc = 1;
  const int bff = (((((double)(n)) / (double)(sizeof(unsigned char) * 8)) == ((double)(((n)) / ((sizeof(unsigned char) * 8)))) ? (((n)) / ((sizeof(unsigned char) * 8))) : (((n)) / ((sizeof(unsigned char) * 8)) + 1)));
  k = 0;
  min_legal = mono_crit[n - 2];
  curNode = (int *)malloc(n * sizeof(int));
  lvisited = (unsigned char *)malloc(bff);
  rvisited = (unsigned char *)malloc(bff);
  curNode[k] = (n * 2) - 2;
  bzero(lvisited, bff);
  bzero(rvisited, bff);
  nc = 0;
  ;
  for (g = n - 2; g >= 0; g--) {
    thresh = mono_crit[g];
    if (thresh > min_legal) {
      continue;
    }
    k = 0;
    curNode[k] = (n * 2) - 2;
    bzero(lvisited, bff);
    bzero(rvisited, bff);
    nc = 0;
    ms = -1;
    while (k >= 0) {
      ndid = curNode[k];
      Zrow = Z + ((ndid - n) * 4);
      lid = (int)Zrow[0];
      rid = (int)Zrow[1];
      maxmono_crit = mono_crit[ndid - n];
      if (maxmono_crit <= thresh) {
        nc++;
        k--;
        ((lvisited)[(ndid - n) / (sizeof(unsigned char) * 8)] |= ((0x1) << (((sizeof(unsigned char) * 8) - 1) - ((ndid - n) % (sizeof(unsigned char) * 8)))));
        ((rvisited)[(ndid - n) / (sizeof(unsigned char) * 8)] |= ((0x1) << (((sizeof(unsigned char) * 8) - 1) - ((ndid - n) % (sizeof(unsigned char) * 8)))));
        continue;
      }
      if (!(((lvisited)[(ndid - n) / (sizeof(unsigned char) * 8)] >> (((sizeof(unsigned char) * 8) - 1) - ((ndid - n) % (sizeof(unsigned char) * 8)))) & 0x1)) {
        ((lvisited)[(ndid - n) / (sizeof(unsigned char) * 8)] |= ((0x1) << (((sizeof(unsigned char) * 8) - 1) - ((ndid - n) % (sizeof(unsigned char) * 8)))));
        if (lid >= n) {
          curNode[k + 1] = lid;
          k++;
          continue;
        } else if (lid < n) {
          nc++;
        }
      }
      if (!(((rvisited)[(ndid - n) / (sizeof(unsigned char) * 8)] >> (((sizeof(unsigned char) * 8) - 1) - ((ndid - n) % (sizeof(unsigned char) * 8)))) & 0x1)) {
        if (rid >= n) {
          ((rvisited)[(ndid - n) / (sizeof(unsigned char) * 8)] |= ((0x1) << (((sizeof(unsigned char) * 8) - 1) - ((ndid - n) % (sizeof(unsigned char) * 8)))));
          curNode[k + 1] = rid;
          k++;
          continue;
        } else if (rid < n) {
          nc++;
        }
      }
      k--;
    }
    if (thresh > max_illegal && nc > mc) {
      ;
      max_illegal = thresh;
      continue;
    }
    if (thresh < min_legal && nc <= mc) {
      min_legal = thresh;
      min_legal_nc = nc;
      ;
    }
  }
  form_flat_clusters_from_monotonic_criterion(Z, mono_crit, T, min_legal, n);
  free(curNode);
  free(lvisited);
  free(rvisited);
}
```