#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 long long int64_t;

/* Variables and functions */
int rle_enc1(uint8_t *p, int c, int64_t l) {
  if (l < 1LL << 4) {
    *p = l << 3 | c;
    return 1;
  } else if (l < 1LL << 8) {
    *p = 0xC0 | l >> 6 << 3 | c;
    p[1] = 0x80 | (l & 0x3f);
    return 2;
  } else if (l < 1LL << 19) {
    *p = 0xE0 | l >> 18 << 3 | c;
    p[1] = 0x80 | (l >> 12 & 0x3f);
    p[2] = 0x80 | (l >> 6 & 0x3f);
    p[3] = 0x80 | (l & 0x3f);
    return 4;
  } else {
    int i, shift = 36;
    *p = 0xF0 | l >> 42 << 3 | c;
    for (i = 1; i < 8; ++i, shift -= 6)
      p[i] = 0x80 | (l >> shift & 0x3f);
    return 8;
  }
}


x86 assembly (clang, -O0):
<rle_enc1>:
push   %rbp
mov    %rsp,%rbp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
cmpq   $0x10,-0x20(%rbp)
jge    113d <rle_enc1+0x3d>
mov    -0x20(%rbp),%rax
shl    $0x3,%rax
movslq -0x14(%rbp),%rcx
or     %rcx,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
movl   $0x1,-0x4(%rbp)
jmp    128f <rle_enc1+0x18f>
cmpq   $0x100,-0x20(%rbp)
jge    118f <rle_enc1+0x8f>
mov    -0x20(%rbp),%rax
sar    $0x6,%rax
shl    $0x3,%rax
or     $0xc0,%rax
movslq -0x14(%rbp),%rcx
or     %rcx,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0x4(%rax)
movl   $0x2,-0x4(%rbp)
jmp    128f <rle_enc1+0x18f>
cmpq   $0x80000,-0x20(%rbp)
jge    1217 <rle_enc1+0x117>
mov    -0x20(%rbp),%rax
sar    $0x12,%rax
shl    $0x3,%rax
or     $0xe0,%rax
movslq -0x14(%rbp),%rcx
or     %rcx,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
sar    $0xc,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0x4(%rax)
mov    -0x20(%rbp),%rax
sar    $0x6,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0x8(%rax)
mov    -0x20(%rbp),%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,0xc(%rax)
movl   $0x4,-0x4(%rbp)
jmp    128f <rle_enc1+0x18f>
movl   $0x24,-0x28(%rbp)
mov    -0x20(%rbp),%rax
sar    $0x2a,%rax
shl    $0x3,%rax
or     $0xf0,%rax
movslq -0x14(%rbp),%rcx
or     %rcx,%rax
mov    %eax,%ecx
mov    -0x10(%rbp),%rax
mov    %ecx,(%rax)
movl   $0x1,-0x24(%rbp)
cmpl   $0x8,-0x24(%rbp)
jge    1288 <rle_enc1+0x188>
mov    -0x20(%rbp),%rax
mov    -0x28(%rbp),%ecx
sar    %cl,%rax
and    $0x3f,%rax
or     $0x80,%rax
mov    %eax,%edx
mov    -0x10(%rbp),%rax
movslq -0x24(%rbp),%rcx
mov    %edx,(%rax,%rcx,4)
mov    -0x24(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x24(%rbp)
mov    -0x28(%rbp),%eax
sub    $0x6,%eax
mov    %eax,-0x28(%rbp)
jmp    1246 <rle_enc1+0x146>
movl   $0x8,-0x4(%rbp)
mov    -0x4(%rbp),%eax
pop    %rbp
ret

x86 assembly (clang, -O2):
<rle_enc1>:
cmp    $0xf,%rdx
jg     1113 <rle_enc1+0x13>
shl    $0x3,%edx
or     %esi,%edx
mov    %edx,(%rdi)
mov    $0x1,%eax
ret
mov    %rdx,%rax
cmp    $0xff,%rdx
ja     1143 <rle_enc1+0x43>
shr    $0x3,%rax
and    $0xffffff38,%eax
or     %esi,%eax
or     $0xc0,%eax
mov    %eax,(%rdi)
and    $0x3f,%edx
or     $0x80,%edx
mov    %edx,0x4(%rdi)
mov    $0x2,%eax
ret
cmp    $0x7ffff,%rdx
ja     1190 <rle_enc1+0x90>
shr    $0xf,%rax
and    $0xffffff18,%eax
or     %esi,%eax
or     $0xe0,%eax
mov    %eax,(%rdi)
mov    %edx,%eax
shr    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %eax,0x4(%rdi)
mov    %edx,%eax
shr    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %eax,0x8(%rdi)
and    $0x3f,%edx
or     $0x80,%edx
mov    %edx,0xc(%rdi)
mov    $0x4,%eax
ret
shr    $0x27,%rax
and    $0x1ffff08,%eax
or     %esi,%eax
or     $0xf0,%eax
movq   %rdx,%xmm0
pshufd $0x44,%xmm0,%xmm1
psrlq  $0x24,%xmm0
psrlq  $0x1e,%xmm1
movsd  %xmm0,%xmm1
mov    %edx,%ecx
shr    $0x18,%ecx
movd   %ecx,%xmm0
mov    %edx,%ecx
shr    $0x12,%ecx
movd   %ecx,%xmm2
punpcklqdq %xmm0,%xmm2
shufps $0x28,%xmm2,%xmm1
andps  0xe27(%rip),%xmm1
mov    %eax,(%rdi)
orps   0xe2e(%rip),%xmm1
movups %xmm1,0x4(%rdi)
mov    %edx,%eax
shr    $0xc,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %eax,0x14(%rdi)
mov    %edx,%eax
shr    $0x6,%eax
and    $0x3f,%eax
or     $0x80,%eax
mov    %eax,0x18(%rdi)
and    $0x3f,%edx
or     $0x80,%edx
mov    %edx,0x1c(%rdi)
mov    $0x8,%eax
ret

LLVM IR (-O0):
define i32 @rle_enc1(i32* %0, i32 %1, i64 %2) {
%4 = alloca i32
%5 = alloca i32*
%6 = alloca i32
%7 = alloca i64
%8 = alloca i32
%9 = alloca i32
store i32* %0, i32** %5
store i32 %1, i32* %6
store i64 %2, i64* %7
%10 = load i64, i64* %7
%11 = icmp slt i64 %10, 16
br i1 %11, label %12, label %20
12: ; preds = %3
%13 = load i64, i64* %7
%14 = shl i64 %13, 3
%15 = load i32, i32* %6
%16 = sext i32 %15 to i64
%17 = or i64 %14, %16
%18 = trunc i64 %17 to i32
%19 = load i32*, i32** %5
store i32 %18, i32* %19
store i32 1, i32* %4
br label %103
20: ; preds = %3
%21 = load i64, i64* %7
%22 = icmp slt i64 %21, 256
br i1 %22, label %23, label %39
23: ; preds = %20
%24 = load i64, i64* %7
%25 = ashr i64 %24, 6
%26 = shl i64 %25, 3
%27 = or i64 192, %26
%28 = load i32, i32* %6
%29 = sext i32 %28 to i64
%30 = or i64 %27, %29
%31 = trunc i64 %30 to i32
%32 = load i32*, i32** %5
store i32 %31, i32* %32
%33 = load i64, i64* %7
%34 = and i64 %33, 63
%35 = or i64 128, %34
%36 = trunc i64 %35 to i32
%37 = load i32*, i32** %5
%38 = getelementptr inbounds i32, i32* %37, i64 1
store i32 %36, i32* %38
store i32 2, i32* %4
br label %103
39: ; preds = %20
%40 = load i64, i64* %7
%41 = icmp slt i64 %40, 524288
br i1 %41, label %42, label %72
42: ; preds = %39
%43 = load i64, i64* %7
%44 = ashr i64 %43, 18
%45 = shl i64 %44, 3
%46 = or i64 224, %45
%47 = load i32, i32* %6
%48 = sext i32 %47 to i64
%49 = or i64 %46, %48
%50 = trunc i64 %49 to i32
%51 = load i32*, i32** %5
store i32 %50, i32* %51
%52 = load i64, i64* %7
%53 = ashr i64 %52, 12
%54 = and i64 %53, 63
%55 = or i64 128, %54
%56 = trunc i64 %55 to i32
%57 = load i32*, i32** %5
%58 = getelementptr inbounds i32, i32* %57, i64 1
store i32 %56, i32* %58
%59 = load i64, i64* %7
%60 = ashr i64 %59, 6
%61 = and i64 %60, 63
%62 = or i64 128, %61
%63 = trunc i64 %62 to i32
%64 = load i32*, i32** %5
%65 = getelementptr inbounds i32, i32* %64, i64 2
store i32 %63, i32* %65
%66 = load i64, i64* %7
%67 = and i64 %66, 63
%68 = or i64 128, %67
%69 = trunc i64 %68 to i32
%70 = load i32*, i32** %5
%71 = getelementptr inbounds i32, i32* %70, i64 3
store i32 %69, i32* %71
store i32 4, i32* %4
br label %103
72: ; preds = %39
store i32 36, i32* %9
%73 = load i64, i64* %7
%74 = ashr i64 %73, 42
%75 = shl i64 %74, 3
%76 = or i64 240, %75
%77 = load i32, i32* %6
%78 = sext i32 %77 to i64
%79 = or i64 %76, %78
%80 = trunc i64 %79 to i32
%81 = load i32*, i32** %5
store i32 %80, i32* %81
store i32 1, i32* %8
br label %82
82: ; preds = %97, %72
%83 = load i32, i32* %8
%84 = icmp slt i32 %83, 8
br i1 %84, label %85, label %102
85: ; preds = %82
%86 = load i64, i64* %7
%87 = load i32, i32* %9
%88 = zext i32 %87 to i64
%89 = ashr i64 %86, %88
%90 = and i64 %89, 63
%91 = or i64 128, %90
%92 = trunc i64 %91 to i32
%93 = load i32*, i32** %5
%94 = load i32, i32* %8
%95 = sext i32 %94 to i64
%96 = getelementptr inbounds i32, i32* %93, i64 %95
store i32 %92, i32* %96
br label %97
97: ; preds = %85
%98 = load i32, i32* %8
%99 = add nsw i32 %98, 1
store i32 %99, i32* %8
%100 = load i32, i32* %9
%101 = sub nsw i32 %100, 6
store i32 %101, i32* %9
br label %82
102: ; preds = %82
store i32 8, i32* %4
br label %103
103: ; preds = %102, %42, %23, %12
%104 = load i32, i32* %4
ret i32 %104
}

LLVM IR (-O2):
define i32 @rle_enc1(i32* nocapture writeonly %0, i32 %1, i64 %2) {
%4 = icmp slt i64 %2, 16
br i1 %4, label %5, label %9
5: ; preds = %3
%6 = trunc i64 %2 to i32
%7 = shl i32 %6, 3
%8 = or i32 %7, %1
store i32 %8, i32* %0
br label %76
9: ; preds = %3
%10 = icmp ult i64 %2, 256
br i1 %10, label %11, label %21
11: ; preds = %9
%12 = lshr i64 %2, 3
%13 = trunc i64 %12 to i32
%14 = and i32 %13, -200
%15 = or i32 %14, %1
%16 = or i32 %15, 192
store i32 %16, i32* %0
%17 = trunc i64 %2 to i32
%18 = and i32 %17, 63
%19 = or i32 %18, 128
%20 = getelementptr inbounds i32, i32* %0, i64 1
store i32 %19, i32* %20
br label %76
21: ; preds = %9
%22 = icmp ult i64 %2, 524288
br i1 %22, label %23, label %41
23: ; preds = %21
%24 = lshr i64 %2, 15
%25 = trunc i64 %24 to i32
%26 = and i32 %25, -232
%27 = or i32 %26, %1
%28 = or i32 %27, 224
store i32 %28, i32* %0
%29 = trunc i64 %2 to i32
%30 = lshr i32 %29, 12
%31 = and i32 %30, 63
%32 = or i32 %31, 128
%33 = getelementptr inbounds i32, i32* %0, i64 1
store i32 %32, i32* %33
%34 = lshr i32 %29, 6
%35 = and i32 %34, 63
%36 = or i32 %35, 128
%37 = getelementptr inbounds i32, i32* %0, i64 2
store i32 %36, i32* %37
%38 = and i32 %29, 63
%39 = or i32 %38, 128
%40 = getelementptr inbounds i32, i32* %0, i64 3
store i32 %39, i32* %40
br label %76
41: ; preds = %21
%42 = lshr i64 %2, 39
%43 = trunc i64 %42 to i32
%44 = and i32 %43, 33554184
%45 = or i32 %44, %1
%46 = or i32 %45, 240
store i32 %46, i32* %0
%47 = getelementptr inbounds i32, i32* %0, i64 1
%48 = insertelement <2 x i64> poison, i64 %2, i64 0
%49 = shufflevector <2 x i64> %48, <2 x i64> poison, <2 x i32> zeroinitializer
%50 = lshr <2 x i64> %49, <i64 36, i64 30>
%51 = trunc <2 x i64> %50 to <2 x i32>
%52 = trunc i64 %2 to i32
%53 = lshr i32 %52, 24
%54 = trunc i64 %2 to i32
%55 = lshr i32 %54, 18
%56 = shufflevector <2 x i32> %51, <2 x i32> poison, <4 x i32> <i32 0, i32 1, i32 undef, i32 undef>
%57 = insertelement <4 x i32> %56, i32 %53, i64 2
%58 = insertelement <4 x i32> %57, i32 %55, i64 3
%59 = and <4 x i32> %58, <i32 63, i32 63, i32 63, i32 63>
%60 = or <4 x i32> %59, <i32 128, i32 128, i32 128, i32 128>
%61 = bitcast i32* %47 to <4 x i32>*
store <4 x i32> %60, <4 x i32>* %61
%62 = trunc i64 %2 to i32
%63 = lshr i32 %62, 12
%64 = and i32 %63, 63
%65 = or i32 %64, 128
%66 = getelementptr inbounds i32, i32* %0, i64 5
store i32 %65, i32* %66
%67 = trunc i64 %2 to i32
%68 = lshr i32 %67, 6
%69 = and i32 %68, 63
%70 = or i32 %69, 128
%71 = getelementptr inbounds i32, i32* %0, i64 6
store i32 %70, i32* %71
%72 = trunc i64 %2 to i32
%73 = and i32 %72, 63
%74 = or i32 %73, 128
%75 = getelementptr inbounds i32, i32* %0, i64 7
store i32 %74, i32* %75
br label %76
76: ; preds = %41, %23, %11, %5
%77 = phi i32 [ 1, %5 ], [ 2, %11 ], [ 4, %23 ], [ 8, %41 ]
ret i32 %77
}