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

```asm
<UARTConfigSetExpClk>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %rdi,-0x18(%rbp)
  mov    %rsi,-0x20(%rbp)
  mov    %rdx,-0x28(%rbp)
  mov    %rcx,-0x30(%rbp)
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <UARTBaseValid@plt>
  mov    %eax,%edi
  call   <DEBUG_ASSERT@plt>
  cmpq   $0x0,-0x28(%rbp)
  setne  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <DEBUG_ASSERT@plt>
  mov    $0x400fe000,%eax
  mov    (%rax),%rax
  and    $0x70000000,%eax
  test   %rax,%rax
  je     L16
  mov    $0x400fe000,%eax
  mov    (%rax),%rax
  and    $0x70ff0000,%eax
  cmp    $0x10000000,%rax
  je     L16
  mov    $0x400fe000,%eax
  mov    (%rax),%rax
  and    $0x70ff0000,%eax
  cmp    $0x10010000,%rax
  jne    L88
  mov    $0x400fe000,%eax
  mov    (%rax),%rax
  movzwl %ax,%eax
  cmp    $0x2,%rax
  je     L16
L88:
  mov    $0x400fe000,%eax
  mov    (%rax),%rax
  and    $0x70ff0000,%eax
  cmp    $0x10030000,%rax
  jne    L77
  mov    $0x400fe000,%eax
  mov    (%rax),%rax
  movzwl %ax,%eax
  test   %rax,%rax
  jne    L77
L16:
  mov    $0x10,%eax
  jmp    L9
L77:
  mov    $0x8,%eax
L9:
  imul   -0x28(%rbp),%rax
  cmp    %rax,-0x20(%rbp)
  setae  %al
  movzbl %al,%eax
  mov    %eax,%edi
  call   <DEBUG_ASSERT@plt>
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <UARTDisable@plt>
  mov    -0x28(%rbp),%rax
  shl    $0x4,%rax
  cmp    %rax,-0x20(%rbp)
  jae    L82
  mov    -0x18(%rbp),%rax
  add    $0x30,%rax
  mov    (%rax),%rax
  mov    -0x18(%rbp),%rdx
  add    $0x30,%rdx
  or     $0x20,%rax
  mov    %rax,(%rdx)
  mov    -0x28(%rbp),%rax
  shr    %rax
  mov    %rax,-0x28(%rbp)
  jmp    L45
L82:
  mov    -0x18(%rbp),%rax
  add    $0x30,%rax
  mov    (%rax),%rax
  mov    -0x18(%rbp),%rdx
  add    $0x30,%rdx
  and    $0xffffffffffffffdf,%rax
  mov    %rax,(%rdx)
L45:
  mov    -0x20(%rbp),%rax
  shl    $0x3,%rax
  mov    $0x0,%edx
  divq   -0x28(%rbp)
  add    $0x1,%rax
  shr    %rax
  mov    %rax,-0x8(%rbp)
  mov    -0x18(%rbp),%rax
  add    $0x24,%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  shr    $0x6,%rax
  mov    %rax,(%rdx)
  mov    -0x18(%rbp),%rax
  add    $0x28,%rax
  mov    %rax,%rdx
  mov    -0x8(%rbp),%rax
  and    $0x3f,%eax
  mov    %rax,(%rdx)
  mov    -0x18(%rbp),%rax
  add    $0x2c,%rax
  mov    %rax,%rdx
  mov    -0x30(%rbp),%rax
  mov    %rax,(%rdx)
  mov    -0x18(%rbp),%rax
  add    $0x18,%rax
  movq   $0x0,(%rax)
  mov    -0x18(%rbp),%rax
  mov    %rax,%rdi
  call   <UARTEnable@plt>
  nop
  leave
  ret
```

assistant: ```c
void UARTConfigSetExpClk(unsigned long ulBase, unsigned long ulUARTClk, unsigned long ulBaud, unsigned long ulConfig) {
  unsigned long ulDiv;
  DEBUG_ASSERT(UARTBaseValid(ulBase));
  DEBUG_ASSERT(ulBaud != 0);
  DEBUG_ASSERT(ulUARTClk >= (ulBaud * ((((((*((volatile unsigned long *)(0x400FE000))) & 0x70000000) == 0x00000000) || (((*((volatile unsigned long *)(0x400FE000))) & (0x70000000 | 0x00FF0000)) == (0x10000000 | 0x00000000))) || ((((*((volatile unsigned long *)(0x400FE000))) & (0x70000000 | 0x00FF0000)) == (0x10000000 | 0x00010000)) && (((*((volatile unsigned long *)(0x400FE000))) & (0x0000FF00 | 0x000000FF)) == (0x00000000 | 0x00000002))) || ((((*((volatile unsigned long *)(0x400FE000))) & (0x70000000 | 0x00FF0000)) == (0x10000000 | 0x00030000)) && (((*((volatile unsigned long *)(0x400FE000))) & (0x0000FF00 | 0x000000FF)) == (0x00000000 | 0x00000000)))) ? 16 : 8)));
  UARTDisable(ulBase);
  if ((ulBaud * 16) > ulUARTClk) {
    (*((volatile unsigned long *)(ulBase + 0x00000030))) |= 0x00000020;
    ulBaud /= 2;
  } else {
    (*((volatile unsigned long *)(ulBase + 0x00000030))) &= ~(0x00000020);
  }
  ulDiv = (((ulUARTClk * 8) / ulBaud) + 1) / 2;
  (*((volatile unsigned long *)(ulBase + 0x00000024))) = ulDiv / 64;
  (*((volatile unsigned long *)(ulBase + 0x00000028))) = ulDiv % 64;
  (*((volatile unsigned long *)(ulBase + 0x0000002C))) = ulConfig;
  (*((volatile unsigned long *)(ulBase + 0x00000018))) = 0;
  UARTEnable(ulBase);
}
```