user: 请显示与下面列出的汇编代码相匹配的C语言实现：

```asm
<sort_faces>:
  endbr64
  push   %r15
  movslq %ecx,%r11
  xor    %eax,%eax
  push   %r14
  lea    0x0(,%r11,4),%r15
  mov    %rdx,%r14
  push   %r13
  mov    %r11,%r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rsi,%rbx
  sub    $0x38,%rsp
  mov    %rdi,0x18(%rsp)
  mov    %r15,%rdi
  mov    %r11,0x28(%rsp)
  call   <check_malloc@plt>
  mov    %r15,%rdi
  cltq
  mov    %rax,0x8(%rsp)
  xor    %eax,%eax
  call   <check_malloc@plt>
  mov    %r15,%rdi
  movslq %eax,%r12
  xor    %eax,%eax
  call   <check_malloc@plt>
  lea    0x0(%r13,%r13,1),%edi
  cltq
  movslq %edi,%rdi
  shl    $0x2,%rdi
  mov    %rax,0x10(%rsp)
  xor    %eax,%eax
  mov    %rdi,0x20(%rsp)
  call   <check_malloc@plt>
  mov    0x20(%rsp),%rdi
  movslq %eax,%rbp
  xor    %eax,%eax
  call   <check_malloc@plt>
  movslq %eax,%r8
  test   %r13d,%r13d
  jle    L68
  mov    0x28(%rsp),%r11
  lea    (%r15,%r12,1),%rcx
  mov    %r12,%rax
  mov    %r13d,%esi
  mov    %rbp,0x20(%rsp)
  mov    %r12,%rdx
  shl    $0x3,%r11
  cmp    %rbp,%rcx
  lea    0x0(%rbp,%r11,1),%r10
  setbe  %dil
  cmp    %r12,%r10
  setbe  %r9b
  or     %r9d,%edi
  lea    0x4(%r14),%r9
  sub    %r9,%rax
  cmp    $0x8,%rax
  seta   %r9b
  and    %edi,%r9d
  cmp    $0x1,%r13d
  setne  %dil
  and    %r9d,%edi
  lea    (%rbx,%r11,1),%r9
  cmp    %r9,%r12
  setae  %r9b
  cmp    %rcx,%rbx
  lea    (%r14,%r15,1),%rcx
  setae  %r11b
  or     %r11d,%r9d
  and    %edi,%r9d
  cmp    %rcx,%rbp
  setae  %cl
  cmp    %r10,%r14
  setae  %dil
  or     %edi,%ecx
  test   %cl,%r9b
  je     L62
  lea    0x20(%rbx),%rcx
  lea    0x20(%rbp),%rdi
  cmp    %rcx,%rbp
  setae  %cl
  cmp    %rdi,%rbx
  setae  %dil
  or     %dil,%cl
  je     L62
  lea    -0x1(%r13),%ecx
  cmp    $0x2,%ecx
  jbe    L8
  shr    $0x2,%esi
  mov    %r14,%rdi
  mov    %rbx,%rcx
  mov    %rbp,%rax
  shl    $0x5,%rsi
  sub    %r12,%rdi
  sub    %rbp,%rcx
  add    %rbp,%rsi
  nopl   0x0(%rax,%rax,1)
L98:
  movdqu (%rdx,%rdi,1),%xmm1
  add    $0x10,%rdx
  movups %xmm1,-0x10(%rdx)
  movdqu 0x10(%rcx,%rax,1),%xmm0
  movdqu (%rcx,%rax,1),%xmm2
  add    $0x20,%rax
  movups %xmm2,-0x20(%rax)
  movups %xmm0,-0x10(%rax)
  cmp    %rax,%rsi
  jne    L98
  mov    %r13d,%edx
  and    $0xfffffffc,%edx
  mov    %edx,%eax
  cmp    %edx,%r13d
  je     L68
  mov    %r13d,%esi
  sub    %edx,%esi
  cmp    $0x1,%esi
  je     L60
L14:
  mov    (%r14,%rdx,4),%r9
  lea    0x0(,%rdx,8),%rcx
  lea    (%rbx,%rcx,1),%rdi
  add    %rbp,%rcx
  mov    %r9,(%r12,%rdx,4)
  mov    0x8(%rdi),%rdx
  mov    (%rdi),%r9
  mov    %rdx,0x8(%rcx)
  mov    %esi,%edx
  and    $0xfffffffe,%edx
  mov    %r9,(%rcx)
  add    %edx,%eax
  cmp    %edx,%esi
  je     L68
L60:
  cltq
  mov    (%r14,%rax,4),%edx
  mov    %edx,(%r12,%rax,4)
  shl    $0x3,%rax
  add    %rax,%rbx
  add    %rbp,%rax
  mov    (%rbx),%edx
  mov    %edx,(%rax)
  mov    0x4(%rbx),%edx
  mov    %edx,0x4(%rax)
L68:
  sub    $0x8,%rsp
  mov    %r12,%r9
  mov    %rbp,%rcx
  mov    %r13d,%edx
  mov    0x18(%rsp),%r15
  xor    %eax,%eax
  push   %r15
  mov    0x18(%rsp),%rbx
  mov    0x28(%rsp),%rdi
  mov    %rbx,%rsi
  mov    %r8,0x20(%rsp)
  call   <global_msort@plt>
  mov    %rbx,%rdi
  xor    %eax,%eax
  call   <check_free@plt>
  mov    %r12,%rdi
  xor    %eax,%eax
  call   <check_free@plt>
  mov    %r15,%rdi
  xor    %eax,%eax
  call   <check_free@plt>
  mov    %rbp,%rdi
  xor    %eax,%eax
  call   <check_free@plt>
  mov    0x20(%rsp),%rdi
  add    $0x48,%rsp
  xor    %eax,%eax
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  jmp    1070 <check_free@plt>
  nopl   (%rax)
L62:
  mov    %r13d,%eax
  mov    %rbp,%rdi
  sub    %r12,%r14
  lea    (%r12,%rax,4),%rsi
  sub    %rbx,%rdi
  mov    %r12,%rax
  nopl   0x0(%rax,%rax,1)
L97:
  mov    (%r14,%rax,1),%edx
  add    $0x4,%rax
  mov    %edx,-0x4(%rax)
  mov    (%rbx),%ecx
  lea    (%rdi,%rbx,1),%rdx
  add    $0x8,%rbx
  mov    %ecx,(%rdx)
  mov    -0x4(%rbx),%ecx
  mov    %ecx,0x4(%rdx)
  cmp    %rax,%rsi
  jne    L97
  jmp    L68
L8:
  xor    %edx,%edx
  xor    %eax,%eax
  jmp    L14
```

assistant: ```c
void sort_faces(int pm[], int fpoint[][2], int ttype[], int nfaces) {
  int *pm_tmp = check_malloc(nfaces * sizeof(int));
  int *tp = check_malloc(nfaces * sizeof(int));
  int *tp_tmp = check_malloc(nfaces * sizeof(int));
  int(*fp)[2] = check_malloc(2 * nfaces * sizeof(int));
  int(*fp_tmp)[2] = check_malloc(2 * nfaces * sizeof(int));
  int face;
  for (face = 0; face < nfaces; face++) {
    tp[face] = ttype[face];
    fp[face][0] = fpoint[face][0];
    fp[face][1] = fpoint[face][1];
  }
  global_msort(pm, pm_tmp, nfaces, fp, fp_tmp, tp, tp_tmp);
  check_free(pm_tmp);
  check_free(tp);
  check_free(tp_tmp);
  check_free(fp);
  check_free(fp_tmp);
}
```