user: Translate the below assembly code into C programming language:

```asm
<FFTNXCorr>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x60,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %rcx,-0x50(%rbp)
  mov    %r8,-0x58(%rbp)
  mov    -0x50(%rbp),%rdx
  mov    -0x40(%rbp),%rax
  cmp    %rax,%rdx
  cmovae %rdx,%rax
  mov    %rax,%rdi
  call   <nextpow2@plt>
  mov    %rax,-0x28(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  shl    $0x3,%eax
  mov    %eax,%edi
  call   <safe_malloc@plt>
  mov    %rax,-0x20(%rbp)
  mov    -0x28(%rbp),%rax
  add    $0x1,%rax
  shl    $0x3,%eax
  mov    %eax,%edi
  call   <safe_malloc@plt>
  mov    %rax,-0x18(%rbp)
  mov    -0x40(%rbp),%rax
  sub    $0x1,%rax
  mov    %rax,-0x30(%rbp)
  jmp    L106
L101:
  mov    -0x38(%rbp),%rax
  lea    0x4(%rax),%rdx
  mov    %rdx,-0x38(%rbp)
  mov    -0x30(%rbp),%rdx
  lea    0x0(,%rdx,4),%rcx
  mov    -0x20(%rbp),%rdx
  add    %rcx,%rdx
  movss  (%rax),%xmm0
  movss  %xmm0,(%rdx)
  subq   $0x1,-0x30(%rbp)
L106:
  cmpq   $0x0,-0x30(%rbp)
  jns    L101
  mov    -0x40(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  jmp    L82
L78:
  mov    -0x30(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  pxor   %xmm0,%xmm0
  movss  %xmm0,(%rax)
  addq   $0x1,-0x30(%rbp)
L82:
  mov    -0x28(%rbp),%rax
  add    %rax,%rax
  cmp    %rax,-0x30(%rbp)
  jl     L78
  mov    -0x28(%rbp),%rax
  add    %eax,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <RealFFT@plt>
  movq   $0x0,-0x30(%rbp)
  jmp    L97
L90:
  mov    -0x30(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x48(%rbp),%rax
  add    %rax,%rdx
  mov    -0x30(%rbp),%rax
  lea    0x0(,%rax,4),%rcx
  mov    -0x18(%rbp),%rax
  add    %rcx,%rax
  movss  (%rdx),%xmm0
  movss  %xmm0,(%rax)
  addq   $0x1,-0x30(%rbp)
L97:
  mov    -0x50(%rbp),%rax
  cmp    %rax,-0x30(%rbp)
  jl     L90
  mov    -0x50(%rbp),%rax
  mov    %rax,-0x30(%rbp)
  jmp    L76
L114:
  mov    -0x30(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  pxor   %xmm0,%xmm0
  movss  %xmm0,(%rax)
  addq   $0x1,-0x30(%rbp)
L76:
  mov    -0x28(%rbp),%rax
  add    %rax,%rax
  cmp    %rax,-0x30(%rbp)
  jl     L114
  mov    -0x28(%rbp),%rax
  add    %eax,%eax
  mov    %eax,%edx
  mov    -0x18(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <RealFFT@plt>
  movq   $0x0,-0x30(%rbp)
  jmp    L92
L54:
  mov    -0x30(%rbp),%rax
  add    %rax,%rax
  mov    %rax,-0x8(%rbp)
  mov    -0x8(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movss  (%rax),%xmm2
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  movss  (%rax),%xmm3
  mov    -0x8(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movss  (%rax),%xmm0
  mulss  %xmm2,%xmm0
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movss  (%rax),%xmm1
  mulss  %xmm3,%xmm1
  mov    -0x8(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  subss  %xmm1,%xmm0
  movss  %xmm0,(%rax)
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movss  (%rax),%xmm0
  movaps %xmm2,%xmm1
  mulss  %xmm0,%xmm1
  mov    -0x8(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x18(%rbp),%rax
  add    %rdx,%rax
  movss  (%rax),%xmm0
  mulss  %xmm3,%xmm0
  mov    -0x8(%rbp),%rax
  add    $0x1,%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x20(%rbp),%rax
  add    %rdx,%rax
  addss  %xmm1,%xmm0
  movss  %xmm0,(%rax)
  addq   $0x1,-0x30(%rbp)
L92:
  mov    -0x30(%rbp),%rax
  cmp    -0x28(%rbp),%rax
  jle    L54
  mov    -0x28(%rbp),%rax
  add    %eax,%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%rax
  mov    %edx,%esi
  mov    %rax,%rdi
  call   <RealIFFT@plt>
  mov    -0x40(%rbp),%rdx
  mov    -0x50(%rbp),%rax
  add    %rdx,%rax
  sub    $0x1,%rax
  mov    %rax,-0x10(%rbp)
  movq   $0x0,-0x30(%rbp)
  jmp    L100
L20:
  mov    -0x30(%rbp),%rax
  lea    0x0(,%rax,4),%rdx
  mov    -0x20(%rbp),%rax
  add    %rax,%rdx
  mov    -0x30(%rbp),%rax
  lea    0x0(,%rax,4),%rcx
  mov    -0x58(%rbp),%rax
  add    %rcx,%rax
  movss  (%rdx),%xmm0
  movss  %xmm0,(%rax)
  addq   $0x1,-0x30(%rbp)
L100:
  mov    -0x30(%rbp),%rax
  cmp    -0x10(%rbp),%rax
  jl     L20
  mov    -0x20(%rbp),%rax
  mov    %rax,%rdi
  call   <safe_free@plt>
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <safe_free@plt>
  mov    -0x10(%rbp),%rax
  leave
  ret
```

assistant: ```c
unsigned long FFTNXCorr(float *x1, unsigned long n1, float *x2, unsigned long n2, float *y) {
  register float r1, i1;
  float *tmp1;
  float *tmp2;
  long C, D, Nx, Ny;
  Nx = nextpow2((((n1) > (n2)) ? (n1) : (n2)));
  tmp1 = (float *)safe_malloc(sizeof(float) * (2 * Nx + 2));
  tmp2 = (float *)safe_malloc(sizeof(float) * (2 * Nx + 2));
  for (C = n1 - 1; C >= 0; C--) {
    tmp1[C] = *(x1++);
  }
  for (C = n1; C < 2 * Nx; C++)
    tmp1[C] = 0.0;
  RealFFT(tmp1, 2 * Nx);
  for (C = 0; C < (long)n2; C++) {
    tmp2[C] = x2[C];
  }
  for (C = n2; C < 2 * Nx; C++)
    tmp2[C] = 0.0;
  RealFFT(tmp2, 2 * Nx);
  for (C = 0; C <= Nx; C++) {
    D = C << 1;
    r1 = tmp1[D];
    i1 = tmp1[1 + D];
    tmp1[D] = r1 * tmp2[D] - i1 * tmp2[1 + D];
    tmp1[1 + D] = r1 * tmp2[1 + D] + i1 * tmp2[D];
  }
  RealIFFT(tmp1, 2 * Nx);
  Ny = n1 + n2 - 1;
  for (C = 0; C < Ny; C++)
    y[C] = tmp1[C];
  safe_free(tmp1);
  safe_free(tmp2);
  return Ny;
}
```