#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 */
int /*<<< orphan*/ Init_Decrunchers();
int /*<<< orphan*/ Unpack_DEEP(unsigned char *, unsigned char *,
                               unsigned short);
int /*<<< orphan*/ Unpack_HEAVY(unsigned char *, unsigned char *, unsigned char,
                                unsigned short);
int /*<<< orphan*/ Unpack_MEDIUM(unsigned char *, unsigned char *,
                                 unsigned short);
int /*<<< orphan*/ Unpack_QUICK(unsigned char *, unsigned char *,
                                unsigned short);
int /*<<< orphan*/ Unpack_RLE(unsigned char *, unsigned char *, unsigned short);
int /*<<< orphan*/ memcpy(unsigned char *, unsigned char *, size_t);
unsigned short Unpack_Track(unsigned char *b1, unsigned char *b2,
                            unsigned short pklen2, unsigned short unpklen,
                            unsigned char cmode, unsigned char flags) {
  switch (cmode) {
  case 0:
    memcpy(b2, b1, (size_t)unpklen);
    break;
  case 1:
    if (Unpack_RLE(b1, b2, unpklen))
      return 14;
    break;
  case 2:
    if (Unpack_QUICK(b1, b2, pklen2))
      return 14;
    if (Unpack_RLE(b2, b1, unpklen))
      return 14;
    memcpy(b2, b1, (size_t)unpklen);
    break;
  case 3:
    if (Unpack_MEDIUM(b1, b2, pklen2))
      return 14;
    if (Unpack_RLE(b2, b1, unpklen))
      return 14;
    memcpy(b2, b1, (size_t)unpklen);
    break;
  case 4:
    if (Unpack_DEEP(b1, b2, pklen2))
      return 14;
    if (Unpack_RLE(b2, b1, unpklen))
      return 14;
    memcpy(b2, b1, (size_t)unpklen);
    break;
  case 5:
  case 6:
    if (cmode == 5) {
      if (Unpack_HEAVY(b1, b2, (unsigned char)(flags & 7), pklen2))
        return 14;
    } else {
      if (Unpack_HEAVY(b1, b2, (unsigned char)(flags | (unsigned char)8),
                       pklen2))
        return 14;
    }
    if (flags & 4) {
      if (Unpack_RLE(b2, b1, unpklen))
        return 14;
      memcpy(b2, b1, (size_t)unpklen);
    }
    break;
  default:
    return 15;
  }
  if (!(flags & 1))
    Init_Decrunchers();
  return 0;
}


x86 assembly (clang, -O0):
<Unpack_Track>:
push   %rbp
mov    %rsp,%rbp
sub    $0x40,%rsp
mov    %r8d,-0x3c(%rbp)
mov    %ecx,%eax
mov    -0x3c(%rbp),%ecx
mov    %eax,-0x38(%rbp)
mov    %edx,%eax
mov    -0x38(%rbp),%edx
mov    %eax,-0x34(%rbp)
mov    %rsi,%rax
mov    -0x34(%rbp),%esi
mov    %rax,-0x30(%rbp)
mov    %rdi,%r8
mov    -0x30(%rbp),%rdi
mov    %r9b,%al
mov    %r8,-0x10(%rbp)
mov    %rdi,-0x18(%rbp)
mov    %si,-0x1a(%rbp)
mov    %dx,-0x1c(%rbp)
mov    %cl,-0x1d(%rbp)
mov    %al,-0x1e(%rbp)
movzbl -0x1d(%rbp),%eax
mov    %rax,-0x28(%rbp)
sub    $0x6,%rax
ja     1406 <Unpack_Track+0x296>
mov    -0x28(%rbp),%rax
lea    0xe2d(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%eax
mov    %eax,%edx
call   1070 <memcpy@plt>
jmp    1411 <Unpack_Track+0x2a1>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
movzwl -0x1c(%rbp),%edx
call   1080 <Unpack_RLE@plt>
cmp    $0x0,%eax
je     1219 <Unpack_Track+0xa9>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
jmp    1411 <Unpack_Track+0x2a1>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
movzwl -0x1a(%rbp),%edx
call   1060 <Unpack_QUICK@plt>
cmp    $0x0,%eax
je     1243 <Unpack_Track+0xd3>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%edx
call   1080 <Unpack_RLE@plt>
cmp    $0x0,%eax
je     1268 <Unpack_Track+0xf8>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%eax
mov    %eax,%edx
call   1070 <memcpy@plt>
jmp    1411 <Unpack_Track+0x2a1>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
movzwl -0x1a(%rbp),%edx
call   1030 <Unpack_MEDIUM@plt>
cmp    $0x0,%eax
je     12a5 <Unpack_Track+0x135>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%edx
call   1080 <Unpack_RLE@plt>
cmp    $0x0,%eax
je     12ca <Unpack_Track+0x15a>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%eax
mov    %eax,%edx
call   1070 <memcpy@plt>
jmp    1411 <Unpack_Track+0x2a1>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
movzwl -0x1a(%rbp),%edx
call   1040 <Unpack_DEEP@plt>
cmp    $0x0,%eax
je     1307 <Unpack_Track+0x197>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%edx
call   1080 <Unpack_RLE@plt>
cmp    $0x0,%eax
je     132c <Unpack_Track+0x1bc>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%eax
mov    %eax,%edx
call   1070 <memcpy@plt>
jmp    1411 <Unpack_Track+0x2a1>
movzbl -0x1d(%rbp),%eax
cmp    $0x5,%eax
jne    1385 <Unpack_Track+0x215>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
movzbl -0x1e(%rbp),%eax
and    $0x7,%eax
movzbl %al,%edx
movzwl -0x1a(%rbp),%ecx
call   1090 <Unpack_HEAVY@plt>
cmp    $0x0,%eax
je     1380 <Unpack_Track+0x210>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
jmp    13b9 <Unpack_Track+0x249>
mov    -0x10(%rbp),%rdi
mov    -0x18(%rbp),%rsi
movzbl -0x1e(%rbp),%eax
or     $0x8,%eax
movzbl %al,%edx
movzwl -0x1a(%rbp),%ecx
call   1090 <Unpack_HEAVY@plt>
cmp    $0x0,%eax
je     13b4 <Unpack_Track+0x244>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
jmp    13b9 <Unpack_Track+0x249>
movzbl -0x1e(%rbp),%eax
and    $0x4,%eax
cmp    $0x0,%eax
je     1401 <Unpack_Track+0x291>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%edx
call   1080 <Unpack_RLE@plt>
cmp    $0x0,%eax
je     13ee <Unpack_Track+0x27e>
movw   $0xe,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
mov    -0x18(%rbp),%rdi
mov    -0x10(%rbp),%rsi
movzwl -0x1c(%rbp),%eax
mov    %eax,%edx
call   1070 <memcpy@plt>
jmp    1411 <Unpack_Track+0x2a1>
movw   $0xf,-0x2(%rbp)
jmp    142e <Unpack_Track+0x2be>
movzbl -0x1e(%rbp),%eax
and    $0x1,%eax
cmp    $0x0,%eax
jne    1428 <Unpack_Track+0x2b8>
mov    $0x0,%al
call   1050 <Init_Decrunchers@plt>
movw   $0x0,-0x2(%rbp)
movzwl -0x2(%rbp),%eax
add    $0x40,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<Unpack_Track>:
push   %rbp
push   %r15
push   %r14
push   %r12
push   %rbx
cmp    $0x6,%r8b
ja     11bd <Unpack_Track+0x4d>
mov    %r9d,%r14d
mov    %ecx,%r15d
mov    %rsi,%r12
mov    %rdi,%rbp
mov    %r8d,%eax
lea    0xe6c(%rip),%rcx
movslq (%rcx,%rax,4),%rax
add    %rcx,%rax
jmp    *%rax
movzwl %r15w,%edx
mov    %rbp,%rdi
mov    %r12,%rsi
call   1080 <Unpack_RLE@plt>
mov    $0xe,%bx
test   %eax,%eax
jne    1271 <Unpack_Track+0x101>
jmp    1262 <Unpack_Track+0xf2>
mov    $0xf,%bx
jmp    1271 <Unpack_Track+0x101>
movzwl %dx,%edx
mov    %rbp,%rdi
mov    %r12,%rsi
call   1060 <Unpack_QUICK@plt>
jmp    11f4 <Unpack_Track+0x84>
movzwl %dx,%edx
mov    %rbp,%rdi
mov    %r12,%rsi
call   1030 <Unpack_MEDIUM@plt>
jmp    11f4 <Unpack_Track+0x84>
movzwl %dx,%edx
mov    %rbp,%rdi
mov    %r12,%rsi
call   1040 <Unpack_DEEP@plt>
mov    $0xe,%bx
test   %eax,%eax
jne    1271 <Unpack_Track+0x101>
movzwl %r15w,%edx
mov    %r12,%rdi
mov    %rbp,%rsi
call   1080 <Unpack_RLE@plt>
test   %eax,%eax
jne    1271 <Unpack_Track+0x101>
jmp    1253 <Unpack_Track+0xe3>
mov    %r14d,%eax
and    $0x7,%al
jmp    121d <Unpack_Track+0xad>
mov    %r14d,%eax
or     $0x8,%al
movzwl %dx,%ecx
movzbl %al,%edx
mov    %rbp,%rdi
mov    %r12,%rsi
call   1090 <Unpack_HEAVY@plt>
mov    $0xe,%bx
test   %eax,%eax
jne    1271 <Unpack_Track+0x101>
test   $0x4,%r14b
je     1262 <Unpack_Track+0xf2>
movzwl %r15w,%edx
mov    %r12,%rdi
mov    %rbp,%rsi
call   1080 <Unpack_RLE@plt>
mov    $0xe,%bx
test   %eax,%eax
jne    1271 <Unpack_Track+0x101>
movzwl %r15w,%edx
mov    %r12,%rdi
mov    %rbp,%rsi
call   1070 <memcpy@plt>
xor    %ebx,%ebx
test   $0x1,%r14b
jne    1271 <Unpack_Track+0x101>
xor    %eax,%eax
call   1050 <Init_Decrunchers@plt>
mov    %ebx,%eax
pop    %rbx
pop    %r12
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
define zeroext i16 @Unpack_Track(i8* %0, i8* %1, i16 zeroext %2, i16 zeroext %3, i8 zeroext %4, i8 zeroext %5) {
%7 = alloca i16
%8 = alloca i8*
%9 = alloca i8*
%10 = alloca i16
%11 = alloca i16
%12 = alloca i8
%13 = alloca i8
store i8* %0, i8** %8
store i8* %1, i8** %9
store i16 %2, i16* %10
store i16 %3, i16* %11
store i8 %4, i8* %12
store i8 %5, i8* %13
%14 = load i8, i8* %12
%15 = zext i8 %14 to i32
switch i32 %15, label %137 [
i32 0, label %16
i32 1, label %22
i32 2, label %30
i32 3, label %50
i32 4, label %70
i32 5, label %90
i32 6, label %90
]
16: ; preds = %6
%17 = load i8*, i8** %9
%18 = load i8*, i8** %8
%19 = load i16, i16* %11
%20 = zext i16 %19 to i64
%21 = call i32 @memcpy(i8* %17, i8* %18, i64 %20)
br label %138
22: ; preds = %6
%23 = load i8*, i8** %8
%24 = load i8*, i8** %9
%25 = load i16, i16* %11
%26 = call i32 @Unpack_RLE(i8* %23, i8* %24, i16 zeroext %25)
%27 = icmp ne i32 %26, 0
br i1 %27, label %28, label %29
28: ; preds = %22
store i16 14, i16* %7
br label %146
29: ; preds = %22
br label %138
30: ; preds = %6
%31 = load i8*, i8** %8
%32 = load i8*, i8** %9
%33 = load i16, i16* %10
%34 = call i32 @Unpack_QUICK(i8* %31, i8* %32, i16 zeroext %33)
%35 = icmp ne i32 %34, 0
br i1 %35, label %36, label %37
36: ; preds = %30
store i16 14, i16* %7
br label %146
37: ; preds = %30
%38 = load i8*, i8** %9
%39 = load i8*, i8** %8
%40 = load i16, i16* %11
%41 = call i32 @Unpack_RLE(i8* %38, i8* %39, i16 zeroext %40)
%42 = icmp ne i32 %41, 0
br i1 %42, label %43, label %44
43: ; preds = %37
store i16 14, i16* %7
br label %146
44: ; preds = %37
%45 = load i8*, i8** %9
%46 = load i8*, i8** %8
%47 = load i16, i16* %11
%48 = zext i16 %47 to i64
%49 = call i32 @memcpy(i8* %45, i8* %46, i64 %48)
br label %138
50: ; preds = %6
%51 = load i8*, i8** %8
%52 = load i8*, i8** %9
%53 = load i16, i16* %10
%54 = call i32 @Unpack_MEDIUM(i8* %51, i8* %52, i16 zeroext %53)
%55 = icmp ne i32 %54, 0
br i1 %55, label %56, label %57
56: ; preds = %50
store i16 14, i16* %7
br label %146
57: ; preds = %50
%58 = load i8*, i8** %9
%59 = load i8*, i8** %8
%60 = load i16, i16* %11
%61 = call i32 @Unpack_RLE(i8* %58, i8* %59, i16 zeroext %60)
%62 = icmp ne i32 %61, 0
br i1 %62, label %63, label %64
63: ; preds = %57
store i16 14, i16* %7
br label %146
64: ; preds = %57
%65 = load i8*, i8** %9
%66 = load i8*, i8** %8
%67 = load i16, i16* %11
%68 = zext i16 %67 to i64
%69 = call i32 @memcpy(i8* %65, i8* %66, i64 %68)
br label %138
70: ; preds = %6
%71 = load i8*, i8** %8
%72 = load i8*, i8** %9
%73 = load i16, i16* %10
%74 = call i32 @Unpack_DEEP(i8* %71, i8* %72, i16 zeroext %73)
%75 = icmp ne i32 %74, 0
br i1 %75, label %76, label %77
76: ; preds = %70
store i16 14, i16* %7
br label %146
77: ; preds = %70
%78 = load i8*, i8** %9
%79 = load i8*, i8** %8
%80 = load i16, i16* %11
%81 = call i32 @Unpack_RLE(i8* %78, i8* %79, i16 zeroext %80)
%82 = icmp ne i32 %81, 0
br i1 %82, label %83, label %84
83: ; preds = %77
store i16 14, i16* %7
br label %146
84: ; preds = %77
%85 = load i8*, i8** %9
%86 = load i8*, i8** %8
%87 = load i16, i16* %11
%88 = zext i16 %87 to i64
%89 = call i32 @memcpy(i8* %85, i8* %86, i64 %88)
br label %138
90: ; preds = %6, %6
%91 = load i8, i8* %12
%92 = zext i8 %91 to i32
%93 = icmp eq i32 %92, 5
br i1 %93, label %94, label %106
94: ; preds = %90
%95 = load i8*, i8** %8
%96 = load i8*, i8** %9
%97 = load i8, i8* %13
%98 = zext i8 %97 to i32
%99 = and i32 %98, 7
%100 = trunc i32 %99 to i8
%101 = load i16, i16* %10
%102 = call i32 @Unpack_HEAVY(i8* %95, i8* %96, i8 zeroext %100, i16 zeroext %101)
%103 = icmp ne i32 %102, 0
br i1 %103, label %104, label %105
104: ; preds = %94
store i16 14, i16* %7
br label %146
105: ; preds = %94
br label %118
106: ; preds = %90
%107 = load i8*, i8** %8
%108 = load i8*, i8** %9
%109 = load i8, i8* %13
%110 = zext i8 %109 to i32
%111 = or i32 %110, 8
%112 = trunc i32 %111 to i8
%113 = load i16, i16* %10
%114 = call i32 @Unpack_HEAVY(i8* %107, i8* %108, i8 zeroext %112, i16 zeroext %113)
%115 = icmp ne i32 %114, 0
br i1 %115, label %116, label %117
116: ; preds = %106
store i16 14, i16* %7
br label %146
117: ; preds = %106
br label %118
118: ; preds = %117, %105
%119 = load i8, i8* %13
%120 = zext i8 %119 to i32
%121 = and i32 %120, 4
%122 = icmp ne i32 %121, 0
br i1 %122, label %123, label %136
123: ; preds = %118
%124 = load i8*, i8** %9
%125 = load i8*, i8** %8
%126 = load i16, i16* %11
%127 = call i32 @Unpack_RLE(i8* %124, i8* %125, i16 zeroext %126)
%128 = icmp ne i32 %127, 0
br i1 %128, label %129, label %130
129: ; preds = %123
store i16 14, i16* %7
br label %146
130: ; preds = %123
%131 = load i8*, i8** %9
%132 = load i8*, i8** %8
%133 = load i16, i16* %11
%134 = zext i16 %133 to i64
%135 = call i32 @memcpy(i8* %131, i8* %132, i64 %134)
br label %136
136: ; preds = %130, %118
br label %138
137: ; preds = %6
store i16 15, i16* %7
br label %146
138: ; preds = %136, %84, %64, %44, %29, %16
%139 = load i8, i8* %13
%140 = zext i8 %139 to i32
%141 = and i32 %140, 1
%142 = icmp ne i32 %141, 0
br i1 %142, label %145, label %143
143: ; preds = %138
%144 = call i32 (...) @Init_Decrunchers()
br label %145
145: ; preds = %143, %138
store i16 0, i16* %7
br label %146
146: ; preds = %145, %137, %129, %116, %104, %83, %76, %63, %56, %43, %36, %28
%147 = load i16, i16* %7
ret i16 %147
}

LLVM IR (-O2):
define zeroext i16 @Unpack_Track(i8* %0, i8* %1, i16 zeroext %2, i16 zeroext %3, i8 zeroext %4, i8 zeroext %5) {
switch i8 %4, label %50 [
i8 0, label %42
i8 1, label %7
i8 2, label %10
i8 3, label %16
i8 4, label %22
i8 5, label %28
i8 6, label %32
]
7: ; preds = %6
%8 = tail call i32 @Unpack_RLE(i8* %0, i8* %1, i16 zeroext %3)
%9 = icmp eq i32 %8, 0
br i1 %9, label %45, label %50
10: ; preds = %6
%11 = tail call i32 @Unpack_QUICK(i8* %0, i8* %1, i16 zeroext %2)
%12 = icmp eq i32 %11, 0
br i1 %12, label %13, label %50
13: ; preds = %10
%14 = tail call i32 @Unpack_RLE(i8* %1, i8* %0, i16 zeroext %3)
%15 = icmp eq i32 %14, 0
br i1 %15, label %42, label %50
16: ; preds = %6
%17 = tail call i32 @Unpack_MEDIUM(i8* %0, i8* %1, i16 zeroext %2)
%18 = icmp eq i32 %17, 0
br i1 %18, label %19, label %50
19: ; preds = %16
%20 = tail call i32 @Unpack_RLE(i8* %1, i8* %0, i16 zeroext %3)
%21 = icmp eq i32 %20, 0
br i1 %21, label %42, label %50
22: ; preds = %6
%23 = tail call i32 @Unpack_DEEP(i8* %0, i8* %1, i16 zeroext %2)
%24 = icmp eq i32 %23, 0
br i1 %24, label %25, label %50
25: ; preds = %22
%26 = tail call i32 @Unpack_RLE(i8* %1, i8* %0, i16 zeroext %3)
%27 = icmp eq i32 %26, 0
br i1 %27, label %42, label %50
28: ; preds = %6
%29 = and i8 %5, 7
%30 = tail call i32 @Unpack_HEAVY(i8* %0, i8* %1, i8 zeroext %29, i16 zeroext %2)
%31 = icmp eq i32 %30, 0
br i1 %31, label %36, label %50
32: ; preds = %6
%33 = or i8 %5, 8
%34 = tail call i32 @Unpack_HEAVY(i8* %0, i8* %1, i8 zeroext %33, i16 zeroext %2)
%35 = icmp eq i32 %34, 0
br i1 %35, label %36, label %50
36: ; preds = %32, %28
%37 = and i8 %5, 4
%38 = icmp eq i8 %37, 0
br i1 %38, label %45, label %39
39: ; preds = %36
%40 = tail call i32 @Unpack_RLE(i8* %1, i8* %0, i16 zeroext %3)
%41 = icmp eq i32 %40, 0
br i1 %41, label %42, label %50
42: ; preds = %39, %25, %19, %13, %6
%43 = zext i16 %3 to i64
%44 = tail call i32 @memcpy(i8* %1, i8* %0, i64 %43)
br label %45
45: ; preds = %42, %36, %7
%46 = and i8 %5, 1
%47 = icmp eq i8 %46, 0
br i1 %47, label %48, label %50
48: ; preds = %45
%49 = tail call i32 (...) @Init_Decrunchers()
br label %50
50: ; preds = %45, %48, %6, %39, %32, %28, %25, %22, %19, %16, %13, %10, %7
%51 = phi i16 [ 14, %7 ], [ 14, %10 ], [ 14, %13 ], [ 14, %16 ], [ 14, %19 ], [ 14, %22 ], [ 14, %25 ], [ 14, %28 ], [ 14, %32 ], [ 14, %39 ], [ 15, %6 ], [ 0, %48 ], [ 0, %45 ]
ret i16 %51
}