// File: /workspace/github_cpp_makefile_star2_O2/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 0x2f58f
andl $0x0, 0x50(%rbx)
movzbl 0x71(%rbx), %eax
testl %eax, %eax
je 0x2f63e
movl 0x5c(%rbx), %edx
xorl %ecx, %ecx
cmpl $0x3, %edx
setne %cl
cmpl $0x2, %edx
leal 0x18(,%rcx,8), %esi
pushq $0x10
popq %rcx
cmovnel %esi, %ecx
cmpl %eax, %ecx
cmovael %eax, %ecx
pushq $-0x1
popq %rax
movl %eax, %esi
shll %cl, %esi
notl %esi
orl $0xffff, %esi           # imm = 0xFFFF
cmpl $0x20, %ecx
cmovael %eax, %esi
movl %esi, %r12d
orl $0x3ffff, %r12d         # imm = 0x3FFFF
cmpl $0x5, %edx
cmovbl %esi, %r12d
movq %rbx, %rdi
movl %r15d, %esi
callq 0x2f74f
cmpl %eax, %r12d
cmovael %eax, %r12d
movq 0x480(%rbx), %rsi
movl %r15d, %eax
cmpq %rax, %rsi
jae 0x2f670
movq %rbx, %rdi
callq 0x2f74f
cmpl %eax, %r12d
cmovbl %r12d, %eax
jmp 0x2f673
addl %eax, %r8d
setb %cl
cmpl %r15d, %eax
setb %al
orb %cl, %al
testb $0x1, %al
jne 0x2f72f
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), %r12d
addl $0x11080, %r12d         # imm = 0x11080
movl %esi, %ecx
addl $0x11080, %ecx          # imm = 0x11080
andl %edx, %r12d
cmpl %eax, %ecx
cmovael %edx, %r12d
cmpl $0xfffeffff, %r8d       # imm = 0xFFFEFFFF
ja 0x2f72f
cmpl $0x1000000, %eax        # imm = 0x1000000
jb 0x2f72f
testl %r12d, %r12d
je 0x2f72f
movq 0x40(%rbx), %rsi
testq %rsi, %rsi
je 0x2f613
cmpl %r12d, 0x50(%rbx)
je 0x2f504
movq %r14, %rdi
callq *0x8(%r14)
andq $0x0, 0x40(%rbx)
movl %r12d, 0x50(%rbx)
movl %r12d, %esi
movq %r14, %rdi
callq *(%r14)
movq %rax, 0x40(%rbx)
testq %rax, %rax
jne 0x2f504
jmp 0x2f72f
movq %rbx, %rdi
movl %r15d, %esi
callq 0x2f7a5
movl %eax, %r12d
movq 0x480(%rbx), %rsi
movl %r15d, %eax
cmpq %rax, %rsi
jae 0x2f670
movq %rbx, %rdi
callq 0x2f7a5
movl %eax, %ecx
cmpl %r12d, %eax
movl %r12d, %eax
cmovbl %ecx, %eax
jmp 0x2f673
movl %r12d, %eax
leal 0x1(%r15), %ecx
movl %eax, 0x38(%rbx)
movl 0x5c(%rbx), %edx
xorl %r13d, %r13d
movl $0x0, %eax
cmpl $0x3, %edx
jb 0x2f6ad
movb 0x70(%rbx), %sil
xorl %eax, %eax
cmpb $0x3, %sil
setb %al
shll $0xa, %eax
cmpl $0x3, %edx
je 0x2f6ad
orl $0x10000, %eax          # imm = 0x10000
xorl %edx, %edx
cmpb $0x4, %sil
cmovael %edx, %eax
movl %eax, 0x6c(%rbx)
movl %ebp, 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 0x2f73d
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
pushq $0x1
popq %r13
testq %rsi, %rsi
je 0x2f6fc
cmpq %r15, 0x478(%rbx)
jae 0x2f73d
movq %r14, %rdi
callq *0x8(%r14)
andq $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 0x2f72f
leaq (%rax,%r12,4), %rax
movq %rax, 0x30(%rbx)
jmp 0x2f73d
movq %rbx, %rdi
movq %r14, %rsi
callq 0x2f496
xorl %r13d, %r13d
movl %r13d, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq