long double ldexpl(long double x, int exp) {
  long double factor;
  int bit;
  if (x != x || x + x == x)
    return x;
  if (exp < 0) {
    exp = -exp;
    factor = 0.5L;
  } else
    factor = 2.0L;
  for (bit = 1; bit <= exp; bit <<= 1, factor *= factor)
    if (exp & bit)
      x *= factor;
  return x;
}


x86 assembly (clang, -O0):
<ldexpl>:
push   %rbp
mov    %rsp,%rbp
fldt   0x10(%rbp)
fstpt  -0x20(%rbp)
mov    %edi,-0x24(%rbp)
fldt   -0x20(%rbp)
fucomip %st(0),%st
jp     1139 <ldexpl+0x39>
jmp    111d <ldexpl+0x1d>
fldt   -0x20(%rbp)
fld    %st(0)
fadd   %st(1),%st
fucomip %st(1),%st
fstp   %st(0)
jne    1144 <ldexpl+0x44>
jp     1144 <ldexpl+0x44>
jmp    1139 <ldexpl+0x39>
fldt   -0x20(%rbp)
fstpt  -0x10(%rbp)
jmp    11ba <ldexpl+0xba>
cmpl   $0x0,-0x24(%rbp)
jge    1164 <ldexpl+0x64>
mov    -0x24(%rbp),%eax
neg    %eax
mov    %eax,-0x24(%rbp)
flds   0xea8(%rip)
fstpt  -0x40(%rbp)
jmp    116d <ldexpl+0x6d>
flds   0xe96(%rip)
fstpt  -0x40(%rbp)
movl   $0x1,-0x44(%rbp)
mov    -0x44(%rbp),%eax
cmp    -0x24(%rbp),%eax
jg     11b4 <ldexpl+0xb4>
mov    -0x24(%rbp),%eax
and    -0x44(%rbp),%eax
cmp    $0x0,%eax
je     119a <ldexpl+0x9a>
fldt   -0x40(%rbp)
fldt   -0x20(%rbp)
fmulp  %st,%st(1)
fstpt  -0x20(%rbp)
jmp    119f <ldexpl+0x9f>
mov    -0x44(%rbp),%eax
add    %eax,%eax
mov    %eax,-0x44(%rbp)
fldt   -0x40(%rbp)
fmul   %st,%st(0)
fstpt  -0x40(%rbp)
jmp    1174 <ldexpl+0x74>
fldt   -0x20(%rbp)
fstpt  -0x10(%rbp)
fldt   -0x10(%rbp)
pop    %rbp
ret

x86 assembly (clang, -O2):
<ldexpl>:
fldt   0x8(%rsp)
fucomi %st(0),%st
fld    %st(0)
fadd   %st(1),%st
jp     1156 <ldexpl+0x56>
fucomip %st(1),%st
jne    1112 <ldexpl+0x12>
jnp    1158 <ldexpl+0x58>
mov    %edi,%eax
neg    %eax
cmovs  %edi,%eax
test   %eax,%eax
jle    1158 <ldexpl+0x58>
shr    $0x1f,%edi
shl    $0x4,%rdi
lea    0xed5(%rip),%rcx
fldt   (%rdi,%rcx,1)
mov    $0x1,%ecx
fld1
cs nopw 0x0(%rax,%rax,1)
nop
test   %eax,%ecx
fld    %st(1)
fcmove %st(1),%st
fmulp  %st,%st(3)
add    %ecx,%ecx
fxch   %st(1)
fmul   %st,%st(0)
cmp    %eax,%ecx
fxch   %st(1)
jle    1140 <ldexpl+0x40>
jmp    115c <ldexpl+0x5c>
fstp   %st(0)
fldz
fldz
fstp   %st(1)
fstp   %st(0)
ret

LLVM IR (-O0):
define x86_fp80 @ldexpl(x86_fp80 %0, i32 %1) {
%3 = alloca x86_fp80
%4 = alloca x86_fp80
%5 = alloca i32
%6 = alloca x86_fp80
%7 = alloca i32
store x86_fp80 %0, x86_fp80* %4
store i32 %1, i32* %5
%8 = load x86_fp80, x86_fp80* %4
%9 = load x86_fp80, x86_fp80* %4
%10 = fcmp une x86_fp80 %8, %9
br i1 %10, label %17, label %11
11: ; preds = %2
%12 = load x86_fp80, x86_fp80* %4
%13 = load x86_fp80, x86_fp80* %4
%14 = fadd x86_fp80 %12, %13
%15 = load x86_fp80, x86_fp80* %4
%16 = fcmp oeq x86_fp80 %14, %15
br i1 %16, label %17, label %19
17: ; preds = %11, %2
%18 = load x86_fp80, x86_fp80* %4
store x86_fp80 %18, x86_fp80* %3
br label %49
19: ; preds = %11
%20 = load i32, i32* %5
%21 = icmp slt i32 %20, 0
br i1 %21, label %22, label %25
22: ; preds = %19
%23 = load i32, i32* %5
%24 = sub nsw i32 0, %23
store i32 %24, i32* %5
store x86_fp80 0xK3FFE8000000000000000, x86_fp80* %6
br label %26
25: ; preds = %19
store x86_fp80 0xK40008000000000000000, x86_fp80* %6
br label %26
26: ; preds = %25, %22
store i32 1, i32* %7
br label %27
27: ; preds = %41, %26
%28 = load i32, i32* %7
%29 = load i32, i32* %5
%30 = icmp sle i32 %28, %29
br i1 %30, label %31, label %47
31: ; preds = %27
%32 = load i32, i32* %5
%33 = load i32, i32* %7
%34 = and i32 %32, %33
%35 = icmp ne i32 %34, 0
br i1 %35, label %36, label %40
36: ; preds = %31
%37 = load x86_fp80, x86_fp80* %6
%38 = load x86_fp80, x86_fp80* %4
%39 = fmul x86_fp80 %38, %37
store x86_fp80 %39, x86_fp80* %4
br label %40
40: ; preds = %36, %31
br label %41
41: ; preds = %40
%42 = load i32, i32* %7
%43 = shl i32 %42, 1
store i32 %43, i32* %7
%44 = load x86_fp80, x86_fp80* %6
%45 = load x86_fp80, x86_fp80* %6
%46 = fmul x86_fp80 %45, %44
store x86_fp80 %46, x86_fp80* %6
br label %27
47: ; preds = %27
%48 = load x86_fp80, x86_fp80* %4
store x86_fp80 %48, x86_fp80* %3
br label %49
49: ; preds = %47, %17
%50 = load x86_fp80, x86_fp80* %3
ret x86_fp80 %50
}

LLVM IR (-O2):
define x86_fp80 @ldexpl(x86_fp80 %0, i32 %1) {
%3 = fcmp uno x86_fp80 %0, 0xK00000000000000000000
%4 = fadd x86_fp80 %0, %0
%5 = fcmp oeq x86_fp80 %4, %0
%6 = or i1 %3, %5
br i1 %6, label %25, label %7
7: ; preds = %2
%8 = icmp slt i32 %1, 0
%9 = sub nsw i32 0, %1
%10 = select i1 %8, i32 %9, i32 %1
%11 = icmp slt i32 %10, 1
br i1 %11, label %25, label %12
12: ; preds = %7
%13 = select i1 %8, x86_fp80 0xK3FFE8000000000000000, x86_fp80 0xK40008000000000000000
br label %14
14: ; preds = %12, %14
%15 = phi i32 [ %22, %14 ], [ 1, %12 ]
%16 = phi x86_fp80 [ %23, %14 ], [ %13, %12 ]
%17 = phi x86_fp80 [ %21, %14 ], [ %0, %12 ]
%18 = and i32 %15, %10
%19 = icmp eq i32 %18, 0
%20 = select i1 %19, x86_fp80 0xK3FFF8000000000000000, x86_fp80 %16
%21 = fmul x86_fp80 %17, %20
%22 = shl i32 %15, 1
%23 = fmul x86_fp80 %16, %16
%24 = icmp sgt i32 %22, %10
br i1 %24, label %25, label %14
25: ; preds = %14, %7, %2
%26 = phi x86_fp80 [ %0, %2 ], [ %0, %7 ], [ %21, %14 ]
ret x86_fp80 %26
}