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

```asm
<generic_partition>:
  endbr64
  push   %r15
  mov    %rsi,%r15
  sub    $0x1,%rsi
  push   %r14
  mov    %rcx,%r14
  mov    %rdx,%rcx
  push   %r13
  imul   %r14,%rcx
  push   %r12
  push   %rbp
  push   %rbx
  lea    (%rdi,%rcx,1),%r12
  sub    $0x38,%rsp
  mov    %rdi,0x18(%rsp)
  mov    %r8,(%rsp)
  mov    %rsi,0x8(%rsp)
  mov    %r14d,0x24(%rsp)
  mov    %r14d,0x28(%rsp)
  cmp    %r15,%rdx
  jbe    L45
  mov    %rdi,%rax
  mov    %r14,%rdi
  mov    %rdx,%rbx
  imul   %r15,%rdi
  lea    -0x4(%r14),%edx
  lea    (%rax,%rdi,1),%r13
  mov    %edx,%eax
  shr    $0x2,%eax
  lea    0x1(%rax),%ecx
  shl    $0x2,%eax
  sub    %eax,%edx
  lea    0x0(,%rcx,4),%rsi
  mov    %r15,%rax
  mov    %r13,%r15
  mov    %rsi,0x10(%rsp)
  mov    %rax,%r13
  mov    %edx,0x2c(%rsp)
  jmp    L13
  cs nopw 0x0(%rax,%rax,1)
L98:
  add    $0x1,%r13
  add    %r14,%r15
  cmp    %r13,%rbx
  je     L117
L13:
  mov    (%rsp),%rax
  mov    %r15,%rbp
  mov    %r12,%rsi
  mov    %r15,%rdi
  call   *%rax
  test   %eax,%eax
  jg     L98
  addq   $0x1,0x8(%rsp)
  mov    0x8(%rsp),%r10
  imul   %r14,%r10
  add    0x18(%rsp),%r10
  cmpl   $0x3,0x28(%rsp)
  jbe    L131
  mov    0x10(%rsp),%rax
  lea    (%r15,%rax,1),%r9
  mov    %r10,%rax
  xchg   %ax,%ax
L138:
  mov    (%rax),%ecx
  mov    0x0(%rbp),%edx
  add    $0x4,%rbp
  add    $0x4,%rax
  mov    %ecx,-0x4(%rbp)
  mov    %edx,-0x4(%rax)
  cmp    %r9,%rbp
  jne    L138
  mov    0x2c(%rsp),%edx
  add    0x10(%rsp),%r10
L103:
  test   %edx,%edx
  je     L98
  xor    %eax,%eax
L52:
  movzbl (%r9,%rax,1),%ecx
  movzbl (%r10,%rax,1),%esi
  mov    %sil,(%r9,%rax,1)
  mov    %cl,(%r10,%rax,1)
  add    $0x1,%rax
  cmp    %rdx,%rax
  jne    L52
  add    $0x1,%r13
  add    %r14,%r15
  cmp    %r13,%rbx
  jne    L13
  nopw   0x0(%rax,%rax,1)
L117:
  mov    0x8(%rsp),%r15
  add    $0x1,%r15
L45:
  mov    %r15,%r8
  imul   %r14,%r8
  add    0x18(%rsp),%r8
  cmp    $0x3,%r14d
  jbe    L47
  lea    -0x4(%r14),%r10d
  mov    %r8,%rax
  mov    %r10d,%ebx
  shr    $0x2,%ebx
  lea    0x1(%rbx),%r11d
  shl    $0x2,%r11
  lea    (%r12,%r11,1),%rdi
L130:
  mov    (%rax),%edx
  mov    (%r12),%ecx
  add    $0x4,%r12
  add    $0x4,%rax
  mov    %ecx,-0x4(%rax)
  mov    %edx,-0x4(%r12)
  cmp    %rdi,%r12
  jne    L130
  shl    $0x2,%ebx
  add    %r11,%r8
  sub    %ebx,%r10d
  mov    %r10d,0x24(%rsp)
L31:
  mov    0x24(%rsp),%esi
  xor    %eax,%eax
  test   %esi,%esi
  je     L67
L87:
  movzbl (%r8,%rax,1),%edx
  movzbl (%rdi,%rax,1),%ecx
  mov    %cl,(%r8,%rax,1)
  mov    %dl,(%rdi,%rax,1)
  add    $0x1,%rax
  cmp    %rsi,%rax
  jne    L87
L67:
  add    $0x38,%rsp
  mov    %r15d,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  xchg   %ax,%ax
L131:
  mov    0x24(%rsp),%edx
  mov    %r15,%r9
  jmp    L103
L47:
  mov    %r12,%rdi
  jmp    L31
```

assistant: ```c
int generic_partition(void *array, size_t p, size_t r, size_t size, int (*compare)(const void *, const void *)) {
  unsigned char *a = (unsigned char *)array;
  unsigned char *x = &a[r * size];
  size_t i = p - 1;
  int temp, k;
  unsigned char *ptr1, *ptr2;
  for (size_t j = p; j < r; ++j) {
    if (compare(&a[j * size], x) <= 0) {
      ++i;
      k = size;
      ptr1 = &a[j * size];
      ptr2 = &a[i * size];
      while (k >= sizeof(int)) {
        temp = *(int *)ptr1;
        *(int *)ptr1 = *(int *)ptr2;
        *(int *)ptr2 = temp;
        k -= sizeof(int);
        ptr1 += sizeof(int);
        ptr2 += sizeof(int);
      }
      while (k) {
        temp = *ptr1;
        *ptr1 = *ptr2;
        *ptr2 = temp;
        --k;
        ++ptr1;
        ++ptr2;
      }
    }
  }
  ++i;
  k = size;
  ptr1 = &a[i * size];
  while (k >= sizeof(int)) {
    temp = *(int *)ptr1;
    *(int *)ptr1 = *(int *)x;
    *(int *)x = temp;
    k -= sizeof(int);
    ptr1 += sizeof(int);
    x += sizeof(int);
  }
  while (k) {
    temp = *ptr1;
    *ptr1 = *x;
    *x = temp;
    --k;
    ++ptr1;
    ++x;
  }
  return i;
}
```