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

```asm
<get_cputype>:
  endbr64
  push   %rbx
  sub    $0x20,%rsp
  mov    %edi,%ebx
  mov    %fs:0x28,%rax
  mov    %rax,0x18(%rsp)
  xor    %eax,%eax
  lea    0x10(%rsp),%rcx
  lea    0xc(%rsp),%rdx
  lea    0x8(%rsp),%rsi
  lea    0x14(%rsp),%r8
  mov    $0x1,%edi
  call   <cpuid@plt>
  cmp    $0xd,%ebx
  ja     L60
  mov    %ebx,%ebx
  lea    D3(%rip),%rdx
  movslq (%rdx,%rbx,4),%rax
  add    %rdx,%rax
  notrack jmp *%rax
  mov    0x8(%rsp),%ebx
  sar    $0x14,%ebx
  movzbl %bl,%ebx
L209:
  mov    0x18(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L141
  mov    %ebx,%eax
  add    $0x20,%rsp
  pop    %rbx
  ret
  movswl 0xa(%rsp),%ebx
  and    $0xf,%ebx
  jmp    L209
  mov    0x8(%rsp),%ebx
  sar    $0xc,%ebx
  and    $0x3,%ebx
  jmp    L209
  mov    0x8(%rsp),%ebx
  sar    $0x8,%ebx
  and    $0xf,%ebx
  jmp    L209
  mov    0x8(%rsp),%ebx
  sar    $0x4,%ebx
  and    $0xf,%ebx
  jmp    L209
  movsbl 0xf(%rsp),%ebx
  and    $0xf,%ebx
  jmp    L209
  movswl 0xe(%rsp),%ebx
  and    $0xf,%ebx
  jmp    L209
  mov    0xc(%rsp),%ebx
  sar    $0x8,%ebx
  and    $0xf,%ebx
  jmp    L209
  mov    0x8(%rsp),%ebx
  and    $0xf,%ebx
  jmp    L209
  movzbl 0xc(%rsp),%ebx
  jmp    L209
  mov    $0x0,%eax
  call   <have_cpuid@plt>
  mov    $0x0,%ebx
  cmp    $0x3,%eax
  jle    L209
  lea    0x10(%rsp),%rcx
  lea    0xc(%rsp),%rdx
  lea    0x8(%rsp),%rsi
  lea    0x14(%rsp),%r8
  mov    $0x4,%edi
  call   <cpuid@plt>
  mov    0x8(%rsp),%ebx
  sar    $0xe,%ebx
  and    $0xfff,%ebx
  jmp    L209
  mov    $0x0,%eax
  call   <have_cpuid@plt>
  mov    $0x0,%ebx
  cmp    $0x3,%eax
  jle    L209
  lea    0x10(%rsp),%rcx
  lea    0xc(%rsp),%rdx
  lea    0x8(%rsp),%rsi
  lea    0x14(%rsp),%r8
  mov    $0x4,%edi
  call   <cpuid@plt>
  mov    0x8(%rsp),%ebx
  shr    $0x1a,%ebx
  jmp    L209
  mov    0x14(%rsp),%eax
  mov    %eax,%ebx
  shl    $0x9,%ebx
  and    $0x1000,%ebx
  mov    %ebx,%edx
  or     $0x8,%dh
  test   $0x80,%ah
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x20,%dh
  test   $0x80000,%eax
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x1,%dh
  test   $0x800000,%eax
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x1,%edx
  test   $0x2000000,%eax
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x2,%edx
  test   $0x4000000,%eax
  cmovne %edx,%ebx
  test   $0x8000000,%eax
  je     L173
  mov    %ebx,%eax
  or     $0x40,%ah
  testb  $0xf,0xe(%rsp)
  cmovne %eax,%ebx
L173:
  mov    0x10(%rsp),%eax
  mov    %ebx,%edx
  or     $0x4,%edx
  test   $0x1,%al
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x8,%edx
  test   $0x2,%ah
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x10,%edx
  test   $0x80000,%eax
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x20,%edx
  test   $0x100000,%eax
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x40000,%edx
  test   $0x10000000,%eax
  cmovne %edx,%ebx
  mov    $0x0,%eax
  call   <have_excpuid@plt>
  test   %eax,%eax
  jg     L107
L35:
  mov    $0x0,%eax
  call   <have_excpuid@plt>
  cmp    $0x19,%eax
  jle    L209
  lea    0x10(%rsp),%rcx
  lea    0xc(%rsp),%rdx
  lea    0x8(%rsp),%rsi
  lea    0x14(%rsp),%r8
  mov    $0x8000001a,%edi
  call   <cpuid@plt>
  mov    0x8(%rsp),%eax
  mov    %ebx,%edx
  or     $0x10000,%edx
  test   $0x1,%al
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x20000,%edx
  test   $0x2,%al
  cmovne %edx,%ebx
  jmp    L209
L107:
  lea    0x10(%rsp),%rcx
  lea    0xc(%rsp),%rdx
  lea    0x8(%rsp),%rsi
  lea    0x14(%rsp),%r8
  mov    $0x80000001,%edi
  call   <cpuid@plt>
  mov    0x10(%rsp),%eax
  mov    %ebx,%edx
  or     $0x40,%edx
  test   $0x40,%al
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x80,%dh
  test   $0x80,%al
  cmovne %edx,%ebx
  mov    0x14(%rsp),%eax
  mov    %ebx,%edx
  or     $0x4,%dh
  test   $0x40000000,%eax
  cmovne %edx,%ebx
  mov    %ebx,%edx
  or     $0x2,%dh
  test   %eax,%eax
  cmovs  %edx,%ebx
  jmp    L35
L60:
  mov    $0x0,%ebx
  jmp    L209
L141:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
int get_cputype(int gettype) {
  int eax, ebx, ecx, edx;
  int extend_family, family;
  int extend_model, model;
  int type, stepping;
  int feature = 0;
  cpuid(1, &eax, &ebx, &ecx, &edx);
  switch (gettype) {
  case 1:
    return ((((eax) >> (20)) & (0xff)));
  case 2:
    return ((((eax) >> (16)) & (0x0f)));
  case 3:
    return ((((eax) >> (12)) & (0x03)));
  case 4:
    return ((((eax) >> (8)) & (0x0f)));
  case 5:
    return ((((eax) >> (4)) & (0x0f)));
  case 6:
    return ((((ebx) >> (24)) & (0x0f)));
  case 7:
    return ((((ebx) >> (16)) & (0x0f)));
  case 8:
    return ((((ebx) >> (8)) & (0x0f)));
  case 9:
    return ((((eax) >> (0)) & (0x0f)));
  case 10:
    return ((((ebx) >> (0)) & (0xff)));
  case 12:
    if (have_cpuid() < 4)
      return 0;
    cpuid(4, &eax, &ebx, &ecx, &edx);
    return ((((eax) >> (14)) & (0xfff)));
  case 13:
    if (have_cpuid() < 4)
      return 0;
    cpuid(4, &eax, &ebx, &ecx, &edx);
    return ((((eax) >> (26)) & (0x3f)));
  case 11:
    if ((edx & (1 << 3)) != 0)
      feature |= (1 << 12);
    if ((edx & (1 << 15)) != 0)
      feature |= (1 << 11);
    if ((edx & (1 << 19)) != 0)
      feature |= (1 << 13);
    if ((edx & (1 << 23)) != 0)
      feature |= (1 << 8);
    if ((edx & (1 << 25)) != 0)
      feature |= (1 << 0);
    if ((edx & (1 << 26)) != 0)
      feature |= (1 << 1);
    if ((edx & (1 << 27)) != 0) {
      if (((((ebx) >> (16)) & (0x0f))) > 0)
        feature |= (1 << 14);
    }
    if ((ecx & (1 << 0)) != 0)
      feature |= (1 << 2);
    if ((ecx & (1 << 9)) != 0)
      feature |= (1 << 3);
    if ((ecx & (1 << 19)) != 0)
      feature |= (1 << 4);
    if ((ecx & (1 << 20)) != 0)
      feature |= (1 << 5);
    if ((ecx & (1 << 28)) != 0)
      feature |= (1 << 18);
    if (have_excpuid() >= 0x01) {
      cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
      if ((ecx & (1 << 6)) != 0)
        feature |= (1 << 6);
      if ((ecx & (1 << 7)) != 0)
        feature |= (1 << 15);
      if ((edx & (1 << 30)) != 0)
        feature |= (1 << 10);
      if ((edx & (1 << 31)) != 0)
        feature |= (1 << 9);
    }
    if (have_excpuid() >= 0x1a) {
      cpuid(0x8000001a, &eax, &ebx, &ecx, &edx);
      if ((eax & (1 << 0)) != 0)
        feature |= (1 << 16);
      if ((eax & (1 << 1)) != 0)
        feature |= (1 << 17);
    }
  }
  return feature;
}
```