user: 请显示与下面列出的汇编代码相匹配的C语言实现:

```asm
<fp_exp>:
  endbr64
  push   %rbp
  mov    %rsp,%rbp
  sub    $0x30,%rsp
  mov    %edi,-0x24(%rbp)
  mov    %esi,-0x28(%rbp)
  mov    %edx,-0x2c(%rbp)
  mov    -0x2c(%rbp),%eax
  test   %rax,%rax
  js     L14
  pxor   %xmm0,%xmm0
  cvtsi2sd %rax,%xmm0
  jmp    L31
L14:
  mov    %rax,%rdx
  shr    %rdx
  and    $0x1,%eax
  or     %rax,%rdx
  pxor   %xmm0,%xmm0
  cvtsi2sd %rdx,%xmm0
  addsd  %xmm0,%xmm0
L31:
  movsd  D0(%rip),%xmm1
  mulsd  %xmm0,%xmm1
  movsd  D5(%rip),%xmm0
  addsd  %xmm1,%xmm0
  movsd  %xmm0,-0x8(%rbp)
  mov    -0x8(%rbp),%rdx
  mov    -0x18(%rbp),%eax
  movq   %rdx,%xmm0
  mov    %eax,%edi
  call   <mpf_init2@plt>
  mov    -0x8(%rbp),%rdx
  mov    -0x14(%rbp),%eax
  movq   %rdx,%xmm0
  mov    %eax,%edi
  call   <mpf_init2@plt>
  mov    -0x28(%rbp),%edx
  mov    -0x18(%rbp),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <mpf_set@plt>
  mov    -0x18(%rbp),%edx
  mov    -0x14(%rbp),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <mpf_floor@plt>
  mov    -0x14(%rbp),%edx
  mov    -0x18(%rbp),%ecx
  mov    -0x18(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpf_sub@plt>
  mov    -0x14(%rbp),%eax
  mov    %eax,%edi
  call   <mpf_get_si@plt>
  mov    %rax,-0x10(%rbp)
  mov    D7(%rip),%rdx
  mov    -0x18(%rbp),%eax
  movq   %rdx,%xmm0
  mov    %eax,%edi
  call   <mpf_cmp_d@plt>
  test   %rax,%rax
  jle    L49
  mov    -0x18(%rbp),%ecx
  mov    -0x18(%rbp),%eax
  mov    $0x1,%edx
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpf_sub_ui@plt>
  addq   $0x1,-0x10(%rbp)
L49:
  mov    -0x2c(%rbp),%edx
  mov    -0x18(%rbp),%ecx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <fp_exp_helper@plt>
  cmpq   $0x0,-0x10(%rbp)
  je     L22
  mov    -0x2c(%rbp),%edx
  mov    -0x18(%rbp),%eax
  mov    %edx,%esi
  mov    %eax,%edi
  call   <fp_e@plt>
  cmpq   $0x0,-0x10(%rbp)
  jle    L10
  mov    -0x10(%rbp),%rdx
  mov    -0x18(%rbp),%ecx
  mov    -0x14(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpf_pow_ui@plt>
  mov    -0x14(%rbp),%edx
  mov    -0x24(%rbp),%ecx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpf_mul@plt>
  jmp    L22
L10:
  mov    -0x10(%rbp),%rax
  neg    %rax
  mov    %rax,%rdx
  mov    -0x18(%rbp),%ecx
  mov    -0x14(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpf_pow_ui@plt>
  mov    -0x14(%rbp),%edx
  mov    -0x24(%rbp),%ecx
  mov    -0x24(%rbp),%eax
  mov    %ecx,%esi
  mov    %eax,%edi
  call   <mpf_div@plt>
L22:
  mov    -0x18(%rbp),%eax
  mov    %eax,%edi
  call   <mpf_clear@plt>
  mov    -0x14(%rbp),%eax
  mov    %eax,%edi
  call   <mpf_clear@plt>
  nop
  leave
  ret
```

tool_calls: name: disassemble_data
arguments: data_tag: D0
type: f64
name: disassemble_data
arguments: data_tag: D5
type: byte[8]
name: disassemble_data
arguments: data_tag: D7
type: f64

tool: D0: 3.3219281

tool: {"D5": [0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x40]}

tool: D7: 0.5

assistant: ```c
void fp_exp(mpf_t ex, const mpf_t z, unsigned int prec) {
  mp_bitcnt_t bits = ((double)prec) * 3.3219281 + 50;
  mpf_t zee, zf;
  mpf_init2(zee, bits);
  mpf_init2(zf, bits);
  mpf_set(zee, z);
  mpf_floor(zf, zee);
  mpf_sub(zee, zee, zf);
  long intpart = mpf_get_si(zf);
  if (mpf_cmp_d(zee, 0.5) > 0) {
    mpf_sub_ui(zee, zee, 1);
    intpart++;
  }
  fp_exp_helper(ex, zee, prec);
  if (intpart) {
    fp_e(zee, prec);
    if (0 < intpart) {
      mpf_pow_ui(zf, zee, intpart);
      mpf_mul(ex, ex, zf);
    } else {
      mpf_pow_ui(zf, zee, -intpart);
      mpf_div(ex, ex, zf);
    }
  }
  mpf_clear(zee);
  mpf_clear(zf);
}
```