user: Demonstrate the C code that generates the assembly output below:

```asm
<read_mosaic_grid_data>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x360,%rsp
  mov    %rdi,-0x338(%rbp)
  mov    %rsi,-0x340(%rbp)
  mov    %edx,-0x344(%rbp)
  mov    %ecx,-0x348(%rbp)
  mov    %r8,-0x350(%rbp)
  mov    %r9d,-0x354(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  lea    -0x110(%rbp),%rdx
  mov    -0x338(%rbp),%rax
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <get_file_dir@plt>
  lea    -0x354(%rbp),%rcx
  lea    -0x210(%rbp),%rdx
  mov    -0x338(%rbp),%rax
  lea    D3(%rip),%rsi
  mov    %rax,%rdi
  call   <get_string_data_level@plt>
  lea    -0x210(%rbp),%rcx
  lea    -0x110(%rbp),%rdx
  lea    -0x310(%rbp),%rax
  lea    D14(%rip),%rsi
  mov    %rax,%rdi
  call   <sprintf@plt>
  lea    -0x310(%rbp),%rax
  lea    D46(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <get_dimlen@plt>
  mov    %eax,-0x328(%rbp)
  lea    -0x310(%rbp),%rax
  lea    D19(%rip),%rdx
  mov    %rdx,%rsi
  mov    %rax,%rdi
  call   <get_dimlen@plt>
  mov    %eax,-0x324(%rbp)
  mov    -0x344(%rbp),%eax
  add    %eax,%eax
  cmp    %eax,-0x328(%rbp)
  jne    L1
  mov    -0x348(%rbp),%eax
  add    %eax,%eax
  cmp    %eax,-0x324(%rbp)
  je     L10
L1:
  lea    D20(%rip),%rax
  mov    %rax,%rdi
  call   <error_handler@plt>
L10:
  mov    -0x328(%rbp),%eax
  lea    0x1(%rax),%edx
  mov    -0x324(%rbp),%eax
  add    $0x1,%eax
  imul   %edx,%eax
  cltq
  shl    $0x3,%eax
  mov    %eax,%edi
  call   <malloc@plt>
  mov    %rax,-0x318(%rbp)
  mov    -0x318(%rbp),%rdx
  mov    -0x340(%rbp),%rcx
  lea    -0x310(%rbp),%rax
  mov    %rcx,%rsi
  mov    %rax,%rdi
  call   <get_double_data@plt>
  mov    -0x344(%rbp),%eax
  add    $0x1,%eax
  sub    0x10(%rbp),%eax
  mov    %eax,-0x320(%rbp)
  mov    -0x348(%rbp),%eax
  add    $0x1,%eax
  sub    0x18(%rbp),%eax
  mov    %eax,-0x31c(%rbp)
  movl   $0x0,-0x32c(%rbp)
  jmp    L11
L0:
  movl   $0x0,-0x330(%rbp)
  jmp    L32
L13:
  mov    -0x32c(%rbp),%eax
  lea    (%rax,%rax,1),%edx
  mov    0x18(%rbp),%eax
  add    %eax,%edx
  mov    -0x328(%rbp),%eax
  add    $0x1,%eax
  imul   %eax,%edx
  mov    -0x330(%rbp),%eax
  add    %eax,%eax
  add    %eax,%edx
  mov    0x10(%rbp),%eax
  add    %edx,%eax
  cltq
  lea    0x0(,%rax,8),%rdx
  mov    -0x318(%rbp),%rax
  add    %rax,%rdx
  mov    -0x32c(%rbp),%eax
  imul   -0x320(%rbp),%eax
  mov    %eax,%ecx
  mov    -0x330(%rbp),%eax
  add    %ecx,%eax
  cltq
  lea    0x0(,%rax,8),%rcx
  mov    -0x350(%rbp),%rax
  add    %rcx,%rax
  movsd  (%rdx),%xmm0
  movsd  %xmm0,(%rax)
  addl   $0x1,-0x330(%rbp)
L32:
  mov    -0x330(%rbp),%eax
  cmp    -0x320(%rbp),%eax
  jl     L13
  addl   $0x1,-0x32c(%rbp)
L11:
  mov    -0x32c(%rbp),%eax
  cmp    -0x31c(%rbp),%eax
  jl     L0
  mov    -0x318(%rbp),%rax
  mov    %rax,%rdi
  call   <free@plt>
  nop
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L20
  call   <__stack_chk_fail@plt>
L20:
  leave
  ret
```

tool_calls: name: retrieve_data
arguments: label: D3
type_infered: string
name: retrieve_data
arguments: label: D14
type_infered: string
name: retrieve_data
arguments: label: D46
type_infered: string
name: retrieve_data
arguments: label: D19
type_infered: string
name: retrieve_data
arguments: label: D20
type_infered: string

tool: D3: gridfiles

tool: D14: %s/%s

tool: D46: nx

tool: D19: ny

tool: D20: supergrid size should be double of the model grid size

assistant: ```c
void read_mosaic_grid_data(const char *mosaic_file, const char *name, int nx, int ny, double *data, int level, int ioff, int joff) {
  char tilefile[255], gridfile[255], dir[255];
  double *tmp;
  int ni, nj, nxp, nyp, i, j;
  get_file_dir(mosaic_file, dir);
  get_string_data_level(mosaic_file, "gridfiles", gridfile, &level);
  sprintf(tilefile, "%s/%s", dir, gridfile);
  ni = get_dimlen(tilefile, "nx");
  nj = get_dimlen(tilefile, "ny");
  if (ni != nx * 2 || nj != ny * 2)
    error_handler("supergrid size should be double of the model grid size");
  tmp = (double *)malloc((ni + 1) * (nj + 1) * sizeof(double));
  get_double_data(tilefile, name, tmp);
  nxp = nx + 1 - ioff;
  nyp = ny + 1 - joff;
  for (j = 0; j < nyp; j++)
    for (i = 0; i < nxp; i++)
      data[j * nxp + i] = tmp[(2 * j + joff) * (ni + 1) + 2 * i + ioff];
  free(tmp);
}
```