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

```asm
<matrix_vector_product_omp>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x38(%rbp)
  mov    %rsi,-0x40(%rbp)
  mov    %rdx,-0x48(%rbp)
  mov    %ecx,-0x4c(%rbp)
  mov    %r8d,-0x50(%rbp)
  mov    $0x0,%eax
  call   <omp_get_wtime@plt>
  movq   %xmm0,%rax
  mov    %rax,-0x8(%rbp)
  mov    $0x0,%eax
  call   <omp_get_num_threads@plt>
  mov    %eax,-0x1c(%rbp)
  mov    $0x0,%eax
  call   <omp_get_thread_num@plt>
  mov    %eax,-0x18(%rbp)
  mov    -0x4c(%rbp),%eax
  cltd
  idivl  -0x1c(%rbp)
  mov    %eax,-0x14(%rbp)
  mov    -0x18(%rbp),%eax
  imul   -0x14(%rbp),%eax
  mov    %eax,-0x10(%rbp)
  mov    -0x1c(%rbp),%eax
  sub    $0x1,%eax
  cmp    %eax,-0x18(%rbp)
  jne    L43
  mov    -0x4c(%rbp),%eax
  sub    $0x1,%eax
  jmp    L58
L43:
  mov    -0x10(%rbp),%edx
  mov    -0x14(%rbp),%eax
  add    %edx,%eax
  sub    $0x1,%eax
L58:
  mov    %eax,-0xc(%rbp)
  mov    -0x10(%rbp),%eax
  mov    %eax,-0x24(%rbp)
  jmp    L38
L17:
  mov    -0x24(%rbp),%eax
  cltq
  lea    0x0(,%rax,8),%rdx
  mov    -0x48(%rbp),%rax
  add    %rdx,%rax
  pxor   %xmm0,%xmm0
  movsd  %xmm0,(%rax)
  movl   $0x0,-0x20(%rbp)
  jmp    L20
L10:
  mov    -0x24(%rbp),%eax
  cltq
  lea    0x0(,%rax,8),%rdx
  mov    -0x48(%rbp),%rax
  add    %rdx,%rax
  movsd  (%rax),%xmm1
  mov    -0x24(%rbp),%eax
  imul   -0x50(%rbp),%eax
  mov    %eax,%edx
  mov    -0x20(%rbp),%eax
  add    %edx,%eax
  cltq
  lea    0x0(,%rax,8),%rdx
  mov    -0x38(%rbp),%rax
  add    %rdx,%rax
  movsd  (%rax),%xmm2
  mov    -0x20(%rbp),%eax
  cltq
  lea    0x0(,%rax,8),%rdx
  mov    -0x40(%rbp),%rax
  add    %rdx,%rax
  movsd  (%rax),%xmm0
  mulsd  %xmm2,%xmm0
  mov    -0x24(%rbp),%eax
  cltq
  lea    0x0(,%rax,8),%rdx
  mov    -0x48(%rbp),%rax
  add    %rdx,%rax
  addsd  %xmm1,%xmm0
  movsd  %xmm0,(%rax)
  addl   $0x1,-0x20(%rbp)
L20:
  mov    -0x20(%rbp),%eax
  cmp    -0x50(%rbp),%eax
  jl     L10
  addl   $0x1,-0x24(%rbp)
L38:
  mov    -0x24(%rbp),%eax
  cmp    -0xc(%rbp),%eax
  jle    L17
  mov    $0x0,%eax
  call   <omp_get_wtime@plt>
  movq   %xmm0,%rax
  movq   %rax,%xmm0
  subsd  -0x8(%rbp),%xmm0
  movsd  %xmm0,-0x8(%rbp)
  mov    -0xc(%rbp),%eax
  sub    -0x10(%rbp),%eax
  lea    0x1(%rax),%esi
  mov    -0x8(%rbp),%rcx
  mov    -0xc(%rbp),%r8d
  mov    -0x10(%rbp),%edi
  mov    -0x1c(%rbp),%edx
  mov    -0x18(%rbp),%eax
  movq   %rcx,%xmm0
  mov    %r8d,%r9d
  mov    %edi,%r8d
  mov    %esi,%ecx
  mov    %eax,%esi
  lea    D5(%rip),%rax
  mov    %rax,%rdi
  call   <printf@plt>
  nop
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: data_label: D5
datatype: string

tool: D5: Thread %d/%d rows %d [%10d - %10d]: %.6f sec.


assistant: ```c
void matrix_vector_product_omp(double *a, double *b, double *c, int m, int n) {
#pragma omp parallel
  {
    double t = omp_get_wtime();
    int nthreads = omp_get_num_threads();
    int threadid = omp_get_thread_num();
    int items_per_thread = m / nthreads;
    int lb = threadid * items_per_thread;
    int ub = (threadid == nthreads - 1) ? (m - 1) : (lb + items_per_thread - 1);
    for (int i = lb; i <= ub; i++) {
      c[i] = 0.0;
      for (int j = 0; j < n; j++)
        c[i] += a[i * n + j] * b[j];
    }
    t = omp_get_wtime() - t;
    printf("Thread %d/%d rows %d [%10d - %10d]: %.6f sec.\n", threadid, nthreads, ub - lb + 1, lb, ub, t);
  }
}
```