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

```asm
<gemver>:
  endbr64
  push   %r15
  mov    %rdi,%rax
  mov    %rdx,%r10
  mov    %rsi,%r11
  push   %r14
  lea    0x8000000(%rax),%rdx
  lea    0x8(%r8),%r14
  push   %r13
  lea    0x8(%r10),%r13
  push   %r12
  push   %rbp
  lea    0x8000(%rax),%rbp
  push   %rbx
  mov    0x48(%rsp),%r15
  mov    %rcx,%rbx
  mov    %r9,-0x18(%rsp)
  mov    %rax,-0x10(%rsp)
  mov    %rdi,-0x20(%rsp)
  mov    %r8,%rdi
L128:
  mov    %r11,%rcx
  mov    %rbx,%rsi
  add    $0x8,%r11
  add    $0x8,%rbx
  cmp    %r13,%rax
  setne  %r9b
  cmp    %r14,%rax
  setne  %r8b
  and    %r8d,%r9d
  cmp    %rbp,%rcx
  setae  %r8b
  cmp    %r11,%rax
  setae  %r12b
  or     %r12d,%r8d
  test   %r8b,%r9b
  je     L44
  cmp    %rsi,%rbp
  setbe  %r9b
  cmp    %rbx,%rax
  setae  %r8b
  or     %r9b,%r8b
  je     L44
  movsd  (%rcx),%xmm3
  movsd  (%rsi),%xmm2
  xor    %ecx,%ecx
  unpcklpd %xmm3,%xmm3
  unpcklpd %xmm2,%xmm2
  nopl   0x0(%rax)
L19:
  movupd (%r10,%rcx,1),%xmm0
  movupd (%rdi,%rcx,1),%xmm1
  movupd (%rax,%rcx,1),%xmm4
  mulpd  %xmm3,%xmm0
  mulpd  %xmm2,%xmm1
  addpd  %xmm4,%xmm0
  addpd  %xmm1,%xmm0
  movups %xmm0,(%rax,%rcx,1)
  add    $0x10,%rcx
  cmp    $0x8000,%rcx
  jne    L19
L78:
  add    $0x8000,%rax
  add    $0x8000,%rbp
  cmp    %rdx,%rax
  jne    L128
  mov    0x38(%rsp),%rsi
  mov    -0x20(%rsp),%r9
  mov    -0x10(%rsp),%rcx
  mov    0x40(%rsp),%r10
  mov    %rsi,%r8
  add    $0x8008000,%r9
L86:
  movsd  (%r8),%xmm1
  lea    -0x8000000(%rdx),%rax
  mov    %r10,%rdi
  nopl   0x0(%rax)
L32:
  movsd  (%rax),%xmm0
  mulsd  (%rdi),%xmm0
  add    $0x8000,%rax
  add    $0x8,%rdi
  addsd  %xmm0,%xmm1
  movsd  %xmm1,(%r8)
  cmp    %rdx,%rax
  jne    L32
  lea    0x8(%rax),%rdx
  add    $0x8,%r8
  cmp    %r9,%rdx
  jne    L86
  lea    0x8(%r15),%rax
  cmp    %rax,%rsi
  mov    $0x0,%eax
  je     L59
L84:
  movupd (%r15,%rax,1),%xmm0
  movupd (%rsi,%rax,1),%xmm5
  addpd  %xmm5,%xmm0
  movups %xmm0,(%rsi,%rax,1)
  add    $0x10,%rax
  cmp    $0x8000,%rax
  jne    L84
L122:
  mov    -0x18(%rsp),%rdx
  lea    0x8000(%rdx),%rdi
L110:
  movsd  (%rdx),%xmm1
  xor    %eax,%eax
  nopl   0x0(%rax)
L20:
  movsd  (%rcx,%rax,1),%xmm0
  mulsd  (%rsi,%rax,1),%xmm0
  add    $0x8,%rax
  addsd  %xmm0,%xmm1
  movsd  %xmm1,(%rdx)
  cmp    $0x8000,%rax
  jne    L20
  add    $0x8,%rdx
  add    $0x8000,%rcx
  cmp    %rdi,%rdx
  jne    L110
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
L59:
  movsd  (%rsi,%rax,1),%xmm0
  addsd  (%r15,%rax,1),%xmm0
  movsd  %xmm0,(%rsi,%rax,1)
  add    $0x8,%rax
  cmp    $0x8000,%rax
  jne    L59
  jmp    L122
  nop
L44:
  xor    %r8d,%r8d
  nopl   0x0(%rax,%rax,1)
L82:
  movsd  (%rsi),%xmm1
  mulsd  (%rdi,%r8,1),%xmm1
  movsd  (%rcx),%xmm0
  mulsd  (%r10,%r8,1),%xmm0
  addsd  (%rax,%r8,1),%xmm0
  addsd  %xmm1,%xmm0
  movsd  %xmm0,(%rax,%r8,1)
  add    $0x8,%r8
  cmp    $0x8000,%r8
  jne    L82
  jmp    L78
```

assistant: ```c
void gemver(double A[4096][4096], double u1[4096], double v1[4096], double u2[4096], double v2[4096], double w[4096], double x[4096], double y[4096], double z[4096]) {
  int i, j;
#pragma scop
#pragma live - out w
  for (i = 0; i < 4096; i++)
    for (j = 0; j < 4096; j++)
      A[i][j] = A[i][j] + u1[i] * v1[j] + u2[i] * v2[j];
  for (i = 0; i < 4096; i++)
    for (j = 0; j < 4096; j++)
      x[i] = x[i] + A[j][i] * y[j];
  for (i = 0; i < 4096; i++)
    x[i] = x[i] + z[i];
  for (i = 0; i < 4096; i++)
    for (j = 0; j < 4096; j++)
      w[i] = w[i] + A[i][j] * x[j];
#pragma endscop
}
```