unsigned short CRC16(const unsigned char *nData, unsigned short wLength) {
  static const unsigned short wCRCTable[] = {
      0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241, 0XC601,
      0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440, 0XCC01, 0X0CC0,
      0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40, 0X0A00, 0XCAC1, 0XCB81,
      0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841, 0XD801, 0X18C0, 0X1980, 0XD941,
      0X1B00, 0XDBC1, 0XDA81, 0X1A40, 0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01,
      0X1DC0, 0X1C80, 0XDC41, 0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0,
      0X1680, 0XD641, 0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081,
      0X1040, 0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
      0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441, 0X3C00,
      0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41, 0XFA01, 0X3AC0,
      0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840, 0X2800, 0XE8C1, 0XE981,
      0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41, 0XEE01, 0X2EC0, 0X2F80, 0XEF41,
      0X2D00, 0XEDC1, 0XEC81, 0X2C40, 0XE401, 0X24C0, 0X2580, 0XE541, 0X2700,
      0XE7C1, 0XE681, 0X2640, 0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0,
      0X2080, 0XE041, 0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281,
      0X6240, 0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
      0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41, 0XAA01,
      0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840, 0X7800, 0XB8C1,
      0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41, 0XBE01, 0X7EC0, 0X7F80,
      0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40, 0XB401, 0X74C0, 0X7580, 0XB541,
      0X7700, 0XB7C1, 0XB681, 0X7640, 0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101,
      0X71C0, 0X7080, 0XB041, 0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0,
      0X5280, 0X9241, 0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481,
      0X5440, 0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
      0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841, 0X8801,
      0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40, 0X4E00, 0X8EC1,
      0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41, 0X4400, 0X84C1, 0X8581,
      0X4540, 0X8701, 0X47C0, 0X4680, 0X8641, 0X8201, 0X42C0, 0X4380, 0X8341,
      0X4100, 0X81C1, 0X8081, 0X4040};
  unsigned char nTemp;
  unsigned short wCRCWord = 0xFFFF;
  while (wLength--) {
    nTemp = *nData++ ^ wCRCWord;
    wCRCWord >>= 8;
    wCRCWord ^= wCRCTable[nTemp];
  }
  return wCRCWord;
}


x86 assembly (clang, -O0):
<CRC16>:
push   %rbp
mov    %rsp,%rbp
mov    %si,%ax
mov    %rdi,-0x8(%rbp)
mov    %ax,-0xa(%rbp)
movw   $0xffff,-0xe(%rbp)
mov    -0xa(%rbp),%ax
mov    %ax,%cx
add    $0xffff,%cx
mov    %cx,-0xa(%rbp)
cmp    $0x0,%ax
je     1174 <CRC16+0x74>
mov    -0x8(%rbp),%rax
mov    %rax,%rcx
add    $0x1,%rcx
mov    %rcx,-0x8(%rbp)
movzbl (%rax),%eax
movzwl -0xe(%rbp),%ecx
xor    %ecx,%eax
mov    %al,-0xb(%rbp)
movzwl -0xe(%rbp),%eax
sar    $0x8,%eax
mov    %ax,-0xe(%rbp)
movzbl -0xb(%rbp),%eax
mov    %eax,%ecx
lea    0xe9f(%rip),%rax
movzwl (%rax,%rcx,2),%ecx
movzwl -0xe(%rbp),%eax
xor    %ecx,%eax
mov    %ax,-0xe(%rbp)
jmp    1115 <CRC16+0x15>
movzwl -0xe(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<CRC16>:
test   %esi,%esi
je     1110 <CRC16+0x10>
cmp    $0x1,%si
jne    1115 <CRC16+0x15>
mov    $0xffff,%ax
jmp    115d <CRC16+0x5d>
mov    $0xffff,%ax
ret
mov    %esi,%ecx
and    $0xfffe,%ecx
mov    $0xffff,%ax
lea    0xed8(%rip),%r8
nopl   0x0(%rax,%rax,1)
movzwl %ax,%edx
movzbl (%rdi),%eax
xor    %dl,%al
shr    $0x8,%edx
movzbl %al,%eax
movzwl (%r8,%rax,2),%eax
xor    %eax,%edx
xor    0x1(%rdi),%dl
add    $0x2,%rdi
shr    $0x8,%eax
movzbl %dl,%edx
xor    (%r8,%rdx,2),%ax
add    $0xfffe,%cx
jne    1130 <CRC16+0x30>
test   $0x1,%sil
je     117b <CRC16+0x7b>
movzwl %ax,%eax
mov    (%rdi),%cl
xor    %al,%cl
shr    $0x8,%eax
movzbl %cl,%ecx
lea    0xe89(%rip),%rdx
xor    (%rdx,%rcx,2),%ax
ret

LLVM IR (-O0):
@CRC16.wCRCTable = internal constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
define zeroext i16 @CRC16(i8* %0, i16 zeroext %1) {
%3 = alloca i8*
%4 = alloca i16
%5 = alloca i8
%6 = alloca i16
store i8* %0, i8** %3
store i16 %1, i16* %4
store i16 -1, i16* %6
br label %7
7: ; preds = %11, %2
%8 = load i16, i16* %4
%9 = add i16 %8, -1
store i16 %9, i16* %4
%10 = icmp ne i16 %8, 0
br i1 %10, label %11, label %33
11: ; preds = %7
%12 = load i8*, i8** %3
%13 = getelementptr inbounds i8, i8* %12, i32 1
store i8* %13, i8** %3
%14 = load i8, i8* %12
%15 = zext i8 %14 to i32
%16 = load i16, i16* %6
%17 = zext i16 %16 to i32
%18 = xor i32 %15, %17
%19 = trunc i32 %18 to i8
store i8 %19, i8* %5
%20 = load i16, i16* %6
%21 = zext i16 %20 to i32
%22 = ashr i32 %21, 8
%23 = trunc i32 %22 to i16
store i16 %23, i16* %6
%24 = load i8, i8* %5
%25 = zext i8 %24 to i64
%26 = getelementptr inbounds [256 x i16], [256 x i16]* @CRC16.wCRCTable, i64 0, i64 %25
%27 = load i16, i16* %26
%28 = zext i16 %27 to i32
%29 = load i16, i16* %6
%30 = zext i16 %29 to i32
%31 = xor i32 %30, %28
%32 = trunc i32 %31 to i16
store i16 %32, i16* %6
br label %7
33: ; preds = %7
%34 = load i16, i16* %6
ret i16 %34
}

LLVM IR (-O2):
@CRC16.wCRCTable = internal unnamed_addr constant [256 x i16] [i16 0, i16 -16191, i16 -15999, i16 320, i16 -15615, i16 960, i16 640, i16 -15807, i16 -14847, i16 1728, i16 1920, i16 -14527, i16 1280, i16 -14911, i16 -15231, i16 1088, i16 -13311, i16 3264, i16 3456, i16 -12991, i16 3840, i16 -12351, i16 -12671, i16 3648, i16 2560, i16 -13631, i16 -13439, i16 2880, i16 -14079, i16 2496, i16 2176, i16 -14271, i16 -10239, i16 6336, i16 6528, i16 -9919, i16 6912, i16 -9279, i16 -9599, i16 6720, i16 7680, i16 -8511, i16 -8319, i16 8000, i16 -8959, i16 7616, i16 7296, i16 -9151, i16 5120, i16 -11071, i16 -10879, i16 5440, i16 -10495, i16 6080, i16 5760, i16 -10687, i16 -11775, i16 4800, i16 4992, i16 -11455, i16 4352, i16 -11839, i16 -12159, i16 4160, i16 -4095, i16 12480, i16 12672, i16 -3775, i16 13056, i16 -3135, i16 -3455, i16 12864, i16 13824, i16 -2367, i16 -2175, i16 14144, i16 -2815, i16 13760, i16 13440, i16 -3007, i16 15360, i16 -831, i16 -639, i16 15680, i16 -255, i16 16320, i16 16000, i16 -447, i16 -1535, i16 15040, i16 15232, i16 -1215, i16 14592, i16 -1599, i16 -1919, i16 14400, i16 10240, i16 -5951, i16 -5759, i16 10560, i16 -5375, i16 11200, i16 10880, i16 -5567, i16 -4607, i16 11968, i16 12160, i16 -4287, i16 11520, i16 -4671, i16 -4991, i16 11328, i16 -7167, i16 9408, i16 9600, i16 -6847, i16 9984, i16 -6207, i16 -6527, i16 9792, i16 8704, i16 -7487, i16 -7295, i16 9024, i16 -7935, i16 8640, i16 8320, i16 -8127, i16 -24575, i16 24768, i16 24960, i16 -24255, i16 25344, i16 -23615, i16 -23935, i16 25152, i16 26112, i16 -22847, i16 -22655, i16 26432, i16 -23295, i16 26048, i16 25728, i16 -23487, i16 27648, i16 -21311, i16 -21119, i16 27968, i16 -20735, i16 28608, i16 28288, i16 -20927, i16 -22015, i16 27328, i16 27520, i16 -21695, i16 26880, i16 -22079, i16 -22399, i16 26688, i16 30720, i16 -18239, i16 -18047, i16 31040, i16 -17663, i16 31680, i16 31360, i16 -17855, i16 -16895, i16 32448, i16 32640, i16 -16575, i16 32000, i16 -16959, i16 -17279, i16 31808, i16 -19455, i16 29888, i16 30080, i16 -19135, i16 30464, i16 -18495, i16 -18815, i16 30272, i16 29184, i16 -19775, i16 -19583, i16 29504, i16 -20223, i16 29120, i16 28800, i16 -20415, i16 20480, i16 -28479, i16 -28287, i16 20800, i16 -27903, i16 21440, i16 21120, i16 -28095, i16 -27135, i16 22208, i16 22400, i16 -26815, i16 21760, i16 -27199, i16 -27519, i16 21568, i16 -25599, i16 23744, i16 23936, i16 -25279, i16 24320, i16 -24639, i16 -24959, i16 24128, i16 23040, i16 -25919, i16 -25727, i16 23360, i16 -26367, i16 22976, i16 22656, i16 -26559, i16 -30719, i16 18624, i16 18816, i16 -30399, i16 19200, i16 -29759, i16 -30079, i16 19008, i16 19968, i16 -28991, i16 -28799, i16 20288, i16 -29439, i16 19904, i16 19584, i16 -29631, i16 17408, i16 -31551, i16 -31359, i16 17728, i16 -30975, i16 18368, i16 18048, i16 -31167, i16 -32255, i16 17088, i16 17280, i16 -31935, i16 16640, i16 -32319, i16 -32639, i16 16448]
define zeroext i16 @CRC16(i8* nocapture %0, i16 zeroext %1) {
%3 = icmp eq i16 %1, 0
br i1 %3, label %47, label %4
4: ; preds = %2
%5 = and i16 %1, 1
%6 = icmp eq i16 %1, 1
br i1 %6, label %33, label %7
7: ; preds = %4
%8 = and i16 %1, -2
br label %9
9: ; preds = %9, %7
%10 = phi i16 [ -1, %7 ], [ %30, %9 ]
%11 = phi i8* [ %0, %7 ], [ %22, %9 ]
%12 = phi i16 [ 0, %7 ], [ %31, %9 ]
%13 = getelementptr inbounds i8, i8* %11, i64 1
%14 = load i8, i8* %11
%15 = trunc i16 %10 to i8
%16 = xor i8 %14, %15
%17 = lshr i16 %10, 8
%18 = zext i8 %16 to i64
%19 = getelementptr inbounds [256 x i16], [256 x i16]* @CRC16.wCRCTable, i64 0, i64 %18
%20 = load i16, i16* %19
%21 = xor i16 %20, %17
%22 = getelementptr inbounds i8, i8* %11, i64 2
%23 = load i8, i8* %13
%24 = trunc i16 %21 to i8
%25 = xor i8 %23, %24
%26 = lshr i16 %20, 8
%27 = zext i8 %25 to i64
%28 = getelementptr inbounds [256 x i16], [256 x i16]* @CRC16.wCRCTable, i64 0, i64 %27
%29 = load i16, i16* %28
%30 = xor i16 %29, %26
%31 = add i16 %12, 2
%32 = icmp eq i16 %31, %8
br i1 %32, label %33, label %9
33: ; preds = %9, %4
%34 = phi i16 [ undef, %4 ], [ %30, %9 ]
%35 = phi i16 [ -1, %4 ], [ %30, %9 ]
%36 = phi i8* [ %0, %4 ], [ %22, %9 ]
%37 = icmp eq i16 %5, 0
br i1 %37, label %47, label %38
38: ; preds = %33
%39 = load i8, i8* %36
%40 = trunc i16 %35 to i8
%41 = xor i8 %39, %40
%42 = lshr i16 %35, 8
%43 = zext i8 %41 to i64
%44 = getelementptr inbounds [256 x i16], [256 x i16]* @CRC16.wCRCTable, i64 0, i64 %43
%45 = load i16, i16* %44
%46 = xor i16 %45, %42
br label %47
47: ; preds = %38, %33, %2
%48 = phi i16 [ -1, %2 ], [ %34, %33 ], [ %46, %38 ]
ret i16 %48
}