short binarySearch(const unsigned short *table, unsigned short tablen,
                   unsigned short code) {
  unsigned short head, tail, middle;
  head = 0;
  tail = tablen - 1;
  if ((code < table[head]) || (code > table[tail]))
    return (-1);
  while (head <= tail) {
    middle = (head + tail) / 2;
    if (code == table[middle])
      return (middle);
    else if (code > table[middle])
      head = middle + 1;
    else
      tail = middle - 1;
  }
  return (-1);
}


x86 assembly (clang, -O0):
<binarySearch>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %si,%cx
mov    %rdi,-0x10(%rbp)
mov    %cx,-0x12(%rbp)
mov    %ax,-0x14(%rbp)
movw   $0x0,-0x16(%rbp)
movzwl -0x12(%rbp),%eax
sub    $0x1,%eax
mov    %ax,-0x18(%rbp)
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzwl -0x16(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jl     1157 <binarySearch+0x57>
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzwl -0x18(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jle    1162 <binarySearch+0x62>
movw   $0xffff,-0x2(%rbp)
jmp    11f5 <binarySearch+0xf5>
jmp    1167 <binarySearch+0x67>
movzwl -0x16(%rbp),%eax
movzwl -0x18(%rbp),%ecx
cmp    %ecx,%eax
jg     11ef <binarySearch+0xef>
movzwl -0x16(%rbp),%eax
movzwl -0x18(%rbp),%ecx
add    %ecx,%eax
mov    $0x2,%ecx
cltd
idiv   %ecx
mov    %ax,-0x1a(%rbp)
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzwl -0x1a(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jne    11b2 <binarySearch+0xb2>
mov    -0x1a(%rbp),%ax
mov    %ax,-0x2(%rbp)
jmp    11f5 <binarySearch+0xf5>
movzwl -0x14(%rbp),%eax
mov    -0x10(%rbp),%rcx
movzwl -0x1a(%rbp),%edx
movzwl (%rcx,%rdx,2),%ecx
cmp    %ecx,%eax
jle    11da <binarySearch+0xda>
movzwl -0x1a(%rbp),%eax
add    $0x1,%eax
mov    %ax,-0x16(%rbp)
jmp    11e5 <binarySearch+0xe5>
movzwl -0x1a(%rbp),%eax
sub    $0x1,%eax
mov    %ax,-0x18(%rbp)
jmp    11ea <binarySearch+0xea>
jmp    1167 <binarySearch+0x67>
movw   $0xffff,-0x2(%rbp)
movswl -0x2(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<binarySearch>:
mov    $0xffff,%ax
cmp    %dx,(%rdi)
ja     1150 <binarySearch+0x50>
add    $0xffffffff,%esi
movzwl %si,%ecx
cmp    %dx,(%rdi,%rcx,2)
jb     1150 <binarySearch+0x50>
xor    %r8d,%r8d
nopl   0x0(%rax,%rax,1)
movzwl %si,%r9d
movzwl %r8w,%ecx
add    %r9d,%ecx
shr    %ecx
movzwl (%rdi,%rcx,2),%r9d
cmp    %dx,%r9w
je     1151 <binarySearch+0x51>
lea    0x1(%rcx),%r10d
add    $0xffffffff,%ecx
cmp    %dx,%r9w
cmovb  %r10d,%r8d
cmovae %ecx,%esi
cmp    %si,%r8w
jbe    1120 <binarySearch+0x20>
ret
mov    %ecx,%eax
ret

LLVM IR (-O0):
define signext i16 @binarySearch(i16* %0, i16 zeroext %1, i16 zeroext %2) {
%4 = alloca i16
%5 = alloca i16*
%6 = alloca i16
%7 = alloca i16
%8 = alloca i16
%9 = alloca i16
%10 = alloca i16
store i16* %0, i16** %5
store i16 %1, i16* %6
store i16 %2, i16* %7
store i16 0, i16* %8
%11 = load i16, i16* %6
%12 = zext i16 %11 to i32
%13 = sub nsw i32 %12, 1
%14 = trunc i32 %13 to i16
store i16 %14, i16* %9
%15 = load i16, i16* %7
%16 = zext i16 %15 to i32
%17 = load i16*, i16** %5
%18 = load i16, i16* %8
%19 = zext i16 %18 to i64
%20 = getelementptr inbounds i16, i16* %17, i64 %19
%21 = load i16, i16* %20
%22 = zext i16 %21 to i32
%23 = icmp slt i32 %16, %22
br i1 %23, label %34, label %24
24: ; preds = %3
%25 = load i16, i16* %7
%26 = zext i16 %25 to i32
%27 = load i16*, i16** %5
%28 = load i16, i16* %9
%29 = zext i16 %28 to i64
%30 = getelementptr inbounds i16, i16* %27, i64 %29
%31 = load i16, i16* %30
%32 = zext i16 %31 to i32
%33 = icmp sgt i32 %26, %32
br i1 %33, label %34, label %35
34: ; preds = %24, %3
store i16 -1, i16* %4
br label %84
35: ; preds = %24
br label %36
36: ; preds = %82, %35
%37 = load i16, i16* %8
%38 = zext i16 %37 to i32
%39 = load i16, i16* %9
%40 = zext i16 %39 to i32
%41 = icmp sle i32 %38, %40
br i1 %41, label %42, label %83
42: ; preds = %36
%43 = load i16, i16* %8
%44 = zext i16 %43 to i32
%45 = load i16, i16* %9
%46 = zext i16 %45 to i32
%47 = add nsw i32 %44, %46
%48 = sdiv i32 %47, 2
%49 = trunc i32 %48 to i16
store i16 %49, i16* %10
%50 = load i16, i16* %7
%51 = zext i16 %50 to i32
%52 = load i16*, i16** %5
%53 = load i16, i16* %10
%54 = zext i16 %53 to i64
%55 = getelementptr inbounds i16, i16* %52, i64 %54
%56 = load i16, i16* %55
%57 = zext i16 %56 to i32
%58 = icmp eq i32 %51, %57
br i1 %58, label %59, label %61
59: ; preds = %42
%60 = load i16, i16* %10
store i16 %60, i16* %4
br label %84
61: ; preds = %42
%62 = load i16, i16* %7
%63 = zext i16 %62 to i32
%64 = load i16*, i16** %5
%65 = load i16, i16* %10
%66 = zext i16 %65 to i64
%67 = getelementptr inbounds i16, i16* %64, i64 %66
%68 = load i16, i16* %67
%69 = zext i16 %68 to i32
%70 = icmp sgt i32 %63, %69
br i1 %70, label %71, label %76
71: ; preds = %61
%72 = load i16, i16* %10
%73 = zext i16 %72 to i32
%74 = add nsw i32 %73, 1
%75 = trunc i32 %74 to i16
store i16 %75, i16* %8
br label %81
76: ; preds = %61
%77 = load i16, i16* %10
%78 = zext i16 %77 to i32
%79 = sub nsw i32 %78, 1
%80 = trunc i32 %79 to i16
store i16 %80, i16* %9
br label %81
81: ; preds = %76, %71
br label %82
82: ; preds = %81
br label %36
83: ; preds = %36
store i16 -1, i16* %4
br label %84
84: ; preds = %83, %59, %34
%85 = load i16, i16* %4
ret i16 %85
}

LLVM IR (-O2):
define signext i16 @binarySearch(i16* nocapture %0, i16 zeroext %1, i16 zeroext %2) {
%4 = add i16 %1, -1
%5 = load i16, i16* %0
%6 = icmp ugt i16 %5, %2
br i1 %6, label %33, label %7
7: ; preds = %3
%8 = zext i16 %4 to i64
%9 = getelementptr inbounds i16, i16* %0, i64 %8
%10 = load i16, i16* %9
%11 = icmp ult i16 %10, %2
br i1 %11, label %33, label %12
12: ; preds = %7, %25
%13 = phi i16 [ %31, %25 ], [ %4, %7 ]
%14 = phi i16 [ %30, %25 ], [ 0, %7 ]
%15 = zext i16 %13 to i32
%16 = zext i16 %14 to i32
%17 = add nuw nsw i32 %15, %16
%18 = lshr i32 %17, 1
%19 = zext i32 %18 to i64
%20 = getelementptr inbounds i16, i16* %0, i64 %19
%21 = load i16, i16* %20
%22 = icmp eq i16 %21, %2
br i1 %22, label %23, label %25
23: ; preds = %12
%24 = trunc i32 %18 to i16
br label %33
25: ; preds = %12
%26 = icmp ult i16 %21, %2
%27 = trunc i32 %18 to i16
%28 = add i16 %27, 1
%29 = add i16 %27, -1
%30 = select i1 %26, i16 %28, i16 %14
%31 = select i1 %26, i16 %13, i16 %29
%32 = icmp ugt i16 %30, %31
br i1 %32, label %33, label %12
33: ; preds = %25, %3, %7, %23
%34 = phi i16 [ %24, %23 ], [ -1, %7 ], [ -1, %3 ], [ -1, %25 ]
ret i16 %34
}