user: 请将这段汇编代码片段转换成等效的C代码:

```asm
<fmod>:
  endbr64
  push   %r15
  movd   %xmm1,%r15d
  movapd %xmm0,%xmm2
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  sub    $0x18,%rsp
  add    %r15d,%r15d
  jne    L186
L17:
  mulsd  %xmm1,%xmm2
  divsd  %xmm2,%xmm2
  movapd %xmm2,%xmm0
L1:
  add    $0x18,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L186:
  movd   %xmm0,%ebp
  mov    $0x34,%ecx
  movq   %xmm0,%r13
  movsd  %xmm0,0x8(%rsp)
  sar    %cl,%ebp
  movapd %xmm1,%xmm0
  movq   %xmm1,%r12
  movsd  %xmm1,(%rsp)
  and    $0x7ff,%ebp
  movd   %xmm1,%r14d
  mov    %r13d,%ebx
  call   <isnan@plt>
  cmp    $0x7ff,%ebp
  movsd  (%rsp),%xmm1
  movsd  0x8(%rsp),%xmm2
  je     L17
  test   %rax,%rax
  jne    L17
  lea    (%rbx,%rbx,1),%edi
  cmp    %edi,%r15d
  jge    L182
  mov    %r12d,%eax
  mov    $0x34,%ecx
  sar    %cl,%eax
  and    $0x7ff,%eax
  test   %ebp,%ebp
  jne    L184
  mov    %ebx,%edx
  mov    $0x3f,%ecx
  shl    $0xc,%edx
  mov    %edx,%esi
  sar    %cl,%esi
  test   %esi,%esi
  jne    L23
  nopl   0x0(%rax,%rax,1)
L73:
  add    %edx,%edx
  mov    $0x3f,%ecx
  sub    $0x1,%esi
  mov    %edx,%edi
  sar    %cl,%edi
  test   %edi,%edi
  je     L73
  mov    $0x1,%ecx
  mov    %esi,%ebp
  sub    %esi,%ecx
  shl    %cl,%ebx
L29:
  test   %eax,%eax
  jne    L175
L79:
  mov    %r12d,%edx
  mov    $0x3f,%ecx
  shl    $0xc,%edx
  mov    %edx,%eax
  sar    %cl,%eax
  test   %eax,%eax
  jne    L253
  nopl   0x0(%rax)
L18:
  add    %edx,%edx
  mov    $0x3f,%ecx
  sub    $0x1,%eax
  mov    %edx,%esi
  sar    %cl,%esi
  test   %esi,%esi
  je     L18
  mov    $0x1,%ecx
  mov    %r12d,%r14d
  sub    %eax,%ecx
  shl    %cl,%r14d
L100:
  cmp    %ebp,%eax
  jge    L175
  nopw   0x0(%rax,%rax,1)
L242:
  mov    %ebx,%edx
  mov    $0x3f,%ecx
  sub    %r14d,%edx
  mov    %edx,%edi
  sar    %cl,%edi
  test   %edi,%edi
  jne    L250
  test   %edx,%edx
  je     L162
  mov    %edx,%ebx
L250:
  sub    $0x1,%ebp
  add    %ebx,%ebx
  cmp    %eax,%ebp
  jne    L242
L213:
  mov    %ebx,%edx
  mov    $0x3f,%ecx
  sub    %r14d,%edx
  mov    %edx,%esi
  sar    %cl,%esi
  test   %esi,%esi
  jne    L260
  mov    %edx,%ebx
  test   %edx,%edx
  jne    L260
  nopl   0x0(%rax)
L162:
  pxor   %xmm0,%xmm0
  mulsd  %xmm2,%xmm0
  jmp    L1
  nopl   (%rax)
L182:
  movapd %xmm2,%xmm0
  jne    L1
  jmp    L162
  nopl   0x0(%rax)
L72:
  add    %ebx,%ebx
  sub    $0x1,%eax
L260:
  mov    %ebx,%edx
  mov    $0x34,%ecx
  sar    %cl,%edx
  test   %edx,%edx
  je     L72
  test   %eax,%eax
  jle    L214
L141:
  movabs $0xffffffff00000000,%rax
  and    %rax,%r13
  or     %rbx,%r13
  movq   %r13,%xmm0
  jmp    L1
L184:
  test   %eax,%eax
  jne    L100
  jmp    L79
  nopl   (%rax)
L214:
  mov    $0x1,%ecx
  sub    %eax,%ecx
  sar    %cl,%ebx
  jmp    L141
L23:
  mov    %edi,%ebx
  jmp    L29
L253:
  mov    %r15d,%r14d
  xor    %eax,%eax
  jmp    L100
L175:
  mov    %ebp,%eax
  jmp    L213
```

assistant: ```c
double fmod(double x, double y) {
  union {
    double f;
    uint64_t i;
  } ux = {x}, uy = {y};
  int ex = ux.i >> 52 & 0x7ff;
  int ey = uy.i >> 52 & 0x7ff;
  int sx = ux.i >> 63;
  uint64_t i;
  uint64_t uxi = ux.i;
  if (uy.i << 1 == 0 || isnan(y) || ex == 0x7ff)
    return (x * y) / (x * y);
  if (uxi << 1 <= uy.i << 1) {
    if (uxi << 1 == uy.i << 1)
      return 0 * x;
    return x;
  }
  if (!ex) {
    for (i = uxi << 12; i >> 63 == 0; ex--, i <<= 1)
      ;
    uxi <<= -ex + 1;
  } else {
    uxi &= -1ULL >> 12;
    uxi |= 1ULL << 52;
  }
  if (!ey) {
    for (i = uy.i << 12; i >> 63 == 0; ey--, i <<= 1)
      ;
    uy.i <<= -ey + 1;
  } else {
    uy.i &= -1ULL >> 12;
    uy.i |= 1ULL << 52;
  }
  for (; ex > ey; ex--) {
    i = uxi - uy.i;
    if (i >> 63 == 0) {
      if (i == 0)
        return 0 * x;
      uxi = i;
    }
    uxi <<= 1;
  }
  i = uxi - uy.i;
  if (i >> 63 == 0) {
    if (i == 0)
      return 0 * x;
    uxi = i;
  }
  for (; uxi >> 52 == 0; uxi <<= 1, ex--)
    ;
  if (ex > 0) {
    uxi -= 1ULL << 52;
    uxi |= (uint64_t)ex << 52;
  } else {
    uxi >>= -ex + 1;
  }
  uxi |= (uint64_t)sx << 63;
  ux.i = uxi;
  return ux.f;
}
```