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

```asm
<init_serial_port>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %edi,-0x24(%rbp)
  mov    %esi,-0x28(%rbp)
  mov    %fs:0x28,%rax
  mov    %rax,-0x8(%rbp)
  xor    %eax,%eax
  mov    -0x28(%rbp),%eax
  mov    %eax,%edi
  call   <to_speed@plt>
  mov    %eax,-0x1c(%rbp)
  mov    D86(%rip),%rax
  mov    (%rax),%eax
  cmp    %eax,-0x1c(%rbp)
  jne    L73
  mov    D91(%rip),%rax
  mov    (%rax),%ecx
  lea    -0x14(%rbp),%rdx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <ioctl@plt>
  cmp    $0xffffffff,%eax
  jne    L24
  mov    $0xffffffff,%eax
  jmp    L62
L24:
  mov    -0x14(%rbp),%edx
  mov    D30(%rip),%rax
  mov    (%rax),%eax
  not    %eax
  and    %eax,%edx
  mov    D62(%rip),%rax
  mov    (%rax),%eax
  or     %edx,%eax
  mov    %eax,-0x14(%rbp)
  mov    -0xc(%rbp),%edx
  mov    -0x28(%rbp),%eax
  mov    %eax,%ecx
  shr    $0x1f,%ecx
  add    %ecx,%eax
  sar    %eax
  add    %edx,%eax
  cltd
  idivl  -0x28(%rbp)
  mov    %eax,-0x10(%rbp)
  mov    -0xc(%rbp),%eax
  mov    -0x10(%rbp),%esi
  cltd
  idiv   %esi
  mov    %eax,-0x18(%rbp)
  mov    -0x28(%rbp),%eax
  imul   $0x62,%eax,%eax
  movslq %eax,%rdx
  imul   $0x51eb851f,%rdx,%rdx
  shr    $0x20,%rdx
  sar    $0x5,%edx
  sar    $0x1f,%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  cmp    %eax,-0x18(%rbp)
  jl     L31
  mov    -0x28(%rbp),%eax
  imul   $0x66,%eax,%eax
  movslq %eax,%rdx
  imul   $0x51eb851f,%rdx,%rdx
  shr    $0x20,%rdx
  sar    $0x5,%edx
  sar    $0x1f,%eax
  mov    %eax,%ecx
  mov    %edx,%eax
  sub    %ecx,%eax
  cmp    %eax,-0x18(%rbp)
  jle    L37
L31:
  mov    D20(%rip),%rax
  mov    (%rax),%edx
  mov    D70(%rip),%rax
  mov    %edx,(%rax)
  mov    $0xffffffff,%eax
  jmp    L62
L37:
  mov    D84(%rip),%rax
  mov    (%rax),%ecx
  lea    -0x14(%rbp),%rdx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <ioctl@plt>
  cmp    $0xffffffff,%eax
  jne    L84
  mov    $0xffffffff,%eax
  jmp    L62
L84:
  mov    D98(%rip),%rax
  mov    (%rax),%eax
  mov    %eax,-0x1c(%rbp)
L73:
  mov    D71(%rip),%rax
  mov    (%rax),%eax
  or     -0x1c(%rbp),%eax
  mov    %eax,%edx
  mov    D100(%rip),%rax
  mov    (%rax),%eax
  or     %eax,%edx
  mov    D12(%rip),%rax
  mov    (%rax),%eax
  or     %edx,%eax
  mov    %eax,-0x14(%rbp)
  lea    -0x14(%rbp),%rax
  mov    %rax,%rdi
  call   <cfmakeraw@plt>
  mov    D2(%rip),%rax
  mov    (%rax),%ecx
  lea    -0x14(%rbp),%rdx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <tcsetattr@plt>
  cmp    $0xffffffff,%eax
  jne    L3
  mov    $0xffffffff,%eax
  jmp    L62
L3:
  mov    $0x0,%eax
L62:
  mov    -0x8(%rbp),%rdx
  sub    %fs:0x28,%rdx
  je     L97
  call   <__stack_chk_fail@plt>
L97:
  leave
  ret
```

assistant: ```c
int init_serial_port(int fd, int speed) {
  tcflag_t speed_preset = to_speed(speed);
  if (speed_preset == B0) {
    struct serial_struct serial;
    if (ioctl(fd, TIOCGSERIAL, &serial) == -1)
      return -1;
    serial.flags = (serial.flags & ~ASYNC_SPD_MASK) | ASYNC_SPD_CUST;
    serial.custom_divisor = (serial.baud_base + (speed / 2)) / speed;
    int real_speed = serial.baud_base / serial.custom_divisor;
    if (real_speed < speed * 98 / 100 || real_speed > speed * 102 / 100) {
      errno = ENOTSUP;
      return -1;
    }
    if (ioctl(fd, TIOCSSERIAL, &serial) == -1)
      return -1;
    speed_preset = B38400;
  }
  struct termios term;
  term.c_cflag = speed_preset | CS8 | CLOCAL | CREAD;
  cfmakeraw(&term);
  if (tcsetattr(fd, TCSANOW, &term) == -1)
    return -1;
  return 0;
}
```