double bin_interp(upcount, lwcount, upthr, lwthr, Margin, tol)
double upcount, lwcount, upthr, lwthr, Margin, tol;
{
  double midcount, midthr, diff;
  register long iterno;
  if (tol < 0.)
    tol = -tol;
  iterno = 1;
  if ((diff = fabs((upcount - upthr) - Margin)) < tol)
    return upcount;
  if ((diff = fabs((lwcount - lwthr) - Margin)) < tol)
    return lwcount;
  midcount = (upcount + lwcount) / 2.0;
  midthr = (upthr + lwthr) / 2.0;
  while ((diff = (midcount - midthr) - Margin, fabs(diff)) > tol) {
    if (++iterno > 20)
      tol *= 1.1;
    if (diff > tol) {
      midcount = (upcount + midcount) / 2.0;
      midthr = (upthr + midthr) / 2.0;
    } else if (diff < -tol) {
      midcount = (midcount + lwcount) / 2.0;
      midthr = (midthr + lwthr) / 2.0;
    }
  }
  return (midcount);
}


x86 assembly (clang, -O0):
<bin_interp>:
push   %rbp
mov    %rsp,%rbp
movsd  %xmm0,-0x10(%rbp)
movsd  %xmm1,-0x18(%rbp)
movsd  %xmm2,-0x20(%rbp)
movsd  %xmm3,-0x28(%rbp)
movsd  %xmm4,-0x30(%rbp)
movsd  %xmm5,-0x38(%rbp)
xorps  %xmm0,%xmm0
ucomisd -0x38(%rbp),%xmm0
jbe    1151 <bin_interp+0x51>
movsd  -0x38(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
movsd  %xmm0,-0x38(%rbp)
movq   $0x1,-0x58(%rbp)
movsd  -0x10(%rbp),%xmm1
subsd  -0x20(%rbp),%xmm1
subsd  -0x30(%rbp),%xmm1
movaps 0xe91(%rip),%xmm0
pand   %xmm0,%xmm1
movsd  %xmm1,-0x50(%rbp)
movsd  -0x38(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    1196 <bin_interp+0x96>
movsd  -0x10(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1320 <bin_interp+0x220>
movsd  -0x18(%rbp),%xmm1
subsd  -0x28(%rbp),%xmm1
subsd  -0x30(%rbp),%xmm1
movaps 0xe54(%rip),%xmm0
pand   %xmm0,%xmm1
movsd  %xmm1,-0x50(%rbp)
movsd  -0x38(%rbp),%xmm0
ucomisd %xmm1,%xmm0
jbe    11d3 <bin_interp+0xd3>
movsd  -0x18(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
jmp    1320 <bin_interp+0x220>
movsd  -0x10(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  0xe2b(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x20(%rbp),%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  0xe10(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
movsd  -0x40(%rbp),%xmm0
subsd  -0x48(%rbp),%xmm0
subsd  -0x30(%rbp),%xmm0
movsd  %xmm0,-0x50(%rbp)
movsd  -0x50(%rbp),%xmm0
movaps 0xdd7(%rip),%xmm1
pand   %xmm1,%xmm0
ucomisd -0x38(%rbp),%xmm0
jbe    1316 <bin_interp+0x216>
mov    -0x58(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x58(%rbp)
cmp    $0x14,%rax
jle    1260 <bin_interp+0x160>
movsd  0xdc2(%rip),%xmm0
mulsd  -0x38(%rbp),%xmm0
movsd  %xmm0,-0x38(%rbp)
movsd  -0x50(%rbp),%xmm0
ucomisd -0x38(%rbp),%xmm0
jbe    12ab <bin_interp+0x1ab>
movsd  -0x10(%rbp),%xmm0
addsd  -0x40(%rbp),%xmm0
movsd  0xd8e(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x20(%rbp),%xmm0
addsd  -0x48(%rbp),%xmm0
movsd  0xd73(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
jmp    1311 <bin_interp+0x211>
movsd  -0x50(%rbp),%xmm1
movsd  -0x38(%rbp),%xmm0
movq   %xmm0,%rax
movabs $0x8000000000000000,%rcx
xor    %rcx,%rax
movq   %rax,%xmm0
ucomisd %xmm1,%xmm0
jbe    130c <bin_interp+0x20c>
movsd  -0x40(%rbp),%xmm0
addsd  -0x18(%rbp),%xmm0
movsd  0xd28(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x40(%rbp)
movsd  -0x48(%rbp),%xmm0
addsd  -0x28(%rbp),%xmm0
movsd  0xd0d(%rip),%xmm1
divsd  %xmm1,%xmm0
movsd  %xmm0,-0x48(%rbp)
jmp    1311 <bin_interp+0x211>
jmp    1209 <bin_interp+0x109>
movsd  -0x40(%rbp),%xmm0
movsd  %xmm0,-0x8(%rbp)
movsd  -0x8(%rbp),%xmm0
pop    %rbp
ret

x86 assembly (clang, -O2):
<bin_interp>:
movapd 0xef8(%rip),%xmm6
xorpd  %xmm5,%xmm6
xorpd  %xmm8,%xmm8
movapd %xmm5,%xmm7
cmpltsd %xmm8,%xmm7
andpd  %xmm7,%xmm6
andnpd %xmm5,%xmm7
orpd   %xmm6,%xmm7
movapd %xmm0,%xmm5
subsd  %xmm2,%xmm5
subsd  %xmm4,%xmm5
andpd  0xed5(%rip),%xmm5
ucomisd %xmm5,%xmm7
ja     1235 <bin_interp+0x135>
movapd %xmm1,%xmm5
subsd  %xmm3,%xmm5
subsd  %xmm4,%xmm5
andpd  0xeb7(%rip),%xmm5
ucomisd %xmm5,%xmm7
jbe    1164 <bin_interp+0x64>
movapd %xmm1,%xmm0
ret
unpcklpd %xmm2,%xmm0
unpcklpd %xmm3,%xmm1
movapd %xmm0,%xmm5
addpd  %xmm1,%xmm5
mulpd  0xea4(%rip),%xmm5
movapd %xmm5,%xmm3
unpckhpd %xmm5,%xmm3
movapd %xmm5,%xmm2
subsd  %xmm3,%xmm2
subsd  %xmm4,%xmm2
movapd 0xe78(%rip),%xmm3
andpd  %xmm2,%xmm3
ucomisd %xmm7,%xmm3
jbe    1231 <bin_interp+0x131>
mov    $0x1,%eax
movsd  0xe7c(%rip),%xmm10
movapd 0xe63(%rip),%xmm9
movapd 0xe4b(%rip),%xmm3
movapd 0xe32(%rip),%xmm8
jmp    11ff <bin_interp+0xff>
addpd  %xmm0,%xmm5
mulpd  %xmm9,%xmm5
movapd %xmm5,%xmm6
unpckhpd %xmm5,%xmm6
movapd %xmm5,%xmm2
subsd  %xmm6,%xmm2
subsd  %xmm4,%xmm2
movapd %xmm2,%xmm6
andpd  %xmm3,%xmm6
add    $0x1,%rax
ucomisd %xmm7,%xmm6
jbe    1231 <bin_interp+0x131>
movapd %xmm7,%xmm6
mulsd  %xmm10,%xmm6
cmp    $0x14,%rax
jae    1212 <bin_interp+0x112>
movapd %xmm7,%xmm6
movapd %xmm6,%xmm7
ucomisd %xmm6,%xmm2
ja     11d0 <bin_interp+0xd0>
movapd %xmm7,%xmm6
xorpd  %xmm8,%xmm6
ucomisd %xmm2,%xmm6
jbe    11d9 <bin_interp+0xd9>
addpd  %xmm1,%xmm5
jmp    11d4 <bin_interp+0xd4>
movapd %xmm5,%xmm0
ret

LLVM IR (-O0):
define double @bin_interp(double %0, double %1, double %2, double %3, double %4, double %5) {
%7 = alloca double
%8 = alloca double
%9 = alloca double
%10 = alloca double
%11 = alloca double
%12 = alloca double
%13 = alloca double
%14 = alloca double
%15 = alloca double
%16 = alloca double
%17 = alloca i64
store double %0, double* %8
store double %1, double* %9
store double %2, double* %10
store double %3, double* %11
store double %4, double* %12
store double %5, double* %13
%18 = load double, double* %13
%19 = fcmp olt double %18, 0.000000e+00
br i1 %19, label %20, label %23
20: ; preds = %6
%21 = load double, double* %13
%22 = fneg double %21
store double %22, double* %13
br label %23
23: ; preds = %20, %6
store i64 1, i64* %17
%24 = load double, double* %8
%25 = load double, double* %10
%26 = fsub double %24, %25
%27 = load double, double* %12
%28 = fsub double %26, %27
%29 = call double @llvm.fabs.f64(double %28)
store double %29, double* %16
%30 = load double, double* %13
%31 = fcmp olt double %29, %30
br i1 %31, label %32, label %34
32: ; preds = %23
%33 = load double, double* %8
store double %33, double* %7
br label %102
34: ; preds = %23
%35 = load double, double* %9
%36 = load double, double* %11
%37 = fsub double %35, %36
%38 = load double, double* %12
%39 = fsub double %37, %38
%40 = call double @llvm.fabs.f64(double %39)
store double %40, double* %16
%41 = load double, double* %13
%42 = fcmp olt double %40, %41
br i1 %42, label %43, label %45
43: ; preds = %34
%44 = load double, double* %9
store double %44, double* %7
br label %102
45: ; preds = %34
%46 = load double, double* %8
%47 = load double, double* %9
%48 = fadd double %46, %47
%49 = fdiv double %48, 2.000000e+00
store double %49, double* %14
%50 = load double, double* %10
%51 = load double, double* %11
%52 = fadd double %50, %51
%53 = fdiv double %52, 2.000000e+00
store double %53, double* %15
br label %54
54: ; preds = %99, %45
%55 = load double, double* %14
%56 = load double, double* %15
%57 = fsub double %55, %56
%58 = load double, double* %12
%59 = fsub double %57, %58
store double %59, double* %16
%60 = load double, double* %16
%61 = call double @llvm.fabs.f64(double %60)
%62 = load double, double* %13
%63 = fcmp ogt double %61, %62
br i1 %63, label %64, label %100
64: ; preds = %54
%65 = load i64, i64* %17
%66 = add nsw i64 %65, 1
store i64 %66, i64* %17
%67 = icmp sgt i64 %66, 20
br i1 %67, label %68, label %71
68: ; preds = %64
%69 = load double, double* %13
%70 = fmul double %69, 1.100000e+00
store double %70, double* %13
br label %71
71: ; preds = %68, %64
%72 = load double, double* %16
%73 = load double, double* %13
%74 = fcmp ogt double %72, %73
br i1 %74, label %75, label %84
75: ; preds = %71
%76 = load double, double* %8
%77 = load double, double* %14
%78 = fadd double %76, %77
%79 = fdiv double %78, 2.000000e+00
store double %79, double* %14
%80 = load double, double* %10
%81 = load double, double* %15
%82 = fadd double %80, %81
%83 = fdiv double %82, 2.000000e+00
store double %83, double* %15
br label %99
84: ; preds = %71
%85 = load double, double* %16
%86 = load double, double* %13
%87 = fneg double %86
%88 = fcmp olt double %85, %87
br i1 %88, label %89, label %98
89: ; preds = %84
%90 = load double, double* %14
%91 = load double, double* %9
%92 = fadd double %90, %91
%93 = fdiv double %92, 2.000000e+00
store double %93, double* %14
%94 = load double, double* %15
%95 = load double, double* %11
%96 = fadd double %94, %95
%97 = fdiv double %96, 2.000000e+00
store double %97, double* %15
br label %98
98: ; preds = %89, %84
br label %99
99: ; preds = %98, %75
br label %54
100: ; preds = %54
%101 = load double, double* %14
store double %101, double* %7
br label %102
102: ; preds = %100, %43, %32
%103 = load double, double* %7
ret double %103
}

LLVM IR (-O2):
define double @bin_interp(double %0, double %1, double %2, double %3, double %4, double %5) {
%7 = fcmp olt double %5, 0.000000e+00
%8 = fneg double %5
%9 = select i1 %7, double %8, double %5
%10 = fsub double %0, %2
%11 = fsub double %10, %4
%12 = tail call double @llvm.fabs.f64(double %11)
%13 = fcmp olt double %12, %9
br i1 %13, label %62, label %14
14: ; preds = %6
%15 = fsub double %1, %3
%16 = fsub double %15, %4
%17 = tail call double @llvm.fabs.f64(double %16)
%18 = fcmp olt double %17, %9
br i1 %18, label %62, label %19
19: ; preds = %14
%20 = insertelement <2 x double> poison, double %0, i64 0
%21 = insertelement <2 x double> %20, double %2, i64 1
%22 = insertelement <2 x double> poison, double %1, i64 0
%23 = insertelement <2 x double> %22, double %3, i64 1
%24 = fadd <2 x double> %21, %23
%25 = fmul <2 x double> %24, <double 5.000000e-01, double 5.000000e-01>
%26 = extractelement <2 x double> %25, i64 0
%27 = shufflevector <2 x double> %25, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%28 = fsub <2 x double> %25, %27
%29 = extractelement <2 x double> %28, i64 0
%30 = fsub double %29, %4
%31 = tail call double @llvm.fabs.f64(double %30)
%32 = fcmp ogt double %31, %9
br i1 %32, label %33, label %62
33: ; preds = %19, %52
%34 = phi double [ %57, %52 ], [ %30, %19 ]
%35 = phi i64 [ %38, %52 ], [ 1, %19 ]
%36 = phi double [ %41, %52 ], [ %9, %19 ]
%37 = phi <2 x double> [ %53, %52 ], [ %25, %19 ]
%38 = add nuw nsw i64 %35, 1
%39 = icmp ugt i64 %35, 19
%40 = fmul double %36, 1.100000e+00
%41 = select i1 %39, double %40, double %36
%42 = fcmp ogt double %34, %41
br i1 %42, label %43, label %46
43: ; preds = %33
%44 = fadd <2 x double> %37, %21
%45 = fmul <2 x double> %44, <double 5.000000e-01, double 5.000000e-01>
br label %52
46: ; preds = %33
%47 = fneg double %41
%48 = fcmp olt double %34, %47
br i1 %48, label %49, label %52
49: ; preds = %46
%50 = fadd <2 x double> %37, %23
%51 = fmul <2 x double> %50, <double 5.000000e-01, double 5.000000e-01>
br label %52
52: ; preds = %46, %49, %43
%53 = phi <2 x double> [ %45, %43 ], [ %51, %49 ], [ %37, %46 ]
%54 = shufflevector <2 x double> %53, <2 x double> poison, <2 x i32> <i32 1, i32 undef>
%55 = fsub <2 x double> %53, %54
%56 = extractelement <2 x double> %55, i64 0
%57 = fsub double %56, %4
%58 = tail call double @llvm.fabs.f64(double %57)
%59 = fcmp ogt double %58, %41
br i1 %59, label %33, label %60
60: ; preds = %52
%61 = extractelement <2 x double> %53, i64 0
br label %62
62: ; preds = %60, %19, %14, %6
%63 = phi double [ %0, %6 ], [ %1, %14 ], [ %26, %19 ], [ %61, %60 ]
ret double %63
}