double ldexp(fr, exp)
double fr;
int exp;
{
  double huge = 1.701411834604692293e38;
  int neg;
  int i;
  neg = 0;
  if (fr < 0) {
    fr = -fr;
    neg = 1;
  }
  fr = frexp(fr, &i);
  while (fr < 0.5) {
    fr = 2 * fr;
    i = i - 1;
  }
  exp = exp + i;
  if (exp > 127) {
    if (neg)
      return (-huge);
    else
      return (huge);
  }
  if (exp < -127)
    return (0);
  while (exp > 30) {
    fr = fr * (1L << 30);
    exp = exp - 30;
  }
  while (exp < -30) {
    fr = fr / (1L << 30);
    exp = exp + 30;
  }
  if (exp > 0)
    fr = fr * (1L << exp);
  if (exp < 0)
    fr = fr / (1L << -exp);
  if (neg)
    fr = -fr;
  return (fr);
}


x86 assembly (clang, -O0):
<ldexp>:
push   %rbp
mov    %rsp,%rbp
sub    $0x30,%rsp
movsd  %xmm0,-0x10(%rbp)
mov    %edi,-0x14(%rbp)
movsd  0xed8(%rip),%xmm0
movsd  %xmm0,-0x20(%rbp)
movl   $0x0,-0x24(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    116a <ldexp+0x5a>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x10(%rbp)
movl   $0x1,-0x24(%rbp)
movsd  -0x10(%rbp),%xmm0
lea    -0x28(%rbp),%rdi
call   1030 <frexp@plt>
movsd  %xmm0,-0x10(%rbp)
movsd  0xe83(%rip),%xmm0
ucomisd -0x10(%rbp),%xmm0
jbe    11b0 <ldexp+0xa0>
movsd  0xe80(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    -0x28(%rbp),%eax
sub    $0x1,%eax
mov    %eax,-0x28(%rbp)
jmp    117d <ldexp+0x6d>
mov    -0x14(%rbp),%eax
add    -0x28(%rbp),%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x7f,-0x14(%rbp)
jle    1202 <ldexp+0xf2>
cmpl   $0x0,-0x24(%rbp)
je     11f3 <ldexp+0xe3>
movsd  -0x20(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1308 <ldexp+0x1f8>
movsd  -0x20(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1308 <ldexp+0x1f8>
cmpl   $0xffffff81,-0x14(%rbp)
jge    1219 <ldexp+0x109>
xorps  %xmm0,%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1308 <ldexp+0x1f8>
jmp    121e <ldexp+0x10e>
cmpl   $0x1e,-0x14(%rbp)
jle    1248 <ldexp+0x138>
movsd  0xde0(%rip),%xmm0
mulsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x1e,%eax
mov    %eax,-0x14(%rbp)
jmp    121e <ldexp+0x10e>
jmp    124d <ldexp+0x13d>
cmpl   $0xffffffe2,-0x14(%rbp)
jge    127b <ldexp+0x16b>
movsd  -0x10(%rbp),%xmm0
movsd  0xdac(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0x1e,%eax
mov    %eax,-0x14(%rbp)
jmp    124d <ldexp+0x13d>
cmpl   $0x0,-0x14(%rbp)
jle    12a5 <ldexp+0x195>
movsd  -0x10(%rbp),%xmm0
mov    -0x14(%rbp),%eax
mov    %eax,%ecx
mov    $0x1,%eax
shl    %cl,%rax
cvtsi2sd %rax,%xmm1
mulsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
cmpl   $0x0,-0x14(%rbp)
jge    12d3 <ldexp+0x1c3>
movsd  -0x10(%rbp),%xmm0
xor    %eax,%eax
sub    -0x14(%rbp),%eax
mov    %eax,%eax
mov    %eax,%ecx
mov    $0x1,%eax
shl    %cl,%rax
cvtsi2sd %rax,%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x10(%rbp)
cmpl   $0x0,-0x24(%rbp)
je     12fe <ldexp+0x1ee>
movsd  -0x10(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x10(%rbp)
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
add    $0x30,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<ldexp>:
push   %rbx
sub    $0x20,%rsp
mov    %edi,%ebx
movapd %xmm0,%xmm3
movapd 0xedd(%rip),%xmm1
xorpd  %xmm0,%xmm1
xorpd  %xmm2,%xmm2
cmpltsd %xmm2,%xmm0
andpd  %xmm0,%xmm1
movapd %xmm3,0x10(%rsp)
andnpd %xmm3,%xmm0
orpd   %xmm1,%xmm0
lea    0xc(%rsp),%rdi
call   1030 <frexp@plt>
mov    0xc(%rsp),%ecx
movsd  0xec8(%rip),%xmm1
ucomisd %xmm0,%xmm1
jbe    116d <ldexp+0x5d>
xchg   %ax,%ax
addsd  %xmm0,%xmm0
add    $0xffffffff,%ecx
ucomisd %xmm0,%xmm1
ja     1160 <ldexp+0x50>
add    %ebx,%ecx
cmp    $0x80,%ecx
jl     1197 <ldexp+0x87>
xorpd  %xmm0,%xmm0
xor    %eax,%eax
ucomisd 0x10(%rsp),%xmm0
seta   %al
lea    0xe83(%rip),%rcx
movsd  (%rcx,%rax,8),%xmm1
jmp    1275 <ldexp+0x165>
xorpd  %xmm1,%xmm1
cmp    $0xffffff81,%ecx
jl     1275 <ldexp+0x165>
cmp    $0x1f,%ecx
jl     11e4 <ldexp+0xd4>
movsd  0xe87(%rip),%xmm1
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %ecx,%eax
mulsd  %xmm1,%xmm0
lea    -0x1e(%rax),%ecx
cmp    $0x3c,%eax
ja     11c0 <ldexp+0xb0>
mov    $0x1,%eax
shl    %cl,%rax
xorps  %xmm1,%xmm1
cvtsi2sd %rax,%xmm1
mulsd  %xmm1,%xmm0
jmp    124a <ldexp+0x13a>
cmp    $0xffffffe1,%ecx
jg     1210 <ldexp+0x100>
movsd  0xe3f(%rip),%xmm1
mov    %ecx,%eax
cs nopw 0x0(%rax,%rax,1)
nopl   (%rax)
mulsd  %xmm1,%xmm0
lea    0x1e(%rax),%ecx
cmp    $0xffffffc4,%eax
mov    %ecx,%eax
jb     1200 <ldexp+0xf0>
jmp    1234 <ldexp+0x124>
mov    $0x1,%eax
shl    %cl,%rax
test   %ecx,%ecx
jg     1226 <ldexp+0x116>
movsd  0xe04(%rip),%xmm1
jmp    122e <ldexp+0x11e>
xorps  %xmm1,%xmm1
cvtsi2sd %rax,%xmm1
mulsd  %xmm1,%xmm0
jns    124a <ldexp+0x13a>
neg    %cl
mov    $0x1,%eax
shl    %cl,%rax
xorps  %xmm1,%xmm1
cvtsi2sd %rax,%xmm1
divsd  %xmm1,%xmm0
movapd 0xdae(%rip),%xmm1
xorpd  %xmm0,%xmm1
xorpd  %xmm2,%xmm2
movapd 0x10(%rsp),%xmm3
cmpltsd %xmm2,%xmm3
andpd  %xmm3,%xmm1
andnpd %xmm0,%xmm3
orpd   %xmm1,%xmm3
movapd %xmm3,%xmm1
movapd %xmm1,%xmm0
add    $0x20,%rsp
pop    %rbx
ret

LLVM IR (-O0):
define double @ldexp(double %0, i32 %1) {
%3 = alloca double
%4 = alloca double
%5 = alloca i32
%6 = alloca double
%7 = alloca i32
%8 = alloca i32
store double %0, double* %4
store i32 %1, i32* %5
store double 0x47E0000000000000, double* %6
store i32 0, i32* %7
%9 = load double, double* %4
%10 = fcmp olt double %9, 0.000000e+00
br i1 %10, label %11, label %14
11: ; preds = %2
%12 = load double, double* %4
%13 = fneg double %12
store double %13, double* %4
store i32 1, i32* %7
br label %14
14: ; preds = %11, %2
%15 = load double, double* %4
%16 = call double @frexp(double %15, i32* %8)
store double %16, double* %4
br label %17
17: ; preds = %20, %14
%18 = load double, double* %4
%19 = fcmp olt double %18, 5.000000e-01
br i1 %19, label %20, label %25
20: ; preds = %17
%21 = load double, double* %4
%22 = fmul double 2.000000e+00, %21
store double %22, double* %4
%23 = load i32, i32* %8
%24 = sub nsw i32 %23, 1
store i32 %24, i32* %8
br label %17
25: ; preds = %17
%26 = load i32, i32* %5
%27 = load i32, i32* %8
%28 = add nsw i32 %26, %27
store i32 %28, i32* %5
%29 = load i32, i32* %5
%30 = icmp sgt i32 %29, 127
br i1 %30, label %31, label %39
31: ; preds = %25
%32 = load i32, i32* %7
%33 = icmp ne i32 %32, 0
br i1 %33, label %34, label %37
34: ; preds = %31
%35 = load double, double* %6
%36 = fneg double %35
store double %36, double* %3
br label %90
37: ; preds = %31
%38 = load double, double* %6
store double %38, double* %3
br label %90
39: ; preds = %25
%40 = load i32, i32* %5
%41 = icmp slt i32 %40, -127
br i1 %41, label %42, label %43
42: ; preds = %39
store double 0.000000e+00, double* %3
br label %90
43: ; preds = %39
br label %44
44: ; preds = %47, %43
%45 = load i32, i32* %5
%46 = icmp sgt i32 %45, 30
br i1 %46, label %47, label %52
47: ; preds = %44
%48 = load double, double* %4
%49 = fmul double %48, 0x41D0000000000000
store double %49, double* %4
%50 = load i32, i32* %5
%51 = sub nsw i32 %50, 30
store i32 %51, i32* %5
br label %44
52: ; preds = %44
br label %53
53: ; preds = %56, %52
%54 = load i32, i32* %5
%55 = icmp slt i32 %54, -30
br i1 %55, label %56, label %61
56: ; preds = %53
%57 = load double, double* %4
%58 = fdiv double %57, 0x41D0000000000000
store double %58, double* %4
%59 = load i32, i32* %5
%60 = add nsw i32 %59, 30
store i32 %60, i32* %5
br label %53
61: ; preds = %53
%62 = load i32, i32* %5
%63 = icmp sgt i32 %62, 0
br i1 %63, label %64, label %71
64: ; preds = %61
%65 = load double, double* %4
%66 = load i32, i32* %5
%67 = zext i32 %66 to i64
%68 = shl i64 1, %67
%69 = sitofp i64 %68 to double
%70 = fmul double %65, %69
store double %70, double* %4
br label %71
71: ; preds = %64, %61
%72 = load i32, i32* %5
%73 = icmp slt i32 %72, 0
br i1 %73, label %74, label %82
74: ; preds = %71
%75 = load double, double* %4
%76 = load i32, i32* %5
%77 = sub nsw i32 0, %76
%78 = zext i32 %77 to i64
%79 = shl i64 1, %78
%80 = sitofp i64 %79 to double
%81 = fdiv double %75, %80
store double %81, double* %4
br label %82
82: ; preds = %74, %71
%83 = load i32, i32* %7
%84 = icmp ne i32 %83, 0
br i1 %84, label %85, label %88
85: ; preds = %82
%86 = load double, double* %4
%87 = fneg double %86
store double %87, double* %4
br label %88
88: ; preds = %85, %82
%89 = load double, double* %4
store double %89, double* %3
br label %90
90: ; preds = %88, %42, %37, %34
%91 = load double, double* %3
ret double %91
}

LLVM IR (-O2):
define double @ldexp(double %0, i32 %1) {
%3 = alloca i32
%4 = bitcast i32* %3 to i8*
%5 = fcmp olt double %0, 0.000000e+00
%6 = fneg double %0
%7 = select i1 %5, double %6, double %0
%8 = call double @frexp(double %7, i32* %3)
%9 = load i32, i32* %3
%10 = fcmp olt double %8, 5.000000e-01
br i1 %10, label %11, label %17
11: ; preds = %2, %11
%12 = phi double [ %14, %11 ], [ %8, %2 ]
%13 = phi i32 [ %15, %11 ], [ %9, %2 ]
%14 = fmul double %12, 2.000000e+00
%15 = add nsw i32 %13, -1
%16 = fcmp olt double %14, 5.000000e-01
br i1 %16, label %11, label %17
17: ; preds = %11, %2
%18 = phi i32 [ %9, %2 ], [ %15, %11 ]
%19 = phi double [ %8, %2 ], [ %14, %11 ]
%20 = add nsw i32 %18, %1
%21 = icmp sgt i32 %20, 127
br i1 %21, label %22, label %24
22: ; preds = %17
%23 = select i1 %5, double 0xC7E0000000000000, double 0x47E0000000000000
br label %67
24: ; preds = %17
%25 = icmp slt i32 %20, -127
br i1 %25, label %67, label %26
26: ; preds = %24
%27 = icmp sgt i32 %20, 30
br i1 %27, label %30, label %28
28: ; preds = %26
%29 = icmp slt i32 %20, -30
br i1 %29, label %41, label %47
30: ; preds = %26, %30
%31 = phi i32 [ %34, %30 ], [ %20, %26 ]
%32 = phi double [ %33, %30 ], [ %19, %26 ]
%33 = fmul double %32, 0x41D0000000000000
%34 = add nsw i32 %31, -30
%35 = icmp ugt i32 %31, 60
br i1 %35, label %30, label %36
36: ; preds = %30
%37 = zext i32 %34 to i64
%38 = shl nuw nsw i64 1, %37
%39 = sitofp i64 %38 to double
%40 = fmul double %33, %39
br label %63
41: ; preds = %28, %41
%42 = phi i32 [ %45, %41 ], [ %20, %28 ]
%43 = phi double [ %44, %41 ], [ %19, %28 ]
%44 = fmul double %43, 0x3E10000000000000
%45 = add nuw nsw i32 %42, 30
%46 = icmp ult i32 %42, -60
br i1 %46, label %41, label %55
47: ; preds = %28
%48 = icmp sgt i32 %20, 0
%49 = zext i32 %20 to i64
%50 = shl nuw i64 1, %49
%51 = sitofp i64 %50 to double
%52 = select i1 %48, double %51, double 1.000000e+00
%53 = fmul double %19, %52
%54 = icmp slt i32 %20, 0
br i1 %54, label %55, label %63
55: ; preds = %41, %47
%56 = phi double [ %53, %47 ], [ %44, %41 ]
%57 = phi i32 [ %20, %47 ], [ %45, %41 ]
%58 = sub nsw i32 0, %57
%59 = zext i32 %58 to i64
%60 = shl nuw nsw i64 1, %59
%61 = sitofp i64 %60 to double
%62 = fdiv double %56, %61
br label %63
63: ; preds = %36, %55, %47
%64 = phi double [ %62, %55 ], [ %53, %47 ], [ %40, %36 ]
%65 = fneg double %64
%66 = select i1 %5, double %65, double %64
br label %67
67: ; preds = %24, %22, %63
%68 = phi double [ %66, %63 ], [ %23, %22 ], [ 0.000000e+00, %24 ]
ret double %68
}