// File: /workspace/github_cpp_makefile_star2_O1/blackle[P]LZMA-Vizualizer/LzmaSpec.cpp
// Function: CLzmaDecoder::Decode(bool, unsigned long)
int CLzmaDecoder::Decode(bool unpackSizeDefined, UInt64 unpackSize)
{
  if (!RangeDec.Init())
    return LZMA_RES_ERROR;

  Init();

  UInt32 rep0 = 0, rep1 = 0, rep2 = 0, rep3 = 0;
  unsigned state = 0;

  for (;;)
  {
    if (unpackSizeDefined && unpackSize == 0 && !markerIsMandatory)
      if (RangeDec.IsFinishedOK())
        return LZMA_RES_FINISHED_WITHOUT_MARKER;

    unsigned posState = OutWindow.TotalPos & ((1 << pb) - 1);

    if (RangeDec.DecodeBit(&IsMatch[(state << kNumPosBitsMax) + posState]) == 0)
    {
      if (unpackSizeDefined && unpackSize == 0)
        return LZMA_RES_ERROR;
      DecodeLiteral(state, rep0);
      PushPerplexities(1);
      Literals.push_back(true);
      state = UpdateState_Literal(state);
      unpackSize--;
      continue;
    }

    unsigned len;

    if (RangeDec.DecodeBit(&IsRep[state]) != 0)
    {
      if (unpackSizeDefined && unpackSize == 0)
        return LZMA_RES_ERROR;
      if (OutWindow.IsEmpty())
        return LZMA_RES_ERROR;
      if (RangeDec.DecodeBit(&IsRepG0[state]) == 0)
      {
        if (RangeDec.DecodeBit(&IsRep0Long[(state << kNumPosBitsMax) + posState]) == 0)
        {
          state = UpdateState_ShortRep(state);
          OutWindow.PutByte(OutWindow.GetByte(rep0 + 1));
          PushPerplexities(1);
          Literals.push_back(false);
          unpackSize--;
          continue;
        }
      }
      else
      {
        UInt32 dist;
        if (RangeDec.DecodeBit(&IsRepG1[state]) == 0)
          dist = rep1;
        else
        {
          if (RangeDec.DecodeBit(&IsRepG2[state]) == 0)
            dist = rep2;
          else
          {
            dist = rep3;
            rep3 = rep2;
          }
          rep2 = rep1;
        }
        rep1 = rep0;
        rep0 = dist;
      }
      len = RepLenDecoder.Decode(&RangeDec, posState);
      state = UpdateState_Rep(state);
    }
    else
    {
      rep3 = rep2;
      rep2 = rep1;
      rep1 = rep0;
      len = LenDecoder.Decode(&RangeDec, posState);
      state = UpdateState_Match(state);
      rep0 = DecodeDistance(len);
      if (rep0 == 0xFFFFFFFF)
        return RangeDec.IsFinishedOK() ?
            LZMA_RES_FINISHED_WITH_MARKER :
            LZMA_RES_ERROR;

      if (unpackSizeDefined && unpackSize == 0)
        return LZMA_RES_ERROR;
      if (rep0 >= dictSize || !OutWindow.CheckDistance(rep0))
        return LZMA_RES_ERROR;
    }
    len += kMatchMinLen;
    bool isError = false;
    if (unpackSizeDefined && unpackSize < len)
    {
      len = (unsigned)unpackSize;
      isError = true;
    }
    OutWindow.CopyMatch(rep0 + 1, len);
    Literals.insert(Literals.end(), len, false);
    PushPerplexities(len);
    unpackSize -= len;
    if (isError)
      return LZMA_RES_ERROR;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x98, %rsp
movq %rdx, %rbx
movl %esi, -0x5c(%rbp)
movq %rdi, %r14
callq 0x245c
movl $0x0, -0x30(%rbp)
testb %al, %al
je 0x2c05
movq %r14, %rdi
callq 0x3b24
movq %rbx, %rsi
leaq 0x18(%r14), %rax
movq %rax, -0x78(%rbp)
leaq 0x3ae(%r14), %rax
movq %rax, -0xb8(%rbp)
leaq 0x52e(%r14), %rax
movq %rax, -0xb0(%rbp)
leaq 0x546(%r14), %rax
movq %rax, -0xa0(%rbp)
leaq 0x55e(%r14), %rax
movq %rax, -0x90(%rbp)
leaq 0x576(%r14), %rax
movq %rax, -0x88(%rbp)
leaq 0x58e(%r14), %rax
movq %rax, -0x80(%rbp)
leaq 0xb12(%r14), %rax
movq %rax, -0x98(%rbp)
leaq 0x60(%r14), %rax
movq %rax, -0x70(%rbp)
leaq 0x70e(%r14), %rax
movq %rax, -0xa8(%rbp)
xorl %r12d, %r12d
xorl %r13d, %r13d
xorl %edx, %edx
movl $0x0, -0x2c(%rbp)
movq $0x0, -0x40(%rbp)
movq %r14, -0x68(%rbp)
testq %rsi, %rsi
sete %r15b
andb -0x5c(%rbp), %r15b
cmpb $0x1, %r15b
jne 0x27e4
cmpb $0x0, 0x88(%r14)
jne 0x27e4
cmpl $0x0, 0x4(%r14)
je 0x2bfe
movq %rsi, -0x48(%rbp)
movl %r12d, -0x4c(%rbp)
movl %edx, -0x38(%rbp)
movb 0x90(%r14), %cl
movl $0xffffffff, %ebx       # imm = 0xFFFFFFFF
shll %cl, %ebx
notl %ebx
andl 0x2c(%r14), %ebx
movq %r14, %r12
movl %r13d, %r14d
shll $0x4, %r13d
addl %ebx, %r13d
movq -0xb8(%rbp), %rax
leaq (%rax,%r13,2), %rsi
movq %r12, %rdi
callq 0x2572
testl %eax, %eax
je 0x2869
movl %r14d, %ecx
movq -0xb0(%rbp), %rax
movq %rcx, -0x58(%rbp)
leaq (%rax,%rcx,2), %rsi
movq %r12, %rdi
callq 0x2572
testl %eax, %eax
je 0x2893
movl %r14d, -0x34(%rbp)
movl $0x1, %eax
testb %r15b, %r15b
je 0x28fc
xorl %esi, %esi
movl $0x0, -0x30(%rbp)
movl -0x38(%rbp), %edx
movl -0x34(%rbp), %r13d
jmp 0x2886
testb %r15b, %r15b
je 0x2925
xorl %esi, %esi
movl $0x1, %eax
movl $0x0, -0x30(%rbp)
movl -0x38(%rbp), %edx
movl %r14d, %r13d
movq -0x68(%rbp), %r14
movl -0x4c(%rbp), %r12d
jmp 0x2b68
movq -0xa8(%rbp), %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x3e98
movl %eax, %ebx
xorl %eax, %eax
cmpl $0x7, %r14d
setae %al
leal 0x7(%rax,%rax,2), %eax
movl %eax, -0x34(%rbp)
movq %r12, %rdi
movl %ebx, %esi
callq 0x3f78
cmpl $-0x1, %eax
movq -0x48(%rbp), %rsi
movq %r12, %r14
je 0x29ee
movl %eax, %r13d
movl $0x1, %eax
testb %r15b, %r15b
movl -0x38(%rbp), %ecx
je 0x2a1c
movl %ecx, %r12d
movl -0x2c(%rbp), %edx
movq -0x40(%rbp), %rcx
movl %ecx, -0x2c(%rbp)
movq %r13, -0x40(%rbp)
xorl %esi, %esi
jmp 0x2a97
movq -0x68(%rbp), %r14
cmpl $0x0, 0x20(%r14)
movl -0x4c(%rbp), %r12d
jne 0x297c
testb $0x1, 0x28(%r14)
jne 0x297c
movl $0x0, -0x30(%rbp)
movq -0x48(%rbp), %rsi
movl -0x38(%rbp), %edx
jmp 0x2b64
movq -0x68(%rbp), %rdi
movl %r14d, %ebx
movq %rdi, %r14
movl %ebx, %esi
movq -0x40(%rbp), %rdx
callq 0x3c56
movq %r14, %rdi
movl $0x1, %esi
callq 0x3d90
movq -0x70(%rbp), %rdi
movl $0x1, %esi
callq 0x3e0c
xorl %ecx, %ecx
cmpl $0x4, %ebx
movl -0x38(%rbp), %edx
movl -0x4c(%rbp), %r12d
movq -0x48(%rbp), %rsi
jb 0x2a4e
cmpl $0x9, %ebx
ja 0x2a49
addl $-0x3, %ebx
jmp 0x2a4c
movq -0xa0(%rbp), %rax
movq -0x58(%rbp), %r15
leaq (%rax,%r15,2), %rsi
movq %r14, %rdi
callq 0x2572
testl %eax, %eax
je 0x2a5e
movq -0x90(%rbp), %rax
leaq (%rax,%r15,2), %rsi
movq %r14, %rdi
callq 0x2572
testl %eax, %eax
je 0x2aa3
movq -0x88(%rbp), %rax
leaq (%rax,%r15,2), %rsi
movq %r14, %rdi
callq 0x2572
testl %eax, %eax
movl %r12d, %eax
movl -0x38(%rbp), %ecx
cmovel %ecx, %eax
cmovel %r12d, %ecx
movl %ecx, %r12d
movl -0x2c(%rbp), %ecx
movq -0x40(%rbp), %rdx
movl %edx, -0x58(%rbp)
movq -0x48(%rbp), %r15
jmp 0x2ab4
xorl %eax, %eax
cmpl $0x0, 0x4(%r14)
sete %al
movl %eax, -0x30(%rbp)
movl $0x1, %eax
movl -0x38(%rbp), %r12d
movl -0x2c(%rbp), %edx
movq -0x40(%rbp), %rcx
movl %ecx, -0x2c(%rbp)
movl $0xffffffff, %ecx       # imm = 0xFFFFFFFF
movq %rcx, -0x40(%rbp)
jmp 0x2b64
cmpl 0x98(%r14), %r13d
jae 0x2a86
cmpl %r13d, 0x20(%r14)
jae 0x2bf5
testb $0x1, 0x28(%r14)
movq -0x40(%rbp), %rdi
jne 0x2ae8
movl %ecx, %r12d
movl -0x2c(%rbp), %edx
movl %edi, -0x2c(%rbp)
jmp 0x2a93
addl $-0x6, %ebx
movl %ebx, %ecx
decq %rsi
movl $0x3, %eax
movl %ecx, %r13d
jmp 0x2b68
movq -0x80(%rbp), %rax
leaq (%rax,%r13,2), %rsi
movq %r14, %rdi
callq 0x2572
testl %eax, %eax
je 0x2b7e
movl -0x2c(%rbp), %eax
movl %eax, -0x58(%rbp)
movq -0x40(%rbp), %rax
movq -0x48(%rbp), %r15
jmp 0x2ab1
movl %ecx, %r12d
movl -0x2c(%rbp), %edx
movq -0x40(%rbp), %rcx
movl %ecx, -0x2c(%rbp)
movq %r13, -0x40(%rbp)
movl $0x0, -0x30(%rbp)
jmp 0x2b64
movq -0x40(%rbp), %rax
movl %eax, -0x58(%rbp)
movq -0x48(%rbp), %r15
movl -0x2c(%rbp), %eax
movl -0x38(%rbp), %ecx
movl %eax, %r13d
movl %ecx, -0x2c(%rbp)
movq -0x98(%rbp), %rdi
movq %r14, %rsi
movl %ebx, %edx
callq 0x3e98
movl %eax, %ebx
xorl %eax, %eax
cmpl $0x7, -0x34(%rbp)
setae %al
leal 0x8(%rax,%rax,2), %eax
movl %eax, -0x34(%rbp)
movl %r12d, %ecx
movl -0x58(%rbp), %eax
movl %eax, %edi
movq %r15, %rsi
movq %rdi, -0x40(%rbp)
addl $0x2, %ebx
cmpq %rbx, %rsi
setb %r12b
andb -0x5c(%rbp), %r12b
leal 0x1(%r13), %esi
testb %r12b, %r12b
movq -0x48(%rbp), %r15
cmovel %ebx, %r15d
movl $0x0, %eax
movl -0x30(%rbp), %edx
cmovnel %eax, %edx
movl %edx, -0x30(%rbp)
movq -0x78(%rbp), %rdi
movl %ecx, %ebx
movl %r15d, %edx
callq 0x40c8
movq 0x70(%r14), %rsi
movl 0x78(%r14), %edx
movq -0x70(%rbp), %rdi
movq %r15, %rcx
xorl %r8d, %r8d
callq 0x5318
movq %r14, %rdi
movl %r15d, %esi
callq 0x3d90
subq %r15, -0x48(%rbp)
movzbl %r12b, %eax
movq -0x48(%rbp), %rsi
movl %ebx, %r12d
movl -0x2c(%rbp), %edx
movq -0x40(%rbp), %rcx
movl %ecx, -0x2c(%rbp)
movq %r13, -0x40(%rbp)
movl -0x34(%rbp), %r13d
testl %eax, %eax
je 0x27be
cmpl $0x3, %eax
je 0x27be
jmp 0x2c05
xorl %ecx, %ecx
cmpl $0x7, -0x34(%rbp)
setae %sil
movq -0x40(%rbp), %rax
leal 0x1(%rax), %edi
movl 0x20(%r14), %eax
movl $0x0, %edx
cmpl %edi, %eax
movq -0x48(%rbp), %rbx
jae 0x2ba4
movl 0x24(%r14), %edx
movb %sil, %cl
leal 0x9(,%rcx,2), %r13d
movq 0x18(%r14), %rcx
movq -0x40(%rbp), %rsi
notl %esi
addl %esi, %eax
addl %edx, %eax
movzbl (%rcx,%rax), %esi
movq -0x78(%rbp), %rdi
callq 0x3e60
movq %r14, %rdi
movl $0x1, %esi
callq 0x3d90
movq -0x70(%rbp), %rdi
xorl %esi, %esi
callq 0x3e0c
movq %rbx, %rsi
decq %rsi
movl $0x3, %eax
movl -0x38(%rbp), %edx
jmp 0x2b68
movq -0x40(%rbp), %rdi
jmp 0x2ae8
movl $0x2, -0x30(%rbp)
movl -0x30(%rbp), %eax
addq $0x98, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq