int count_zeros(unsigned char *op) {
  unsigned char v;
  unsigned int z;
  int i;
  for (i = 0; i < (256 / 8); i++) {
    if (op[i] != 0) {
      z = i * 8;
      v = op[i];
      if (v < 16) {
        v <<= 4;
        z += 4;
      }
      if (v < 64) {
        v <<= 2;
        z += 2;
      }
      if (v < 128) {
        z += 1;
      }
      return z;
    }
  }
  return (256 / 8) * 8;
}


x86 assembly (clang, -O0):
<count_zeros>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
movl   $0x0,-0x1c(%rbp)
cmpl   $0x20,-0x1c(%rbp)
jge    11bb <count_zeros+0xbb>
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
cmp    $0x0,%eax
je     11a8 <count_zeros+0xa8>
mov    -0x1c(%rbp),%eax
shl    $0x3,%eax
mov    %eax,-0x18(%rbp)
mov    -0x10(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    (%rax,%rcx,1),%al
mov    %al,-0x11(%rbp)
movzbl -0x11(%rbp),%eax
cmp    $0x10,%eax
jge    1165 <count_zeros+0x65>
movzbl -0x11(%rbp),%eax
shl    $0x4,%eax
mov    %al,-0x11(%rbp)
mov    -0x18(%rbp),%eax
add    $0x4,%eax
mov    %eax,-0x18(%rbp)
movzbl -0x11(%rbp),%eax
cmp    $0x40,%eax
jge    1185 <count_zeros+0x85>
movzbl -0x11(%rbp),%eax
shl    $0x2,%eax
mov    %al,-0x11(%rbp)
mov    -0x18(%rbp),%eax
add    $0x2,%eax
mov    %eax,-0x18(%rbp)
movzbl -0x11(%rbp),%eax
cmp    $0x80,%eax
jge    119d <count_zeros+0x9d>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
mov    -0x18(%rbp),%eax
mov    %eax,-0x4(%rbp)
jmp    11c2 <count_zeros+0xc2>
jmp    11ad <count_zeros+0xad>
mov    -0x1c(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x1c(%rbp)
jmp    110f <count_zeros+0xf>
movl   $0x100,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<count_zeros>:
mov    (%rdi),%al
xor    %ecx,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x1(%rdi),%al
mov    $0x8,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x2(%rdi),%al
mov    $0x10,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x3(%rdi),%al
mov    $0x18,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x4(%rdi),%al
mov    $0x20,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x5(%rdi),%al
mov    $0x28,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x6(%rdi),%al
mov    $0x30,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x7(%rdi),%al
mov    $0x38,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x8(%rdi),%al
mov    $0x40,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x9(%rdi),%al
mov    $0x48,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0xa(%rdi),%al
mov    $0x50,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0xb(%rdi),%al
mov    $0x58,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0xc(%rdi),%al
mov    $0x60,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0xd(%rdi),%al
mov    $0x68,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0xe(%rdi),%al
mov    $0x70,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0xf(%rdi),%al
mov    $0x78,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x10(%rdi),%al
mov    $0x80,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x11(%rdi),%al
mov    $0x88,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x12(%rdi),%al
mov    $0x90,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x13(%rdi),%al
mov    $0x98,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x14(%rdi),%al
mov    $0xa0,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x15(%rdi),%al
mov    $0xa8,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x16(%rdi),%al
mov    $0xb0,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x17(%rdi),%al
mov    $0xb8,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x18(%rdi),%al
mov    $0xc0,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x19(%rdi),%al
mov    $0xc8,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x1a(%rdi),%al
mov    $0xd0,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x1b(%rdi),%al
mov    $0xd8,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x1c(%rdi),%al
mov    $0xe0,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x1d(%rdi),%al
mov    $0xe8,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x1e(%rdi),%al
mov    $0xf0,%ecx
test   %al,%al
jne    12d0 <count_zeros+0x1d0>
mov    0x1f(%rdi),%al
mov    $0xf8,%ecx
test   %al,%al
je     130b <count_zeros+0x20b>
mov    %eax,%edx
shl    $0x4,%dl
mov    %ecx,%esi
or     $0x4,%esi
cmp    $0x10,%al
movzbl %al,%eax
movzbl %dl,%edx
cmovae %eax,%edx
cmovae %ecx,%esi
lea    0x0(,%rdx,4),%eax
mov    %esi,%ecx
or     $0x2,%ecx
cmp    $0x40,%dl
movzbl %al,%eax
cmovae %edx,%eax
cmovae %esi,%ecx
not    %al
shr    $0x7,%al
movzbl %al,%eax
or     %ecx,%eax
ret
mov    $0x100,%eax
ret

LLVM IR (-O0):
define i32 @count_zeros(i8* %0) {
%2 = alloca i32
%3 = alloca i8*
%4 = alloca i8
%5 = alloca i32
%6 = alloca i32
store i8* %0, i8** %3
store i32 0, i32* %6
br label %7
7: ; preds = %57, %1
%8 = load i32, i32* %6
%9 = icmp slt i32 %8, 32
br i1 %9, label %10, label %60
10: ; preds = %7
%11 = load i8*, i8** %3
%12 = load i32, i32* %6
%13 = sext i32 %12 to i64
%14 = getelementptr inbounds i8, i8* %11, i64 %13
%15 = load i8, i8* %14
%16 = zext i8 %15 to i32
%17 = icmp ne i32 %16, 0
br i1 %17, label %18, label %56
18: ; preds = %10
%19 = load i32, i32* %6
%20 = mul nsw i32 %19, 8
store i32 %20, i32* %5
%21 = load i8*, i8** %3
%22 = load i32, i32* %6
%23 = sext i32 %22 to i64
%24 = getelementptr inbounds i8, i8* %21, i64 %23
%25 = load i8, i8* %24
store i8 %25, i8* %4
%26 = load i8, i8* %4
%27 = zext i8 %26 to i32
%28 = icmp slt i32 %27, 16
br i1 %28, label %29, label %36
29: ; preds = %18
%30 = load i8, i8* %4
%31 = zext i8 %30 to i32
%32 = shl i32 %31, 4
%33 = trunc i32 %32 to i8
store i8 %33, i8* %4
%34 = load i32, i32* %5
%35 = add i32 %34, 4
store i32 %35, i32* %5
br label %36
36: ; preds = %29, %18
%37 = load i8, i8* %4
%38 = zext i8 %37 to i32
%39 = icmp slt i32 %38, 64
br i1 %39, label %40, label %47
40: ; preds = %36
%41 = load i8, i8* %4
%42 = zext i8 %41 to i32
%43 = shl i32 %42, 2
%44 = trunc i32 %43 to i8
store i8 %44, i8* %4
%45 = load i32, i32* %5
%46 = add i32 %45, 2
store i32 %46, i32* %5
br label %47
47: ; preds = %40, %36
%48 = load i8, i8* %4
%49 = zext i8 %48 to i32
%50 = icmp slt i32 %49, 128
br i1 %50, label %51, label %54
51: ; preds = %47
%52 = load i32, i32* %5
%53 = add i32 %52, 1
store i32 %53, i32* %5
br label %54
54: ; preds = %51, %47
%55 = load i32, i32* %5
store i32 %55, i32* %2
br label %61
56: ; preds = %10
br label %57
57: ; preds = %56
%58 = load i32, i32* %6
%59 = add nsw i32 %58, 1
store i32 %59, i32* %6
br label %7
60: ; preds = %7
store i32 256, i32* %2
br label %61
61: ; preds = %60, %54
%62 = load i32, i32* %2
ret i32 %62
}

LLVM IR (-O2):
define i32 @count_zeros(i8* nocapture %0) {
%2 = load i8, i8* %0
%3 = icmp eq i8 %2, 0
br i1 %3, label %21, label %4
4: ; preds = %141, %137, %133, %129, %125, %121, %117, %113, %109, %105, %101, %97, %93, %89, %85, %81, %77, %73, %69, %65, %61, %57, %53, %49, %45, %41, %37, %33, %29, %25, %21, %1
%5 = phi i32 [ 0, %1 ], [ 8, %21 ], [ 16, %25 ], [ 24, %29 ], [ 32, %33 ], [ 40, %37 ], [ 48, %41 ], [ 56, %45 ], [ 64, %49 ], [ 72, %53 ], [ 80, %57 ], [ 88, %61 ], [ 96, %65 ], [ 104, %69 ], [ 112, %73 ], [ 120, %77 ], [ 128, %81 ], [ 136, %85 ], [ 144, %89 ], [ 152, %93 ], [ 160, %97 ], [ 168, %101 ], [ 176, %105 ], [ 184, %109 ], [ 192, %113 ], [ 200, %117 ], [ 208, %121 ], [ 216, %125 ], [ 224, %129 ], [ 232, %133 ], [ 240, %137 ], [ 248, %141 ]
%6 = phi i8 [ %2, %1 ], [ %23, %21 ], [ %27, %25 ], [ %31, %29 ], [ %35, %33 ], [ %39, %37 ], [ %43, %41 ], [ %47, %45 ], [ %51, %49 ], [ %55, %53 ], [ %59, %57 ], [ %63, %61 ], [ %67, %65 ], [ %71, %69 ], [ %75, %73 ], [ %79, %77 ], [ %83, %81 ], [ %87, %85 ], [ %91, %89 ], [ %95, %93 ], [ %99, %97 ], [ %103, %101 ], [ %107, %105 ], [ %111, %109 ], [ %115, %113 ], [ %119, %117 ], [ %123, %121 ], [ %127, %125 ], [ %131, %129 ], [ %135, %133 ], [ %139, %137 ], [ %143, %141 ]
%7 = icmp ult i8 %6, 16
%8 = shl i8 %6, 4
%9 = or i32 %5, 4
%10 = select i1 %7, i8 %8, i8 %6
%11 = select i1 %7, i32 %9, i32 %5
%12 = icmp ult i8 %10, 64
%13 = shl i8 %10, 2
%14 = or i32 %11, 2
%15 = select i1 %12, i8 %13, i8 %10
%16 = select i1 %12, i32 %14, i32 %11
%17 = xor i8 %15, -1
%18 = lshr i8 %17, 7
%19 = zext i8 %18 to i32
%20 = or i32 %16, %19
br label %145
21: ; preds = %1
%22 = getelementptr inbounds i8, i8* %0, i64 1
%23 = load i8, i8* %22
%24 = icmp eq i8 %23, 0
br i1 %24, label %25, label %4
25: ; preds = %21
%26 = getelementptr inbounds i8, i8* %0, i64 2
%27 = load i8, i8* %26
%28 = icmp eq i8 %27, 0
br i1 %28, label %29, label %4
29: ; preds = %25
%30 = getelementptr inbounds i8, i8* %0, i64 3
%31 = load i8, i8* %30
%32 = icmp eq i8 %31, 0
br i1 %32, label %33, label %4
33: ; preds = %29
%34 = getelementptr inbounds i8, i8* %0, i64 4
%35 = load i8, i8* %34
%36 = icmp eq i8 %35, 0
br i1 %36, label %37, label %4
37: ; preds = %33
%38 = getelementptr inbounds i8, i8* %0, i64 5
%39 = load i8, i8* %38
%40 = icmp eq i8 %39, 0
br i1 %40, label %41, label %4
41: ; preds = %37
%42 = getelementptr inbounds i8, i8* %0, i64 6
%43 = load i8, i8* %42
%44 = icmp eq i8 %43, 0
br i1 %44, label %45, label %4
45: ; preds = %41
%46 = getelementptr inbounds i8, i8* %0, i64 7
%47 = load i8, i8* %46
%48 = icmp eq i8 %47, 0
br i1 %48, label %49, label %4
49: ; preds = %45
%50 = getelementptr inbounds i8, i8* %0, i64 8
%51 = load i8, i8* %50
%52 = icmp eq i8 %51, 0
br i1 %52, label %53, label %4
53: ; preds = %49
%54 = getelementptr inbounds i8, i8* %0, i64 9
%55 = load i8, i8* %54
%56 = icmp eq i8 %55, 0
br i1 %56, label %57, label %4
57: ; preds = %53
%58 = getelementptr inbounds i8, i8* %0, i64 10
%59 = load i8, i8* %58
%60 = icmp eq i8 %59, 0
br i1 %60, label %61, label %4
61: ; preds = %57
%62 = getelementptr inbounds i8, i8* %0, i64 11
%63 = load i8, i8* %62
%64 = icmp eq i8 %63, 0
br i1 %64, label %65, label %4
65: ; preds = %61
%66 = getelementptr inbounds i8, i8* %0, i64 12
%67 = load i8, i8* %66
%68 = icmp eq i8 %67, 0
br i1 %68, label %69, label %4
69: ; preds = %65
%70 = getelementptr inbounds i8, i8* %0, i64 13
%71 = load i8, i8* %70
%72 = icmp eq i8 %71, 0
br i1 %72, label %73, label %4
73: ; preds = %69
%74 = getelementptr inbounds i8, i8* %0, i64 14
%75 = load i8, i8* %74
%76 = icmp eq i8 %75, 0
br i1 %76, label %77, label %4
77: ; preds = %73
%78 = getelementptr inbounds i8, i8* %0, i64 15
%79 = load i8, i8* %78
%80 = icmp eq i8 %79, 0
br i1 %80, label %81, label %4
81: ; preds = %77
%82 = getelementptr inbounds i8, i8* %0, i64 16
%83 = load i8, i8* %82
%84 = icmp eq i8 %83, 0
br i1 %84, label %85, label %4
85: ; preds = %81
%86 = getelementptr inbounds i8, i8* %0, i64 17
%87 = load i8, i8* %86
%88 = icmp eq i8 %87, 0
br i1 %88, label %89, label %4
89: ; preds = %85
%90 = getelementptr inbounds i8, i8* %0, i64 18
%91 = load i8, i8* %90
%92 = icmp eq i8 %91, 0
br i1 %92, label %93, label %4
93: ; preds = %89
%94 = getelementptr inbounds i8, i8* %0, i64 19
%95 = load i8, i8* %94
%96 = icmp eq i8 %95, 0
br i1 %96, label %97, label %4
97: ; preds = %93
%98 = getelementptr inbounds i8, i8* %0, i64 20
%99 = load i8, i8* %98
%100 = icmp eq i8 %99, 0
br i1 %100, label %101, label %4
101: ; preds = %97
%102 = getelementptr inbounds i8, i8* %0, i64 21
%103 = load i8, i8* %102
%104 = icmp eq i8 %103, 0
br i1 %104, label %105, label %4
105: ; preds = %101
%106 = getelementptr inbounds i8, i8* %0, i64 22
%107 = load i8, i8* %106
%108 = icmp eq i8 %107, 0
br i1 %108, label %109, label %4
109: ; preds = %105
%110 = getelementptr inbounds i8, i8* %0, i64 23
%111 = load i8, i8* %110
%112 = icmp eq i8 %111, 0
br i1 %112, label %113, label %4
113: ; preds = %109
%114 = getelementptr inbounds i8, i8* %0, i64 24
%115 = load i8, i8* %114
%116 = icmp eq i8 %115, 0
br i1 %116, label %117, label %4
117: ; preds = %113
%118 = getelementptr inbounds i8, i8* %0, i64 25
%119 = load i8, i8* %118
%120 = icmp eq i8 %119, 0
br i1 %120, label %121, label %4
121: ; preds = %117
%122 = getelementptr inbounds i8, i8* %0, i64 26
%123 = load i8, i8* %122
%124 = icmp eq i8 %123, 0
br i1 %124, label %125, label %4
125: ; preds = %121
%126 = getelementptr inbounds i8, i8* %0, i64 27
%127 = load i8, i8* %126
%128 = icmp eq i8 %127, 0
br i1 %128, label %129, label %4
129: ; preds = %125
%130 = getelementptr inbounds i8, i8* %0, i64 28
%131 = load i8, i8* %130
%132 = icmp eq i8 %131, 0
br i1 %132, label %133, label %4
133: ; preds = %129
%134 = getelementptr inbounds i8, i8* %0, i64 29
%135 = load i8, i8* %134
%136 = icmp eq i8 %135, 0
br i1 %136, label %137, label %4
137: ; preds = %133
%138 = getelementptr inbounds i8, i8* %0, i64 30
%139 = load i8, i8* %138
%140 = icmp eq i8 %139, 0
br i1 %140, label %141, label %4
141: ; preds = %137
%142 = getelementptr inbounds i8, i8* %0, i64 31
%143 = load i8, i8* %142
%144 = icmp eq i8 %143, 0
br i1 %144, label %145, label %4
145: ; preds = %141, %4
%146 = phi i32 [ %20, %4 ], [ 256, %141 ]
ret i32 %146
}