// File: sisong[P]ApkDiffPatch/lzma/C/LzmaEnc.c
// Function: GetOptimumFast
static unsigned GetOptimumFast(CLzmaEnc *p)
{
  UInt32 numAvail, mainDist;
  unsigned mainLen, numPairs, repIndex, repLen, i;
  const Byte *data;

  if (p->additionalOffset == 0)
    mainLen = ReadMatchDistances(p, &numPairs);
  else
  {
    mainLen = p->longestMatchLen;
    numPairs = p->numPairs;
  }

  numAvail = p->numAvail;
  p->backRes = MARK_LIT;
  if (numAvail < 2)
    return 1;
  // if (mainLen < 2 && p->state == 0) return 1; // 18.06.notused
  if (numAvail > LZMA_MATCH_LEN_MAX)
    numAvail = LZMA_MATCH_LEN_MAX;
  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  repLen = repIndex = 0;
  
  for (i = 0; i < LZMA_NUM_REPS; i++)
  {
    unsigned len;
    const Byte *data2 = data - p->reps[i];
    if (data[0] != data2[0] || data[1] != data2[1])
      continue;
    for (len = 2; len < numAvail && data[len] == data2[len]; len++)
    {}
    if (len >= p->numFastBytes)
    {
      p->backRes = (UInt32)i;
      MOVE_POS(p, len - 1)
      return len;
    }
    if (len > repLen)
    {
      repIndex = i;
      repLen = len;
    }
  }

  if (mainLen >= p->numFastBytes)
  {
    p->backRes = p->matches[(size_t)numPairs - 1] + LZMA_NUM_REPS;
    MOVE_POS(p, mainLen - 1)
    return mainLen;
  }

  mainDist = 0; /* for GCC */
  
  if (mainLen >= 2)
  {
    mainDist = p->matches[(size_t)numPairs - 1];
    while (numPairs > 2)
    {
      UInt32 dist2;
      if (mainLen != p->matches[(size_t)numPairs - 4] + 1)
        break;
      dist2 = p->matches[(size_t)numPairs - 3];
      if (!ChangePair(dist2, mainDist))
        break;
      numPairs -= 2;
      mainLen--;
      mainDist = dist2;
    }
    if (mainLen == 2 && mainDist >= 0x80)
      mainLen = 1;
  }

  if (repLen >= 2)
    if (    repLen + 1 >= mainLen
        || (repLen + 2 >= mainLen && mainDist >= (1 << 9))
        || (repLen + 3 >= mainLen && mainDist >= (1 << 15)))
  {
    p->backRes = (UInt32)repIndex;
    MOVE_POS(p, repLen - 1)
    return repLen;
  }
  
  if (mainLen < 2 || numAvail <= 2)
    return 1;

  {
    unsigned len1 = ReadMatchDistances(p, &p->numPairs);
    p->longestMatchLen = len1;
  
    if (len1 >= 2)
    {
      UInt32 newDist = p->matches[(size_t)p->numPairs - 1];
      if (   (len1 >= mainLen && newDist < mainDist)
          || (len1 == mainLen + 1 && !ChangePair(mainDist, newDist))
          || (len1 >  mainLen + 1)
          || (len1 + 1 >= mainLen && mainLen >= 3 && ChangePair(newDist, mainDist)))
        return 1;
    }
  }
  
  data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
  
  for (i = 0; i < LZMA_NUM_REPS; i++)
  {
    unsigned len, limit;
    const Byte *data2 = data - p->reps[i];
    if (data[0] != data2[0] || data[1] != data2[1])
      continue;
    limit = mainLen - 1;
    for (len = 2;; len++)
    {
      if (len >= limit)
        return 1;
      if (data[len] != data2[len])
        break;
    }
  }
  
  p->backRes = mainDist + LZMA_NUM_REPS;
  if (mainLen != 2)
  {
    MOVE_POS(p, mainLen - 2)
  }
  return mainLen;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x70, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x0, 0x4c(%rax)
jne 0x6afb8
movq -0x10(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x6ac60
movl %eax, -0x1c(%rbp)
jmp 0x6afcc
movq -0x10(%rbp), %rax
movl 0x38(%rax), %eax
movl %eax, -0x1c(%rbp)
movq -0x10(%rbp), %rax
movl 0x3c(%rax), %eax
movl %eax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movl 0x40(%rax), %eax
movl %eax, -0x14(%rbp)
movq -0x10(%rbp), %rax
movl $0xffffffff, 0xb8(%rax) # imm = 0xFFFFFFFF
cmpl $0x2, -0x14(%rbp)
jae 0x6aff6
movl $0x1, -0x4(%rbp)
jmp 0x6b472
cmpl $0x111, -0x14(%rbp)     # imm = 0x111
jbe 0x6b006
movl $0x111, -0x14(%rbp)     # imm = 0x111
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdi
callq *%rax
addq $-0x1, %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x24(%rbp)
movl $0x0, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
cmpl $0x4, -0x2c(%rbp)
jae 0x6b13d
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
movl -0x2c(%rbp), %edx
movl 0x50(%rcx,%rdx,4), %ecx
movl %ecx, %edx
xorl %ecx, %ecx
subq %rdx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
movq -0x48(%rbp), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x6b081
movq -0x38(%rbp), %rax
movzbl 0x1(%rax), %eax
movq -0x48(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
cmpl %ecx, %eax
je 0x6b086
jmp 0x6b12f
movl $0x2, -0x3c(%rbp)
movl -0x3c(%rbp), %ecx
xorl %eax, %eax
cmpl -0x14(%rbp), %ecx
movb %al, -0x69(%rbp)
jae 0x6b0b8
movq -0x38(%rbp), %rax
movl -0x3c(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movq -0x48(%rbp), %rcx
movl -0x3c(%rbp), %edx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
sete %al
movb %al, -0x69(%rbp)
movb -0x69(%rbp), %al
testb $0x1, %al
jne 0x6b0c1
jmp 0x6b0ce
jmp 0x6b0c3
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x3c(%rbp)
jmp 0x6b08d
movl -0x3c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x48(%rcx), %eax
jb 0x6b119
movl -0x2c(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xb8(%rax)
movl -0x3c(%rbp), %ecx
subl $0x1, %ecx
movq -0x10(%rbp), %rax
addl 0x4c(%rax), %ecx
movl %ecx, 0x4c(%rax)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdi
movl -0x3c(%rbp), %esi
subl $0x1, %esi
callq *%rax
movl -0x3c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x6b472
movl -0x3c(%rbp), %eax
cmpl -0x28(%rbp), %eax
jbe 0x6b12d
movl -0x2c(%rbp), %eax
movl %eax, -0x24(%rbp)
movl -0x3c(%rbp), %eax
movl %eax, -0x28(%rbp)
jmp 0x6b12f
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x6b034
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
cmpl 0x48(%rcx), %eax
jb 0x6b19a
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
subq $0x1, %rcx
movl 0xd30(%rax,%rcx,4), %ecx
addl $0x4, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xb8(%rax)
movl -0x1c(%rbp), %ecx
subl $0x1, %ecx
movq -0x10(%rbp), %rax
addl 0x4c(%rax), %ecx
movl %ecx, 0x4c(%rax)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdi
movl -0x1c(%rbp), %esi
subl $0x1, %esi
callq *%rax
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x6b472
movl $0x0, -0x18(%rbp)
cmpl $0x2, -0x1c(%rbp)
jb 0x6b238
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
subq $0x1, %rcx
movl 0xd30(%rax,%rcx,4), %eax
movl %eax, -0x18(%rbp)
cmpl $0x2, -0x20(%rbp)
jbe 0x6b220
movl -0x1c(%rbp), %eax
movq -0x10(%rbp), %rcx
movl -0x20(%rbp), %edx
subq $0x4, %rdx
movl 0xd30(%rcx,%rdx,4), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
je 0x6b1e4
jmp 0x6b220
movq -0x10(%rbp), %rax
movl -0x20(%rbp), %ecx
subq $0x3, %rcx
movl 0xd30(%rax,%rcx,4), %eax
movl %eax, -0x4c(%rbp)
movl -0x18(%rbp), %eax
shrl $0x7, %eax
cmpl -0x4c(%rbp), %eax
ja 0x6b206
jmp 0x6b220
movl -0x20(%rbp), %eax
subl $0x2, %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x1c(%rbp)
movl -0x4c(%rbp), %eax
movl %eax, -0x18(%rbp)
jmp 0x6b1c0
cmpl $0x2, -0x1c(%rbp)
jne 0x6b236
cmpl $0x80, -0x18(%rbp)
jb 0x6b236
movl $0x1, -0x1c(%rbp)
jmp 0x6b238
cmpl $0x2, -0x28(%rbp)
jb 0x6b2b2
movl -0x28(%rbp), %eax
addl $0x1, %eax
cmpl -0x1c(%rbp), %eax
jae 0x6b271
movl -0x28(%rbp), %eax
addl $0x2, %eax
cmpl -0x1c(%rbp), %eax
jb 0x6b25d
cmpl $0x200, -0x18(%rbp)     # imm = 0x200
jae 0x6b271
movl -0x28(%rbp), %eax
addl $0x3, %eax
cmpl -0x1c(%rbp), %eax
jb 0x6b2b0
cmpl $0x8000, -0x18(%rbp)    # imm = 0x8000
jb 0x6b2b0
movl -0x24(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xb8(%rax)
movl -0x28(%rbp), %ecx
subl $0x1, %ecx
movq -0x10(%rbp), %rax
addl 0x4c(%rax), %ecx
movl %ecx, 0x4c(%rax)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdi
movl -0x28(%rbp), %esi
subl $0x1, %esi
callq *%rax
movl -0x28(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x6b472
jmp 0x6b2b2
cmpl $0x2, -0x1c(%rbp)
jb 0x6b2be
cmpl $0x2, -0x14(%rbp)
ja 0x6b2ca
movl $0x1, -0x4(%rbp)
jmp 0x6b472
movq -0x10(%rbp), %rdi
movq -0x10(%rbp), %rsi
addq $0x3c, %rsi
callq 0x6ac60
movl %eax, -0x50(%rbp)
movl -0x50(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x38(%rax)
cmpl $0x2, -0x50(%rbp)
jb 0x6b366
movq -0x10(%rbp), %rax
movq -0x10(%rbp), %rcx
movl 0x3c(%rcx), %ecx
subq $0x1, %rcx
movl 0xd30(%rax,%rcx,4), %eax
movl %eax, -0x54(%rbp)
movl -0x50(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jb 0x6b317
movl -0x54(%rbp), %eax
cmpl -0x18(%rbp), %eax
jb 0x6b358
movl -0x50(%rbp), %eax
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
jne 0x6b32f
movl -0x54(%rbp), %eax
shrl $0x7, %eax
cmpl -0x18(%rbp), %eax
jbe 0x6b358
movl -0x50(%rbp), %eax
movl -0x1c(%rbp), %ecx
addl $0x1, %ecx
cmpl %ecx, %eax
ja 0x6b358
movl -0x50(%rbp), %eax
addl $0x1, %eax
cmpl -0x1c(%rbp), %eax
jb 0x6b364
cmpl $0x3, -0x1c(%rbp)
jb 0x6b364
movl -0x18(%rbp), %eax
shrl $0x7, %eax
cmpl -0x54(%rbp), %eax
jbe 0x6b364
movl $0x1, -0x4(%rbp)
jmp 0x6b472
jmp 0x6b366
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdi
callq *%rax
addq $-0x1, %rax
movq %rax, -0x38(%rbp)
movl $0x0, -0x2c(%rbp)
cmpl $0x4, -0x2c(%rbp)
jae 0x6b42f
movq -0x38(%rbp), %rax
movq -0x10(%rbp), %rcx
movl -0x2c(%rbp), %edx
movl 0x50(%rcx,%rdx,4), %ecx
movl %ecx, %edx
xorl %ecx, %ecx
subq %rdx, %rcx
addq %rcx, %rax
movq %rax, -0x68(%rbp)
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
movq -0x68(%rbp), %rcx
movzbl (%rcx), %ecx
cmpl %ecx, %eax
jne 0x6b3d3
movq -0x38(%rbp), %rax
movzbl 0x1(%rax), %eax
movq -0x68(%rbp), %rcx
movzbl 0x1(%rcx), %ecx
cmpl %ecx, %eax
je 0x6b3d5
jmp 0x6b421
movl -0x1c(%rbp), %eax
subl $0x1, %eax
movl %eax, -0x5c(%rbp)
movl $0x2, -0x58(%rbp)
movl -0x58(%rbp), %eax
cmpl -0x5c(%rbp), %eax
jb 0x6b3f6
movl $0x1, -0x4(%rbp)
jmp 0x6b472
movq -0x38(%rbp), %rax
movl -0x58(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movq -0x68(%rbp), %rcx
movl -0x58(%rbp), %edx
movzbl (%rcx,%rdx), %ecx
cmpl %ecx, %eax
je 0x6b412
jmp 0x6b41f
jmp 0x6b414
movl -0x58(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x58(%rbp)
jmp 0x6b3e5
jmp 0x6b421
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0x6b386
movl -0x18(%rbp), %ecx
addl $0x4, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0xb8(%rax)
cmpl $0x2, -0x1c(%rbp)
je 0x6b46c
movl -0x1c(%rbp), %ecx
subl $0x2, %ecx
movq -0x10(%rbp), %rax
addl 0x4c(%rax), %ecx
movl %ecx, 0x4c(%rax)
movq -0x10(%rbp), %rax
movq 0x28(%rax), %rax
movq -0x10(%rbp), %rcx
movq (%rcx), %rdi
movl -0x1c(%rbp), %esi
subl $0x2, %esi
callq *%rax
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x70, %rsp
popq %rbp
retq
nopl (%rax,%rax)