#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
typedef int uint8_t;
typedef int uint16_t;

/* Variables and functions */
uint16_t crc_x25(uint16_t crc, void *void_buf, size_t size) {
  static const uint16_t crc_table[16] = {
      0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
      0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
  };
  uint8_t *buf, data;
  for (buf = void_buf; size; size--) {
    data = *buf++;
    crc = (crc << 4) ^ crc_table[((crc >> 12) ^ (data >> 4)) & 0xf];
    crc = (crc << 4) ^ crc_table[((crc >> 12) ^ (data >> 0)) & 0xf];
  }
  return crc;
}


x86 assembly (clang, -O0):
<crc_x25>:
push   %rbp
mov    %rsp,%rbp
mov    %edi,-0x4(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
mov    -0x10(%rbp),%rax
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x18(%rbp)
je     1195 <crc_x25+0x95>
mov    -0x20(%rbp),%rax
mov    %rax,%rcx
add    $0x4,%rcx
mov    %rcx,-0x20(%rbp)
mov    (%rax),%eax
mov    %eax,-0x24(%rbp)
mov    -0x4(%rbp),%eax
shl    $0x4,%eax
mov    -0x4(%rbp),%ecx
sar    $0xc,%ecx
mov    -0x24(%rbp),%edx
sar    $0x4,%edx
xor    %edx,%ecx
and    $0xf,%ecx
movslq %ecx,%rdx
lea    0xea9(%rip),%rcx
xor    (%rcx,%rdx,4),%eax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
shl    $0x4,%eax
mov    -0x4(%rbp),%ecx
sar    $0xc,%ecx
mov    -0x24(%rbp),%edx
sar    $0x0,%edx
xor    %edx,%ecx
and    $0xf,%ecx
movslq %ecx,%rdx
lea    0xe82(%rip),%rcx
xor    (%rcx,%rdx,4),%eax
mov    %eax,-0x4(%rbp)
mov    -0x18(%rbp),%rax
add    $0xffffffffffffffff,%rax
mov    %rax,-0x18(%rbp)
jmp    1117 <crc_x25+0x17>
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<crc_x25>:
mov    %edi,%eax
test   %rdx,%rdx
je     1156 <crc_x25+0x56>
xor    %r10d,%r10d
lea    0xeef(%rip),%r8
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    (%rsi,%r10,4),%r9d
mov    %eax,%edi
shl    $0x4,%edi
shr    $0xc,%eax
mov    %r9d,%ecx
shr    $0x4,%ecx
xor    %eax,%ecx
and    $0xf,%ecx
xor    (%r8,%rcx,4),%edi
mov    %edi,%eax
shl    $0x4,%eax
shr    $0xc,%edi
xor    %r9d,%edi
and    $0xf,%edi
xor    (%r8,%rdi,4),%eax
add    $0x1,%r10
cmp    %r10,%rdx
jne    1120 <crc_x25+0x20>
ret

LLVM IR (-O0):
@crc_x25.crc_table = internal constant [16 x i32] [i32 0, i32 4129, i32 8258, i32 12387, i32 16516, i32 20645, i32 24774, i32 28903, i32 33032, i32 37161, i32 41290, i32 45419, i32 49548, i32 53677, i32 57806, i32 61935]
define i32 @crc_x25(i32 %0, i8* %1, i64 %2) {
%4 = alloca i32
%5 = alloca i8*
%6 = alloca i64
%7 = alloca i32*
%8 = alloca i32
store i32 %0, i32* %4
store i8* %1, i8** %5
store i64 %2, i64* %6
%9 = load i8*, i8** %5
%10 = bitcast i8* %9 to i32*
store i32* %10, i32** %7
br label %11
11: ; preds = %42, %3
%12 = load i64, i64* %6
%13 = icmp ne i64 %12, 0
br i1 %13, label %14, label %45
14: ; preds = %11
%15 = load i32*, i32** %7
%16 = getelementptr inbounds i32, i32* %15, i32 1
store i32* %16, i32** %7
%17 = load i32, i32* %15
store i32 %17, i32* %8
%18 = load i32, i32* %4
%19 = shl i32 %18, 4
%20 = load i32, i32* %4
%21 = ashr i32 %20, 12
%22 = load i32, i32* %8
%23 = ashr i32 %22, 4
%24 = xor i32 %21, %23
%25 = and i32 %24, 15
%26 = sext i32 %25 to i64
%27 = getelementptr inbounds [16 x i32], [16 x i32]* @crc_x25.crc_table, i64 0, i64 %26
%28 = load i32, i32* %27
%29 = xor i32 %19, %28
store i32 %29, i32* %4
%30 = load i32, i32* %4
%31 = shl i32 %30, 4
%32 = load i32, i32* %4
%33 = ashr i32 %32, 12
%34 = load i32, i32* %8
%35 = ashr i32 %34, 0
%36 = xor i32 %33, %35
%37 = and i32 %36, 15
%38 = sext i32 %37 to i64
%39 = getelementptr inbounds [16 x i32], [16 x i32]* @crc_x25.crc_table, i64 0, i64 %38
%40 = load i32, i32* %39
%41 = xor i32 %31, %40
store i32 %41, i32* %4
br label %42
42: ; preds = %14
%43 = load i64, i64* %6
%44 = add i64 %43, -1
store i64 %44, i64* %6
br label %11
45: ; preds = %11
%46 = load i32, i32* %4
ret i32 %46
}

LLVM IR (-O2):
@crc_x25.crc_table = internal unnamed_addr constant [16 x i32] [i32 0, i32 4129, i32 8258, i32 12387, i32 16516, i32 20645, i32 24774, i32 28903, i32 33032, i32 37161, i32 41290, i32 45419, i32 49548, i32 53677, i32 57806, i32 61935]
define i32 @crc_x25(i32 %0, i8* nocapture %1, i64 %2) {
%4 = icmp eq i64 %2, 0
br i1 %4, label %32, label %5
5: ; preds = %3
%6 = bitcast i8* %1 to i32*
br label %7
7: ; preds = %5, %7
%8 = phi i32 [ %29, %7 ], [ %0, %5 ]
%9 = phi i32* [ %11, %7 ], [ %6, %5 ]
%10 = phi i64 [ %30, %7 ], [ %2, %5 ]
%11 = getelementptr inbounds i32, i32* %9, i64 1
%12 = load i32, i32* %9
%13 = shl i32 %8, 4
%14 = lshr i32 %8, 12
%15 = lshr i32 %12, 4
%16 = xor i32 %15, %14
%17 = and i32 %16, 15
%18 = zext i32 %17 to i64
%19 = getelementptr inbounds [16 x i32], [16 x i32]* @crc_x25.crc_table, i64 0, i64 %18
%20 = load i32, i32* %19
%21 = xor i32 %20, %13
%22 = shl i32 %21, 4
%23 = lshr i32 %21, 12
%24 = xor i32 %23, %12
%25 = and i32 %24, 15
%26 = zext i32 %25 to i64
%27 = getelementptr inbounds [16 x i32], [16 x i32]* @crc_x25.crc_table, i64 0, i64 %26
%28 = load i32, i32* %27
%29 = xor i32 %22, %28
%30 = add i64 %10, -1
%31 = icmp eq i64 %30, 0
br i1 %31, label %32, label %7
32: ; preds = %7, %3
%33 = phi i32 [ %0, %3 ], [ %29, %7 ]
ret i32 %33
}