// File: /workspace/github_cpp_makefile_star2_O1/sisong[P]ApkDiffPatch/lzma/C/LzFind.c
// Function: MatchFinder_Create
int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
    UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
    ISzAllocPtr alloc)
{
  /* we need one additional byte in (p->keepSizeBefore),
     since we use MoveBlock() after (p->pos++) and before dictionary using */
  // keepAddBufferBefore = (UInt32)0xFFFFFFFF - (1 << 22); // for debug
  p->keepSizeBefore = historySize + keepAddBufferBefore + 1;

  keepAddBufferAfter += matchMaxLen;
  /* we need (p->keepSizeAfter >= p->numHashBytes) */
  if (keepAddBufferAfter < p->numHashBytes)
    keepAddBufferAfter = p->numHashBytes;
  // keepAddBufferAfter -= 2; // for debug
  p->keepSizeAfter = keepAddBufferAfter;

  if (p->directInput)
    p->blockSize = 0;
  if (p->directInput || LzInWindow_Create2(p, GetBlockSize(p, historySize), alloc))
  {
    size_t hashSizeSum;
    {
      UInt32 hs;
      UInt32 hsCur;
      
      if (p->numHashOutBits != 0)
      {
        unsigned numBits = p->numHashOutBits;
        const unsigned nbMax =
            (p->numHashBytes == 2 ? 16 :
            (p->numHashBytes == 3 ? 24 : 32));
        if (numBits > nbMax)
          numBits = nbMax;
        if (numBits >= 32)
          hs = (UInt32)0 - 1;
        else
          hs = ((UInt32)1 << numBits) - 1;
        // (hash_size >= (1 << 16)) : Required for (numHashBytes > 2)
        hs |= (1 << 16) - 1; /* don't change it! */
        if (p->numHashBytes >= 5)
          hs |= (256 << kLzHash_CrcShift_2) - 1;
        {
          const UInt32 hs2 = MatchFinder_GetHashMask2(p, historySize);
          if (hs > hs2)
            hs = hs2;
        }
        hsCur = hs;
        if (p->expectedDataSize < historySize)
        {
          const UInt32 hs2 = MatchFinder_GetHashMask2(p, (UInt32)p->expectedDataSize);
          if (hsCur > hs2)
            hsCur = hs2;
        }
      }
      else
      {
        hs = MatchFinder_GetHashMask(p, historySize);
        hsCur = hs;
        if (p->expectedDataSize < historySize)
        {
          hsCur = MatchFinder_GetHashMask(p, (UInt32)p->expectedDataSize);
          if (hsCur > hs) // is it possible?
            hsCur = hs;
        }
      }

      p->hashMask = hsCur;

      hashSizeSum = hs;
      hashSizeSum++;
      if (hashSizeSum < hs)
        return 0;
      {
        UInt32 fixedHashSize = 0;
        if (p->numHashBytes > 2 && p->numHashBytes_Min <= 2) fixedHashSize += kHash2Size;
        if (p->numHashBytes > 3 && p->numHashBytes_Min <= 3) fixedHashSize += kHash3Size;
        // if (p->numHashBytes > 4) p->fixedHashSize += hs4; // kHash4Size;
        hashSizeSum += fixedHashSize;
        p->fixedHashSize = fixedHashSize;
      }
    }

    p->matchMaxLen = matchMaxLen;

    {
      size_t newSize;
      size_t numSons;
      const UInt32 newCyclicBufferSize = historySize + 1; // do not change it
      p->historySize = historySize;
      p->cyclicBufferSize = newCyclicBufferSize; // it must be = (historySize + 1)
      
      numSons = newCyclicBufferSize;
      if (p->btMode)
        numSons <<= 1;
      newSize = hashSizeSum + numSons;

      if (numSons < newCyclicBufferSize || newSize < numSons)
        return 0;

      // aligned size is not required here, but it can be better for some loops
      #define NUM_REFS_ALIGN_MASK 0xF
      newSize = (newSize + NUM_REFS_ALIGN_MASK) & ~(size_t)NUM_REFS_ALIGN_MASK;

      // 22.02: we don't reallocate buffer, if old size is enough
      if (p->hash && p->numRefs >= newSize)
        return 1;
      
      MatchFinder_FreeThisClassMemory(p, alloc);
      p->numRefs = newSize;
      p->hash = AllocRefs(newSize, alloc);
      
      if (p->hash)
      {
        p->son = p->hash + hashSizeSum;
        return 1;
      }
    }
  }

  MatchFinder_Free(p, alloc);
  return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
movl %ecx, %ebp
movl %esi, %r15d
movq %rdi, %rbx
leal (%r15,%rdx), %eax
incl %eax
movl %eax, 0x54(%rdi)
addl %ecx, %r8d
movl 0x5c(%rdi), %ecx
cmpl %ecx, %r8d
cmovbel %ecx, %r8d
movq %r9, %r14
movl %r8d, 0x58(%rdi)
cmpb $0x0, 0x23(%rdi)
je 0x37b59
movl $0x0, 0x50(%rbx)
movzbl 0x71(%rbx), %edx
testl %edx, %edx
je 0x37bff
movl 0x5c(%rbx), %eax
xorl %ecx, %ecx
cmpl $0x3, %eax
setne %cl
cmpl $0x2, %eax
leal 0x18(,%rcx,8), %esi
movl $0x10, %ecx
cmovnel %esi, %ecx
cmpl %edx, %ecx
cmovael %edx, %ecx
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
shll %cl, %edx
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
notl %edx
orl $0xffff, %edx           # imm = 0xFFFF
cmpl $0x20, %ecx
cmovael %esi, %edx
movl %edx, %r12d
orl $0x3ffff, %r12d         # imm = 0x3FFFF
cmpl $0x5, %eax
cmovbl %edx, %r12d
movq %rbx, %rdi
movl %r15d, %esi
callq 0x37d28
cmpl %eax, %r12d
cmovael %eax, %r12d
movq 0x480(%rbx), %rsi
movl %r15d, %eax
cmpq %rax, %rsi
jae 0x37c31
movq %rbx, %rdi
callq 0x37d28
cmpl %eax, %r12d
cmovbl %r12d, %eax
jmp 0x37c34
addl %eax, %r8d
setb %cl
cmpl %r15d, %eax
setb %al
orb %cl, %al
xorl %r12d, %r12d
testb $0x1, %al
jne 0x37bb7
cmpl $0x40000000, %r8d       # imm = 0x40000000
movb $0x2, %cl
sbbb $0x0, %cl
movl %r8d, %eax
shrl %cl, %eax
movl $0xffff0000, %ecx       # imm = 0xFFFF0000
movl %r8d, %edx
subl %ecx, %edx
negl %edx
leal (%rax,%r8), %r12d
addl $0x11080, %r12d         # imm = 0x11080
addl $0x11080, %eax          # imm = 0x11080
andl %ecx, %r12d
cmpl %edx, %eax
cmovael %ecx, %r12d
xorl %eax, %eax
cmpl $0x1000000, %edx        # imm = 0x1000000
cmovbl %eax, %r12d
cmpl %ecx, %r8d
cmovael %eax, %r12d
testl %r12d, %r12d
je 0x37cf1
movq 0x40(%rbx), %rsi
testq %rsi, %rsi
je 0x37bcf
cmpl %r12d, 0x50(%rbx)
je 0x37bef
movq %r14, %rdi
callq *0x8(%r14)
movq $0x0, 0x40(%rbx)
movl %r12d, 0x50(%rbx)
movl %r12d, %esi
movq %r14, %rdi
callq *(%r14)
movq %rax, 0x40(%rbx)
cmpq $0x0, 0x40(%rbx)
jne 0x37ac7
jmp 0x37cf1
movq %rbx, %rdi
movl %r15d, %esi
callq 0x37d7e
movl %eax, %r12d
movq 0x480(%rbx), %rsi
movl %r15d, %eax
cmpq %rax, %rsi
jae 0x37c31
movq %rbx, %rdi
callq 0x37d7e
movl %eax, %ecx
cmpl %r12d, %eax
movl %r12d, %eax
cmovbl %ecx, %eax
jmp 0x37c34
movl %r12d, %eax
movl %eax, 0x38(%rbx)
movl 0x5c(%rbx), %ecx
xorl %eax, %eax
cmpl $0x3, %ecx
jb 0x37c4d
xorl %eax, %eax
cmpb $0x3, 0x70(%rbx)
setb %al
shll $0xa, %eax
cmpl $0x4, %ecx
jb 0x37c61
cmpb $0x4, 0x70(%rbx)
leal 0x10000(%rax), %ecx
cmovael %eax, %ecx
movl %ecx, %eax
movl %eax, 0x6c(%rbx)
movl %ebp, 0x24(%rbx)
movl %r15d, 0x68(%rbx)
incl %r15d
movl %r15d, 0x1c(%rbx)
cmpb $0x0, 0x21(%rbx)
setne %cl
movq %r15, %rdx
shlq %cl, %rdx
xorl %r13d, %r13d
cmpq %r15, %rdx
jb 0x37ceb
movl %r12d, %ecx
incq %rcx
movl %eax, %r12d
addq %rcx, %r12
leaq (%r12,%rdx), %r15
addq $0xf, %r15
andq $-0x10, %r15
movq 0x28(%rbx), %rsi
testq %rsi, %rsi
je 0x37cb1
cmpq %r15, 0x478(%rbx)
jae 0x37ce5
movq %r14, %rdi
callq *0x8(%r14)
movq $0x0, 0x28(%rbx)
movq %r15, 0x478(%rbx)
shlq $0x2, %r15
movq %r14, %rdi
movq %r15, %rsi
callq *(%r14)
movq %rax, 0x28(%rbx)
testq %rax, %rax
je 0x37d24
leaq (%rax,%r12,4), %rax
movq %rax, 0x30(%rbx)
movl $0x1, %r13d
xorl %eax, %eax
testb %al, %al
je 0x37d12
movq 0x28(%rbx), %rsi
movq %r14, %rdi
callq *0x8(%r14)
xorl %r13d, %r13d
movq %r13, 0x28(%rbx)
movq 0x40(%rbx), %rsi
movq %r14, %rdi
callq *0x8(%r14)
movq %r13, 0x40(%rbx)
movl %r13d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb $0x1, %al
jmp 0x37ced