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

```asm
<SysCtlUSBPLLConfigSet>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  mov    %rdi,-0x18(%rbp)
  mov    $0x400fb980,%eax
  mov    (%rax),%rax
  mov    %rax,-0x8(%rbp)
  mov    $0x400fb980,%eax
  mov    $0xa5a5a5a5,%esi
  mov    %rsi,(%rax)
  mov    -0x18(%rbp),%rax
  and    $0x3f,%eax
  mov    %rax,%rdx
  mov    $0x400fb824,%eax
  mov    (%rax),%rax
  and    $0x1f,%eax
  cmp    %rax,%rdx
  je     L52
  mov    -0x18(%rbp),%rax
  and    $0x3f,%eax
  mov    %rax,%rcx
  mov    $0x400fb824,%eax
  mov    (%rax),%rax
  and    $0xffffffffffffffe0,%rax
  mov    $0x400fb824,%edx
  or     %rcx,%rax
  mov    %rax,(%rdx)
L52:
  mov    $0x400fb824,%eax
  mov    (%rax),%rax
  xor    -0x18(%rbp),%rax
  and    $0x300,%eax
  test   %rax,%rax
  je     L50
  mov    -0x18(%rbp),%rax
  and    $0x300,%eax
  mov    %rax,%rcx
  mov    $0x400fb824,%eax
  mov    (%rax),%rax
  and    $0xfc,%ah
  mov    $0x400fb824,%edx
  or     %rcx,%rax
  mov    %rax,(%rdx)
L50:
  mov    -0x18(%rbp),%rax
  shr    $0x1f,%rax
  mov    %rax,%rdx
  mov    $0x400fb820,%eax
  mov    (%rax),%rax
  xor    %rdx,%rax
  and    $0x1,%eax
  test   %rax,%rax
  je     L10
  mov    -0x18(%rbp),%rax
  shr    $0x1f,%rax
  and    $0x1,%eax
  mov    %rax,%rcx
  mov    $0x400fb820,%eax
  mov    (%rax),%rax
  and    $0xfffffffffffffffe,%rax
  mov    $0x400fb820,%edx
  or     %rcx,%rax
  mov    %rax,(%rdx)
L10:
  mov    -0x18(%rbp),%rax
  and    $0x40000000,%eax
  test   %rax,%rax
  je     L57
  mov    $0x400fb820,%eax
  mov    (%rax),%rax
  and    $0xfffffffffffffff9,%rax
  mov    $0x400fb820,%edx
  or     $0x2,%rax
  mov    %rax,(%rdx)
  nop
L1:
  mov    $0x400fb828,%eax
  mov    (%rax),%rax
  and    $0x1,%eax
  test   %rax,%rax
  je     L1
  mov    $0x400fb820,%eax
  mov    (%rax),%rax
  mov    $0x400fb820,%edx
  or     $0x4,%rax
  mov    %rax,(%rdx)
  jmp    L5
L57:
  mov    $0x400fb820,%eax
  mov    (%rax),%rax
  mov    $0x400fb820,%edx
  and    $0xfffffffffffffff9,%rax
  mov    %rax,(%rdx)
L5:
  mov    $0x400fb980,%edx
  mov    -0x8(%rbp),%rax
  mov    %rax,(%rdx)
  nop
  pop    %rbp
  ret
```

assistant: ```c
void SysCtlUSBPLLConfigSet(unsigned long ulConfig) {
  unsigned long ulMWRAllow;
  ulMWRAllow = (*((volatile unsigned long *)(0x400FB980)));
  (*((volatile unsigned long *)(0x400FB980))) = 0xA5A5A5A5;
  if ((ulConfig & 0x0000003F) != ((*((volatile unsigned long *)(0x400FB824))) & 0x0000001F)) {
    (*((volatile unsigned long *)(0x400FB824))) = (ulConfig & 0x0000003F) | ((*((volatile unsigned long *)(0x400FB824))) & ~0x0000001F);
  }
  if ((ulConfig & 0x00000300) != ((*((volatile unsigned long *)(0x400FB824))) & 0x00000300)) {
    (*((volatile unsigned long *)(0x400FB824))) = (ulConfig & 0x00000300) | ((*((volatile unsigned long *)(0x400FB824))) & ~0x00000300);
  }
  if (((ulConfig & 0x80000000) >> 31) != ((*((volatile unsigned long *)(0x400FB820))) & 0x00000001)) {
    (*((volatile unsigned long *)(0x400FB820))) = ((ulConfig & 0x80000000) >> 31) | ((*((volatile unsigned long *)(0x400FB820))) & ~0x00000001);
  }
  if (ulConfig & 0x40000000) {
    (*((volatile unsigned long *)(0x400FB820))) = 0x00000002 | ((*((volatile unsigned long *)(0x400FB820))) & ~0x00000004);
    while (!((*((volatile unsigned long *)(0x400FB828))) & 0x00000001))
      ;
    (*((volatile unsigned long *)(0x400FB820))) |= 0x00000004;
  } else {
    (*((volatile unsigned long *)(0x400FB820))) &= ~(0x00000004 | 0x00000002);
  }
  (*((volatile unsigned long *)(0x400FB980))) = ulMWRAllow;
}
```