user: Converte this assembly snippet into its equivalent C code:

```asm
<vtopPageProperty>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x50,%rsp
  mov    %rdi,-0x28(%rbp)
  mov    %esi,-0x2c(%rbp)
  mov    %edx,-0x30(%rbp)
  mov    %ecx,-0x34(%rbp)
  mov    %r8,-0x40(%rbp)
  mov    %r9,-0x48(%rbp)
  mov    -0x30(%rbp),%eax
  and    $0xfffff000,%eax
  mov    %eax,%edx
  mov    -0x34(%rbp),%eax
  shr    $0x14,%eax
  and    $0xfffffffc,%eax
  add    %edx,%eax
  mov    %eax,-0x14(%rbp)
  mov    -0x14(%rbp),%eax
  cmp    -0x2c(%rbp),%eax
  jbe    L72
  mov    -0x14(%rbp),%edx
  mov    -0x34(%rbp),%eax
  mov    %eax,%esi
  lea    D1(%rip),%rax
  mov    %rax,%rdi
  call   <printf@plt>
  mov    $0xffffffff,%eax
  jmp    L45
L72:
  mov    -0x28(%rbp),%rax
  mov    %eax,%edx
  mov    -0x14(%rbp),%eax
  add    %edx,%eax
  mov    %eax,%eax
  mov    (%rax),%eax
  mov    %eax,-0x10(%rbp)
  mov    -0x10(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  jne    L60
  mov    $0xffffffff,%eax
  jmp    L45
L60:
  mov    -0x10(%rbp),%eax
  and    $0x80,%eax
  test   %eax,%eax
  je     L51
  mov    -0x10(%rbp),%eax
  and    $0xffc00fff,%eax
  mov    %eax,-0x1c(%rbp)
  movl   $0x400000,-0x18(%rbp)
  jmp    L88
L51:
  mov    -0x10(%rbp),%eax
  and    $0xfffff000,%eax
  mov    %eax,%edx
  mov    -0x34(%rbp),%eax
  shr    $0xa,%eax
  and    $0xffc,%eax
  or     %edx,%eax
  mov    %eax,-0xc(%rbp)
  mov    -0xc(%rbp),%eax
  cmp    -0x2c(%rbp),%eax
  jbe    L0
  mov    $0xffffffff,%eax
  jmp    L45
L0:
  mov    -0x28(%rbp),%rax
  mov    %eax,%edx
  mov    -0xc(%rbp),%eax
  add    %edx,%eax
  mov    %eax,%eax
  mov    (%rax),%eax
  mov    %eax,-0x1c(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x1,%eax
  test   %eax,%eax
  jne    L44
  mov    $0xffffffff,%eax
  jmp    L45
L44:
  movl   $0x1000,-0x18(%rbp)
L88:
  mov    -0x18(%rbp),%eax
  sub    $0x1,%eax
  and    -0x34(%rbp),%eax
  mov    %eax,-0x8(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0xfffff000,%eax
  mov    %eax,%edx
  mov    -0x8(%rbp),%eax
  add    %edx,%eax
  mov    %eax,-0x4(%rbp)
  mov    -0x1c(%rbp),%eax
  and    $0x2,%eax
  mov    %eax,%edx
  mov    -0x40(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x1c(%rbp),%eax
  and    $0x4,%eax
  mov    %eax,%edx
  mov    -0x48(%rbp),%rax
  mov    %edx,(%rax)
  mov    -0x1c(%rbp),%eax
  and    $0x100,%eax
  mov    %eax,%edx
  mov    0x10(%rbp),%rax
  mov    %edx,(%rax)
  cmpl   $0x400000,-0x18(%rbp)
  jne    L34
  mov    0x18(%rbp),%rax
  movl   $0x1,(%rax)
  jmp    L31
L34:
  mov    0x18(%rbp),%rax
  movl   $0x0,(%rax)
L31:
  mov    -0x4(%rbp),%eax
L45:
  leave
  ret
```

tool_calls: name: unpack_data
arguments: data_tag: D1
type_infered: string

tool: D1: ERROR 1 addr %x pde %x


assistant: ```c
unsigned vtopPageProperty(char *mem, unsigned size, unsigned pgd, unsigned addr, int *rw, int *us, int *g, int *ps) {
  unsigned pde_addr = (pgd & ~0xfff) + ((addr >> 20) & ~3);
  if (pde_addr > size) {
    printf("ERROR 1 addr %x pde %x\n", addr, pde_addr);
    return -1;
  }
  unsigned pde = *(unsigned *)((unsigned)mem + pde_addr);
  unsigned pte;
  unsigned pte_addr;
  unsigned page_size;
  if (!(pde & (1 << 0))) {
    return -1;
  }
  if (pde & (1 << 7)) {
    pte = pde & ~0x003ff000;
    page_size = 4096 * 1024;
  } else {
    pte_addr = ((pde & ~0xfff) + ((addr >> 10) & 0xffc));
    if (pte_addr > size) {
      return -1;
    }
    pte = *(unsigned *)((unsigned)mem + pte_addr);
    if (!(pte & (1 << 0))) {
      return -1;
    }
    page_size = 4096;
  }
  unsigned page_offset = addr & (page_size - 1);
  unsigned paddr = (pte & ~((1 << 12) - 1)) + page_offset;
  *rw = pte & (1 << 1);
  *us = pte & (1 << 2);
  *g = pte & (1 << 8);
  if (page_size == 0x400000)
    *ps = 1;
  else
    *ps = 0;
  return paddr;
}
```