unsigned short crc_dsp(unsigned short reg, unsigned char data_crc) {
  unsigned short msb;
  unsigned short data;
  unsigned short gx = 0x8005, i = 0;
  data = (unsigned short)data_crc;
  data = data << 8;
  reg = reg ^ data;
  do {
    msb = reg & 0x8000;
    reg = reg << 1;
    if (msb == 0x8000) {
      reg = reg ^ gx;
    }
    i++;
  } while (i < 8);
  return (reg);
}


x86 assembly (clang, -O0):
<crc_dsp>:
push   %rbp
mov    %rsp,%rbp
mov    %sil,%al
mov    %di,%cx
mov    %cx,-0x2(%rbp)
mov    %al,-0x3(%rbp)
movw   $0x8005,-0xa(%rbp)
movw   $0x0,-0xc(%rbp)
movzbl -0x3(%rbp),%eax
mov    %ax,-0x8(%rbp)
movzwl -0x8(%rbp),%eax
shl    $0x8,%eax
mov    %ax,-0x8(%rbp)
movzwl -0x2(%rbp),%eax
movzwl -0x8(%rbp),%ecx
xor    %ecx,%eax
mov    %ax,-0x2(%rbp)
movzwl -0x2(%rbp),%eax
and    $0x8000,%eax
mov    %ax,-0x6(%rbp)
movzwl -0x2(%rbp),%eax
shl    $0x1,%eax
mov    %ax,-0x2(%rbp)
movzwl -0x6(%rbp),%eax
cmp    $0x8000,%eax
jne    1173 <crc_dsp+0x73>
movzwl -0x2(%rbp),%eax
movzwl -0xa(%rbp),%ecx
xor    %ecx,%eax
mov    %ax,-0x2(%rbp)
mov    -0xc(%rbp),%ax
add    $0x1,%ax
mov    %ax,-0xc(%rbp)
movzwl -0xc(%rbp),%eax
cmp    $0x8,%eax
jl     113e <crc_dsp+0x3e>
movzwl -0x2(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<crc_dsp>:
shl    $0x8,%esi
xor    %edi,%esi
lea    (%rsi,%rsi,1),%eax
mov    %eax,%ecx
xor    $0xffff8005,%ecx
test   %si,%si
cmovns %eax,%ecx
mov    %ecx,%eax
add    %ecx,%eax
mov    %eax,%edx
xor    $0xffff8005,%edx
test   %cx,%cx
cmovns %eax,%edx
mov    %edx,%eax
add    %edx,%eax
mov    %eax,%ecx
xor    $0xffff8005,%ecx
test   %dx,%dx
cmovns %eax,%ecx
mov    %ecx,%eax
add    %ecx,%eax
mov    %eax,%edx
xor    $0xffff8005,%edx
test   %cx,%cx
cmovns %eax,%edx
mov    %edx,%eax
add    %edx,%eax
mov    %eax,%ecx
xor    $0xffff8005,%ecx
test   %dx,%dx
cmovns %eax,%ecx
mov    %ecx,%eax
add    %ecx,%eax
mov    %eax,%edx
xor    $0xffff8005,%edx
test   %cx,%cx
cmovns %eax,%edx
mov    %edx,%eax
add    %edx,%eax
mov    %eax,%ecx
xor    $0xffff8005,%ecx
test   %dx,%dx
cmovns %eax,%ecx
mov    %ecx,%edx
add    %ecx,%edx
mov    %edx,%eax
xor    $0xffff8005,%eax
test   %cx,%cx
cmovns %edx,%eax
ret

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

LLVM IR (-O2):
define zeroext i16 @crc_dsp(i16 zeroext %0, i8 zeroext %1) {
%3 = zext i8 %1 to i16
%4 = shl nuw i16 %3, 8
%5 = xor i16 %4, %0
%6 = shl i16 %5, 1
%7 = icmp slt i16 %5, 0
%8 = xor i16 %6, -32763
%9 = select i1 %7, i16 %8, i16 %6
%10 = shl i16 %9, 1
%11 = icmp slt i16 %9, 0
%12 = xor i16 %10, -32763
%13 = select i1 %11, i16 %12, i16 %10
%14 = shl i16 %13, 1
%15 = icmp slt i16 %13, 0
%16 = xor i16 %14, -32763
%17 = select i1 %15, i16 %16, i16 %14
%18 = shl i16 %17, 1
%19 = icmp slt i16 %17, 0
%20 = xor i16 %18, -32763
%21 = select i1 %19, i16 %20, i16 %18
%22 = shl i16 %21, 1
%23 = icmp slt i16 %21, 0
%24 = xor i16 %22, -32763
%25 = select i1 %23, i16 %24, i16 %22
%26 = shl i16 %25, 1
%27 = icmp slt i16 %25, 0
%28 = xor i16 %26, -32763
%29 = select i1 %27, i16 %28, i16 %26
%30 = shl i16 %29, 1
%31 = icmp slt i16 %29, 0
%32 = xor i16 %30, -32763
%33 = select i1 %31, i16 %32, i16 %30
%34 = shl i16 %33, 1
%35 = icmp slt i16 %33, 0
%36 = xor i16 %34, -32763
%37 = select i1 %35, i16 %36, i16 %34
ret i16 %37
}