user: Please show me the C implementation that matches the assembly code listed below:

```asm
<print_chip_info>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  add    $0xffffffffffffff80,%rsp
  mov    %edi,-0x74(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  lea    -0x64(%rbp),%rdx
  mov    -0x74(%rbp),%eax
  mov    $0xf000f,%esi
  mov    %eax,%edi
  call   <xscom_read@plt>
  mov    %eax,-0x60(%rbp)
  cmpl   $0x0,-0x60(%rbp)
  jne    L32
  mov    -0x64(%rbp),%eax
  mov    $0x2c,%edx
  mov    %edx,%ecx
  sar    %cl,%eax
  mov    %eax,-0x5c(%rbp)
  mov    -0x5c(%rbp),%eax
  movzbl %al,%eax
  sub    $0xd1,%eax
  cmp    $0x1e,%eax
  ja     L52
  mov    %eax,%eax
  lea    0x0(,%rax,4),%rdx
  lea    D104(%rip),%rax
  mov    (%rdx,%rax,1),%eax
  cltq
  lea    D104(%rip),%rdx
  add    %rdx,%rax
  notrack jmp *%rax
  lea    D52(%rip),%rax
  mov    %rax,-0x58(%rbp)
  jmp    L103
  lea    D67(%rip),%rax
  mov    %rax,-0x58(%rbp)
  jmp    L103
  lea    D27(%rip),%rax
  mov    %rax,-0x58(%rbp)
  jmp    L103
  lea    D87(%rip),%rax
  mov    %rax,-0x58(%rbp)
  jmp    L103
  lea    D69(%rip),%rax
  mov    %rax,-0x58(%rbp)
  jmp    L103
  lea    D5(%rip),%rax
  mov    %rax,-0x58(%rbp)
  jmp    L103
  lea    D14(%rip),%rax
  mov    %rax,-0x58(%rbp)
  jmp    L103
  lea    D93(%rip),%rax
  mov    %rax,-0x58(%rbp)
  jmp    L103
L52:
  mov    -0x5c(%rbp),%eax
  movzbl %al,%edx
  lea    -0x50(%rbp),%rax
  mov    %edx,%ecx
  lea    D59(%rip),%rdx
  mov    $0x40,%esi
  mov    %rax,%rdi
  call   <snprintf@plt>
  lea    -0x50(%rbp),%rax
  mov    %rax,-0x58(%rbp)
L103:
  mov    -0x5c(%rbp),%eax
  sar    $0x8,%eax
  and    $0xf,%eax
  mov    %eax,%ecx
  mov    -0x5c(%rbp),%eax
  sar    $0x10,%eax
  and    $0xf,%eax
  mov    %eax,%edx
  mov    -0x58(%rbp),%rsi
  mov    -0x74(%rbp),%eax
  mov    %rsi,%r8
  mov    %eax,%esi
  lea    D11(%rip),%rax
  mov    %rax,%rdi
  call   <printf@plt>
  jmp    L90
L32:
  nop
L90:
  mov    -0x8(%rbp),%rax
  sub    %fs:0x28,%rax
  je     L114
  call   <__stack_chk_fail@plt>
L114:
  leave
  ret
```

tool_calls: name: read_data
arguments: label: D52
type_guessed: string
name: read_data
arguments: label: D67
type_guessed: string
name: read_data
arguments: label: D27
type_guessed: string
name: read_data
arguments: label: D87
type_guessed: string
name: read_data
arguments: label: D69
type_guessed: string
name: read_data
arguments: label: D5
type_guessed: string
name: read_data
arguments: label: D14
type_guessed: string
name: read_data
arguments: label: D93
type_guessed: string
name: read_data
arguments: label: D59
type_guessed: string
name: read_data
arguments: label: D11
type_guessed: string

tool: D52: P8E (Murano) processor

tool: D67: P8 (Venice) processor

tool: D27: P8NVL (Naples) processor

tool: D87: P9 (Nimbus) processor

tool: D69: P9 (Cumulus) processor

tool: D5: P9P (Axone) processor

tool: D14: P10 processor

tool: D93: Centaur memory buffer

tool: D59: Unknown ID 0x%02lx

tool: D11: %08x | DD%lx.%lx | %s


assistant: ```c
void print_chip_info(uint32_t chip_id) {
  uint64_t f000f, cfam_id;
  const char *name;
  char uname_buf[64];
  int rc;
  rc = xscom_read(chip_id, 0xf000f, &f000f);
  if (rc)
    return;
  cfam_id = f000f >> 44;
  switch (cfam_id & 0xff) {
  case 0xef:
    name = "P8E (Murano) processor";
    break;
  case 0xea:
    name = "P8 (Venice) processor";
    break;
  case 0xd3:
    name = "P8NVL (Naples) processor";
    break;
  case 0xd1:
    name = "P9 (Nimbus) processor";
    break;
  case 0xd4:
    name = "P9 (Cumulus) processor";
    break;
  case 0xd9:
    name = "P9P (Axone) processor";
    break;
  case 0xda:
    name = "P10 processor";
    break;
  case 0xe9:
    name = "Centaur memory buffer";
    break;
  default:
    snprintf(uname_buf, sizeof(uname_buf), "Unknown ID 0x%02lx", cfam_id & 0xff);
    name = uname_buf;
  }
  printf("%08x | DD%lx.%lx | %s\n", chip_id, (cfam_id >> 16) & 0xf, (cfam_id >> 8) & 0xf, name);
}
```