user: Please show me the C implementation that matches the assembly code listed below:

```asm
<rcc_clock_init>:
  endbr64
  mov    0x40021000,%rax
  or     $0x1,%rax
  mov    %rax,0x40021000
  mov    0x40021004,%rax
  and    $0xf8ff0000,%eax
  mov    %rax,0x40021004
  mov    0x40021000,%rax
  and    $0xfef6ffff,%eax
  mov    %rax,0x40021000
  mov    0x40021000,%rax
  and    $0xfffbffff,%eax
  mov    %rax,0x40021000
  mov    0x40021004,%rax
  and    $0xff80ffff,%eax
  mov    %rax,0x40021004
  movq   $0x9f0000,0x40021008
  movq   $0x0,-0x10(%rsp)
  movq   $0x0,-0x8(%rsp)
  mov    0x40021000,%rax
  or     $0x10000,%rax
  mov    %rax,0x40021000
L1:
  mov    0x40021000,%rax
  and    $0x20000,%eax
  mov    %rax,-0x8(%rsp)
  mov    -0x10(%rsp),%rax
  add    $0x1,%rax
  mov    %rax,-0x10(%rsp)
  mov    -0x8(%rsp),%rax
  test   %rax,%rax
  jne    L41
  mov    -0x10(%rsp),%rax
  cmp    $0x500,%rax
  jne    L1
L41:
  mov    0x40021000,%rax
  test   $0x20000,%eax
  je     L2
  movq   $0x1,-0x8(%rsp)
L61:
  mov    -0x8(%rsp),%rax
  cmp    $0x1,%rax
  je     L54
L15:
  ret
L2:
  movq   $0x0,-0x8(%rsp)
  jmp    L61
L54:
  mov    0x40022000,%rax
  or     $0x10,%rax
  mov    %rax,0x40022000
  mov    0x40022000,%rax
  and    $0xfffffffffffffffc,%rax
  mov    %rax,0x40022000
  mov    0x40022000,%rax
  mov    %rax,0x40022000
  mov    0x40021004,%rax
  mov    %rax,0x40021004
  mov    0x40021004,%rax
  mov    %rax,0x40021004
  mov    0x40021004,%rax
  mov    %rax,0x40021004
  mov    0x40021004,%rax
  and    $0xfffffffffffffffc,%rax
  mov    %rax,0x40021004
  mov    0x40021004,%rax
  or     $0x1,%rax
  mov    %rax,0x40021004
L31:
  mov    0x40021004,%rax
  and    $0xc,%eax
  cmp    $0x4,%rax
  jne    L31
  jmp    L15
```

assistant: ```c
void rcc_clock_init(void) {
  *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x00)) |= (uint32_t)0x00000001;
  *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x04)) &= (uint32_t)0xF8FF0000;
  *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x00)) &= (uint32_t)0xFEF6FFFF;
  *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x00)) &= (uint32_t)0xFFFBFFFF;
  *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x04)) &= (uint32_t)0xFF80FFFF;
  *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x08)) = 0x009F0000;
  volatile uint32_t StartUpCounter = 0, HSEStatus = 0;
  *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x00)) |= ((uint32_t)((uint32_t)0x00010000));
  do {
    HSEStatus = *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x00)) & ((uint32_t)0x00020000);
    StartUpCounter++;
  } while ((HSEStatus == 0) && (StartUpCounter != ((uint16_t)0x0500)));
  if ((*((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x00)) & ((uint32_t)0x00020000)) != 0)
    HSEStatus = (uint32_t)0x01;
  else
    HSEStatus = (uint32_t)0x00;
  if (HSEStatus == (uint32_t)0x01) {
    *((volatile uint32_t *)(((volatile uint32_t)0x40022000) + 0x00)) |= ((uint8_t)0x10);
    *((volatile uint32_t *)(((volatile uint32_t)0x40022000) + 0x00)) &= (uint32_t)((uint32_t) ~((uint8_t)0x03));
    *((volatile uint32_t *)(((volatile uint32_t)0x40022000) + 0x00)) |= (uint32_t)((uint8_t)0x00);
    *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x04)) |= (uint32_t)((uint32_t)0x00000000);
    *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x04)) |= (uint32_t)((uint32_t)0x00000000);
    *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x04)) |= (uint32_t)((uint32_t)0x00000000);
    *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x04)) &= (uint32_t)((uint32_t) ~(((uint32_t)0x00000003)));
    *((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x04)) |= (uint32_t)((uint32_t)0x00000001);
    while ((*((volatile uint32_t *)(((volatile uint32_t)0x40021000) + 0x04)) & (uint32_t)((uint32_t)0x0000000C)) != (uint32_t)0x04)
      ;
  } else {
  }
}
```