long double ft_power(long double base, long double ex) {
  long double half_pow;
  if (ex == 0)
    return (1);
  else if (ex < 0)
    return (1 / ft_power(base, -ex));
  else if ((int)ex % 2 == 0) {
    half_pow = ft_power(base, ex / 2);
    return (half_pow * half_pow);
  } else
    return (base * ft_power(base, ex - 1));
}


x86 assembly (clang, -O0):
<ft_power>:
push   %rbp
mov    %rsp,%rbp
sub    $0x80,%rsp
fldt   0x20(%rbp)
fldt   0x10(%rbp)
fstpt  -0x20(%rbp)
fstpt  -0x30(%rbp)
fldt   -0x30(%rbp)
fldz
fxch   %st(1)
fucomip %st(1),%st
fstp   %st(0)
jne    114d <ft_power+0x3d>
jp     114d <ft_power+0x3d>
jmp    1143 <ft_power+0x33>
fld1
fstpt  -0x10(%rbp)
jmp    1203 <ft_power+0xf3>
fldt   -0x30(%rbp)
fldz
fucomip %st(1),%st
fstp   %st(0)
jbe    1182 <ft_power+0x72>
jmp    1161 <ft_power+0x51>
fldt   -0x20(%rbp)
fldt   -0x30(%rbp)
fchs
mov    %rsp,%rax
fstpt  0x10(%rax)
fstpt  (%rax)
call   1030 <ft_power@plt>
fld1
fdivp  %st,%st(1)
fstpt  -0x10(%rbp)
jmp    1203 <ft_power+0xf3>
fldt   -0x30(%rbp)
fnstcw -0x46(%rbp)
movzwl -0x46(%rbp),%eax
or     $0xc00,%eax
mov    %ax,-0x48(%rbp)
fldcw  -0x48(%rbp)
fistpl -0x44(%rbp)
fldcw  -0x46(%rbp)
mov    -0x44(%rbp),%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
cmp    $0x0,%edx
jne    11dd <ft_power+0xcd>
fldt   -0x20(%rbp)
fldt   -0x30(%rbp)
flds   0xe42(%rip)
fdivrp %st,%st(1)
mov    %rsp,%rax
fstpt  0x10(%rax)
fstpt  (%rax)
call   1030 <ft_power@plt>
fstpt  -0x40(%rbp)
fldt   -0x40(%rbp)
fmul   %st,%st(0)
fstpt  -0x10(%rbp)
jmp    1203 <ft_power+0xf3>
fldt   -0x20(%rbp)
fld    %st(0)
fstpt  -0x54(%rbp)
fldt   -0x30(%rbp)
fld1
fchs
faddp  %st,%st(1)
mov    %rsp,%rax
fstpt  0x10(%rax)
fstpt  (%rax)
call   1030 <ft_power@plt>
fldt   -0x54(%rbp)
fmulp  %st,%st(1)
fstpt  -0x10(%rbp)
fldt   -0x10(%rbp)
add    $0x80,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ft_power>:
sub    $0x38,%rsp
fldt   0x50(%rsp)
fldt   0x40(%rsp)
fld1
fldz
fxch   %st(3)
fucomi %st(3),%st
jne    112c <ft_power+0x1c>
jnp    11b4 <ft_power+0xa4>
fstp   %st(1)
fxch   %st(2)
fucomip %st(2),%st
jbe    114a <ft_power+0x3a>
fxch   %st(1)
fchs
fstpt  0x10(%rsp)
fstpt  (%rsp)
call   1030 <ft_power@plt>
fld1
fdivp  %st,%st(1)
jmp    11a6 <ft_power+0x96>
fnstcw 0x24(%rsp)
movzwl 0x24(%rsp),%eax
or     $0xc00,%eax
mov    %ax,0x26(%rsp)
fldcw  0x26(%rsp)
fxch   %st(1)
fistl  0x28(%rsp)
fldcw  0x24(%rsp)
testb  $0x1,0x28(%rsp)
jne    1188 <ft_power+0x78>
fmuls  0xe88(%rip)
fstpt  0x10(%rsp)
fstpt  (%rsp)
call   1030 <ft_power@plt>
fmul   %st,%st(0)
jmp    11a6 <ft_power+0x96>
fld1
fchs
faddp  %st,%st(1)
fld    %st(1)
fstpt  (%rsp)
fstpt  0x10(%rsp)
fstpt  0x2c(%rsp)
call   1030 <ft_power@plt>
fldt   0x2c(%rsp)
fmulp  %st,%st(1)
fldz
fldz
fldz
fxch   %st(1)
fxch   %st(3)
fxch   %st(1)
fxch   %st(2)
fstp   %st(0)
fstp   %st(2)
fstp   %st(0)
add    $0x38,%rsp
ret

LLVM IR (-O0):
define x86_fp80 @ft_power(x86_fp80 %0, x86_fp80 %1) {
%3 = alloca x86_fp80
%4 = alloca x86_fp80
%5 = alloca x86_fp80
%6 = alloca x86_fp80
store x86_fp80 %0, x86_fp80* %4
store x86_fp80 %1, x86_fp80* %5
%7 = load x86_fp80, x86_fp80* %5
%8 = fcmp oeq x86_fp80 %7, 0xK00000000000000000000
br i1 %8, label %9, label %10
9: ; preds = %2
store x86_fp80 0xK3FFF8000000000000000, x86_fp80* %3
br label %39
10: ; preds = %2
%11 = load x86_fp80, x86_fp80* %5
%12 = fcmp olt x86_fp80 %11, 0xK00000000000000000000
br i1 %12, label %13, label %19
13: ; preds = %10
%14 = load x86_fp80, x86_fp80* %4
%15 = load x86_fp80, x86_fp80* %5
%16 = fneg x86_fp80 %15
%17 = call x86_fp80 @ft_power(x86_fp80 %14, x86_fp80 %16)
%18 = fdiv x86_fp80 0xK3FFF8000000000000000, %17
store x86_fp80 %18, x86_fp80* %3
br label %39
19: ; preds = %10
%20 = load x86_fp80, x86_fp80* %5
%21 = fptosi x86_fp80 %20 to i32
%22 = srem i32 %21, 2
%23 = icmp eq i32 %22, 0
br i1 %23, label %24, label %32
24: ; preds = %19
%25 = load x86_fp80, x86_fp80* %4
%26 = load x86_fp80, x86_fp80* %5
%27 = fdiv x86_fp80 %26, 0xK40008000000000000000
%28 = call x86_fp80 @ft_power(x86_fp80 %25, x86_fp80 %27)
store x86_fp80 %28, x86_fp80* %6
%29 = load x86_fp80, x86_fp80* %6
%30 = load x86_fp80, x86_fp80* %6
%31 = fmul x86_fp80 %29, %30
store x86_fp80 %31, x86_fp80* %3
br label %39
32: ; preds = %19
%33 = load x86_fp80, x86_fp80* %4
%34 = load x86_fp80, x86_fp80* %4
%35 = load x86_fp80, x86_fp80* %5
%36 = fsub x86_fp80 %35, 0xK3FFF8000000000000000
%37 = call x86_fp80 @ft_power(x86_fp80 %34, x86_fp80 %36)
%38 = fmul x86_fp80 %33, %37
store x86_fp80 %38, x86_fp80* %3
br label %39
39: ; preds = %32, %24, %13, %9
%40 = load x86_fp80, x86_fp80* %3
ret x86_fp80 %40
}

LLVM IR (-O2):
define x86_fp80 @ft_power(x86_fp80 %0, x86_fp80 %1) {
%3 = fcmp oeq x86_fp80 %1, 0xK00000000000000000000
br i1 %3, label %6, label %4
4: ; preds = %2
%5 = fcmp olt x86_fp80 %1, 0xK00000000000000000000
br i1 %5, label %8, label %12
6: ; preds = %2, %20, %16, %8
%7 = phi x86_fp80 [ %11, %8 ], [ %19, %16 ], [ %23, %20 ], [ 0xK3FFF8000000000000000, %2 ]
ret x86_fp80 %7
8: ; preds = %4
%9 = fneg x86_fp80 %1
%10 = tail call x86_fp80 @ft_power(x86_fp80 %0, x86_fp80 %9)
%11 = fdiv x86_fp80 0xK3FFF8000000000000000, %10
br label %6
12: ; preds = %4
%13 = fptosi x86_fp80 %1 to i32
%14 = and i32 %13, 1
%15 = icmp eq i32 %14, 0
br i1 %15, label %16, label %20
16: ; preds = %12
%17 = fmul x86_fp80 %1, 0xK3FFE8000000000000000
%18 = tail call x86_fp80 @ft_power(x86_fp80 %0, x86_fp80 %17)
%19 = fmul x86_fp80 %18, %18
br label %6
20: ; preds = %12
%21 = fadd x86_fp80 %1, 0xKBFFF8000000000000000
%22 = tail call x86_fp80 @ft_power(x86_fp80 %0, x86_fp80 %21)
%23 = fmul x86_fp80 %22, %0
br label %6
}