#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 */
void ocb_block_lshift(const unsigned char *in, size_t shift,
                      unsigned char *out) {
  int i;
  unsigned char carry = 0, carry_next;
  for (i = 15; i >= 0; i--) {
    carry_next = in[i] >> (8 - shift);
    out[i] = (in[i] << shift) | carry;
    carry = carry_next;
  }
}


x86 assembly (clang, -O0):
<ocb_block_lshift>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    %rdx,-0x18(%rbp)
movb   $0x0,-0x1d(%rbp)
movl   $0xf,-0x1c(%rbp)
cmpl   $0x0,-0x1c(%rbp)
jl     1178 <ocb_block_lshift+0x78>
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    $0x8,%ecx
sub    -0x10(%rbp),%rcx
sar    %cl,%eax
mov    %al,-0x1e(%rbp)
mov    -0x8(%rbp),%rax
movslq -0x1c(%rbp),%rcx
movzbl (%rax,%rcx,1),%eax
mov    -0x10(%rbp),%rcx
shl    %cl,%eax
movzbl -0x1d(%rbp),%ecx
or     %ecx,%eax
mov    %al,%dl
mov    -0x18(%rbp),%rax
movslq -0x1c(%rbp),%rcx
mov    %dl,(%rax,%rcx,1)
mov    -0x1e(%rbp),%al
mov    %al,-0x1d(%rbp)
mov    -0x1c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x1c(%rbp)
jmp    111b <ocb_block_lshift+0x1b>
pop    %rbp
ret

x86 assembly (clang, -O2):
<ocb_block_lshift>:
mov    %rsi,%r8
movzbl 0xf(%rdi),%esi
mov    $0x8,%r9b
sub    %r8b,%r9b
mov    %esi,%eax
mov    %r9d,%ecx
shr    %cl,%eax
mov    %r8d,%ecx
shl    %cl,%esi
mov    %sil,0xf(%rdx)
movzbl 0xe(%rdi),%esi
mov    %esi,%r10d
mov    %r9d,%ecx
shr    %cl,%r10d
mov    %r8d,%ecx
shl    %cl,%esi
or     %eax,%esi
mov    %sil,0xe(%rdx)
movzbl 0xd(%rdi),%eax
mov    %eax,%esi
mov    %r9d,%ecx
shr    %cl,%esi
mov    %r8d,%ecx
shl    %cl,%eax
or     %r10d,%eax
mov    %al,0xd(%rdx)
movzbl 0xc(%rdi),%eax
mov    %eax,%r10d
mov    %r9d,%ecx
shr    %cl,%r10d
mov    %r8d,%ecx
shl    %cl,%eax
or     %esi,%eax
mov    %al,0xc(%rdx)
movzbl 0xb(%rdi),%eax
mov    %eax,%esi
mov    %r9d,%ecx
shr    %cl,%esi
mov    %r8d,%ecx
shl    %cl,%eax
or     %r10d,%eax
mov    %al,0xb(%rdx)
movzbl 0xa(%rdi),%eax
mov    %eax,%r10d
mov    %r9d,%ecx
shr    %cl,%r10d
mov    %r8d,%ecx
shl    %cl,%eax
or     %esi,%eax
mov    %al,0xa(%rdx)
movzbl 0x9(%rdi),%eax
mov    %eax,%esi
mov    %r9d,%ecx
shr    %cl,%esi
mov    %r8d,%ecx
shl    %cl,%eax
or     %r10d,%eax
mov    %al,0x9(%rdx)
movzbl 0x8(%rdi),%eax
mov    %eax,%r10d
mov    %r9d,%ecx
shr    %cl,%r10d
mov    %r8d,%ecx
shl    %cl,%eax
or     %esi,%eax
mov    %al,0x8(%rdx)
movzbl 0x7(%rdi),%eax
mov    %eax,%esi
mov    %r9d,%ecx
shr    %cl,%esi
mov    %r8d,%ecx
shl    %cl,%eax
or     %r10d,%eax
mov    %al,0x7(%rdx)
movzbl 0x6(%rdi),%eax
mov    %eax,%r10d
mov    %r9d,%ecx
shr    %cl,%r10d
mov    %r8d,%ecx
shl    %cl,%eax
or     %esi,%eax
mov    %al,0x6(%rdx)
movzbl 0x5(%rdi),%eax
mov    %eax,%esi
mov    %r9d,%ecx
shr    %cl,%esi
mov    %r8d,%ecx
shl    %cl,%eax
or     %r10d,%eax
mov    %al,0x5(%rdx)
movzbl 0x4(%rdi),%eax
mov    %eax,%r10d
mov    %r9d,%ecx
shr    %cl,%r10d
mov    %r8d,%ecx
shl    %cl,%eax
or     %esi,%eax
mov    %al,0x4(%rdx)
movzbl 0x3(%rdi),%eax
mov    %eax,%esi
mov    %r9d,%ecx
shr    %cl,%esi
mov    %r8d,%ecx
shl    %cl,%eax
or     %r10d,%eax
mov    %al,0x3(%rdx)
movzbl 0x2(%rdi),%eax
mov    %eax,%r10d
mov    %r9d,%ecx
shr    %cl,%r10d
mov    %r8d,%ecx
shl    %cl,%eax
or     %esi,%eax
mov    %al,0x2(%rdx)
movzbl 0x1(%rdi),%eax
mov    %eax,%esi
mov    %r9d,%ecx
shr    %cl,%esi
mov    %r8d,%ecx
shl    %cl,%eax
or     %r10d,%eax
mov    %al,0x1(%rdx)
movzbl (%rdi),%eax
shl    %cl,%eax
or     %esi,%eax
mov    %al,(%rdx)
ret

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

LLVM IR (-O2):
define void @ocb_block_lshift(i8* nocapture %0, i64 %1, i8* nocapture writeonly %2) {
%4 = trunc i64 %1 to i32
%5 = sub i32 8, %4
%6 = getelementptr inbounds i8, i8* %0, i64 15
%7 = load i8, i8* %6
%8 = zext i8 %7 to i32
%9 = lshr i32 %8, %5
%10 = shl i32 %8, %4
%11 = trunc i32 %10 to i8
%12 = getelementptr inbounds i8, i8* %2, i64 15
store i8 %11, i8* %12
%13 = getelementptr inbounds i8, i8* %0, i64 14
%14 = load i8, i8* %13
%15 = zext i8 %14 to i32
%16 = lshr i32 %15, %5
%17 = shl i32 %15, %4
%18 = or i32 %17, %9
%19 = trunc i32 %18 to i8
%20 = getelementptr inbounds i8, i8* %2, i64 14
store i8 %19, i8* %20
%21 = getelementptr inbounds i8, i8* %0, i64 13
%22 = load i8, i8* %21
%23 = zext i8 %22 to i32
%24 = lshr i32 %23, %5
%25 = shl i32 %23, %4
%26 = or i32 %25, %16
%27 = trunc i32 %26 to i8
%28 = getelementptr inbounds i8, i8* %2, i64 13
store i8 %27, i8* %28
%29 = getelementptr inbounds i8, i8* %0, i64 12
%30 = load i8, i8* %29
%31 = zext i8 %30 to i32
%32 = lshr i32 %31, %5
%33 = shl i32 %31, %4
%34 = or i32 %33, %24
%35 = trunc i32 %34 to i8
%36 = getelementptr inbounds i8, i8* %2, i64 12
store i8 %35, i8* %36
%37 = getelementptr inbounds i8, i8* %0, i64 11
%38 = load i8, i8* %37
%39 = zext i8 %38 to i32
%40 = lshr i32 %39, %5
%41 = shl i32 %39, %4
%42 = or i32 %41, %32
%43 = trunc i32 %42 to i8
%44 = getelementptr inbounds i8, i8* %2, i64 11
store i8 %43, i8* %44
%45 = getelementptr inbounds i8, i8* %0, i64 10
%46 = load i8, i8* %45
%47 = zext i8 %46 to i32
%48 = lshr i32 %47, %5
%49 = shl i32 %47, %4
%50 = or i32 %49, %40
%51 = trunc i32 %50 to i8
%52 = getelementptr inbounds i8, i8* %2, i64 10
store i8 %51, i8* %52
%53 = getelementptr inbounds i8, i8* %0, i64 9
%54 = load i8, i8* %53
%55 = zext i8 %54 to i32
%56 = lshr i32 %55, %5
%57 = shl i32 %55, %4
%58 = or i32 %57, %48
%59 = trunc i32 %58 to i8
%60 = getelementptr inbounds i8, i8* %2, i64 9
store i8 %59, i8* %60
%61 = getelementptr inbounds i8, i8* %0, i64 8
%62 = load i8, i8* %61
%63 = zext i8 %62 to i32
%64 = lshr i32 %63, %5
%65 = shl i32 %63, %4
%66 = or i32 %65, %56
%67 = trunc i32 %66 to i8
%68 = getelementptr inbounds i8, i8* %2, i64 8
store i8 %67, i8* %68
%69 = getelementptr inbounds i8, i8* %0, i64 7
%70 = load i8, i8* %69
%71 = zext i8 %70 to i32
%72 = lshr i32 %71, %5
%73 = shl i32 %71, %4
%74 = or i32 %73, %64
%75 = trunc i32 %74 to i8
%76 = getelementptr inbounds i8, i8* %2, i64 7
store i8 %75, i8* %76
%77 = getelementptr inbounds i8, i8* %0, i64 6
%78 = load i8, i8* %77
%79 = zext i8 %78 to i32
%80 = lshr i32 %79, %5
%81 = shl i32 %79, %4
%82 = or i32 %81, %72
%83 = trunc i32 %82 to i8
%84 = getelementptr inbounds i8, i8* %2, i64 6
store i8 %83, i8* %84
%85 = getelementptr inbounds i8, i8* %0, i64 5
%86 = load i8, i8* %85
%87 = zext i8 %86 to i32
%88 = lshr i32 %87, %5
%89 = shl i32 %87, %4
%90 = or i32 %89, %80
%91 = trunc i32 %90 to i8
%92 = getelementptr inbounds i8, i8* %2, i64 5
store i8 %91, i8* %92
%93 = getelementptr inbounds i8, i8* %0, i64 4
%94 = load i8, i8* %93
%95 = zext i8 %94 to i32
%96 = lshr i32 %95, %5
%97 = shl i32 %95, %4
%98 = or i32 %97, %88
%99 = trunc i32 %98 to i8
%100 = getelementptr inbounds i8, i8* %2, i64 4
store i8 %99, i8* %100
%101 = getelementptr inbounds i8, i8* %0, i64 3
%102 = load i8, i8* %101
%103 = zext i8 %102 to i32
%104 = lshr i32 %103, %5
%105 = shl i32 %103, %4
%106 = or i32 %105, %96
%107 = trunc i32 %106 to i8
%108 = getelementptr inbounds i8, i8* %2, i64 3
store i8 %107, i8* %108
%109 = getelementptr inbounds i8, i8* %0, i64 2
%110 = load i8, i8* %109
%111 = zext i8 %110 to i32
%112 = lshr i32 %111, %5
%113 = shl i32 %111, %4
%114 = or i32 %113, %104
%115 = trunc i32 %114 to i8
%116 = getelementptr inbounds i8, i8* %2, i64 2
store i8 %115, i8* %116
%117 = getelementptr inbounds i8, i8* %0, i64 1
%118 = load i8, i8* %117
%119 = zext i8 %118 to i32
%120 = lshr i32 %119, %5
%121 = shl i32 %119, %4
%122 = or i32 %121, %112
%123 = trunc i32 %122 to i8
%124 = getelementptr inbounds i8, i8* %2, i64 1
store i8 %123, i8* %124
%125 = load i8, i8* %0
%126 = zext i8 %125 to i32
%127 = shl i32 %126, %4
%128 = or i32 %127, %120
%129 = trunc i32 %128 to i8
store i8 %129, i8* %2
ret void
}