unsigned short crck(crbuf, count, ldcrc)
register unsigned char *crbuf;
register count;
register unsigned short ldcrc;
{
  register unsigned short n;
  while (--count >= 0) {
    n = (ldcrc << 1);
    n = (n & 0xff00) | ((n + *crbuf++) & 0x00ff);
    if (ldcrc & 0x8000)
      n ^= 0xa097;
    ldcrc = n;
  }
  return (ldcrc);
}


x86 assembly (clang, -O0):
<crck>:
push   %rbp
mov    %rsp,%rbp
mov    %dx,%ax
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %ax,-0xe(%rbp)
mov    -0xc(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0xc(%rbp)
cmp    $0x0,%eax
jl     1188 <crck+0x88>
movzwl -0xe(%rbp),%eax
shl    $0x1,%eax
mov    %ax,-0x10(%rbp)
movzwl -0x10(%rbp),%eax
and    $0xff00,%eax
movzwl -0x10(%rbp),%ecx
mov    -0x8(%rbp),%rdx
mov    %rdx,%rsi
add    $0x1,%rsi
mov    %rsi,-0x8(%rbp)
movzbl (%rdx),%edx
add    %edx,%ecx
and    $0xff,%ecx
or     %ecx,%eax
mov    %ax,-0x10(%rbp)
movzwl -0xe(%rbp),%eax
and    $0x8000,%eax
cmp    $0x0,%eax
je     117b <crck+0x7b>
movzwl -0x10(%rbp),%eax
xor    $0xa097,%eax
mov    %ax,-0x10(%rbp)
mov    -0x10(%rbp),%ax
mov    %ax,-0xe(%rbp)
jmp    1112 <crck+0x12>
movzwl -0xe(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<crck>:
test   %esi,%esi
jle    1116 <crck+0x16>
test   $0x1,%sil
jne    1119 <crck+0x19>
mov    %esi,%ecx
cmp    $0x1,%esi
jne    1150 <crck+0x50>
jmp    11ad <crck+0xad>
mov    %edx,%eax
ret
lea    -0x1(%rsi),%ecx
lea    (%rdx,%rdx,1),%r9d
and    $0xffffff00,%r9d
movzbl (%rdi),%r8d
add    $0x1,%rdi
lea    (%r8,%rdx,2),%eax
movzbl %al,%r8d
or     %r9d,%r8d
mov    %r8d,%eax
xor    $0xffffa097,%eax
test   %dx,%dx
cmovns %r8d,%eax
mov    %eax,%edx
cmp    $0x1,%esi
je     11ad <crck+0xad>
add    $0xffffffff,%ecx
mov    %edx,%eax
cs nopw 0x0(%rax,%rax,1)
nop
lea    (%rax,%rax,1),%edx
and    $0xffffff00,%edx
movzbl (%rdi),%esi
lea    (%rsi,%rax,2),%esi
movzbl %sil,%esi
or     %edx,%esi
mov    %esi,%edx
xor    $0xffffa097,%edx
test   %ax,%ax
cmovns %esi,%edx
mov    %edx,%eax
and    $0xffffff80,%eax
add    %eax,%eax
movzbl 0x1(%rdi),%esi
lea    (%rsi,%rdx,2),%esi
movzbl %sil,%esi
or     %eax,%esi
mov    %esi,%eax
xor    $0xffffa097,%eax
test   %dx,%dx
cmovns %esi,%eax
add    $0x2,%rdi
add    $0xfffffffe,%ecx
jb     1160 <crck+0x60>
ret

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

LLVM IR (-O2):
define zeroext i16 @crck(i8* nocapture %0, i32 %1, i32 %2) {
%4 = trunc i32 %2 to i16
%5 = icmp sgt i32 %1, 0
br i1 %5, label %6, label %57
6: ; preds = %3
%7 = and i32 %1, 1
%8 = icmp eq i32 %7, 0
br i1 %8, label %22, label %9
9: ; preds = %6
%10 = add nsw i32 %1, -1
%11 = shl i16 %4, 1
%12 = and i16 %11, -256
%13 = getelementptr inbounds i8, i8* %0, i64 1
%14 = load i8, i8* %0
%15 = zext i8 %14 to i16
%16 = add i16 %11, %15
%17 = and i16 %16, 255
%18 = or i16 %17, %12
%19 = icmp sgt i16 %4, -1
%20 = xor i16 %18, -24425
%21 = select i1 %19, i16 %18, i16 %20
br label %22
22: ; preds = %9, %6
%23 = phi i16 [ %4, %6 ], [ %21, %9 ]
%24 = phi i32 [ %1, %6 ], [ %10, %9 ]
%25 = phi i8* [ %0, %6 ], [ %13, %9 ]
%26 = phi i16 [ undef, %6 ], [ %21, %9 ]
%27 = icmp eq i32 %1, 1
br i1 %27, label %57, label %28
28: ; preds = %22, %28
%29 = phi i16 [ %54, %28 ], [ %23, %22 ]
%30 = phi i32 [ %43, %28 ], [ %24, %22 ]
%31 = phi i8* [ %46, %28 ], [ %25, %22 ]
%32 = shl i16 %29, 1
%33 = and i16 %32, -256
%34 = getelementptr inbounds i8, i8* %31, i64 1
%35 = load i8, i8* %31
%36 = zext i8 %35 to i16
%37 = add i16 %32, %36
%38 = and i16 %37, 255
%39 = or i16 %38, %33
%40 = icmp sgt i16 %29, -1
%41 = xor i16 %39, -24425
%42 = select i1 %40, i16 %39, i16 %41
%43 = add nsw i32 %30, -2
%44 = shl i16 %42, 1
%45 = and i16 %44, -256
%46 = getelementptr inbounds i8, i8* %31, i64 2
%47 = load i8, i8* %34
%48 = zext i8 %47 to i16
%49 = add i16 %44, %48
%50 = and i16 %49, 255
%51 = or i16 %50, %45
%52 = icmp sgt i16 %42, -1
%53 = xor i16 %51, -24425
%54 = select i1 %52, i16 %51, i16 %53
%55 = add i32 %30, -3
%56 = icmp ult i32 %55, -2
br i1 %56, label %28, label %57
57: ; preds = %22, %28, %3
%58 = phi i16 [ %4, %3 ], [ %26, %22 ], [ %54, %28 ]
ret i16 %58
}