unsigned char crc7_add_byte(unsigned char data, unsigned char previous_crc) {
  unsigned char crc = previous_crc;
  int b;
  for (b = 0; b < 8; b++) {
    unsigned int crcbit = crc & 0x40;
    if ((data & 0x80UL) != 0)
      crcbit ^= 0x40;
    data <<= 1;
    crc <<= 1;
    if (crcbit != 0)
      crc ^= 0x09;
  }
  return crc;
}


x86 assembly (clang, -O0):
<crc7_add_byte>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %dil,%cl
mov    %cl,-0x1(%rbp)
mov    %al,-0x2(%rbp)
mov    -0x2(%rbp),%al
mov    %al,-0x3(%rbp)
movl   $0x0,-0x8(%rbp)
cmpl   $0x8,-0x8(%rbp)
jge    1189 <crc7_add_byte+0x89>
movzbl -0x3(%rbp),%eax
and    $0x40,%eax
mov    %eax,-0xc(%rbp)
movzbl -0x1(%rbp),%eax
and    $0x80,%rax
cmp    $0x0,%rax
je     114e <crc7_add_byte+0x4e>
mov    -0xc(%rbp),%eax
xor    $0x40,%eax
mov    %eax,-0xc(%rbp)
movzbl -0x1(%rbp),%eax
shl    $0x1,%eax
mov    %al,-0x1(%rbp)
movzbl -0x3(%rbp),%eax
shl    $0x1,%eax
mov    %al,-0x3(%rbp)
cmpl   $0x0,-0xc(%rbp)
je     1176 <crc7_add_byte+0x76>
movzbl -0x3(%rbp),%eax
xor    $0x9,%eax
mov    %al,-0x3(%rbp)
jmp    117b <crc7_add_byte+0x7b>
mov    -0x8(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x8(%rbp)
jmp    111d <crc7_add_byte+0x1d>
movzbl -0x3(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<crc7_add_byte>:
lea    (%rsi,%rsi,1),%eax
mov    %esi,%ecx
and    $0x40,%ecx
mov    %ecx,%edx
xor    $0x40,%edx
test   %dil,%dil
cmovns %ecx,%edx
movzbl %al,%ecx
xor    $0x9,%al
test   %edx,%edx
movzbl %al,%eax
cmove  %ecx,%eax
lea    (%rax,%rax,1),%ecx
and    $0x40,%eax
mov    %eax,%edx
xor    $0x40,%edx
test   $0x40,%dil
cmove  %eax,%edx
movzbl %cl,%eax
xor    $0x9,%cl
test   %edx,%edx
movzbl %cl,%ecx
cmove  %eax,%ecx
lea    (%rcx,%rcx,1),%eax
and    $0x40,%ecx
mov    %ecx,%edx
xor    $0x40,%edx
test   $0x20,%dil
cmove  %ecx,%edx
movzbl %al,%ecx
xor    $0x9,%al
test   %edx,%edx
movzbl %al,%eax
cmove  %ecx,%eax
lea    (%rax,%rax,1),%ecx
and    $0x40,%eax
mov    %eax,%edx
xor    $0x40,%edx
test   $0x10,%dil
cmove  %eax,%edx
movzbl %cl,%eax
xor    $0x9,%cl
test   %edx,%edx
movzbl %cl,%ecx
cmove  %eax,%ecx
lea    (%rcx,%rcx,1),%eax
and    $0x40,%ecx
mov    %ecx,%edx
xor    $0x40,%edx
test   $0x8,%dil
cmove  %ecx,%edx
movzbl %al,%ecx
xor    $0x9,%al
test   %edx,%edx
movzbl %al,%eax
cmove  %ecx,%eax
lea    (%rax,%rax,1),%ecx
and    $0x40,%eax
mov    %eax,%edx
xor    $0x40,%edx
test   $0x4,%dil
cmove  %eax,%edx
movzbl %cl,%eax
xor    $0x9,%cl
test   %edx,%edx
movzbl %cl,%ecx
cmove  %eax,%ecx
lea    (%rcx,%rcx,1),%eax
and    $0x40,%ecx
mov    %ecx,%edx
xor    $0x40,%edx
test   $0x2,%dil
cmove  %ecx,%edx
movzbl %al,%ecx
xor    $0x9,%al
test   %edx,%edx
movzbl %al,%eax
cmove  %ecx,%eax
lea    (%rax,%rax,1),%ecx
and    $0x40,%eax
mov    %eax,%edx
xor    $0x40,%edx
test   $0x1,%dil
cmove  %eax,%edx
movzbl %cl,%esi
xor    $0x9,%cl
test   %edx,%edx
movzbl %cl,%eax
cmove  %esi,%eax
ret

LLVM IR (-O0):
define zeroext i8 @crc7_add_byte(i8 zeroext %0, i8 zeroext %1) {
%3 = alloca i8
%4 = alloca i8
%5 = alloca i8
%6 = alloca i32
%7 = alloca i32
store i8 %0, i8* %3
store i8 %1, i8* %4
%8 = load i8, i8* %4
store i8 %8, i8* %5
store i32 0, i32* %6
br label %9
9: ; preds = %40, %2
%10 = load i32, i32* %6
%11 = icmp slt i32 %10, 8
br i1 %11, label %12, label %43
12: ; preds = %9
%13 = load i8, i8* %5
%14 = zext i8 %13 to i32
%15 = and i32 %14, 64
store i32 %15, i32* %7
%16 = load i8, i8* %3
%17 = zext i8 %16 to i64
%18 = and i64 %17, 128
%19 = icmp ne i64 %18, 0
br i1 %19, label %20, label %23
20: ; preds = %12
%21 = load i32, i32* %7
%22 = xor i32 %21, 64
store i32 %22, i32* %7
br label %23
23: ; preds = %20, %12
%24 = load i8, i8* %3
%25 = zext i8 %24 to i32
%26 = shl i32 %25, 1
%27 = trunc i32 %26 to i8
store i8 %27, i8* %3
%28 = load i8, i8* %5
%29 = zext i8 %28 to i32
%30 = shl i32 %29, 1
%31 = trunc i32 %30 to i8
store i8 %31, i8* %5
%32 = load i32, i32* %7
%33 = icmp ne i32 %32, 0
br i1 %33, label %34, label %39
34: ; preds = %23
%35 = load i8, i8* %5
%36 = zext i8 %35 to i32
%37 = xor i32 %36, 9
%38 = trunc i32 %37 to i8
store i8 %38, i8* %5
br label %39
39: ; preds = %34, %23
br label %40
40: ; preds = %39
%41 = load i32, i32* %6
%42 = add nsw i32 %41, 1
store i32 %42, i32* %6
br label %9
43: ; preds = %9
%44 = load i8, i8* %5
ret i8 %44
}

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