unsigned char crc8(unsigned char *data, unsigned short len) {
  unsigned char crc;
  unsigned short i;
  unsigned char bit_counter;
  unsigned char b;
  unsigned char feedback_bit;
  crc = 0x00;
  for (i = 0; i != len; i++) {
    b = data[i];
    bit_counter = 8;
    do {
      feedback_bit = (crc ^ b) & 0x01;
      if (feedback_bit == 0x01) {
        crc = crc ^ 0x18;
      }
      crc = (crc >> 1) & 0x7F;
      if (feedback_bit == 0x01) {
        crc = crc | 0x80;
      }
      b = b >> 1;
      bit_counter--;
    } while (bit_counter > 0);
  }
  return crc;
}


x86 assembly (clang, -O0):
<crc8>:
push   %rbp
mov    %rsp,%rbp
mov    %si,%ax
mov    %rdi,-0x8(%rbp)
mov    %ax,-0xa(%rbp)
movb   $0x0,-0xb(%rbp)
movw   $0x0,-0xe(%rbp)
movzwl -0xe(%rbp),%eax
movzwl -0xa(%rbp),%ecx
cmp    %ecx,%eax
je     11bd <crc8+0xbd>
mov    -0x8(%rbp),%rax
movzwl -0xe(%rbp),%ecx
mov    (%rax,%rcx,1),%al
mov    %al,-0x10(%rbp)
movb   $0x8,-0xf(%rbp)
movzbl -0xb(%rbp),%eax
movzbl -0x10(%rbp),%ecx
xor    %ecx,%eax
and    $0x1,%eax
mov    %al,-0x11(%rbp)
movzbl -0x11(%rbp),%eax
cmp    $0x1,%eax
jne    1162 <crc8+0x62>
movzbl -0xb(%rbp),%eax
xor    $0x18,%eax
mov    %al,-0xb(%rbp)
movzbl -0xb(%rbp),%eax
sar    $0x1,%eax
and    $0x7f,%eax
mov    %al,-0xb(%rbp)
movzbl -0x11(%rbp),%eax
cmp    $0x1,%eax
jne    1188 <crc8+0x88>
movzbl -0xb(%rbp),%eax
or     $0x80,%eax
mov    %al,-0xb(%rbp)
movzbl -0x10(%rbp),%eax
sar    $0x1,%eax
mov    %al,-0x10(%rbp)
mov    -0xf(%rbp),%al
add    $0xff,%al
mov    %al,-0xf(%rbp)
movzbl -0xf(%rbp),%eax
cmp    $0x0,%eax
jg     113b <crc8+0x3b>
jmp    11ac <crc8+0xac>
mov    -0xe(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0xe(%rbp)
jmp    1119 <crc8+0x19>
movzbl -0xb(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<crc8>:
test   %esi,%esi
je     121b <crc8+0x11b>
movzwl %si,%r8d
xor    %r9d,%r9d
xor    %esi,%esi
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movzbl (%rdi,%r9,1),%eax
mov    %esi,%ecx
xor    %al,%cl
shr    %sil
movzbl %sil,%edx
xor    $0xc,%sil
test   $0x1,%cl
movzbl %sil,%esi
cmove  %edx,%esi
shl    $0x7,%cl
or     %sil,%cl
mov    %eax,%edx
shr    %dl
xor    %cl,%dl
shr    %cl
movzbl %cl,%esi
xor    $0xc,%cl
test   $0x1,%dl
movzbl %cl,%ecx
cmove  %esi,%ecx
shl    $0x7,%dl
or     %cl,%dl
mov    %eax,%ecx
shr    $0x2,%cl
xor    %dl,%cl
shr    %dl
movzbl %dl,%esi
xor    $0xc,%dl
test   $0x1,%cl
movzbl %dl,%edx
cmove  %esi,%edx
shl    $0x7,%cl
or     %dl,%cl
mov    %eax,%edx
shr    $0x3,%dl
xor    %cl,%dl
shr    %cl
movzbl %cl,%esi
xor    $0xc,%cl
test   $0x1,%dl
movzbl %cl,%ecx
cmove  %esi,%ecx
shl    $0x7,%dl
or     %cl,%dl
mov    %eax,%ecx
shr    $0x4,%cl
xor    %dl,%cl
shr    %dl
movzbl %dl,%esi
xor    $0xc,%dl
test   $0x1,%cl
movzbl %dl,%edx
cmove  %esi,%edx
shl    $0x7,%cl
or     %dl,%cl
mov    %eax,%edx
shr    $0x5,%dl
xor    %cl,%dl
shr    %cl
movzbl %cl,%esi
xor    $0xc,%cl
test   $0x1,%dl
movzbl %cl,%ecx
cmove  %esi,%ecx
shl    $0x7,%dl
or     %cl,%dl
mov    %eax,%ecx
shr    $0x6,%cl
xor    %dl,%cl
shr    %dl
movzbl %dl,%esi
xor    $0xc,%dl
test   $0x1,%cl
movzbl %dl,%edx
cmove  %esi,%edx
shl    $0x7,%cl
or     %dl,%cl
shr    $0x7,%al
xor    %cl,%al
shr    %cl
movzbl %cl,%edx
xor    $0xc,%cl
test   $0x1,%al
movzbl %cl,%ecx
cmove  %edx,%ecx
shl    $0x7,%al
or     %cl,%al
add    $0x1,%r9
mov    %eax,%esi
cmp    %r9,%r8
jne    1120 <crc8+0x20>
ret
xor    %eax,%eax
ret

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

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