user: 请将以下的汇编代码转换成C语言代码:

```asm
<updateCPneg>:
  endbr64
  mov    %edi,%r11d
  imul   %esi,%r11d
  test   %r11d,%r11d
  jle    L18
  movslq %r11d,%rax
  mov    %rcx,%rdi
  lea    -0x1(%r11),%r9d
  mov    %rax,%rcx
  shl    $0x5,%rcx
  lea    -0x8(%rdx,%rcx,1),%rsi
  lea    (%rax,%rax,2),%rcx
  lea    (%r8,%rcx,8),%rcx
  lea    (%rdi,%rax,8),%rax
  cmp    %rcx,%rdx
  setae  %cl
  cmp    %rsi,%r8
  setae  %r10b
  or     %r10d,%ecx
  cmp    %rax,%rdx
  setae  %al
  cmp    %rsi,%rdi
  setae  %sil
  or     %esi,%eax
  test   %al,%cl
  je     L56
  cmp    $0x1,%r9d
  jbe    L56
  mov    %r9d,%r10d
  push   %r14
  mov    %rdx,%rax
  mov    %rdi,%rsi
  shr    %r10d
  push   %r13
  mov    %r8,%rcx
  push   %r12
  sub    $0x1,%r10d
  push   %rbp
  shl    $0x6,%r10
  push   %rbx
  lea    0x40(%rdx,%r10,1),%r10
  nopl   0x0(%rax,%rax,1)
L27:
  movupd (%rcx),%xmm4
  movupd (%rsi),%xmm5
  add    $0x40,%rax
  add    $0x10,%rsi
  movupd -0x40(%rax),%xmm1
  movupd -0x20(%rax),%xmm6
  add    $0x30,%rcx
  movapd %xmm4,%xmm0
  movhps -0x18(%rcx),%xmm0
  movupd -0x10(%rax),%xmm2
  movhpd -0x30(%rax),%xmm1
  movhpd -0x10(%rax),%xmm6
  movlpd -0x18(%rax),%xmm2
  mulpd  %xmm5,%xmm0
  movapd %xmm1,%xmm3
  unpckhpd %xmm6,%xmm1
  unpcklpd %xmm6,%xmm3
  subpd  %xmm0,%xmm3
  movupd -0x30(%rax),%xmm0
  movlpd -0x38(%rax),%xmm0
  unpcklpd %xmm2,%xmm0
  movapd %xmm4,%xmm2
  shufpd $0x1,%xmm4,%xmm2
  movhpd -0x10(%rcx),%xmm2
  mulpd  %xmm5,%xmm2
  subpd  %xmm2,%xmm0
  movupd -0x20(%rcx),%xmm2
  unpcklpd %xmm4,%xmm2
  movhps -0x8(%rcx),%xmm2
  movlpd %xmm3,-0x40(%rax)
  movhpd %xmm3,-0x20(%rax)
  mulpd  %xmm5,%xmm2
  movlpd %xmm0,-0x38(%rax)
  movhpd %xmm0,-0x18(%rax)
  subpd  %xmm2,%xmm1
  movlpd %xmm1,-0x30(%rax)
  movhpd %xmm1,-0x10(%rax)
  cmp    %r10,%rax
  jne    L27
  mov    %r9d,%eax
  and    $0xfffffffe,%eax
  mov    %eax,%r10d
  lea    (%rax,%rax,2),%ecx
  lea    0x0(,%rax,4),%r9d
  add    $0x1,%eax
  shl    $0x3,%r10
  movslq %ecx,%rsi
  movslq %r9d,%r9
  lea    (%rdi,%r10,1),%r12
  movsd  (%r8,%rsi,8),%xmm1
  lea    0x0(,%r9,8),%rbx
  mulsd  (%r12),%xmm1
  lea    (%rdx,%rbx,1),%r13
  lea    0x0(,%rsi,8),%rbp
  add    $0x1,%rsi
  movsd  0x0(%r13),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,0x0(%r13)
  movsd  (%r8,%rsi,8),%xmm1
  mulsd  (%r12),%xmm1
  lea    0x8(,%r9,8),%r13
  lea    (%rdx,%r13,1),%r14
  lea    0x8(%rdx,%r13,1),%r13
  movsd  (%r14),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,(%r14)
  movsd  0x8(%r8,%rsi,8),%xmm1
  mulsd  (%r12),%xmm1
  movsd  0x0(%r13),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,0x0(%r13)
  cmp    %r11d,%eax
  jge    L40
  lea    0x8(%rdi,%r10,1),%rax
  movsd  0x18(%r8,%rbp,1),%xmm1
  lea    0x20(%rdx,%rbx,1),%rsi
  add    $0x4,%ecx
  mulsd  (%rax),%xmm1
  movsd  (%rsi),%xmm0
  movslq %ecx,%rcx
  subsd  %xmm1,%xmm0
  movsd  %xmm0,(%rsi)
  movsd  (%r8,%rcx,8),%xmm1
  mulsd  (%rax),%xmm1
  lea    0x28(,%r9,8),%rsi
  lea    (%rdx,%rsi,1),%rdi
  lea    0x8(%rdx,%rsi,1),%rdx
  movsd  (%rdi),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,(%rdi)
  movsd  0x8(%r8,%rcx,8),%xmm1
  mulsd  (%rax),%xmm1
  movsd  (%rdx),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,(%rdx)
L40:
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  ret
  nopw   0x0(%rax,%rax,1)
L56:
  mov    %rdx,%rax
  shl    $0x5,%r9
  mov    %rdi,%rdx
  lea    0x20(%rax,%r9,1),%rcx
  nopw   0x0(%rax,%rax,1)
L45:
  movsd  (%rdx),%xmm1
  movsd  (%rax),%xmm0
  add    $0x20,%rax
  add    $0x8,%rdx
  mulsd  (%r8),%xmm1
  add    $0x18,%r8
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x20(%rax)
  movsd  -0x8(%rdx),%xmm1
  mulsd  -0x10(%r8),%xmm1
  movsd  -0x18(%rax),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x18(%rax)
  movsd  -0x8(%rdx),%xmm1
  mulsd  -0x8(%r8),%xmm1
  movsd  -0x10(%rax),%xmm0
  subsd  %xmm1,%xmm0
  movsd  %xmm0,-0x10(%rax)
  cmp    %rax,%rcx
  jne    L45
  ret
  nopw   0x0(%rax,%rax,1)
L18:
  ret
```

assistant: ```c
void updateCPneg(int ncp, int kcp, double *cp, double *gnDir, double *dirOffset) {
  int i;
  for (i = 0; i < kcp * ncp; i++) {
    cp[4 * i] -= gnDir[i] * dirOffset[3 * i];
    cp[4 * i + 1] -= gnDir[i] * dirOffset[3 * i + 1];
    cp[4 * i + 2] -= gnDir[i] * dirOffset[3 * i + 2];
  }
}
```