// File: /workspace/github_c_makefile_star2_O1/skeeto[P]flappy/sqlite3.c
// Function: whereLoopAddBtree
static int whereLoopAddBtree(
  WhereLoopBuilder *pBuilder, /* WHERE clause information */
  Bitmask mExtra              /* Extra prerequesites for using this table */
){
  WhereInfo *pWInfo;          /* WHERE analysis context */
  Index *pProbe;              /* An index we are evaluating */
  Index sPk;                  /* A fake index object for the primary key */
  tRowcnt aiRowEstPk[2];      /* The aiRowEst[] value for the sPk index */
  i16 aiColumnPk = -1;        /* The aColumn[] value for the sPk index */
  SrcList *pTabList;          /* The FROM clause */
  struct SrcList_item *pSrc;  /* The FROM clause btree term to add */
  WhereLoop *pNew;            /* Template WhereLoop object */
  int rc = SQLITE_OK;         /* Return code */
  int iSortIdx = 1;           /* Index number */
  int b;                      /* A boolean value */
  LogEst rSize;               /* number of rows in the table */
  LogEst rLogSize;            /* Logarithm of the number of rows in the table */
  WhereClause *pWC;           /* The parsed WHERE clause */
  Table *pTab;                /* Table being queried */
  
  pNew = pBuilder->pNew;
  pWInfo = pBuilder->pWInfo;
  pTabList = pWInfo->pTabList;
  pSrc = pTabList->a + pNew->iTab;
  pTab = pSrc->pTab;
  pWC = pBuilder->pWC;
  assert( !IsVirtual(pSrc->pTab) );

  if( pSrc->pIndex ){
    /* An INDEXED BY clause specifies a particular index to use */
    pProbe = pSrc->pIndex;
  }else if( !HasRowid(pTab) ){
    pProbe = pTab->pIndex;
  }else{
    /* There is no INDEXED BY clause.  Create a fake Index object in local
    ** variable sPk to represent the rowid primary key index.  Make this
    ** fake index the first in a chain of Index objects with all of the real
    ** indices to follow */
    Index *pFirst;                  /* First of real indices on the table */
    memset(&sPk, 0, sizeof(Index));
    sPk.nKeyCol = 1;
    sPk.aiColumn = &aiColumnPk;
    sPk.aiRowEst = aiRowEstPk;
    sPk.onError = OE_Replace;
    sPk.pTable = pTab;
    aiRowEstPk[0] = pTab->nRowEst;
    aiRowEstPk[1] = 1;
    pFirst = pSrc->pTab->pIndex;
    if( pSrc->notIndexed==0 ){
      /* The real indices of the table are only considered if the
      ** NOT INDEXED qualifier is omitted from the FROM clause */
      sPk.pNext = pFirst;
    }
    pProbe = &sPk;
  }
  rSize = sqlite3LogEst(pTab->nRowEst);
  rLogSize = estLog(rSize);

#ifndef SQLITE_OMIT_AUTOMATIC_INDEX
  /* Automatic indexes */
  if( !pBuilder->pOrSet
   && (pWInfo->pParse->db->flags & SQLITE_AutoIndex)!=0
   && pSrc->pIndex==0
   && !pSrc->viaCoroutine
   && !pSrc->notIndexed
   && HasRowid(pTab)
   && !pSrc->isCorrelated
  ){
    /* Generate auto-index WhereLoops */
    WhereTerm *pTerm;
    WhereTerm *pWCEnd = pWC->a + pWC->nTerm;
    for(pTerm=pWC->a; rc==SQLITE_OK && pTerm<pWCEnd; pTerm++){
      if( pTerm->prereqRight & pNew->maskSelf ) continue;
      if( termCanDriveIndex(pTerm, pSrc, 0) ){
        pNew->u.btree.nEq = 1;
        pNew->u.btree.nSkip = 0;
        pNew->u.btree.pIndex = 0;
        pNew->nLTerm = 1;
        pNew->aLTerm[0] = pTerm;
        /* TUNING: One-time cost for computing the automatic index is
        ** approximately 7*N*log2(N) where N is the number of rows in
        ** the table being indexed. */
        pNew->rSetup = rLogSize + rSize + 28;  assert( 28==sqlite3LogEst(7) );
        /* TUNING: Each index lookup yields 20 rows in the table.  This
        ** is more than the usual guess of 10 rows, since we have no way
        ** of knowning how selective the index will ultimately be.  It would
        ** not be unreasonable to make this value much larger. */
        pNew->nOut = 43;  assert( 43==sqlite3LogEst(20) );
        pNew->rRun = sqlite3LogEstAdd(rLogSize,pNew->nOut);
        pNew->wsFlags = WHERE_AUTO_INDEX;
        pNew->prereq = mExtra | pTerm->prereqRight;
        rc = whereLoopInsert(pBuilder, pNew);
      }
    }
  }
#endif /* SQLITE_OMIT_AUTOMATIC_INDEX */

  /* Loop over all indices
  */
  for(; rc==SQLITE_OK && pProbe; pProbe=pProbe->pNext, iSortIdx++){
    if( pProbe->pPartIdxWhere!=0
     && !whereUsablePartialIndex(pNew->iTab, pWC, pProbe->pPartIdxWhere) ){
      continue;  /* Partial index inappropriate for this query */
    }
    pNew->u.btree.nEq = 0;
    pNew->u.btree.nSkip = 0;
    pNew->nLTerm = 0;
    pNew->iSortIdx = 0;
    pNew->rSetup = 0;
    pNew->prereq = mExtra;
    pNew->nOut = rSize;
    pNew->u.btree.pIndex = pProbe;
    b = indexMightHelpWithOrderBy(pBuilder, pProbe, pSrc->iCursor);
    /* The ONEPASS_DESIRED flags never occurs together with ORDER BY */
    assert( (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0 || b==0 );
    if( pProbe->tnum<=0 ){
      /* Integer primary key index */
      pNew->wsFlags = WHERE_IPK;

      /* Full table scan */
      pNew->iSortIdx = b ? iSortIdx : 0;
      /* TUNING: Cost of full table scan is 3*(N + log2(N)).
      **  +  The extra 3 factor is to encourage the use of indexed lookups
      **     over full scans.  FIXME */
      pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 16;
      whereLoopOutputAdjust(pWC, pNew);
      rc = whereLoopInsert(pBuilder, pNew);
      pNew->nOut = rSize;
      if( rc ) break;
    }else{
      Bitmask m;
      if( pProbe->isCovering ){
        pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED;
        m = 0;
      }else{
        m = pSrc->colUsed & ~columnsInIndex(pProbe);
        pNew->wsFlags = (m==0) ? (WHERE_IDX_ONLY|WHERE_INDEXED) : WHERE_INDEXED;
      }

      /* Full scan via index */
      if( b
       || !HasRowid(pTab)
       || ( m==0
         && pProbe->bUnordered==0
         && (pProbe->szIdxRow<pTab->szTabRow)
         && (pWInfo->wctrlFlags & WHERE_ONEPASS_DESIRED)==0
         && sqlite3GlobalConfig.bUseCis
         && OptimizationEnabled(pWInfo->pParse->db, SQLITE_CoverIdxScan)
          )
      ){
        pNew->iSortIdx = b ? iSortIdx : 0;
        if( m==0 ){
          /* TUNING: Cost of a covering index scan is K*(N + log2(N)).
          **  +  The extra factor K of between 1.1 and 3.0 that depends
          **     on the relative sizes of the table and the index.  K
          **     is smaller for smaller indices, thus favoring them.
          */
          pNew->rRun = sqlite3LogEstAdd(rSize,rLogSize) + 1 +
                        (15*pProbe->szIdxRow)/pTab->szTabRow;
        }else{
          /* TUNING: Cost of scanning a non-covering index is (N+1)*log2(N)
          ** which we will simplify to just N*log2(N) */
          pNew->rRun = rSize + rLogSize;
        }
        whereLoopOutputAdjust(pWC, pNew);
        rc = whereLoopInsert(pBuilder, pNew);
        pNew->nOut = rSize;
        if( rc ) break;
      }
    }

    rc = whereLoopAddBtreeIndex(pBuilder, pSrc, pProbe, 0);
#ifdef SQLITE_ENABLE_STAT3_OR_STAT4
    sqlite3Stat4ProbeFree(pBuilder->pRec);
    pBuilder->nRecValid = 0;
    pBuilder->pRec = 0;
#endif

    /* If there was an INDEXED BY clause, then only that one index is
    ** considered. */
    if( pSrc->pIndex ) break;
  }
  return rc;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, 0x50(%rsp)
movq %rdi, %r15
movw $0xffff, 0x16(%rsp)     # imm = 0xFFFF
movq 0x18(%rdi), %rbx
movq (%rdi), %r14
movq 0x8(%r14), %rax
movzbl 0x10(%rbx), %ecx
imulq $0x68, %rcx, %rcx
leaq (%rax,%rcx), %r13
addq $0x8, %r13
movq 0x20(%r13), %r12
movq 0x60(%r13), %rax
movq %rax, 0x8(%rsp)
testq %rax, %rax
jne 0x5cabc
testb $0x20, 0x48(%r12)
jne 0x5cab2
xorps %xmm0, %xmm0
leaq 0x60(%rsp), %rcx
movaps %xmm0, 0x50(%rcx)
movaps %xmm0, (%rcx)
movaps %xmm0, 0x10(%rcx)
movaps %xmm0, 0x40(%rcx)
movaps %xmm0, 0x30(%rcx)
movaps %xmm0, 0x20(%rcx)
movq $0x0, 0x60(%rcx)
movw $0x1, 0x5e(%rcx)
leaq 0x16(%rsp), %rax
movq %rax, 0x8(%rcx)
leaq 0x58(%rsp), %rax
movq %rax, 0x10(%rcx)
movb $0x5, 0x62(%rcx)
movq %rcx, 0x8(%rsp)
movq %r12, 0x18(%rcx)
movl 0x38(%r12), %ecx
movl %ecx, (%rax)
movl $0x1, 0x4(%rax)
testb $0x1, 0x39(%r13)
jne 0x5cabc
movq 0x20(%r13), %rax
movq 0x10(%rax), %rax
movq %rax, 0x88(%rsp)
jmp 0x5cabc
movq 0x10(%r12), %rax
movq %rax, 0x8(%rsp)
movq 0x8(%r15), %rax
movq %rax, 0x38(%rsp)
movl 0x38(%r12), %edi
callq 0x3530e
movq %rax, 0x18(%rsp)
movswq %ax, %rdi
callq 0x3530e
leal -0x21(%rax), %ecx
xorl %ebp, %ebp
cmpw $0x22, %ax
cmovll %ebp, %ecx
cmpq $0x0, 0x20(%r15)
movq %rcx, 0x20(%rsp)
movswl %cx, %eax
movl %eax, 0x10(%rsp)
movq %rbx, 0x30(%rsp)
movq %r13, 0x28(%rsp)
movq %r14, 0x48(%rsp)
movq %r12, 0x40(%rsp)
jne 0x5cb42
movq (%r14), %rax
movq (%rax), %rax
testb $0x10, 0x2e(%rax)
movq 0x38(%rsp), %rdx
je 0x5cb42
cmpq $0x0, 0x60(%r13)
jne 0x5cb42
movb 0x39(%r13), %al
testb $0x5, %al
jne 0x5cb42
movb 0x48(%r12), %cl
andb $0x20, %cl
andb $0x2, %al
orb %cl, %al
je 0x5cef7
testl %ebp, %ebp
jne 0x5cee3
movq 0x8(%rsp), %rbx
testq %rbx, %rbx
je 0x5cee3
movq 0x20(%rsp), %rax
addl 0x18(%rsp), %eax
movq %rax, 0x20(%rsp)
movl $0x1, 0x4(%rsp)
movq %r15, %r13
movq %rbx, 0x8(%rsp)
movq 0x48(%rbx), %r12
testq %r12, %r12
je 0x5cbc3
movq 0x38(%rsp), %rcx
movl 0x14(%rcx), %r15d
xorl %ebp, %ebp
testl %r15d, %r15d
jle 0x5cbb6
movq 0x30(%rsp), %rax
movzbl 0x10(%rax), %ebx
movq 0x20(%rcx), %r14
movq (%r14), %rdi
movq %r12, %rsi
movl %ebx, %edx
callq 0x5db32
testl %eax, %eax
jne 0x5cbc3
addq $0x38, %r14
decl %r15d
jne 0x5cb9c
movq %r13, %r15
movq 0x8(%rsp), %rbx
jmp 0x5ceca
movq 0x30(%rsp), %r12
movl $0x0, 0x18(%r12)
xorl %eax, %eax
movw %ax, 0x2c(%r12)
movb $0x0, 0x11(%r12)
movw %ax, 0x12(%r12)
movq 0x50(%rsp), %rax
movq %rax, (%r12)
movq 0x18(%rsp), %rbp
movw %bp, 0x16(%r12)
movq 0x8(%rsp), %rbx
movq %rbx, 0x20(%r12)
movb 0x63(%rbx), %al
movb $0x1, %dl
testb $0x4, %al
jne 0x5ccec
movq %r13, %r15
movq (%r13), %rcx
movq 0x10(%rcx), %rsi
testq %rsi, %rsi
je 0x5ccef
movslq (%rsi), %rcx
testq %rcx, %rcx
movq 0x28(%rsp), %r13
jle 0x5ccf4
movl 0x3c(%r13), %edx
movq 0x8(%rsi), %rsi
xorl %edi, %edi
movq %rdi, %r9
shlq $0x5, %r9
movq (%rsi,%r9), %r9
testq %r9, %r9
je 0x5cc74
movl 0x4(%r9), %r10d
btl $0xc, %r10d
jae 0x5cc74
btl $0x12, %r10d
jb 0x5cc67
addq $0x10, %r9
jmp 0x5cc6f
movq 0x20(%r9), %r9
movq 0x8(%r9), %r9
movq (%r9), %r9
jmp 0x5cc4a
xorl %r11d, %r11d
cmpb $-0x67, (%r9)
movl $0x0, %r10d
jne 0x5cccd
cmpl %edx, 0x2c(%r9)
jne 0x5ccba
movzwl 0x5e(%rbx), %r10d
testq %r10, %r10
je 0x5ccba
movzwl 0x30(%r9), %r9d
movq 0x8(%rbx), %rbx
xorl %r14d, %r14d
cmpw (%rbx,%r14,2), %r9w
setne %r11b
je 0x5ccc2
incq %r14
cmpq %r14, %r10
jne 0x5cc9f
movb $0x1, %r11b
movl %r8d, %r10d
jmp 0x5ccc8
movb $0x1, %r11b
movl %r8d, %r10d
jmp 0x5cccd
movl $0x1, %r10d
movq 0x8(%rsp), %rbx
testb %r11b, %r11b
je 0x5cce4
incq %rdi
movl %r10d, %r8d
cmpq %rcx, %rdi
jne 0x5cc3f
xorl %r10d, %r10d
testl %r10d, %r10d
sete %dl
jmp 0x5ccf4
movq %r13, %r15
movq 0x28(%rsp), %r13
cmpl $0x0, 0x58(%rbx)
jle 0x5cd42
testb $0x20, %al
jne 0x5cda1
movzwl 0x60(%rbx), %eax
testq %rax, %rax
je 0x5cdae
movq 0x8(%rbx), %rdi
incq %rax
xorl %esi, %esi
xorl %r9d, %r9d
movzwl -0x4(%rdi,%rax,2), %ecx
movl $0x1, %r8d
shlq %cl, %r8
cmpw $0x3f, %cx
cmovaeq %r9, %r8
orq %r8, %rsi
decq %rax
cmpq $0x1, %rax
jg 0x5cd1b
notq %rsi
jmp 0x5cdb5
movl $0x100, 0x28(%r12)      # imm = 0x100
testb %dl, %dl
movl 0x4(%rsp), %eax
movl $0x0, %ecx
cmovnel %ecx, %eax
movb %al, 0x11(%r12)
movswl %bp, %edi
movl 0x10(%rsp), %esi
callq 0x5d44e
addl $0x10, %eax
movw %ax, 0x14(%r12)
movq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x5d4a5
movq %r15, %rdi
movq %r12, %rsi
callq 0x5d0a1
movq %rbp, %rcx
movw %cx, 0x16(%r12)
testl %eax, %eax
je 0x5ceb1
jmp 0x5cee1
movl $0x240, 0x28(%r12)      # imm = 0x240
movb $0x1, %al
jmp 0x5cdcb
movq $-0x1, %rsi
xorl %eax, %eax
testq %rsi, 0x50(%r13)
sete %al
movl %eax, %ecx
orl $0x8, %ecx
shll $0x6, %ecx
movl %ecx, 0x28(%r12)
movl 0x4(%rsp), %ecx
testb %dl, %dl
je 0x5ce32
xorl %ecx, %ecx
movq 0x40(%rsp), %rdx
testb $0x20, 0x48(%rdx)
jne 0x5ce32
testb %al, %al
je 0x5cea9
testb $0x4, 0x63(%rbx)
jne 0x5cea9
movzwl 0x5c(%rbx), %edx
movq 0x40(%rsp), %rsi
cmpw 0x46(%rsi), %dx
jge 0x5cea9
movq 0x48(%rsp), %rdx
testb $0x4, 0x32(%rdx)
jne 0x5cea9
cmpl $0x0, 0x2c485(%rip)     # 0x892a0
je 0x5cea9
movq 0x48(%rsp), %rdx
movq (%rdx), %rdx
movq (%rdx), %rdx
testb $0x40, 0x4c(%rdx)
jne 0x5cea9
movb %cl, 0x11(%r12)
testb %al, %al
je 0x5ce71
movq 0x18(%rsp), %r14
movswl %r14w, %edi
movl 0x10(%rsp), %esi
callq 0x5d44e
movl %eax, %ecx
movswl 0x5c(%rbx), %eax
leal (%rax,%rax,4), %eax
leal (%rax,%rax,2), %eax
movq 0x40(%rsp), %rdx
movswl 0x46(%rdx), %esi
cltd
idivl %esi
addl %ecx, %eax
incl %eax
movw %ax, 0x14(%r12)
jmp 0x5ce81
movq 0x20(%rsp), %rax
movw %ax, 0x14(%r12)
movq 0x18(%rsp), %r14
movq 0x38(%rsp), %rdi
movq %r12, %rsi
callq 0x5d4a5
movq %r15, %rdi
movq %r12, %rsi
callq 0x5d0a1
movw %r14w, 0x16(%r12)
testl %eax, %eax
je 0x5cea9
movl %eax, %ebp
xorl %eax, %eax
jmp 0x5cead
movb $0x1, %al
xorl %ebp, %ebp
testb %al, %al
je 0x5cee3
movq %r15, %rdi
movq %r13, %rsi
movq %rbx, %rdx
xorl %ecx, %ecx
callq 0x5d566
movl %eax, %ebp
cmpq $0x0, 0x60(%r13)
jne 0x5cee3
testl %ebp, %ebp
jne 0x5cee3
movq 0x28(%rbx), %rbx
incl 0x4(%rsp)
testq %rbx, %rbx
jne 0x5cb6e
jmp 0x5cee3
movl %eax, %ebp
movl %ebp, %eax
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movslq 0x14(%rdx), %rax
testq %rax, %rax
jle 0x5cb42
movq 0x20(%rdx), %r12
imulq $0x38, %rax, %r14
addq %r12, %r14
movq 0x18(%rsp), %rax
movq 0x20(%rsp), %rcx
addl %ecx, %eax
addl $0x1c, %eax
movl %eax, 0x4(%rsp)
addq $0x38, %r12
movq 0x30(%rsp), %rax
movq 0x8(%rax), %rax
xorl %ebp, %ebp
testq %rax, -0x10(%r12)
jne 0x5cfc2
leaq -0x38(%r12), %rbx
xorl %ebp, %ebp
movq %rbx, %rdi
movq %r13, %rsi
xorl %edx, %edx
callq 0x5d3ee
testl %eax, %eax
je 0x5cfc2
movq 0x30(%rsp), %r13
movl $0x1, 0x18(%r13)
movq $0x0, 0x20(%r13)
movw $0x1, 0x2c(%r13)
movq 0x30(%r13), %rax
movq %rbx, (%rax)
movl 0x4(%rsp), %eax
movw %ax, 0x12(%r13)
movw $0x2b, 0x16(%r13)
movl 0x10(%rsp), %edi
movl $0x2b, %esi
callq 0x5d44e
movw %ax, 0x14(%r13)
movl $0x4000, 0x28(%r13)     # imm = 0x4000
movq -0x10(%r12), %rax
orq 0x50(%rsp), %rax
movq %rax, (%r13)
movq %r15, %rdi
movq %r13, %rsi
movq 0x28(%rsp), %r13
callq 0x5d0a1
movl %eax, %ebp
testl %ebp, %ebp
jne 0x5cb42
leaq 0x38(%r12), %rax
cmpq %r14, %r12
movq %rax, %r12
jb 0x5cf26
jmp 0x5cb42