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

```asm
<IsPunct>:
  endbr64
  sub    $0x8,%rsp
  mov    %edi,%edx
  mov    %esi,%edi
  test   %edx,%edx
  je     L51
  cmp    $0x1,%edx
  je     L251
L74:
  mov    %edi,%esi
  lea    -0x21(%rdi),%ecx
  cmp    $0x3f,%ecx
  jbe    L139
L153:
  lea    -0x7b(%rsi),%ecx
  mov    $0x1,%eax
  cmp    $0x3,%ecx
  jbe    L60
  cmp    $0x12,%edx
  ja     L275
  mov    %edx,%edx
  lea    D1(%rip),%rcx
  movslq (%rcx,%rdx,4),%rax
  add    %rcx,%rax
  notrack jmp *%rax
L51:
  call   <ispunct@plt>
L60:
  add    $0x8,%rsp
  ret
L251:
  cmp    $0x3e,%esi
  jle    L206
  lea    -0x5e(%rsi),%eax
  cmp    $0x20,%eax
  ja     L74
  movabs $0x140000005,%rcx
  bt     %rax,%rcx
  jae    L74
  mov    %edx,%eax
  jmp    L60
L206:
  cmp    $0x23,%esi
  jle    L74
  movabs $0x7000081000000000,%rax
  lea    -0x21(%rsi),%ecx
  bt     %rsi,%rax
  jb     L230
L139:
  mov    $0x1,%eax
  movabs $0xfc000000fe007fff,%r8
  bt     %rcx,%r8
  jb     L60
  jmp    L153
  mov    $0x1,%eax
  cmp    $0xad,%edi
  je     L60
  lea    -0xa1(%rsi),%ecx
  mov    $0x1,%eax
  cmp    $0x1e,%ecx
  ja     L148
  mov    $0x44400401,%eax
  shr    %cl,%rax
  xor    $0x1,%rax
  and    $0x1,%eax
L148:
  xor    $0x1,%eax
  movzbl %al,%eax
  jmp    L60
  cmp    $0xad,%edi
  sete   %al
  movzbl %al,%eax
  jmp    L60
  mov    %edi,%eax
  and    $0xffffffef,%eax
  cmp    $0xad,%eax
  sete   %al
  cmp    $0xb7,%edi
  sete   %dl
  or     %edx,%eax
  movzbl %al,%eax
  jmp    L60
  sub    $0xac,%esi
  cmp    $0x1,%esi
  setbe  %al
  and    $0xfffffffb,%edi
  cmp    $0xbb,%edi
  sete   %dl
  or     %edx,%eax
  movzbl %al,%eax
  jmp    L60
  lea    -0xa1(%rsi),%edx
  mov    $0x1,%eax
  cmp    $0x1,%edx
  jbe    L60
  lea    -0xab(%rsi),%ecx
  cmp    $0x10,%ecx
  ja     L219
  mov    $0x11015,%eax
  shr    %cl,%rax
  and    $0x1,%eax
  jmp    L60
  lea    -0xab(%rsi),%ecx
  mov    $0x1,%eax
  cmp    $0x34,%ecx
  ja     L66
  movabs $0x10000000011005,%rax
  shr    %cl,%rax
  xor    $0x1,%rax
  and    $0x1,%eax
L66:
  xor    $0x1,%eax
  movzbl %al,%eax
  jmp    L60
  mov    %edi,%edx
  and    $0xfffffffb,%edx
  mov    $0x1,%eax
  cmp    $0xa1,%edx
  je     L60
  cmp    $0xbb,%edi
  jg     L1
  mov    $0x0,%eax
  cmp    $0xaa,%edi
  jle    L60
  lea    -0xab(%rsi),%ecx
  mov    $0x11205,%eax
  shr    %cl,%rax
  and    $0x1,%eax
  jmp    L60
L1:
  cmp    $0xff,%edi
  sete   %al
  movzbl %al,%eax
  jmp    L60
  mov    $0x1,%eax
  cmp    $0xa5,%edi
  je     L60
  lea    -0xab(%rsi),%ecx
  cmp    $0x10,%ecx
  ja     L131
  mov    $0x11405,%eax
  shr    %cl,%rax
  and    $0x1,%eax
  jmp    L60
  cmp    $0x9e,%edi
  sete   %al
  movzbl %al,%eax
  jmp    L60
L275:
  mov    $0xffffffff,%edi
  call   <exit@plt>
  mov    $0x0,%eax
  jmp    L60
L230:
  mov    %edx,%eax
  jmp    L60
  mov    $0x0,%eax
  jmp    L60
L219:
  mov    $0x0,%eax
  jmp    L60
L131:
  mov    $0x0,%eax
  jmp    L60
```

assistant: ```c
int IsPunct(int enc, int c) {
  if (enc == 0)
    return ispunct(c);
  if (enc == 1) {
    if (c == 0x24 || c == 0x2b || c == 0x5e || c == 0x60 || c == 0x7c || c == 0x7e)
      return 1;
    if (c >= 0x3c && c <= 0x3e)
      return 1;
  }
  if (c >= 0x21 && c <= 0x2f)
    return 1;
  if (c >= 0x3a && c <= 0x40)
    return 1;
  if (c >= 0x5b && c <= 0x60)
    return 1;
  if (c >= 0x7b && c <= 0x7e)
    return 1;
  switch (enc) {
  case 2:
  case 10:
  case 15:
    if (c == 0xad)
      return 1;
  case 1:
    if (c == 0xa1)
      return 1;
    if (c == 0xab)
      return 1;
    if (c == 0xb7)
      return 1;
    if (c == 0xbb)
      return 1;
    if (c == 0xbf)
      return 1;
    break;
  case 3:
  case 5:
  case 6:
  case 14:
    if (c == 0xad)
      return 1;
    break;
  case 4:
  case 11:
    if (c == 0xad)
      return 1;
    if (c == 0xb7)
      return 1;
    if (c == 0xbd)
      return 1;
    break;
  case 7:
    if (c == 0xac)
      return 1;
    if (c == 0xad)
      return 1;
    if (c == 0xbb)
      return 1;
    if (c == 0xbf)
      return 1;
    break;
  case 8:
    if (c == 0xa1 || c == 0xa2)
      return 1;
    if (c == 0xab)
      return 1;
    if (c == 0xaf)
      return 1;
    if (c == 0xad)
      return 1;
    if (c == 0xb7 || c == 0xbb)
      return 1;
    break;
  case 9:
    if (c == 0xab)
      return 1;
    if (c == 0xad)
      return 1;
    if (c == 0xb7)
      return 1;
    if (c == 0xbb)
      return 1;
    if (c == 0xdf)
      return 1;
    break;
  case 13:
    if (c == 0xa1 || c == 0xa5)
      return 1;
    if (c == 0xab || c == 0xad)
      return 1;
    if (c == 0xb4 || c == 0xb7)
      return 1;
    if (c == 0xbb)
      return 1;
    if (c == 0xff)
      return 1;
    break;
  case 16:
    if (c == 0xa5)
      return 1;
    if (c == 0xab)
      return 1;
    if (c == 0xad)
      return 1;
    if (c == 0xb5)
      return 1;
    if (c == 0xb7)
      return 1;
    if (c == 0xbb)
      return 1;
    break;
  case 18:
    if (c == 0x9e)
      return 1;
    break;
  case 12:
  case 17:
    break;
  default:
    exit(-1);
  }
  return 0;
}
```