// File: /workspace/github_cpp_makefile_star2_O3/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, %r12d
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 0x37807
movl $0x0, 0x50(%rbx)
movl %r12d, 0x4(%rsp)
movzbl 0x71(%rbx), %eax
testl %eax, %eax
je 0x378b2
movl 0x5c(%rbx), %r12d
xorl %ecx, %ecx
cmpl $0x3, %r12d
setne %cl
cmpl $0x2, %r12d
leal 0x18(,%rcx,8), %edx
movl $0x10, %ecx
cmovnel %edx, %ecx
cmpl %eax, %ecx
cmovael %eax, %ecx
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
shll %cl, %eax
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
notl %eax
orl $0xffff, %eax           # imm = 0xFFFF
cmpl $0x20, %ecx
cmovael %edx, %eax
movl %eax, %r13d
orl $0x3ffff, %r13d         # imm = 0x3FFFF
cmpl $0x5, %r12d
cmovbl %eax, %r13d
movl %r12d, %edi
movl %r15d, %esi
callq 0x379e4
cmpl %eax, %r13d
cmovael %eax, %r13d
movq 0x480(%rbx), %rsi
movl %r15d, %eax
cmpq %rax, %rsi
jae 0x378e8
movl %r12d, %edi
callq 0x379e4
cmpl %eax, %r13d
cmovbl %r13d, %eax
jmp 0x378eb
addl %eax, %r8d
setb %cl
cmpl %r15d, %eax
setb %al
orb %cl, %al
testb $0x1, %al
jne 0x379b3
movl $0xffff0000, %edx       # imm = 0xFFFF0000
movl $0xffff0000, %eax       # imm = 0xFFFF0000
subl %r8d, %eax
cmpl $0x40000000, %r8d       # imm = 0x40000000
movb $0x2, %cl
sbbb $0x0, %cl
movl %r8d, %esi
shrl %cl, %esi
leal (%rsi,%r8), %ebp
addl $0x11080, %ebp          # imm = 0x11080
movl %esi, %ecx
addl $0x11080, %ecx          # imm = 0x11080
andl %edx, %ebp
cmpl %eax, %ecx
cmovael %edx, %ebp
cmpl $0xfffeffff, %r8d       # imm = 0xFFFEFFFF
ja 0x379b3
cmpl $0x1000000, %eax        # imm = 0x1000000
jb 0x379b3
testl %ebp, %ebp
je 0x379b3
movq 0x40(%rbx), %rsi
testq %rsi, %rsi
je 0x37886
cmpl %ebp, 0x50(%rbx)
je 0x3776d
movq %r14, %rdi
callq *0x8(%r14)
movq $0x0, 0x40(%rbx)
movl %ebp, 0x50(%rbx)
movl %ebp, %esi
movq %r14, %rdi
callq *(%r14)
movq %rax, 0x40(%rbx)
testq %rax, %rax
jne 0x3776d
jmp 0x379b3
movl 0x5c(%rbx), %r12d
movl %r12d, %edi
movl %r15d, %esi
callq 0x37a37
movl %eax, %r13d
movq 0x480(%rbx), %rsi
movl %r15d, %eax
cmpq %rax, %rsi
jae 0x378e8
movl %r12d, %edi
callq 0x37a37
movl %eax, %ecx
cmpl %r13d, %eax
movl %r13d, %eax
cmovbl %ecx, %eax
jmp 0x378eb
movl %r13d, %eax
leal 0x1(%r15), %ecx
movl %eax, 0x38(%rbx)
xorl %ebp, %ebp
movl $0x0, %eax
cmpl $0x3, %r12d
jb 0x37920
movb 0x70(%rbx), %dl
xorl %eax, %eax
cmpb $0x3, %dl
setb %al
shll $0xa, %eax
cmpl $0x3, %r12d
je 0x37920
orl $0x10000, %eax          # imm = 0x10000
xorl %esi, %esi
cmpb $0x4, %dl
cmovael %esi, %eax
movl %eax, 0x6c(%rbx)
movl 0x4(%rsp), %edx
movl %edx, 0x24(%rbx)
movl %r15d, 0x68(%rbx)
movl %ecx, 0x1c(%rbx)
cmpb $0x0, 0x21(%rbx)
movl %ecx, %esi
setne %cl
movq %rsi, %rdx
shlq %cl, %rdx
cmpq %rsi, %rdx
jb 0x379d3
movl %r13d, %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 0x37978
movl $0x1, %ebp
cmpq %r15, 0x478(%rbx)
jae 0x379d3
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 0x379b3
leaq (%rax,%r12,4), %rax
movq %rax, 0x30(%rbx)
movl $0x1, %ebp
jmp 0x379d3
movq 0x28(%rbx), %rsi
movq %r14, %rdi
callq *0x8(%r14)
xorl %ebp, %ebp
movq %rbp, 0x28(%rbx)
movq 0x40(%rbx), %rsi
movq %r14, %rdi
callq *0x8(%r14)
movq %rbp, 0x40(%rbx)
movl %ebp, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq