#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 */

/* Variables and functions */
unsigned long crc32(unsigned char, int, unsigned long);
int /*<<< orphan*/ dump_jreg(char *, unsigned char *, int);
int /*<<< orphan*/ free(unsigned char *);
unsigned char *malloc(int);
int /*<<< orphan*/ memset(unsigned char *, int /*<<< orphan*/, int);
double or1ksim_jtag_shift_dr(unsigned char *, int);
int /*<<< orphan*/ printf(char *, ...);
void *reverse_bits(unsigned long, int);
int process_read_command(int next_jreg, int argc, char *argv[]) {
  printf("Processing READ_COMMAND.\n");
  unsigned long int cmd = 1;
  unsigned long int crc_in;
  crc_in = crc32(0, 1, 0xffffffff);
  crc_in = crc32(cmd, 4, crc_in);
  cmd = reverse_bits(cmd, 4);
  crc_in = reverse_bits(crc_in, 32);
  int num_bytes = 16;
  unsigned char *jreg = malloc(num_bytes);
  if (NULL == jreg) {
    printf("ERROR: malloc for READ_COMMAND register failed.\n");
    return 0;
  }
  memset(jreg, 0, num_bytes);
  jreg[0] = 0x0;
  jreg[0] |= cmd << 1;
  jreg[0] |= crc_in << 5;
  jreg[1] = crc_in >> 3;
  jreg[2] = crc_in >> 11;
  jreg[3] = crc_in >> 19;
  jreg[4] = crc_in >> 27;
  dump_jreg("  shifting in", jreg, num_bytes);
  double t = or1ksim_jtag_shift_dr(jreg, 32 + 4 + 16 + 32 + 4 + 32 + 4 + 1);
  dump_jreg("  shifted out", jreg, num_bytes);
  unsigned char access_type;
  unsigned long int addr;
  unsigned long int len;
  unsigned char status;
  unsigned long int crc_out;
  access_type = ((jreg[4] >> 5) | (jreg[5] << 3)) & 0xf;
  addr = ((unsigned long int)jreg[5] >> 1) | ((unsigned long int)jreg[6] << 7) |
         ((unsigned long int)jreg[7] << 15) |
         ((unsigned long int)jreg[8] << 23) |
         ((unsigned long int)jreg[9] << 31);
  len = ((unsigned long int)jreg[9] >> 1) | ((unsigned long int)jreg[10] << 7) |
        ((unsigned long int)(jreg[11] & 0x1) << 15);
  status = (jreg[11] >> 1) & 0xf;
  crc_out =
      ((unsigned long int)jreg[11] >> 5) | ((unsigned long int)jreg[12] << 3) |
      ((unsigned long int)jreg[13] << 11) |
      ((unsigned long int)jreg[14] << 19) | ((unsigned long int)jreg[15] << 27);
  access_type = reverse_bits(access_type, 4);
  addr = reverse_bits(addr, 32);
  len = reverse_bits(len, 16);
  status = reverse_bits(status, 4);
  crc_out = reverse_bits(crc_out, 32);
  unsigned long int crc_computed;
  crc_computed = crc32(access_type, 4, 0xffffffff);
  crc_computed = crc32(addr, 32, crc_computed);
  crc_computed = crc32(len, 16, crc_computed);
  crc_computed = crc32(status, 4, crc_computed);
  printf("  access_type:  0x%x\n", access_type);
  printf("  address:      0x%lx\n", addr);
  printf("  length:       0x%lx\n", len + 1);
  printf("  status:       0x%x\n", status);
  if (crc_out != crc_computed) {
    printf("  CRC mismatch\n");
    printf("    CRC out:      0x%08lx\n", crc_out);
    printf("    CRC computed: 0x%08lx\n", crc_computed);
  }
  printf("  time taken:   %.12fs\n", t);
  free(jreg);
  return 1;
}


x86 assembly (clang, -O0):
<process_read_command>:
push   %rbp
mov    %rsp,%rbp
sub    $0x70,%rsp
mov    %edi,-0x8(%rbp)
mov    %esi,-0xc(%rbp)
mov    %rdx,-0x18(%rbp)
lea    0xe67(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
movq   $0x1,-0x20(%rbp)
xor    %edi,%edi
mov    $0x1,%esi
mov    $0xffffffff,%edx
call   1040 <crc32@plt>
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%rdx
mov    $0x4,%esi
movzbl %al,%edi
call   1040 <crc32@plt>
mov    %rax,-0x28(%rbp)
mov    -0x20(%rbp),%rdi
mov    $0x4,%esi
call   1060 <reverse_bits@plt>
mov    %rax,-0x20(%rbp)
mov    -0x28(%rbp),%rdi
mov    $0x20,%esi
call   1060 <reverse_bits@plt>
mov    %rax,-0x28(%rbp)
movl   $0x10,-0x2c(%rbp)
mov    -0x2c(%rbp),%edi
call   1090 <malloc@plt>
mov    %rax,-0x38(%rbp)
xor    %eax,%eax
cmp    -0x38(%rbp),%rax
jne    1233 <process_read_command+0xb3>
lea    0xdfa(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
movl   $0x0,-0x4(%rbp)
jmp    1554 <process_read_command+0x3d4>
mov    -0x38(%rbp),%rdi
mov    -0x2c(%rbp),%edx
xor    %esi,%esi
call   1080 <memset@plt>
mov    -0x38(%rbp),%rax
movb   $0x0,(%rax)
mov    -0x20(%rbp),%rdx
shl    $0x1,%rdx
mov    -0x38(%rbp),%rax
movzbl (%rax),%ecx
or     %rdx,%rcx
mov    %cl,(%rax)
mov    -0x28(%rbp),%rdx
shl    $0x5,%rdx
mov    -0x38(%rbp),%rax
movzbl (%rax),%ecx
or     %rdx,%rcx
mov    %cl,(%rax)
mov    -0x28(%rbp),%rax
shr    $0x3,%rax
mov    %al,%cl
mov    -0x38(%rbp),%rax
mov    %cl,0x1(%rax)
mov    -0x28(%rbp),%rax
shr    $0xb,%rax
mov    %al,%cl
mov    -0x38(%rbp),%rax
mov    %cl,0x2(%rax)
mov    -0x28(%rbp),%rax
shr    $0x13,%rax
mov    %al,%cl
mov    -0x38(%rbp),%rax
mov    %cl,0x3(%rax)
mov    -0x28(%rbp),%rax
shr    $0x1b,%rax
mov    %al,%cl
mov    -0x38(%rbp),%rax
mov    %cl,0x4(%rax)
mov    -0x38(%rbp),%rsi
mov    -0x2c(%rbp),%edx
lea    0xd89(%rip),%rdi
call   1050 <dump_jreg@plt>
mov    -0x38(%rbp),%rdi
mov    $0x7d,%esi
call   10a0 <or1ksim_jtag_shift_dr@plt>
movsd  %xmm0,-0x40(%rbp)
mov    -0x38(%rbp),%rsi
mov    -0x2c(%rbp),%edx
lea    0xd71(%rip),%rdi
call   1050 <dump_jreg@plt>
mov    -0x38(%rbp),%rax
movzbl 0x4(%rax),%eax
sar    $0x5,%eax
mov    -0x38(%rbp),%rcx
movzbl 0x5(%rcx),%ecx
shl    $0x3,%ecx
or     %ecx,%eax
and    $0xf,%eax
mov    %al,-0x41(%rbp)
mov    -0x38(%rbp),%rax
movzbl 0x5(%rax),%eax
shr    $0x1,%rax
mov    -0x38(%rbp),%rcx
movzbl 0x6(%rcx),%ecx
shl    $0x7,%rcx
or     %rcx,%rax
mov    -0x38(%rbp),%rcx
movzbl 0x7(%rcx),%ecx
shl    $0xf,%rcx
or     %rcx,%rax
mov    -0x38(%rbp),%rcx
movzbl 0x8(%rcx),%ecx
shl    $0x17,%rcx
or     %rcx,%rax
mov    -0x38(%rbp),%rcx
movzbl 0x9(%rcx),%ecx
shl    $0x1f,%rcx
or     %rcx,%rax
mov    %rax,-0x50(%rbp)
mov    -0x38(%rbp),%rax
movzbl 0x9(%rax),%eax
shr    $0x1,%rax
mov    -0x38(%rbp),%rcx
movzbl 0xa(%rcx),%ecx
shl    $0x7,%rcx
or     %rcx,%rax
mov    -0x38(%rbp),%rcx
movzbl 0xb(%rcx),%ecx
and    $0x1,%ecx
movslq %ecx,%rcx
shl    $0xf,%rcx
or     %rcx,%rax
mov    %rax,-0x58(%rbp)
mov    -0x38(%rbp),%rax
movzbl 0xb(%rax),%eax
sar    $0x1,%eax
and    $0xf,%eax
mov    %al,-0x59(%rbp)
mov    -0x38(%rbp),%rax
movzbl 0xb(%rax),%eax
shr    $0x5,%rax
mov    -0x38(%rbp),%rcx
movzbl 0xc(%rcx),%ecx
shl    $0x3,%rcx
or     %rcx,%rax
mov    -0x38(%rbp),%rcx
movzbl 0xd(%rcx),%ecx
shl    $0xb,%rcx
or     %rcx,%rax
mov    -0x38(%rbp),%rcx
movzbl 0xe(%rcx),%ecx
shl    $0x13,%rcx
or     %rcx,%rax
mov    -0x38(%rbp),%rcx
movzbl 0xf(%rcx),%ecx
shl    $0x1b,%rcx
or     %rcx,%rax
mov    %rax,-0x68(%rbp)
movzbl -0x41(%rbp),%eax
mov    %eax,%edi
mov    $0x4,%esi
call   1060 <reverse_bits@plt>
mov    %al,-0x41(%rbp)
mov    -0x50(%rbp),%rdi
mov    $0x20,%esi
call   1060 <reverse_bits@plt>
mov    %rax,-0x50(%rbp)
mov    -0x58(%rbp),%rdi
mov    $0x10,%esi
call   1060 <reverse_bits@plt>
mov    %rax,-0x58(%rbp)
movzbl -0x59(%rbp),%eax
mov    %eax,%edi
mov    $0x4,%esi
call   1060 <reverse_bits@plt>
mov    %al,-0x59(%rbp)
mov    -0x68(%rbp),%rdi
mov    $0x20,%esi
call   1060 <reverse_bits@plt>
mov    %rax,-0x68(%rbp)
mov    $0x4,%esi
mov    $0xffffffff,%edx
movzbl -0x41(%rbp),%edi
call   1040 <crc32@plt>
mov    %rax,-0x70(%rbp)
mov    -0x50(%rbp),%rax
mov    -0x70(%rbp),%rdx
mov    $0x20,%esi
movzbl %al,%edi
call   1040 <crc32@plt>
mov    %rax,-0x70(%rbp)
mov    -0x58(%rbp),%rax
mov    -0x70(%rbp),%rdx
mov    $0x10,%esi
movzbl %al,%edi
call   1040 <crc32@plt>
mov    %rax,-0x70(%rbp)
mov    -0x59(%rbp),%al
mov    -0x70(%rbp),%rdx
mov    $0x4,%esi
movzbl %al,%edi
call   1040 <crc32@plt>
mov    %rax,-0x70(%rbp)
movzbl -0x41(%rbp),%esi
lea    0xbb7(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
mov    -0x50(%rbp),%rsi
lea    0xbbb(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
mov    -0x58(%rbp),%rsi
add    $0x1,%rsi
lea    0xbbc(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
movzbl -0x59(%rbp),%esi
lea    0xbc1(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
mov    -0x68(%rbp),%rax
cmp    -0x70(%rbp),%rax
je     1531 <process_read_command+0x3b1>
lea    0xbbb(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
mov    -0x68(%rbp),%rsi
lea    0xbb9(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
mov    -0x70(%rbp),%rsi
lea    0xbc2(%rip),%rdi
mov    $0x0,%al
call   1070 <printf@plt>
movsd  -0x40(%rbp),%xmm0
lea    0xbca(%rip),%rdi
mov    $0x1,%al
call   1070 <printf@plt>
mov    -0x38(%rbp),%rdi
call   1030 <free@plt>
movl   $0x1,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x70,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<process_read_command>:
push   %rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x18,%rsp
lea    0xf1f(%rip),%rdi
call   1040 <puts@plt>
xor    %r14d,%r14d
mov    $0xffffffff,%edx
xor    %edi,%edi
mov    $0x1,%esi
call   1050 <crc32@plt>
mov    $0x1,%edi
mov    $0x4,%esi
mov    %rax,%rdx
call   1050 <crc32@plt>
mov    %rax,%rbx
mov    $0x1,%edi
mov    $0x4,%esi
call   1070 <reverse_bits@plt>
mov    %rax,%r15
mov    %rbx,%rdi
mov    $0x20,%esi
call   1070 <reverse_bits@plt>
mov    %rax,%rbp
mov    $0x10,%edi
call   10a0 <malloc@plt>
test   %rax,%rax
je     1463 <process_read_command+0x2d3>
mov    %rax,%rbx
mov    %rax,%rdi
xor    %esi,%esi
mov    $0x10,%edx
call   1090 <memset@plt>
add    %r15d,%r15d
mov    %ebp,%eax
shl    $0x5,%eax
or     %r15d,%eax
mov    %al,(%rbx)
mov    %rbp,%rax
shr    $0x3,%rax
mov    %al,0x1(%rbx)
mov    %rbp,%rax
shr    $0xb,%rax
mov    %al,0x2(%rbx)
mov    %rbp,%rax
shr    $0x13,%rax
mov    %al,0x3(%rbx)
shr    $0x1b,%rbp
mov    %bpl,0x4(%rbx)
lea    0xdac(%rip),%rdi
mov    %rbx,%rsi
mov    $0x10,%edx
call   1060 <dump_jreg@plt>
mov    %rbx,%rdi
mov    $0x7d,%esi
call   10b0 <or1ksim_jtag_shift_dr@plt>
movsd  %xmm0,0x10(%rsp)
lea    0xd93(%rip),%rdi
mov    %rbx,%rsi
mov    $0x10,%edx
call   1060 <dump_jreg@plt>
movzbl 0x4(%rbx),%eax
shr    $0x5,%rax
movzbl 0x5(%rbx),%ecx
mov    %ecx,%edx
and    $0x1,%edx
lea    (%rax,%rdx,8),%rdi
shr    %rcx
movzbl 0x6(%rbx),%eax
shl    $0x7,%rax
or     %rcx,%rax
movzbl 0x7(%rbx),%ecx
shl    $0xf,%rcx
or     %rax,%rcx
movzbl 0x8(%rbx),%eax
shl    $0x17,%rax
or     %rcx,%rax
movzbl 0x9(%rbx),%ecx
mov    %rcx,%r14
shl    $0x1f,%r14
or     %rax,%r14
shr    %rcx
movzbl 0xa(%rbx),%eax
shl    $0x7,%rax
or     %rcx,%rax
movzbl 0xb(%rbx),%ecx
mov    %ecx,%edx
shl    $0xf,%edx
movzwl %dx,%r15d
or     %rax,%r15
mov    %ecx,%ebp
shr    %ebp
and    $0xf,%ebp
shr    $0x5,%rcx
movzbl 0xc(%rbx),%eax
lea    (%rcx,%rax,8),%rax
movzbl 0xd(%rbx),%ecx
shl    $0xb,%rcx
or     %rax,%rcx
movzbl 0xe(%rbx),%eax
shl    $0x13,%rax
or     %rcx,%rax
movzbl 0xf(%rbx),%r13d
shl    $0x1b,%r13
or     %rax,%r13
mov    $0x4,%esi
call   1070 <reverse_bits@plt>
mov    %rax,(%rsp)
mov    %r14,%rdi
mov    $0x20,%esi
call   1070 <reverse_bits@plt>
mov    %rax,%r12
mov    %r15,%rdi
mov    $0x10,%esi
call   1070 <reverse_bits@plt>
mov    %rax,%r15
mov    %rbp,%rdi
mov    $0x4,%esi
call   1070 <reverse_bits@plt>
mov    %rax,%r14
mov    %r13,%rdi
mov    $0x20,%esi
call   1070 <reverse_bits@plt>
mov    %rax,0x8(%rsp)
movzbl (%rsp),%ebp
mov    $0xffffffff,%edx
mov    %ebp,%edi
mov    $0x4,%esi
call   1050 <crc32@plt>
movzbl %r12b,%edi
mov    $0x20,%esi
mov    %rax,%rdx
call   1050 <crc32@plt>
movzbl %r15b,%edi
mov    $0x10,%esi
mov    %rax,%rdx
call   1050 <crc32@plt>
movzbl %r14b,%r14d
mov    %r14d,%edi
mov    $0x4,%esi
mov    %rax,%rdx
call   1050 <crc32@plt>
mov    %rax,%r13
lea    0xc55(%rip),%rdi
mov    %ebp,%esi
xor    %eax,%eax
call   1080 <printf@plt>
lea    0xc5b(%rip),%rdi
mov    %r12,%rsi
xor    %eax,%eax
call   1080 <printf@plt>
add    $0x1,%r15
lea    0xc5d(%rip),%rdi
mov    %r15,%rsi
xor    %eax,%eax
call   1080 <printf@plt>
lea    0xc63(%rip),%rdi
mov    %r14d,%esi
mov    0x8(%rsp),%rbp
xor    %eax,%eax
call   1080 <printf@plt>
cmp    %rbp,%r13
je     143f <process_read_command+0x2af>
lea    0xcc5(%rip),%rdi
call   1040 <puts@plt>
lea    0xc52(%rip),%rdi
mov    %rbp,%rsi
xor    %eax,%eax
call   1080 <printf@plt>
lea    0xc5c(%rip),%rdi
mov    %r13,%rsi
xor    %eax,%eax
call   1080 <printf@plt>
lea    0xc66(%rip),%rdi
movsd  0x10(%rsp),%xmm0
mov    $0x1,%al
call   1080 <printf@plt>
mov    %rbx,%rdi
call   1030 <free@plt>
mov    $0x1,%r14d
jmp    146f <process_read_command+0x2df>
lea    0xc82(%rip),%rdi
call   1040 <puts@plt>
mov    %r14d,%eax
add    $0x18,%rsp
pop    %rbx
pop    %r12
pop    %r13
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@.str = [26 x i8] c"Processing READ_COMMAND.\0A\00"
@.str.1 = [49 x i8] c"ERROR: malloc for READ_COMMAND register failed.\0A\00"
@.str.2 = [14 x i8] c" shifting in\00"
@.str.3 = [14 x i8] c" shifted out\00"
@.str.4 = [22 x i8] c" access_type: 0x%x\0A\00"
@.str.5 = [23 x i8] c" address: 0x%lx\0A\00"
@.str.6 = [23 x i8] c" length: 0x%lx\0A\00"
@.str.7 = [22 x i8] c" status: 0x%x\0A\00"
@.str.8 = [16 x i8] c" CRC mismatch\0A\00"
@.str.9 = [27 x i8] c" CRC out: 0x%08lx\0A\00"
@.str.10 = [27 x i8] c" CRC computed: 0x%08lx\0A\00"
@.str.11 = [24 x i8] c" time taken: %.12fs\0A\00"
define i32 @process_read_command(i32 %0, i32 %1, i8** %2) {
%4 = alloca i32
%5 = alloca i32
%6 = alloca i32
%7 = alloca i8**
%8 = alloca i64
%9 = alloca i64
%10 = alloca i32
%11 = alloca i8*
%12 = alloca double
%13 = alloca i8
%14 = alloca i64
%15 = alloca i64
%16 = alloca i8
%17 = alloca i64
%18 = alloca i64
store i32 %0, i32* %5
store i32 %1, i32* %6
store i8** %2, i8*** %7
%19 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([26 x i8], [26 x i8]* @.str, i64 0, i64 0))
store i64 1, i64* %8
%20 = call i64 @crc32(i8 zeroext 0, i32 1, i64 4294967295)
store i64 %20, i64* %9
%21 = load i64, i64* %8
%22 = trunc i64 %21 to i8
%23 = load i64, i64* %9
%24 = call i64 @crc32(i8 zeroext %22, i32 4, i64 %23)
store i64 %24, i64* %9
%25 = load i64, i64* %8
%26 = call i8* @reverse_bits(i64 %25, i32 4)
%27 = ptrtoint i8* %26 to i64
store i64 %27, i64* %8
%28 = load i64, i64* %9
%29 = call i8* @reverse_bits(i64 %28, i32 32)
%30 = ptrtoint i8* %29 to i64
store i64 %30, i64* %9
store i32 16, i32* %10
%31 = load i32, i32* %10
%32 = call i8* @malloc(i32 %31)
store i8* %32, i8** %11
%33 = load i8*, i8** %11
%34 = icmp eq i8* null, %33
br i1 %34, label %35, label %37
35: ; preds = %3
%36 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([49 x i8], [49 x i8]* @.str.1, i64 0, i64 0))
store i32 0, i32* %4
br label %239
37: ; preds = %3
%38 = load i8*, i8** %11
%39 = load i32, i32* %10
%40 = call i32 @memset(i8* %38, i32 0, i32 %39)
%41 = load i8*, i8** %11
%42 = getelementptr inbounds i8, i8* %41, i64 0
store i8 0, i8* %42
%43 = load i64, i64* %8
%44 = shl i64 %43, 1
%45 = load i8*, i8** %11
%46 = getelementptr inbounds i8, i8* %45, i64 0
%47 = load i8, i8* %46
%48 = zext i8 %47 to i64
%49 = or i64 %48, %44
%50 = trunc i64 %49 to i8
store i8 %50, i8* %46
%51 = load i64, i64* %9
%52 = shl i64 %51, 5
%53 = load i8*, i8** %11
%54 = getelementptr inbounds i8, i8* %53, i64 0
%55 = load i8, i8* %54
%56 = zext i8 %55 to i64
%57 = or i64 %56, %52
%58 = trunc i64 %57 to i8
store i8 %58, i8* %54
%59 = load i64, i64* %9
%60 = lshr i64 %59, 3
%61 = trunc i64 %60 to i8
%62 = load i8*, i8** %11
%63 = getelementptr inbounds i8, i8* %62, i64 1
store i8 %61, i8* %63
%64 = load i64, i64* %9
%65 = lshr i64 %64, 11
%66 = trunc i64 %65 to i8
%67 = load i8*, i8** %11
%68 = getelementptr inbounds i8, i8* %67, i64 2
store i8 %66, i8* %68
%69 = load i64, i64* %9
%70 = lshr i64 %69, 19
%71 = trunc i64 %70 to i8
%72 = load i8*, i8** %11
%73 = getelementptr inbounds i8, i8* %72, i64 3
store i8 %71, i8* %73
%74 = load i64, i64* %9
%75 = lshr i64 %74, 27
%76 = trunc i64 %75 to i8
%77 = load i8*, i8** %11
%78 = getelementptr inbounds i8, i8* %77, i64 4
store i8 %76, i8* %78
%79 = load i8*, i8** %11
%80 = load i32, i32* %10
%81 = call i32 @dump_jreg(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i64 0, i64 0), i8* %79, i32 %80)
%82 = load i8*, i8** %11
%83 = call double @or1ksim_jtag_shift_dr(i8* %82, i32 125)
store double %83, double* %12
%84 = load i8*, i8** %11
%85 = load i32, i32* %10
%86 = call i32 @dump_jreg(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.3, i64 0, i64 0), i8* %84, i32 %85)
%87 = load i8*, i8** %11
%88 = getelementptr inbounds i8, i8* %87, i64 4
%89 = load i8, i8* %88
%90 = zext i8 %89 to i32
%91 = ashr i32 %90, 5
%92 = load i8*, i8** %11
%93 = getelementptr inbounds i8, i8* %92, i64 5
%94 = load i8, i8* %93
%95 = zext i8 %94 to i32
%96 = shl i32 %95, 3
%97 = or i32 %91, %96
%98 = and i32 %97, 15
%99 = trunc i32 %98 to i8
store i8 %99, i8* %13
%100 = load i8*, i8** %11
%101 = getelementptr inbounds i8, i8* %100, i64 5
%102 = load i8, i8* %101
%103 = zext i8 %102 to i64
%104 = lshr i64 %103, 1
%105 = load i8*, i8** %11
%106 = getelementptr inbounds i8, i8* %105, i64 6
%107 = load i8, i8* %106
%108 = zext i8 %107 to i64
%109 = shl i64 %108, 7
%110 = or i64 %104, %109
%111 = load i8*, i8** %11
%112 = getelementptr inbounds i8, i8* %111, i64 7
%113 = load i8, i8* %112
%114 = zext i8 %113 to i64
%115 = shl i64 %114, 15
%116 = or i64 %110, %115
%117 = load i8*, i8** %11
%118 = getelementptr inbounds i8, i8* %117, i64 8
%119 = load i8, i8* %118
%120 = zext i8 %119 to i64
%121 = shl i64 %120, 23
%122 = or i64 %116, %121
%123 = load i8*, i8** %11
%124 = getelementptr inbounds i8, i8* %123, i64 9
%125 = load i8, i8* %124
%126 = zext i8 %125 to i64
%127 = shl i64 %126, 31
%128 = or i64 %122, %127
store i64 %128, i64* %14
%129 = load i8*, i8** %11
%130 = getelementptr inbounds i8, i8* %129, i64 9
%131 = load i8, i8* %130
%132 = zext i8 %131 to i64
%133 = lshr i64 %132, 1
%134 = load i8*, i8** %11
%135 = getelementptr inbounds i8, i8* %134, i64 10
%136 = load i8, i8* %135
%137 = zext i8 %136 to i64
%138 = shl i64 %137, 7
%139 = or i64 %133, %138
%140 = load i8*, i8** %11
%141 = getelementptr inbounds i8, i8* %140, i64 11
%142 = load i8, i8* %141
%143 = zext i8 %142 to i32
%144 = and i32 %143, 1
%145 = sext i32 %144 to i64
%146 = shl i64 %145, 15
%147 = or i64 %139, %146
store i64 %147, i64* %15
%148 = load i8*, i8** %11
%149 = getelementptr inbounds i8, i8* %148, i64 11
%150 = load i8, i8* %149
%151 = zext i8 %150 to i32
%152 = ashr i32 %151, 1
%153 = and i32 %152, 15
%154 = trunc i32 %153 to i8
store i8 %154, i8* %16
%155 = load i8*, i8** %11
%156 = getelementptr inbounds i8, i8* %155, i64 11
%157 = load i8, i8* %156
%158 = zext i8 %157 to i64
%159 = lshr i64 %158, 5
%160 = load i8*, i8** %11
%161 = getelementptr inbounds i8, i8* %160, i64 12
%162 = load i8, i8* %161
%163 = zext i8 %162 to i64
%164 = shl i64 %163, 3
%165 = or i64 %159, %164
%166 = load i8*, i8** %11
%167 = getelementptr inbounds i8, i8* %166, i64 13
%168 = load i8, i8* %167
%169 = zext i8 %168 to i64
%170 = shl i64 %169, 11
%171 = or i64 %165, %170
%172 = load i8*, i8** %11
%173 = getelementptr inbounds i8, i8* %172, i64 14
%174 = load i8, i8* %173
%175 = zext i8 %174 to i64
%176 = shl i64 %175, 19
%177 = or i64 %171, %176
%178 = load i8*, i8** %11
%179 = getelementptr inbounds i8, i8* %178, i64 15
%180 = load i8, i8* %179
%181 = zext i8 %180 to i64
%182 = shl i64 %181, 27
%183 = or i64 %177, %182
store i64 %183, i64* %17
%184 = load i8, i8* %13
%185 = zext i8 %184 to i64
%186 = call i8* @reverse_bits(i64 %185, i32 4)
%187 = ptrtoint i8* %186 to i8
store i8 %187, i8* %13
%188 = load i64, i64* %14
%189 = call i8* @reverse_bits(i64 %188, i32 32)
%190 = ptrtoint i8* %189 to i64
store i64 %190, i64* %14
%191 = load i64, i64* %15
%192 = call i8* @reverse_bits(i64 %191, i32 16)
%193 = ptrtoint i8* %192 to i64
store i64 %193, i64* %15
%194 = load i8, i8* %16
%195 = zext i8 %194 to i64
%196 = call i8* @reverse_bits(i64 %195, i32 4)
%197 = ptrtoint i8* %196 to i8
store i8 %197, i8* %16
%198 = load i64, i64* %17
%199 = call i8* @reverse_bits(i64 %198, i32 32)
%200 = ptrtoint i8* %199 to i64
store i64 %200, i64* %17
%201 = load i8, i8* %13
%202 = call i64 @crc32(i8 zeroext %201, i32 4, i64 4294967295)
store i64 %202, i64* %18
%203 = load i64, i64* %14
%204 = trunc i64 %203 to i8
%205 = load i64, i64* %18
%206 = call i64 @crc32(i8 zeroext %204, i32 32, i64 %205)
store i64 %206, i64* %18
%207 = load i64, i64* %15
%208 = trunc i64 %207 to i8
%209 = load i64, i64* %18
%210 = call i64 @crc32(i8 zeroext %208, i32 16, i64 %209)
store i64 %210, i64* %18
%211 = load i8, i8* %16
%212 = load i64, i64* %18
%213 = call i64 @crc32(i8 zeroext %211, i32 4, i64 %212)
store i64 %213, i64* %18
%214 = load i8, i8* %13
%215 = zext i8 %214 to i32
%216 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.4, i64 0, i64 0), i32 %215)
%217 = load i64, i64* %14
%218 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.5, i64 0, i64 0), i64 %217)
%219 = load i64, i64* %15
%220 = add i64 %219, 1
%221 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([23 x i8], [23 x i8]* @.str.6, i64 0, i64 0), i64 %220)
%222 = load i8, i8* %16
%223 = zext i8 %222 to i32
%224 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([22 x i8], [22 x i8]* @.str.7, i64 0, i64 0), i32 %223)
%225 = load i64, i64* %17
%226 = load i64, i64* %18
%227 = icmp ne i64 %225, %226
br i1 %227, label %228, label %234
228: ; preds = %37
%229 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.8, i64 0, i64 0))
%230 = load i64, i64* %17
%231 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str.9, i64 0, i64 0), i64 %230)
%232 = load i64, i64* %18
%233 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([27 x i8], [27 x i8]* @.str.10, i64 0, i64 0), i64 %232)
br label %234
234: ; preds = %228, %37
%235 = load double, double* %12
%236 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.11, i64 0, i64 0), double %235)
%237 = load i8*, i8** %11
%238 = call i32 @free(i8* %237)
store i32 1, i32* %4
br label %239
239: ; preds = %234, %35
%240 = load i32, i32* %4
ret i32 %240
}

LLVM IR (-O2):
@.str.2 = [14 x i8] c" shifting in\00"
@.str.3 = [14 x i8] c" shifted out\00"
@.str.4 = [22 x i8] c" access_type: 0x%x\0A\00"
@.str.5 = [23 x i8] c" address: 0x%lx\0A\00"
@.str.6 = [23 x i8] c" length: 0x%lx\0A\00"
@.str.7 = [22 x i8] c" status: 0x%x\0A\00"
@.str.9 = [27 x i8] c" CRC out: 0x%08lx\0A\00"
@.str.10 = [27 x i8] c" CRC computed: 0x%08lx\0A\00"
@.str.11 = [24 x i8] c" time taken: %.12fs\0A\00"
@str = [25 x i8] c"Processing READ_COMMAND.\00"
@str.12 = [15 x i8] c" CRC mismatch\00"
@str.13 = [48 x i8] c"ERROR: malloc for READ_COMMAND register failed.\00"
define i32 @process_read_command(i32 %0, i32 %1, i8** nocapture readnone %2) {
%4 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([25 x i8], [25 x i8]* @str, i64 0, i64 0))
%5 = tail call i64 @crc32(i8 zeroext 0, i32 1, i64 4294967295)
%6 = tail call i64 @crc32(i8 zeroext 1, i32 4, i64 %5)
%7 = tail call i8* @reverse_bits(i64 1, i32 4)
%8 = tail call i8* @reverse_bits(i64 %6, i32 32)
%9 = ptrtoint i8* %8 to i64
%10 = tail call dereferenceable_or_null(16) i8* @malloc(i32 16)
%11 = icmp eq i8* %10, null
br i1 %11, label %12, label %14
12: ; preds = %3
%13 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([48 x i8], [48 x i8]* @str.13, i64 0, i64 0))
br label %138
14: ; preds = %3
%15 = ptrtoint i8* %7 to i64
%16 = tail call i32 @memset(i8* %10, i32 0, i32 16)
%17 = shl i64 %15, 1
%18 = shl i64 %9, 5
%19 = or i64 %18, %17
%20 = trunc i64 %19 to i8
store i8 %20, i8* %10
%21 = lshr i64 %9, 3
%22 = trunc i64 %21 to i8
%23 = getelementptr inbounds i8, i8* %10, i64 1
store i8 %22, i8* %23
%24 = lshr i64 %9, 11
%25 = trunc i64 %24 to i8
%26 = getelementptr inbounds i8, i8* %10, i64 2
store i8 %25, i8* %26
%27 = lshr i64 %9, 19
%28 = trunc i64 %27 to i8
%29 = getelementptr inbounds i8, i8* %10, i64 3
store i8 %28, i8* %29
%30 = lshr i64 %9, 27
%31 = trunc i64 %30 to i8
%32 = getelementptr inbounds i8, i8* %10, i64 4
store i8 %31, i8* %32
%33 = tail call i32 @dump_jreg(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.2, i64 0, i64 0), i8* %10, i32 16)
%34 = tail call double @or1ksim_jtag_shift_dr(i8* %10, i32 125)
%35 = tail call i32 @dump_jreg(i8* getelementptr inbounds ([14 x i8], [14 x i8]* @.str.3, i64 0, i64 0), i8* %10, i32 16)
%36 = load i8, i8* %32
%37 = lshr i8 %36, 5
%38 = getelementptr inbounds i8, i8* %10, i64 5
%39 = load i8, i8* %38
%40 = shl i8 %39, 3
%41 = and i8 %40, 8
%42 = or i8 %41, %37
%43 = lshr i8 %39, 1
%44 = zext i8 %43 to i64
%45 = getelementptr inbounds i8, i8* %10, i64 6
%46 = load i8, i8* %45
%47 = zext i8 %46 to i64
%48 = shl nuw nsw i64 %47, 7
%49 = or i64 %48, %44
%50 = getelementptr inbounds i8, i8* %10, i64 7
%51 = load i8, i8* %50
%52 = zext i8 %51 to i64
%53 = shl nuw nsw i64 %52, 15
%54 = or i64 %49, %53
%55 = getelementptr inbounds i8, i8* %10, i64 8
%56 = load i8, i8* %55
%57 = zext i8 %56 to i64
%58 = shl nuw nsw i64 %57, 23
%59 = or i64 %54, %58
%60 = getelementptr inbounds i8, i8* %10, i64 9
%61 = load i8, i8* %60
%62 = zext i8 %61 to i64
%63 = shl nuw nsw i64 %62, 31
%64 = or i64 %59, %63
%65 = lshr i64 %62, 1
%66 = getelementptr inbounds i8, i8* %10, i64 10
%67 = load i8, i8* %66
%68 = zext i8 %67 to i64
%69 = shl nuw nsw i64 %68, 7
%70 = or i64 %69, %65
%71 = getelementptr inbounds i8, i8* %10, i64 11
%72 = load i8, i8* %71
%73 = zext i8 %72 to i64
%74 = shl nuw nsw i64 %73, 15
%75 = and i64 %74, 32768
%76 = or i64 %75, %70
%77 = lshr i8 %72, 1
%78 = and i8 %77, 15
%79 = lshr i8 %72, 5
%80 = zext i8 %79 to i64
%81 = getelementptr inbounds i8, i8* %10, i64 12
%82 = load i8, i8* %81
%83 = zext i8 %82 to i64
%84 = shl nuw nsw i64 %83, 3
%85 = or i64 %84, %80
%86 = getelementptr inbounds i8, i8* %10, i64 13
%87 = load i8, i8* %86
%88 = zext i8 %87 to i64
%89 = shl nuw nsw i64 %88, 11
%90 = or i64 %85, %89
%91 = getelementptr inbounds i8, i8* %10, i64 14
%92 = load i8, i8* %91
%93 = zext i8 %92 to i64
%94 = shl nuw nsw i64 %93, 19
%95 = or i64 %90, %94
%96 = getelementptr inbounds i8, i8* %10, i64 15
%97 = load i8, i8* %96
%98 = zext i8 %97 to i64
%99 = shl nuw nsw i64 %98, 27
%100 = or i64 %95, %99
%101 = zext i8 %42 to i64
%102 = tail call i8* @reverse_bits(i64 %101, i32 4)
%103 = ptrtoint i8* %102 to i64
%104 = trunc i64 %103 to i8
%105 = tail call i8* @reverse_bits(i64 %64, i32 32)
%106 = ptrtoint i8* %105 to i64
%107 = tail call i8* @reverse_bits(i64 %76, i32 16)
%108 = ptrtoint i8* %107 to i64
%109 = zext i8 %78 to i64
%110 = tail call i8* @reverse_bits(i64 %109, i32 4)
%111 = ptrtoint i8* %110 to i64
%112 = trunc i64 %111 to i8
%113 = tail call i8* @reverse_bits(i64 %100, i32 32)
%114 = ptrtoint i8* %113 to i64
%115 = tail call i64 @crc32(i8 zeroext %104, i32 4, i64 4294967295)
%116 = trunc i64 %106 to i8
%117 = tail call i64 @crc32(i8 zeroext %116, i32 32, i64 %115)
%118 = trunc i64 %108 to i8
%119 = tail call i64 @crc32(i8 zeroext %118, i32 16, i64 %117)
%120 = tail call i64 @crc32(i8 zeroext %112, i32 4, i64 %119)
%121 = trunc i64 %103 to i32
%122 = and i32 %121, 255
%123 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([22 x i8], [22 x i8]* @.str.4, i64 0, i64 0), i32 %122)
%124 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([23 x i8], [23 x i8]* @.str.5, i64 0, i64 0), i64 %106)
%125 = add i64 %108, 1
%126 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([23 x i8], [23 x i8]* @.str.6, i64 0, i64 0), i64 %125)
%127 = trunc i64 %111 to i32
%128 = and i32 %127, 255
%129 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([22 x i8], [22 x i8]* @.str.7, i64 0, i64 0), i32 %128)
%130 = icmp eq i64 %120, %114
br i1 %130, label %135, label %131
131: ; preds = %14
%132 = tail call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([15 x i8], [15 x i8]* @str.12, i64 0, i64 0))
%133 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([27 x i8], [27 x i8]* @.str.9, i64 0, i64 0), i64 %114)
%134 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([27 x i8], [27 x i8]* @.str.10, i64 0, i64 0), i64 %120)
br label %135
135: ; preds = %131, %14
%136 = tail call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([24 x i8], [24 x i8]* @.str.11, i64 0, i64 0), double %34)
%137 = tail call i32 @free(i8* %10)
br label %138
138: ; preds = %135, %12
%139 = phi i32 [ 0, %12 ], [ 1, %135 ]
ret i32 %139
}