#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*/ memcmp(unsigned char *, char *, int);
unsigned char *realloc(unsigned char *, int);
int sega_lzs2(unsigned char *src, int insz, unsigned char **ret_out,
              int *ret_outsz) {
  static unsigned char decBuffer[0x1000];
  unsigned char *o;
  int claimed_decompSize, claimed_compSize;
  claimed_decompSize = -1;
  if (!memcmp(src, "CM", 2)) {
    src += 2;
    insz -= 2;
    claimed_decompSize =
        (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
    src += 4;
    insz -= 4;
    claimed_compSize = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
    src += 4;
    insz -= 4;
    if ((claimed_compSize < 0) || (claimed_compSize > insz) ||
        (claimed_decompSize < 0)) {
      src -= (2 + 4 + 4);
      insz += (2 + 4 + 4);
      claimed_decompSize = -1;
    } else if (claimed_decompSize > *ret_outsz) {
      *ret_outsz = claimed_decompSize;
      *ret_out = realloc(*ret_out, *ret_outsz);
      if (!*ret_out)
        return -1;
    }
  } else if (!memcmp(src, "lzs2", 4)) {
    src += 4;
    insz -= 4;
    claimed_decompSize =
        (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
    src += 4;
    insz -= 4;
    if ((claimed_decompSize < 0)) {
      src -= (4 + 4);
      insz += (4 + 4);
      claimed_decompSize = -1;
    } else if (claimed_decompSize > *ret_outsz) {
      *ret_outsz = claimed_decompSize;
      *ret_out = realloc(*ret_out, *ret_outsz);
      if (!*ret_out)
        return -1;
    }
  }
  int currentControlBit = 0;
  int controlByte = 0;
  int dbIndex = 0;
  if (claimed_decompSize < 0)
    claimed_decompSize = *ret_outsz;
  o = *ret_out;
  while (o < ((*ret_out) + claimed_decompSize)) {
    if (currentControlBit == 0) {
      controlByte = *src;
      currentControlBit = 8;
      src++;
    }
    if (controlByte & 0x80) {
      unsigned short value = (src[0] << 8) | src[1];
      src += 2;
      unsigned char *endCopyAt = o + (value >> 12) + 3;
      if (endCopyAt >= o) {
        int dunno = value & 0xFFF;
        do {
          unsigned char thisByte = decBuffer[dunno];
          dunno = (dunno + 1) & 0xFFF;
          decBuffer[dbIndex] = thisByte;
          *o = thisByte;
          o++;
          dbIndex = (dbIndex + 1) & 0xFFF;
        } while (o < endCopyAt);
      }
    } else {
      unsigned char thisByte = *src;
      thisByte ^= dbIndex;
      decBuffer[dbIndex] = thisByte;
      dbIndex = (dbIndex + 1) & 0xFFF;
      src++;
      *o = thisByte;
      o++;
    }
    controlByte <<= 1;
    currentControlBit--;
  }
  return (o - *ret_out);
}


x86 assembly (clang, -O0):
<sega_lzs2>:
push   %rbp
mov    %rsp,%rbp
sub    $0x60,%rsp
mov    %rdi,-0x10(%rbp)
mov    %esi,-0x14(%rbp)
mov    %rdx,-0x20(%rbp)
mov    %rcx,-0x28(%rbp)
movl   $0xffffffff,-0x34(%rbp)
mov    -0x10(%rbp),%rdi
lea    0xeb7(%rip),%rsi
mov    $0x2,%edx
call   1030 <memcmp@plt>
cmp    $0x0,%eax
jne    129b <sega_lzs2+0x17b>
mov    -0x10(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x2,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movzbl 0x3(%rax),%eax
shl    $0x18,%eax
mov    -0x10(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
shl    $0x10,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
shl    $0x8,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movzbl (%rcx),%ecx
or     %ecx,%eax
mov    %eax,-0x34(%rbp)
mov    -0x10(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x4,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movzbl 0x3(%rax),%eax
shl    $0x18,%eax
mov    -0x10(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
shl    $0x10,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
shl    $0x8,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movzbl (%rcx),%ecx
or     %ecx,%eax
mov    %eax,-0x38(%rbp)
mov    -0x10(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x4,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x38(%rbp)
jl     121d <sega_lzs2+0xfd>
mov    -0x38(%rbp),%eax
cmp    -0x14(%rbp),%eax
jg     121d <sega_lzs2+0xfd>
cmpl   $0x0,-0x34(%rbp)
jge    123e <sega_lzs2+0x11e>
mov    -0x10(%rbp),%rax
add    $0xfffffffffffffff6,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0xa,%eax
mov    %eax,-0x14(%rbp)
movl   $0xffffffff,-0x34(%rbp)
jmp    1296 <sega_lzs2+0x176>
mov    -0x34(%rbp),%eax
mov    -0x28(%rbp),%rcx
cmp    (%rcx),%eax
jle    1291 <sega_lzs2+0x171>
mov    -0x34(%rbp),%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
mov    (%rax),%rdi
mov    -0x28(%rbp),%rax
mov    (%rax),%esi
call   1040 <realloc@plt>
mov    %rax,%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x20(%rbp),%rax
cmpq   $0x0,(%rax)
jne    128c <sega_lzs2+0x16c>
movl   $0xffffffff,-0x4(%rbp)
jmp    1566 <sega_lzs2+0x446>
jmp    1291 <sega_lzs2+0x171>
jmp    1296 <sega_lzs2+0x176>
jmp    13a1 <sega_lzs2+0x281>
mov    -0x10(%rbp),%rdi
lea    0xd5d(%rip),%rsi
mov    $0x4,%edx
call   1030 <memcmp@plt>
cmp    $0x0,%eax
jne    139c <sega_lzs2+0x27c>
mov    -0x10(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x4,%eax
mov    %eax,-0x14(%rbp)
mov    -0x10(%rbp),%rax
movzbl 0x3(%rax),%eax
shl    $0x18,%eax
mov    -0x10(%rbp),%rcx
movzbl 0x2(%rcx),%ecx
shl    $0x10,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
shl    $0x8,%ecx
or     %ecx,%eax
mov    -0x10(%rbp),%rcx
movzbl (%rcx),%ecx
or     %ecx,%eax
mov    %eax,-0x34(%rbp)
mov    -0x10(%rbp),%rax
add    $0x4,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
sub    $0x4,%eax
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x34(%rbp)
jge    133f <sega_lzs2+0x21f>
mov    -0x10(%rbp),%rax
add    $0xfffffffffffffff8,%rax
mov    %rax,-0x10(%rbp)
mov    -0x14(%rbp),%eax
add    $0x8,%eax
mov    %eax,-0x14(%rbp)
movl   $0xffffffff,-0x34(%rbp)
jmp    1397 <sega_lzs2+0x277>
mov    -0x34(%rbp),%eax
mov    -0x28(%rbp),%rcx
cmp    (%rcx),%eax
jle    1392 <sega_lzs2+0x272>
mov    -0x34(%rbp),%ecx
mov    -0x28(%rbp),%rax
mov    %ecx,(%rax)
mov    -0x20(%rbp),%rax
mov    (%rax),%rdi
mov    -0x28(%rbp),%rax
mov    (%rax),%esi
call   1040 <realloc@plt>
mov    %rax,%rcx
mov    -0x20(%rbp),%rax
mov    %rcx,(%rax)
mov    -0x20(%rbp),%rax
cmpq   $0x0,(%rax)
jne    138d <sega_lzs2+0x26d>
movl   $0xffffffff,-0x4(%rbp)
jmp    1566 <sega_lzs2+0x446>
jmp    1392 <sega_lzs2+0x272>
jmp    1397 <sega_lzs2+0x277>
jmp    139c <sega_lzs2+0x27c>
jmp    13a1 <sega_lzs2+0x281>
movl   $0x0,-0x3c(%rbp)
movl   $0x0,-0x40(%rbp)
movl   $0x0,-0x44(%rbp)
cmpl   $0x0,-0x34(%rbp)
jge    13c9 <sega_lzs2+0x2a9>
mov    -0x28(%rbp),%rax
mov    (%rax),%eax
mov    %eax,-0x34(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x30(%rbp)
mov    -0x30(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    (%rcx),%rcx
movslq -0x34(%rbp),%rdx
add    %rdx,%rcx
cmp    %rcx,%rax
jae    1555 <sega_lzs2+0x435>
cmpl   $0x0,-0x3c(%rbp)
jne    1416 <sega_lzs2+0x2f6>
mov    -0x10(%rbp),%rax
movzbl (%rax),%eax
mov    %eax,-0x40(%rbp)
movl   $0x8,-0x3c(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x40(%rbp),%eax
and    $0x80,%eax
cmp    $0x0,%eax
je     14e9 <sega_lzs2+0x3c9>
mov    -0x10(%rbp),%rax
movzbl (%rax),%eax
shl    $0x8,%eax
mov    -0x10(%rbp),%rcx
movzbl 0x1(%rcx),%ecx
or     %ecx,%eax
mov    %ax,-0x46(%rbp)
mov    -0x10(%rbp),%rax
add    $0x2,%rax
mov    %rax,-0x10(%rbp)
mov    -0x30(%rbp),%rax
movzwl -0x46(%rbp),%ecx
sar    $0xc,%ecx
movslq %ecx,%rcx
add    %rcx,%rax
add    $0x3,%rax
mov    %rax,-0x50(%rbp)
mov    -0x50(%rbp),%rax
cmp    -0x30(%rbp),%rax
jb     14e4 <sega_lzs2+0x3c4>
movzwl -0x46(%rbp),%eax
and    $0xfff,%eax
mov    %eax,-0x54(%rbp)
movslq -0x54(%rbp),%rcx
lea    0x2bb7(%rip),%rax
mov    (%rax,%rcx,1),%al
mov    %al,-0x55(%rbp)
mov    -0x54(%rbp),%eax
add    $0x1,%eax
and    $0xfff,%eax
mov    %eax,-0x54(%rbp)
mov    -0x55(%rbp),%dl
movslq -0x44(%rbp),%rcx
lea    0x2b95(%rip),%rax
mov    %dl,(%rax,%rcx,1)
mov    -0x55(%rbp),%cl
mov    -0x30(%rbp),%rax
mov    %cl,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x44(%rbp),%eax
add    $0x1,%eax
and    $0xfff,%eax
mov    %eax,-0x44(%rbp)
mov    -0x30(%rbp),%rax
cmp    -0x50(%rbp),%rax
jb     147e <sega_lzs2+0x35e>
jmp    14e4 <sega_lzs2+0x3c4>
jmp    153e <sega_lzs2+0x41e>
mov    -0x10(%rbp),%rax
mov    (%rax),%al
mov    %al,-0x56(%rbp)
mov    -0x44(%rbp),%ecx
movzbl -0x56(%rbp),%eax
xor    %ecx,%eax
mov    %al,-0x56(%rbp)
mov    -0x56(%rbp),%dl
movslq -0x44(%rbp),%rcx
lea    0x2b34(%rip),%rax
mov    %dl,(%rax,%rcx,1)
mov    -0x44(%rbp),%eax
add    $0x1,%eax
and    $0xfff,%eax
mov    %eax,-0x44(%rbp)
mov    -0x10(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x10(%rbp)
mov    -0x56(%rbp),%cl
mov    -0x30(%rbp),%rax
mov    %cl,(%rax)
mov    -0x30(%rbp),%rax
add    $0x1,%rax
mov    %rax,-0x30(%rbp)
mov    -0x40(%rbp),%eax
shl    $0x1,%eax
mov    %eax,-0x40(%rbp)
mov    -0x3c(%rbp),%eax
add    $0xffffffff,%eax
mov    %eax,-0x3c(%rbp)
jmp    13d4 <sega_lzs2+0x2b4>
mov    -0x30(%rbp),%rax
mov    -0x20(%rbp),%rcx
mov    (%rcx),%rcx
sub    %rcx,%rax
mov    %eax,-0x4(%rbp)
mov    -0x4(%rbp),%eax
add    $0x60,%rsp
pop    %rbp
ret

x86 assembly (clang, -O2):
<sega_lzs2>:
push   %rbp
push   %r15
push   %r14
push   %rbx
push   %rax
mov    %rcx,%r15
mov    %rdx,%r14
mov    %esi,%ebp
mov    %rdi,%rbx
lea    0xec7(%rip),%rsi
mov    $0x2,%edx
call   1030 <memcmp@plt>
test   %eax,%eax
je     1171 <sega_lzs2+0x51>
lea    0xeb5(%rip),%rsi
mov    %rbx,%rdi
mov    $0x4,%edx
call   1030 <memcmp@plt>
test   %eax,%eax
jne    11ae <sega_lzs2+0x8e>
mov    0x4(%rbx),%ebp
test   %ebp,%ebp
js     11ae <sega_lzs2+0x8e>
add    $0x8,%rbx
cmp    (%r15),%ebp
jg     118f <sega_lzs2+0x6f>
jmp    11b1 <sega_lzs2+0x91>
mov    0x6(%rbx),%eax
test   %eax,%eax
js     11ae <sega_lzs2+0x8e>
add    $0xfffffff6,%ebp
cmp    %ebp,%eax
jg     11ae <sega_lzs2+0x8e>
mov    0x2(%rbx),%ebp
test   %ebp,%ebp
js     11ae <sega_lzs2+0x8e>
add    $0xa,%rbx
cmp    (%r15),%ebp
jle    11b1 <sega_lzs2+0x91>
mov    %ebp,(%r15)
mov    (%r14),%rdi
mov    %ebp,%esi
call   1040 <realloc@plt>
mov    %rax,(%r14)
test   %rax,%rax
jne    11b1 <sega_lzs2+0x91>
mov    $0xffffffff,%eax
jmp    12d5 <sega_lzs2+0x1b5>
mov    (%r15),%ebp
mov    (%r14),%rax
test   %ebp,%ebp
jle    12d0 <sega_lzs2+0x1b0>
movslq %ebp,%r8
xor    %edx,%edx
lea    0x2e78(%rip),%rsi
xor    %r10d,%r10d
xor    %r11d,%r11d
jmp    1208 <sega_lzs2+0xe8>
xor    %edx,%ecx
movslq %edx,%rdi
mov    %cl,(%rdi,%rsi,1)
add    $0x1,%edx
and    $0xfff,%edx
add    $0x1,%rbx
mov    %cl,(%rax)
add    $0x1,%rax
mov    %rbx,%r9
add    %r10d,%r10d
add    $0xffffffff,%r11d
mov    (%r14),%rcx
lea    (%rcx,%r8,1),%rdi
mov    %r9,%rbx
cmp    %rdi,%rax
jae    12d3 <sega_lzs2+0x1b3>
test   %r11d,%r11d
jne    121b <sega_lzs2+0xfb>
movzbl (%rbx),%r10d
add    $0x1,%rbx
mov    $0x8,%r11d
movzbl (%rbx),%ecx
test   $0x80,%r10b
je     11d0 <sega_lzs2+0xb0>
lea    0x2(%rbx),%r9
mov    %rcx,%rbp
shr    $0x4,%rbp
lea    (%rax,%rbp,1),%rdi
add    $0x3,%rdi
cmp    %rax,%rdi
jb     11ee <sega_lzs2+0xce>
movzbl 0x1(%rbx),%ebx
and    $0xf,%ecx
shl    $0x8,%rcx
or     %rbx,%rcx
test   $0x1,%bpl
jne    1280 <sega_lzs2+0x160>
mov    (%rcx,%rsi,1),%bl
add    $0x1,%ecx
and    $0xfff,%ecx
movslq %edx,%rdx
mov    %bl,(%rdx,%rsi,1)
mov    %bl,(%rax)
add    $0x1,%rax
add    $0x1,%edx
and    $0xfff,%edx
cs nopw 0x0(%rax,%rax,1)
nopl   0x0(%rax,%rax,1)
mov    %ecx,%ebx
movzbl (%rbx,%rsi,1),%ebx
lea    0x1(%rcx),%ebp
and    $0xfff,%ebp
movslq %edx,%rdx
mov    %bl,(%rdx,%rsi,1)
mov    %bl,(%rax)
lea    0x1(%rdx),%ebx
and    $0xfff,%ebx
movzbl 0x0(%rbp,%rsi,1),%ebp
add    $0x2,%ecx
and    $0xfff,%ecx
mov    %bpl,(%rbx,%rsi,1)
mov    %bpl,0x1(%rax)
add    $0x2,%edx
and    $0xfff,%edx
add    $0x2,%rax
cmp    %rdi,%rax
jne    1280 <sega_lzs2+0x160>
mov    %rdi,%rax
jmp    11ee <sega_lzs2+0xce>
mov    %rax,%rcx
sub    %ecx,%eax
add    $0x8,%rsp
pop    %rbx
pop    %r14
pop    %r15
pop    %rbp
ret

LLVM IR (-O0):
@sega_lzs2.decBuffer = internal global [4096 x i8] zeroinitializer
@.str = [3 x i8] c"CM\00"
@.str.1 = [5 x i8] c"lzs2\00"
define i32 @sega_lzs2(i8* %0, i32 %1, i8** %2, i32* %3) {
%5 = alloca i32
%6 = alloca i8*
%7 = alloca i32
%8 = alloca i8**
%9 = alloca i32*
%10 = alloca i8*
%11 = alloca i32
%12 = alloca i32
%13 = alloca i32
%14 = alloca i32
%15 = alloca i32
%16 = alloca i16
%17 = alloca i8*
%18 = alloca i32
%19 = alloca i8
%20 = alloca i8
store i8* %0, i8** %6
store i32 %1, i32* %7
store i8** %2, i8*** %8
store i32* %3, i32** %9
store i32 -1, i32* %11
%21 = load i8*, i8** %6
%22 = call i32 @memcmp(i8* %21, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32 2)
%23 = icmp ne i32 %22, 0
br i1 %23, label %116, label %24
24: ; preds = %4
%25 = load i8*, i8** %6
%26 = getelementptr inbounds i8, i8* %25, i64 2
store i8* %26, i8** %6
%27 = load i32, i32* %7
%28 = sub nsw i32 %27, 2
store i32 %28, i32* %7
%29 = load i8*, i8** %6
%30 = getelementptr inbounds i8, i8* %29, i64 3
%31 = load i8, i8* %30
%32 = zext i8 %31 to i32
%33 = shl i32 %32, 24
%34 = load i8*, i8** %6
%35 = getelementptr inbounds i8, i8* %34, i64 2
%36 = load i8, i8* %35
%37 = zext i8 %36 to i32
%38 = shl i32 %37, 16
%39 = or i32 %33, %38
%40 = load i8*, i8** %6
%41 = getelementptr inbounds i8, i8* %40, i64 1
%42 = load i8, i8* %41
%43 = zext i8 %42 to i32
%44 = shl i32 %43, 8
%45 = or i32 %39, %44
%46 = load i8*, i8** %6
%47 = getelementptr inbounds i8, i8* %46, i64 0
%48 = load i8, i8* %47
%49 = zext i8 %48 to i32
%50 = or i32 %45, %49
store i32 %50, i32* %11
%51 = load i8*, i8** %6
%52 = getelementptr inbounds i8, i8* %51, i64 4
store i8* %52, i8** %6
%53 = load i32, i32* %7
%54 = sub nsw i32 %53, 4
store i32 %54, i32* %7
%55 = load i8*, i8** %6
%56 = getelementptr inbounds i8, i8* %55, i64 3
%57 = load i8, i8* %56
%58 = zext i8 %57 to i32
%59 = shl i32 %58, 24
%60 = load i8*, i8** %6
%61 = getelementptr inbounds i8, i8* %60, i64 2
%62 = load i8, i8* %61
%63 = zext i8 %62 to i32
%64 = shl i32 %63, 16
%65 = or i32 %59, %64
%66 = load i8*, i8** %6
%67 = getelementptr inbounds i8, i8* %66, i64 1
%68 = load i8, i8* %67
%69 = zext i8 %68 to i32
%70 = shl i32 %69, 8
%71 = or i32 %65, %70
%72 = load i8*, i8** %6
%73 = getelementptr inbounds i8, i8* %72, i64 0
%74 = load i8, i8* %73
%75 = zext i8 %74 to i32
%76 = or i32 %71, %75
store i32 %76, i32* %12
%77 = load i8*, i8** %6
%78 = getelementptr inbounds i8, i8* %77, i64 4
store i8* %78, i8** %6
%79 = load i32, i32* %7
%80 = sub nsw i32 %79, 4
store i32 %80, i32* %7
%81 = load i32, i32* %12
%82 = icmp slt i32 %81, 0
br i1 %82, label %90, label %83
83: ; preds = %24
%84 = load i32, i32* %12
%85 = load i32, i32* %7
%86 = icmp sgt i32 %84, %85
br i1 %86, label %90, label %87
87: ; preds = %83
%88 = load i32, i32* %11
%89 = icmp slt i32 %88, 0
br i1 %89, label %90, label %95
90: ; preds = %87, %83, %24
%91 = load i8*, i8** %6
%92 = getelementptr inbounds i8, i8* %91, i64 -10
store i8* %92, i8** %6
%93 = load i32, i32* %7
%94 = add nsw i32 %93, 10
store i32 %94, i32* %7
store i32 -1, i32* %11
br label %115
95: ; preds = %87
%96 = load i32, i32* %11
%97 = load i32*, i32** %9
%98 = load i32, i32* %97
%99 = icmp sgt i32 %96, %98
br i1 %99, label %100, label %114
100: ; preds = %95
%101 = load i32, i32* %11
%102 = load i32*, i32** %9
store i32 %101, i32* %102
%103 = load i8**, i8*** %8
%104 = load i8*, i8** %103
%105 = load i32*, i32** %9
%106 = load i32, i32* %105
%107 = call i8* @realloc(i8* %104, i32 %106)
%108 = load i8**, i8*** %8
store i8* %107, i8** %108
%109 = load i8**, i8*** %8
%110 = load i8*, i8** %109
%111 = icmp ne i8* %110, null
br i1 %111, label %113, label %112
112: ; preds = %100
store i32 -1, i32* %5
br label %297
113: ; preds = %100
br label %114
114: ; preds = %113, %95
br label %115
115: ; preds = %114, %90
br label %180
116: ; preds = %4
%117 = load i8*, i8** %6
%118 = call i32 @memcmp(i8* %117, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0), i32 4)
%119 = icmp ne i32 %118, 0
br i1 %119, label %179, label %120
120: ; preds = %116
%121 = load i8*, i8** %6
%122 = getelementptr inbounds i8, i8* %121, i64 4
store i8* %122, i8** %6
%123 = load i32, i32* %7
%124 = sub nsw i32 %123, 4
store i32 %124, i32* %7
%125 = load i8*, i8** %6
%126 = getelementptr inbounds i8, i8* %125, i64 3
%127 = load i8, i8* %126
%128 = zext i8 %127 to i32
%129 = shl i32 %128, 24
%130 = load i8*, i8** %6
%131 = getelementptr inbounds i8, i8* %130, i64 2
%132 = load i8, i8* %131
%133 = zext i8 %132 to i32
%134 = shl i32 %133, 16
%135 = or i32 %129, %134
%136 = load i8*, i8** %6
%137 = getelementptr inbounds i8, i8* %136, i64 1
%138 = load i8, i8* %137
%139 = zext i8 %138 to i32
%140 = shl i32 %139, 8
%141 = or i32 %135, %140
%142 = load i8*, i8** %6
%143 = getelementptr inbounds i8, i8* %142, i64 0
%144 = load i8, i8* %143
%145 = zext i8 %144 to i32
%146 = or i32 %141, %145
store i32 %146, i32* %11
%147 = load i8*, i8** %6
%148 = getelementptr inbounds i8, i8* %147, i64 4
store i8* %148, i8** %6
%149 = load i32, i32* %7
%150 = sub nsw i32 %149, 4
store i32 %150, i32* %7
%151 = load i32, i32* %11
%152 = icmp slt i32 %151, 0
br i1 %152, label %153, label %158
153: ; preds = %120
%154 = load i8*, i8** %6
%155 = getelementptr inbounds i8, i8* %154, i64 -8
store i8* %155, i8** %6
%156 = load i32, i32* %7
%157 = add nsw i32 %156, 8
store i32 %157, i32* %7
store i32 -1, i32* %11
br label %178
158: ; preds = %120
%159 = load i32, i32* %11
%160 = load i32*, i32** %9
%161 = load i32, i32* %160
%162 = icmp sgt i32 %159, %161
br i1 %162, label %163, label %177
163: ; preds = %158
%164 = load i32, i32* %11
%165 = load i32*, i32** %9
store i32 %164, i32* %165
%166 = load i8**, i8*** %8
%167 = load i8*, i8** %166
%168 = load i32*, i32** %9
%169 = load i32, i32* %168
%170 = call i8* @realloc(i8* %167, i32 %169)
%171 = load i8**, i8*** %8
store i8* %170, i8** %171
%172 = load i8**, i8*** %8
%173 = load i8*, i8** %172
%174 = icmp ne i8* %173, null
br i1 %174, label %176, label %175
175: ; preds = %163
store i32 -1, i32* %5
br label %297
176: ; preds = %163
br label %177
177: ; preds = %176, %158
br label %178
178: ; preds = %177, %153
br label %179
179: ; preds = %178, %116
br label %180
180: ; preds = %179, %115
store i32 0, i32* %13
store i32 0, i32* %14
store i32 0, i32* %15
%181 = load i32, i32* %11
%182 = icmp slt i32 %181, 0
br i1 %182, label %183, label %186
183: ; preds = %180
%184 = load i32*, i32** %9
%185 = load i32, i32* %184
store i32 %185, i32* %11
br label %186
186: ; preds = %183, %180
%187 = load i8**, i8*** %8
%188 = load i8*, i8** %187
store i8* %188, i8** %10
br label %189
189: ; preds = %284, %186
%190 = load i8*, i8** %10
%191 = load i8**, i8*** %8
%192 = load i8*, i8** %191
%193 = load i32, i32* %11
%194 = sext i32 %193 to i64
%195 = getelementptr inbounds i8, i8* %192, i64 %194
%196 = icmp ult i8* %190, %195
br i1 %196, label %197, label %289
197: ; preds = %189
%198 = load i32, i32* %13
%199 = icmp eq i32 %198, 0
br i1 %199, label %200, label %206
200: ; preds = %197
%201 = load i8*, i8** %6
%202 = load i8, i8* %201
%203 = zext i8 %202 to i32
store i32 %203, i32* %14
store i32 8, i32* %13
%204 = load i8*, i8** %6
%205 = getelementptr inbounds i8, i8* %204, i32 1
store i8* %205, i8** %6
br label %206
206: ; preds = %200, %197
%207 = load i32, i32* %14
%208 = and i32 %207, 128
%209 = icmp ne i32 %208, 0
br i1 %209, label %210, label %263
210: ; preds = %206
%211 = load i8*, i8** %6
%212 = getelementptr inbounds i8, i8* %211, i64 0
%213 = load i8, i8* %212
%214 = zext i8 %213 to i32
%215 = shl i32 %214, 8
%216 = load i8*, i8** %6
%217 = getelementptr inbounds i8, i8* %216, i64 1
%218 = load i8, i8* %217
%219 = zext i8 %218 to i32
%220 = or i32 %215, %219
%221 = trunc i32 %220 to i16
store i16 %221, i16* %16
%222 = load i8*, i8** %6
%223 = getelementptr inbounds i8, i8* %222, i64 2
store i8* %223, i8** %6
%224 = load i8*, i8** %10
%225 = load i16, i16* %16
%226 = zext i16 %225 to i32
%227 = ashr i32 %226, 12
%228 = sext i32 %227 to i64
%229 = getelementptr inbounds i8, i8* %224, i64 %228
%230 = getelementptr inbounds i8, i8* %229, i64 3
store i8* %230, i8** %17
%231 = load i8*, i8** %17
%232 = load i8*, i8** %10
%233 = icmp uge i8* %231, %232
br i1 %233, label %234, label %262
234: ; preds = %210
%235 = load i16, i16* %16
%236 = zext i16 %235 to i32
%237 = and i32 %236, 4095
store i32 %237, i32* %18
br label %238
238: ; preds = %257, %234
%239 = load i32, i32* %18
%240 = sext i32 %239 to i64
%241 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %240
%242 = load i8, i8* %241
store i8 %242, i8* %19
%243 = load i32, i32* %18
%244 = add nsw i32 %243, 1
%245 = and i32 %244, 4095
store i32 %245, i32* %18
%246 = load i8, i8* %19
%247 = load i32, i32* %15
%248 = sext i32 %247 to i64
%249 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %248
store i8 %246, i8* %249
%250 = load i8, i8* %19
%251 = load i8*, i8** %10
store i8 %250, i8* %251
%252 = load i8*, i8** %10
%253 = getelementptr inbounds i8, i8* %252, i32 1
store i8* %253, i8** %10
%254 = load i32, i32* %15
%255 = add nsw i32 %254, 1
%256 = and i32 %255, 4095
store i32 %256, i32* %15
br label %257
257: ; preds = %238
%258 = load i8*, i8** %10
%259 = load i8*, i8** %17
%260 = icmp ult i8* %258, %259
br i1 %260, label %238, label %261
261: ; preds = %257
br label %262
262: ; preds = %261, %210
br label %284
263: ; preds = %206
%264 = load i8*, i8** %6
%265 = load i8, i8* %264
store i8 %265, i8* %20
%266 = load i32, i32* %15
%267 = load i8, i8* %20
%268 = zext i8 %267 to i32
%269 = xor i32 %268, %266
%270 = trunc i32 %269 to i8
store i8 %270, i8* %20
%271 = load i8, i8* %20
%272 = load i32, i32* %15
%273 = sext i32 %272 to i64
%274 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %273
store i8 %271, i8* %274
%275 = load i32, i32* %15
%276 = add nsw i32 %275, 1
%277 = and i32 %276, 4095
store i32 %277, i32* %15
%278 = load i8*, i8** %6
%279 = getelementptr inbounds i8, i8* %278, i32 1
store i8* %279, i8** %6
%280 = load i8, i8* %20
%281 = load i8*, i8** %10
store i8 %280, i8* %281
%282 = load i8*, i8** %10
%283 = getelementptr inbounds i8, i8* %282, i32 1
store i8* %283, i8** %10
br label %284
284: ; preds = %263, %262
%285 = load i32, i32* %14
%286 = shl i32 %285, 1
store i32 %286, i32* %14
%287 = load i32, i32* %13
%288 = add nsw i32 %287, -1
store i32 %288, i32* %13
br label %189
289: ; preds = %189
%290 = load i8*, i8** %10
%291 = load i8**, i8*** %8
%292 = load i8*, i8** %291
%293 = ptrtoint i8* %290 to i64
%294 = ptrtoint i8* %292 to i64
%295 = sub i64 %293, %294
%296 = trunc i64 %295 to i32
store i32 %296, i32* %5
br label %297
297: ; preds = %289, %175, %112
%298 = load i32, i32* %5
ret i32 %298
}

LLVM IR (-O2):
@sega_lzs2.decBuffer = internal unnamed_addr global [4096 x i8] zeroinitializer
@.str = [3 x i8] c"CM\00"
@.str.1 = [5 x i8] c"lzs2\00"
define i32 @sega_lzs2(i8* %0, i32 %1, i8** nocapture %2, i32* nocapture %3) {
%5 = tail call i32 @memcmp(i8* %0, i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str, i64 0, i64 0), i32 2)
%6 = icmp eq i32 %5, 0
br i1 %6, label %7, label %58
7: ; preds = %4
%8 = getelementptr inbounds i8, i8* %0, i64 2
%9 = getelementptr inbounds i8, i8* %0, i64 5
%10 = load i8, i8* %9
%11 = zext i8 %10 to i32
%12 = shl nuw i32 %11, 24
%13 = getelementptr inbounds i8, i8* %0, i64 4
%14 = load i8, i8* %13
%15 = zext i8 %14 to i32
%16 = shl nuw nsw i32 %15, 16
%17 = or i32 %16, %12
%18 = getelementptr inbounds i8, i8* %0, i64 3
%19 = load i8, i8* %18
%20 = zext i8 %19 to i32
%21 = shl nuw nsw i32 %20, 8
%22 = or i32 %17, %21
%23 = load i8, i8* %8
%24 = zext i8 %23 to i32
%25 = or i32 %22, %24
%26 = getelementptr inbounds i8, i8* %0, i64 6
%27 = getelementptr inbounds i8, i8* %0, i64 9
%28 = load i8, i8* %27
%29 = zext i8 %28 to i32
%30 = shl nuw i32 %29, 24
%31 = getelementptr inbounds i8, i8* %0, i64 8
%32 = load i8, i8* %31
%33 = zext i8 %32 to i32
%34 = shl nuw nsw i32 %33, 16
%35 = or i32 %34, %30
%36 = getelementptr inbounds i8, i8* %0, i64 7
%37 = load i8, i8* %36
%38 = zext i8 %37 to i32
%39 = shl nuw nsw i32 %38, 8
%40 = or i32 %35, %39
%41 = load i8, i8* %26
%42 = zext i8 %41 to i32
%43 = or i32 %40, %42
%44 = getelementptr inbounds i8, i8* %0, i64 10
%45 = icmp slt i32 %43, 0
br i1 %45, label %89, label %46
46: ; preds = %7
%47 = add nsw i32 %1, -10
%48 = icmp sgt i32 %43, %47
%49 = icmp slt i32 %25, 0
%50 = select i1 %48, i1 true, i1 %49
br i1 %50, label %89, label %51
51: ; preds = %46
%52 = load i32, i32* %3
%53 = icmp sgt i32 %25, %52
br i1 %53, label %54, label %91
54: ; preds = %51
store i32 %25, i32* %3
%55 = load i8*, i8** %2
%56 = tail call i8* @realloc(i8* %55, i32 %25)
store i8* %56, i8** %2
%57 = icmp eq i8* %56, null
br i1 %57, label %198, label %91
58: ; preds = %4
%59 = tail call i32 @memcmp(i8* %0, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.1, i64 0, i64 0), i32 4)
%60 = icmp eq i32 %59, 0
br i1 %60, label %61, label %89
61: ; preds = %58
%62 = getelementptr inbounds i8, i8* %0, i64 4
%63 = getelementptr inbounds i8, i8* %0, i64 7
%64 = load i8, i8* %63
%65 = zext i8 %64 to i32
%66 = shl nuw i32 %65, 24
%67 = getelementptr inbounds i8, i8* %0, i64 6
%68 = load i8, i8* %67
%69 = zext i8 %68 to i32
%70 = shl nuw nsw i32 %69, 16
%71 = or i32 %70, %66
%72 = getelementptr inbounds i8, i8* %0, i64 5
%73 = load i8, i8* %72
%74 = zext i8 %73 to i32
%75 = shl nuw nsw i32 %74, 8
%76 = or i32 %71, %75
%77 = load i8, i8* %62
%78 = zext i8 %77 to i32
%79 = or i32 %76, %78
%80 = getelementptr inbounds i8, i8* %0, i64 8
%81 = icmp slt i32 %79, 0
br i1 %81, label %89, label %82
82: ; preds = %61
%83 = load i32, i32* %3
%84 = icmp sgt i32 %79, %83
br i1 %84, label %85, label %91
85: ; preds = %82
store i32 %79, i32* %3
%86 = load i8*, i8** %2
%87 = tail call i8* @realloc(i8* %86, i32 %79)
store i8* %87, i8** %2
%88 = icmp eq i8* %87, null
br i1 %88, label %198, label %91
89: ; preds = %58, %46, %7, %61
%90 = load i32, i32* %3
br label %91
91: ; preds = %51, %54, %85, %82, %89
%92 = phi i8* [ %0, %89 ], [ %80, %85 ], [ %80, %82 ], [ %44, %54 ], [ %44, %51 ]
%93 = phi i32 [ %90, %89 ], [ %79, %85 ], [ %79, %82 ], [ %25, %54 ], [ %25, %51 ]
%94 = load i8*, i8** %2
%95 = sext i32 %93 to i64
%96 = icmp sgt i32 %93, 0
br i1 %96, label %97, label %191
97: ; preds = %91, %182
%98 = phi i8* [ %185, %182 ], [ %92, %91 ]
%99 = phi i8* [ %184, %182 ], [ %94, %91 ]
%100 = phi i32 [ %183, %182 ], [ 0, %91 ]
%101 = phi i32 [ %186, %182 ], [ 0, %91 ]
%102 = phi i32 [ %187, %182 ], [ 0, %91 ]
%103 = icmp eq i32 %102, 0
br i1 %103, label %104, label %108
104: ; preds = %97
%105 = load i8, i8* %98
%106 = zext i8 %105 to i32
%107 = getelementptr inbounds i8, i8* %98, i64 1
br label %108
108: ; preds = %104, %97
%109 = phi i32 [ 8, %104 ], [ %102, %97 ]
%110 = phi i32 [ %106, %104 ], [ %101, %97 ]
%111 = phi i8* [ %107, %104 ], [ %98, %97 ]
%112 = and i32 %110, 128
%113 = icmp eq i32 %112, 0
%114 = load i8, i8* %111
br i1 %113, label %173, label %115
115: ; preds = %108
%116 = zext i8 %114 to i32
%117 = getelementptr inbounds i8, i8* %111, i64 2
%118 = lshr i32 %116, 4
%119 = zext i32 %118 to i64
%120 = getelementptr inbounds i8, i8* %99, i64 3
%121 = getelementptr i8, i8* %120, i64 %119
%122 = icmp ult i8* %121, %99
br i1 %122, label %182, label %123
123: ; preds = %115
%124 = shl nuw nsw i32 %116, 8
%125 = getelementptr inbounds i8, i8* %111, i64 1
%126 = load i8, i8* %125
%127 = zext i8 %126 to i32
%128 = and i32 %124, 3840
%129 = or i32 %128, %127
%130 = and i64 %119, 1
%131 = icmp eq i64 %130, 0
br i1 %131, label %132, label %143
132: ; preds = %123
%133 = zext i32 %129 to i64
%134 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %133
%135 = load i8, i8* %134
%136 = add nuw nsw i32 %129, 1
%137 = and i32 %136, 4095
%138 = sext i32 %100 to i64
%139 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %138
store i8 %135, i8* %139
store i8 %135, i8* %99
%140 = getelementptr inbounds i8, i8* %99, i64 1
%141 = add nsw i32 %100, 1
%142 = and i32 %141, 4095
br label %143
143: ; preds = %123, %132
%144 = phi i32 [ undef, %123 ], [ %142, %132 ]
%145 = phi i32 [ %100, %123 ], [ %142, %132 ]
%146 = phi i8* [ %99, %123 ], [ %140, %132 ]
%147 = phi i32 [ %129, %123 ], [ %137, %132 ]
br label %148
148: ; preds = %148, %143
%149 = phi i32 [ %145, %143 ], [ %171, %148 ]
%150 = phi i8* [ %146, %143 ], [ %169, %148 ]
%151 = phi i32 [ %147, %143 ], [ %166, %148 ]
%152 = zext i32 %151 to i64
%153 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %152
%154 = load i8, i8* %153
%155 = add nuw nsw i32 %151, 1
%156 = and i32 %155, 4095
%157 = sext i32 %149 to i64
%158 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %157
store i8 %154, i8* %158
store i8 %154, i8* %150
%159 = getelementptr inbounds i8, i8* %150, i64 1
%160 = add nsw i32 %149, 1
%161 = and i32 %160, 4095
%162 = zext i32 %156 to i64
%163 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %162
%164 = load i8, i8* %163
%165 = add nsw i32 %151, 2
%166 = and i32 %165, 4095
%167 = zext i32 %161 to i64
%168 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %167
store i8 %164, i8* %168
store i8 %164, i8* %159
%169 = getelementptr inbounds i8, i8* %150, i64 2
%170 = add i32 %149, 2
%171 = and i32 %170, 4095
%172 = icmp eq i8* %169, %121
br i1 %172, label %182, label %148
173: ; preds = %108
%174 = trunc i32 %100 to i8
%175 = xor i8 %114, %174
%176 = sext i32 %100 to i64
%177 = getelementptr inbounds [4096 x i8], [4096 x i8]* @sega_lzs2.decBuffer, i64 0, i64 %176
store i8 %175, i8* %177
%178 = add nsw i32 %100, 1
%179 = and i32 %178, 4095
%180 = getelementptr inbounds i8, i8* %111, i64 1
store i8 %175, i8* %99
%181 = getelementptr inbounds i8, i8* %99, i64 1
br label %182
182: ; preds = %148, %115, %173
%183 = phi i32 [ %179, %173 ], [ %100, %115 ], [ %171, %148 ]
%184 = phi i8* [ %181, %173 ], [ %99, %115 ], [ %121, %148 ]
%185 = phi i8* [ %180, %173 ], [ %117, %115 ], [ %117, %148 ]
%186 = shl i32 %110, 1
%187 = add nsw i32 %109, -1
%188 = load i8*, i8** %2
%189 = getelementptr inbounds i8, i8* %188, i64 %95
%190 = icmp ult i8* %184, %189
br i1 %190, label %97, label %191
191: ; preds = %182, %91
%192 = phi i8* [ %94, %91 ], [ %184, %182 ]
%193 = phi i8* [ %94, %91 ], [ %188, %182 ]
%194 = ptrtoint i8* %192 to i64
%195 = ptrtoint i8* %193 to i64
%196 = sub i64 %194, %195
%197 = trunc i64 %196 to i32
br label %198
198: ; preds = %85, %54, %191
%199 = phi i32 [ %197, %191 ], [ -1, %54 ], [ -1, %85 ]
ret i32 %199
}