unsigned short CRC16Calculate(unsigned char *Buffer, int BufferSize) {
  unsigned short CRCTable[0x100];
  unsigned short crc;
  int i;
  for (i = 0; i < 0x100; i++) {
    unsigned short r = i;
    unsigned int j;
    for (j = 0; j < 8; j++) {
      if (r & 1)
        r = (r >> 1) ^ 0xA001;
      else
        r >>= 1;
    }
    CRCTable[i] = r;
  }
  crc = 0;
  for (i = 0; i < BufferSize; i++)
    crc = CRCTable[(crc ^ Buffer[i]) & 0xFF] ^ (crc >> 8);
  return crc;
}


x86 assembly (clang, -O0):
<CRC16Calculate>:
push   %rbp
mov    %rsp,%rbp
sub    $0x1a0,%rsp
mov    %rdi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
movl   $0x0,-0x218(%rbp)
cmpl   $0x100,-0x218(%rbp)
jge    11d2 <CRC16Calculate+0xd2>
mov    -0x218(%rbp),%eax
mov    %ax,-0x21a(%rbp)
movl   $0x0,-0x220(%rbp)
cmpl   $0x8,-0x220(%rbp)
jae    11a8 <CRC16Calculate+0xa8>
movzwl -0x21a(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
je     117e <CRC16Calculate+0x7e>
movzwl -0x21a(%rbp),%eax
sar    $0x1,%eax
xor    $0xa001,%eax
mov    %ax,-0x21a(%rbp)
jmp    118f <CRC16Calculate+0x8f>
movzwl -0x21a(%rbp),%eax
sar    $0x1,%eax
mov    %ax,-0x21a(%rbp)
jmp    1194 <CRC16Calculate+0x94>
mov    -0x220(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x220(%rbp)
jmp    1143 <CRC16Calculate+0x43>
mov    -0x21a(%rbp),%cx
movslq -0x218(%rbp),%rax
mov    %cx,-0x210(%rbp,%rax,2)
ff
mov    -0x218(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x218(%rbp)
jmp    111c <CRC16Calculate+0x1c>
movw   $0x0,-0x212(%rbp)
movl   $0x0,-0x218(%rbp)
mov    -0x218(%rbp),%eax
cmp    -0xc(%rbp),%eax
jge    1242 <CRC16Calculate+0x142>
movzwl -0x212(%rbp),%eax
mov    -0x8(%rbp),%rcx
movslq -0x218(%rbp),%rdx
movzbl (%rcx,%rdx,1),%ecx
xor    %ecx,%eax
and    $0xff,%eax
cltq
movzwl -0x210(%rbp,%rax,2),%eax
ff
movzwl -0x212(%rbp),%ecx
sar    $0x8,%ecx
xor    %ecx,%eax
mov    %ax,-0x212(%rbp)
mov    -0x218(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x218(%rbp)
jmp    11e5 <CRC16Calculate+0xe5>
movzwl -0x212(%rbp),%eax
add    $0x1a0,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<CRC16Calculate>:
sub    $0x188,%rsp
movdqa 0xef1(%rip),%xmm0
xor    %eax,%eax
movdqa 0xef7(%rip),%xmm1
movdqa 0xeff(%rip),%xmm2
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
movdqa %xmm0,%xmm3
psrlw  $0x1,%xmm3
movdqa %xmm0,%xmm4
psllw  $0xf,%xmm4
psraw  $0xf,%xmm4
movdqa %xmm4,%xmm5
pandn  %xmm3,%xmm5
pxor   %xmm1,%xmm3
pand   %xmm4,%xmm3
por    %xmm5,%xmm3
movdqa %xmm3,%xmm4
psrlw  $0x1,%xmm4
psllw  $0xf,%xmm3
psraw  $0xf,%xmm3
movdqa %xmm3,%xmm5
pandn  %xmm4,%xmm5
pxor   %xmm1,%xmm4
pand   %xmm3,%xmm4
por    %xmm5,%xmm4
movdqa %xmm4,%xmm3
psrlw  $0x1,%xmm3
psllw  $0xf,%xmm4
psraw  $0xf,%xmm4
movdqa %xmm4,%xmm5
pandn  %xmm3,%xmm5
pxor   %xmm1,%xmm3
pand   %xmm4,%xmm3
por    %xmm5,%xmm3
movdqa %xmm3,%xmm4
psrlw  $0x1,%xmm4
psllw  $0xf,%xmm3
psraw  $0xf,%xmm3
movdqa %xmm3,%xmm5
pandn  %xmm4,%xmm5
pxor   %xmm1,%xmm4
pand   %xmm3,%xmm4
por    %xmm5,%xmm4
movdqa %xmm4,%xmm3
psrlw  $0x1,%xmm3
psllw  $0xf,%xmm4
psraw  $0xf,%xmm4
movdqa %xmm4,%xmm5
pandn  %xmm3,%xmm5
pxor   %xmm1,%xmm3
pand   %xmm4,%xmm3
por    %xmm5,%xmm3
movdqa %xmm3,%xmm4
psrlw  $0x1,%xmm4
psllw  $0xf,%xmm3
psraw  $0xf,%xmm3
movdqa %xmm3,%xmm5
pandn  %xmm4,%xmm5
pxor   %xmm1,%xmm4
pand   %xmm3,%xmm4
por    %xmm5,%xmm4
movdqa %xmm4,%xmm3
psrlw  $0x1,%xmm3
psllw  $0xf,%xmm4
psraw  $0xf,%xmm4
movdqa %xmm4,%xmm5
pandn  %xmm3,%xmm5
pxor   %xmm1,%xmm3
pand   %xmm4,%xmm3
por    %xmm5,%xmm3
movdqa %xmm3,%xmm4
psrlw  $0x1,%xmm4
psllw  $0xf,%xmm3
psraw  $0xf,%xmm3
movdqa %xmm3,%xmm5
pandn  %xmm4,%xmm5
pxor   %xmm1,%xmm4
pand   %xmm3,%xmm4
por    %xmm5,%xmm4
movdqa %xmm4,-0x80(%rsp,%rax,2)
add    $0x8,%rax
paddw  %xmm2,%xmm0
cmp    $0x100,%rax
jne    1130 <CRC16Calculate+0x30>
test   %esi,%esi
jle    1298 <CRC16Calculate+0x198>
mov    %esi,%r8d
cmp    $0x1,%esi
jne    12a2 <CRC16Calculate+0x1a2>
xor    %edx,%edx
xor    %eax,%eax
jmp    12e5 <CRC16Calculate+0x1e5>
xor    %eax,%eax
add    $0x188,%rsp
ret
mov    %r8d,%r9d
and    $0xfffffffe,%r9d
xor    %edx,%edx
xor    %eax,%eax
nopl   (%rax)
movzbl (%rdi,%rdx,1),%ecx
movzwl %ax,%esi
movzbl %sil,%eax
xor    %rcx,%rax
shr    $0x8,%esi
movzbl 0x1(%rdi,%rdx,1),%ecx
movzwl -0x80(%rsp,%rax,2),%eax
xor    %eax,%esi
movzbl %sil,%esi
xor    %rcx,%rsi
shr    $0x8,%eax
xor    -0x80(%rsp,%rsi,2),%ax
add    $0x2,%rdx
cmp    %rdx,%r9
jne    12b0 <CRC16Calculate+0x1b0>
test   $0x1,%r8b
je     129a <CRC16Calculate+0x19a>
movzbl (%rdi,%rdx,1),%ecx
movzwl %ax,%eax
movzbl %al,%edx
xor    %rcx,%rdx
shr    $0x8,%eax
xor    -0x80(%rsp,%rdx,2),%ax
add    $0x188,%rsp
ret

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

LLVM IR (-O2):
define zeroext i16 @CRC16Calculate(i8* nocapture %0, i32 %1) {
%3 = alloca [256 x i16]
%4 = bitcast [256 x i16]* %3 to i8*
br label %5
5: ; preds = %5, %2
%6 = phi i64 [ 0, %2 ], [ %50, %5 ]
%7 = phi <8 x i16> [ <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, %2 ], [ %51, %5 ]
%8 = and <8 x i16> %7, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%9 = icmp eq <8 x i16> %8, zeroinitializer
%10 = lshr <8 x i16> %7, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%11 = xor <8 x i16> %10, <i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575>
%12 = select <8 x i1> %9, <8 x i16> %10, <8 x i16> %11
%13 = and <8 x i16> %12, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%14 = icmp eq <8 x i16> %13, zeroinitializer
%15 = lshr <8 x i16> %12, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%16 = xor <8 x i16> %15, <i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575>
%17 = select <8 x i1> %14, <8 x i16> %15, <8 x i16> %16
%18 = and <8 x i16> %17, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%19 = icmp eq <8 x i16> %18, zeroinitializer
%20 = lshr <8 x i16> %17, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%21 = xor <8 x i16> %20, <i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575>
%22 = select <8 x i1> %19, <8 x i16> %20, <8 x i16> %21
%23 = and <8 x i16> %22, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%24 = icmp eq <8 x i16> %23, zeroinitializer
%25 = lshr <8 x i16> %22, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%26 = xor <8 x i16> %25, <i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575>
%27 = select <8 x i1> %24, <8 x i16> %25, <8 x i16> %26
%28 = and <8 x i16> %27, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%29 = icmp eq <8 x i16> %28, zeroinitializer
%30 = lshr <8 x i16> %27, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%31 = xor <8 x i16> %30, <i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575>
%32 = select <8 x i1> %29, <8 x i16> %30, <8 x i16> %31
%33 = and <8 x i16> %32, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%34 = icmp eq <8 x i16> %33, zeroinitializer
%35 = lshr <8 x i16> %32, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%36 = xor <8 x i16> %35, <i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575>
%37 = select <8 x i1> %34, <8 x i16> %35, <8 x i16> %36
%38 = and <8 x i16> %37, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%39 = icmp eq <8 x i16> %38, zeroinitializer
%40 = lshr <8 x i16> %37, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%41 = xor <8 x i16> %40, <i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575>
%42 = select <8 x i1> %39, <8 x i16> %40, <8 x i16> %41
%43 = and <8 x i16> %42, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%44 = icmp eq <8 x i16> %43, zeroinitializer
%45 = lshr <8 x i16> %42, <i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1, i16 1>
%46 = xor <8 x i16> %45, <i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575, i16 -24575>
%47 = select <8 x i1> %44, <8 x i16> %45, <8 x i16> %46
%48 = getelementptr inbounds [256 x i16], [256 x i16]* %3, i64 0, i64 %6
%49 = bitcast i16* %48 to <8 x i16>*
store <8 x i16> %47, <8 x i16>* %49
%50 = add nuw i64 %6, 8
%51 = add <8 x i16> %7, <i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8, i16 8>
%52 = icmp eq i64 %50, 256
br i1 %52, label %53, label %5
53: ; preds = %5
%54 = icmp sgt i32 %1, 0
br i1 %54, label %55, label %105
55: ; preds = %53
%56 = zext i32 %1 to i64
%57 = and i64 %56, 1
%58 = icmp eq i32 %1, 1
br i1 %58, label %89, label %59
59: ; preds = %55
%60 = and i64 %56, 4294967294
br label %61
61: ; preds = %61, %59
%62 = phi i64 [ 0, %59 ], [ %86, %61 ]
%63 = phi i16 [ 0, %59 ], [ %85, %61 ]
%64 = phi i64 [ 0, %59 ], [ %87, %61 ]
%65 = getelementptr inbounds i8, i8* %0, i64 %62
%66 = load i8, i8* %65
%67 = zext i8 %66 to i64
%68 = and i16 %63, 255
%69 = zext i16 %68 to i64
%70 = xor i64 %67, %69
%71 = getelementptr inbounds [256 x i16], [256 x i16]* %3, i64 0, i64 %70
%72 = load i16, i16* %71
%73 = lshr i16 %63, 8
%74 = or i64 %62, 1
%75 = getelementptr inbounds i8, i8* %0, i64 %74
%76 = load i8, i8* %75
%77 = zext i8 %76 to i64
%78 = and i16 %72, 255
%79 = xor i16 %78, %73
%80 = zext i16 %79 to i64
%81 = xor i64 %77, %80
%82 = getelementptr inbounds [256 x i16], [256 x i16]* %3, i64 0, i64 %81
%83 = load i16, i16* %82
%84 = lshr i16 %72, 8
%85 = xor i16 %83, %84
%86 = add nuw nsw i64 %62, 2
%87 = add i64 %64, 2
%88 = icmp eq i64 %87, %60
br i1 %88, label %89, label %61
89: ; preds = %61, %55
%90 = phi i16 [ undef, %55 ], [ %85, %61 ]
%91 = phi i64 [ 0, %55 ], [ %86, %61 ]
%92 = phi i16 [ 0, %55 ], [ %85, %61 ]
%93 = icmp eq i64 %57, 0
br i1 %93, label %105, label %94
94: ; preds = %89
%95 = getelementptr inbounds i8, i8* %0, i64 %91
%96 = load i8, i8* %95
%97 = zext i8 %96 to i64
%98 = and i16 %92, 255
%99 = zext i16 %98 to i64
%100 = xor i64 %97, %99
%101 = getelementptr inbounds [256 x i16], [256 x i16]* %3, i64 0, i64 %100
%102 = load i16, i16* %101
%103 = lshr i16 %92, 8
%104 = xor i16 %102, %103
br label %105
105: ; preds = %94, %89, %53
%106 = phi i16 [ 0, %53 ], [ %90, %89 ], [ %104, %94 ]
ret i16 %106
}