// File: /workspace/github_c_makefile_star2_O0/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: whereLoopAddVirtual
static int whereLoopAddVirtual(
  WhereLoopBuilder *pBuilder,  /* WHERE clause information */
  Bitmask mPrereq,             /* Tables that must be scanned before this one */
  Bitmask mUnusable            /* Tables that must be scanned after this one */
){
  int rc = SQLITE_OK;          /* Return code */
  WhereInfo *pWInfo;           /* WHERE analysis context */
  Parse *pParse;               /* The parsing context */
  WhereClause *pWC;            /* The WHERE clause */
  struct SrcList_item *pSrc;   /* The FROM clause term to search */
  sqlite3_index_info *p;       /* Object to pass to xBestIndex() */
  int nConstraint;             /* Number of constraints in p */
  int bIn;                     /* True if plan uses IN(...) operator */
  WhereLoop *pNew;
  Bitmask mBest;               /* Tables used by best possible plan */
  u16 mNoOmit;

  assert( (mPrereq & mUnusable)==0 );
  pWInfo = pBuilder->pWInfo;
  pParse = pWInfo->pParse;
  pWC = pBuilder->pWC;
  pNew = pBuilder->pNew;
  pSrc = &pWInfo->pTabList->a[pNew->iTab];
  assert( IsVirtual(pSrc->pTab) );
  p = allocateIndexInfo(pParse, pWC, mUnusable, pSrc, pBuilder->pOrderBy,
      &mNoOmit);
  if( p==0 ) return SQLITE_NOMEM_BKPT;
  pNew->rSetup = 0;
  pNew->wsFlags = WHERE_VIRTUALTABLE;
  pNew->nLTerm = 0;
  pNew->u.vtab.needFree = 0;
  nConstraint = p->nConstraint;
  if( whereLoopResize(pParse->db, pNew, nConstraint) ){
    sqlite3DbFree(pParse->db, p);
    return SQLITE_NOMEM_BKPT;
  }

  /* First call xBestIndex() with all constraints usable. */
  WHERETRACE(0x800, ("BEGIN %s.addVirtual()\n", pSrc->pTab->zName));
  WHERETRACE(0x40, ("  VirtualOne: all usable\n"));
  rc = whereLoopAddVirtualOne(pBuilder, mPrereq, ALLBITS, 0, p, mNoOmit, &bIn);

  /* If the call to xBestIndex() with all terms enabled produced a plan
  ** that does not require any source tables (IOW: a plan with mBest==0)
  ** and does not use an IN(...) operator, then there is no point in making
  ** any further calls to xBestIndex() since they will all return the same
  ** result (if the xBestIndex() implementation is sane). */
  if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){
    int seenZero = 0;             /* True if a plan with no prereqs seen */
    int seenZeroNoIN = 0;         /* Plan with no prereqs and no IN(...) seen */
    Bitmask mPrev = 0;
    Bitmask mBestNoIn = 0;

    /* If the plan produced by the earlier call uses an IN(...) term, call
    ** xBestIndex again, this time with IN(...) terms disabled. */
    if( bIn ){
      WHERETRACE(0x40, ("  VirtualOne: all usable w/o IN\n"));
      rc = whereLoopAddVirtualOne(
          pBuilder, mPrereq, ALLBITS, WO_IN, p, mNoOmit, &bIn);
      assert( bIn==0 );
      mBestNoIn = pNew->prereq & ~mPrereq;
      if( mBestNoIn==0 ){
        seenZero = 1;
        seenZeroNoIN = 1;
      }
    }

    /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq)
    ** in the set of terms that apply to the current virtual table.  */
    while( rc==SQLITE_OK ){
      int i;
      Bitmask mNext = ALLBITS;
      assert( mNext>0 );
      for(i=0; i<nConstraint; i++){
        Bitmask mThis = (
            pWC->a[p->aConstraint[i].iTermOffset].prereqRight & ~mPrereq
        );
        if( mThis>mPrev && mThis<mNext ) mNext = mThis;
      }
      mPrev = mNext;
      if( mNext==ALLBITS ) break;
      if( mNext==mBest || mNext==mBestNoIn ) continue;
      WHERETRACE(0x40, ("  VirtualOne: mPrev=%04llx mNext=%04llx\n",
                       (sqlite3_uint64)mPrev, (sqlite3_uint64)mNext));
      rc = whereLoopAddVirtualOne(
          pBuilder, mPrereq, mNext|mPrereq, 0, p, mNoOmit, &bIn);
      if( pNew->prereq==mPrereq ){
        seenZero = 1;
        if( bIn==0 ) seenZeroNoIN = 1;
      }
    }

    /* If the calls to xBestIndex() in the above loop did not find a plan
    ** that requires no source tables at all (i.e. one guaranteed to be
    ** usable), make a call here with all source tables disabled */
    if( rc==SQLITE_OK && seenZero==0 ){
      WHERETRACE(0x40, ("  VirtualOne: all disabled\n"));
      rc = whereLoopAddVirtualOne(
          pBuilder, mPrereq, mPrereq, 0, p, mNoOmit, &bIn);
      if( bIn==0 ) seenZeroNoIN = 1;
    }

    /* If the calls to xBestIndex() have so far failed to find a plan
    ** that requires no source tables at all and does not use an IN(...)
    ** operator, make a final call to obtain one here.  */
    if( rc==SQLITE_OK && seenZeroNoIN==0 ){
      WHERETRACE(0x40, ("  VirtualOne: all disabled and w/o IN\n"));
      rc = whereLoopAddVirtualOne(
          pBuilder, mPrereq, mPrereq, WO_IN, p, mNoOmit, &bIn);
    }
  }

  if( p->needToFreeIdxStr ) sqlite3_free(p->idxStr);
  sqlite3DbFreeNN(pParse->db, p);
  WHERETRACE(0x800, ("END %s.addVirtual(), rc=%d\n", pSrc->pTab->zName, rc));
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xb0, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq %rdx, -0x20(%rbp)
movl $0x0, -0x24(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movq 0x18(%rax), %rax
movq %rax, -0x60(%rbp)
movq -0x30(%rbp), %rax
movq 0x8(%rax), %rax
addq $0x8, %rax
movq -0x60(%rbp), %rcx
movzbl 0x10(%rcx), %ecx
imulq $0x70, %rcx, %rcx
addq %rcx, %rax
movq %rax, -0x48(%rbp)
movq -0x38(%rbp), %rdi
movq -0x40(%rbp), %rsi
movq -0x20(%rbp), %rdx
movq -0x48(%rbp), %rcx
movq -0x10(%rbp), %rax
movq 0x10(%rax), %r8
leaq -0x6a(%rbp), %r9
callq 0x452270
movq %rax, -0x50(%rbp)
cmpq $0x0, -0x50(%rbp)
jne 0x450e93
movl $0x7, -0x4(%rbp)
jmp 0x4511be
movq -0x60(%rbp), %rax
movw $0x0, 0x12(%rax)
movq -0x60(%rbp), %rax
movl $0x400, 0x28(%rax)      # imm = 0x400
movq -0x60(%rbp), %rax
movw $0x0, 0x2c(%rax)
movq -0x60(%rbp), %rax
movb $0x0, 0x1c(%rax)
movq -0x50(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x54(%rbp)
movq -0x38(%rbp), %rax
movq (%rax), %rdi
movq -0x60(%rbp), %rsi
movl -0x54(%rbp), %edx
callq 0x4527a0
cmpl $0x0, %eax
je 0x450ef7
movq -0x38(%rbp), %rax
movq (%rax), %rdi
movq -0x50(%rbp), %rsi
callq 0x3c00a0
movl $0x7, -0x4(%rbp)
jmp 0x4511be
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x50(%rbp), %r8
movq $-0x1, %rdx
xorl %ecx, %ecx
leaq -0x58(%rbp), %rax
movzwl -0x6a(%rbp), %r9d
movq %rax, (%rsp)
callq 0x452870
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x24(%rbp)
jne 0x451191
movq -0x60(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, -0x68(%rbp)
cmpq $0x0, %rax
jne 0x450f51
cmpl $0x0, -0x58(%rbp)
je 0x451191
movl $0x0, -0x70(%rbp)
movl $0x0, -0x74(%rbp)
movq $0x0, -0x80(%rbp)
movq $0x0, -0x88(%rbp)
cmpl $0x0, -0x58(%rbp)
je 0x450fd8
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x50(%rbp), %r8
movq $-0x1, %rdx
movl $0x1, %ecx
leaq -0x58(%rbp), %rax
movzwl -0x6a(%rbp), %r9d
movq %rax, (%rsp)
callq 0x452870
movl %eax, -0x24(%rbp)
movq -0x60(%rbp), %rax
movq (%rax), %rax
movq -0x18(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
jne 0x450fd6
movl $0x1, -0x70(%rbp)
movl $0x1, -0x74(%rbp)
jmp 0x450fd8
jmp 0x450fda
cmpl $0x0, -0x24(%rbp)
jne 0x451117
movq $-0x1, -0x98(%rbp)
movl $0x0, -0x8c(%rbp)
movl -0x8c(%rbp), %eax
cmpl -0x54(%rbp), %eax
jge 0x451088
movq -0x40(%rbp), %rax
movq 0x20(%rax), %rax
movq -0x50(%rbp), %rcx
movq 0x8(%rcx), %rcx
movslq -0x8c(%rbp), %rdx
imulq $0xc, %rdx, %rdx
addq %rdx, %rcx
movslq 0x8(%rcx), %rcx
shlq $0x6, %rcx
addq %rcx, %rax
movq 0x30(%rax), %rax
movq -0x18(%rbp), %rcx
xorq $-0x1, %rcx
andq %rcx, %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0x80(%rbp), %rax
jbe 0x451072
movq -0xa0(%rbp), %rax
cmpq -0x98(%rbp), %rax
jae 0x451072
movq -0xa0(%rbp), %rax
movq %rax, -0x98(%rbp)
jmp 0x451074
movl -0x8c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x8c(%rbp)
jmp 0x450ff9
movq -0x98(%rbp), %rax
movq %rax, -0x80(%rbp)
cmpq $-0x1, -0x98(%rbp)
jne 0x45109f
jmp 0x451117
movq -0x98(%rbp), %rax
cmpq -0x68(%rbp), %rax
je 0x4510bc
movq -0x98(%rbp), %rax
cmpq -0x88(%rbp), %rax
jne 0x4510c1
jmp 0x450fda
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x98(%rbp), %rdx
orq -0x18(%rbp), %rdx
movq -0x50(%rbp), %r8
xorl %ecx, %ecx
leaq -0x58(%rbp), %rax
movzwl -0x6a(%rbp), %r9d
movq %rax, (%rsp)
callq 0x452870
movl %eax, -0x24(%rbp)
movq -0x60(%rbp), %rax
movq (%rax), %rax
cmpq -0x18(%rbp), %rax
jne 0x451112
movl $0x1, -0x70(%rbp)
cmpl $0x0, -0x58(%rbp)
jne 0x451110
movl $0x1, -0x74(%rbp)
jmp 0x451112
jmp 0x450fda
cmpl $0x0, -0x24(%rbp)
jne 0x451159
cmpl $0x0, -0x70(%rbp)
jne 0x451159
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x50(%rbp), %r8
xorl %ecx, %ecx
leaq -0x58(%rbp), %rax
movzwl -0x6a(%rbp), %r9d
movq %rax, (%rsp)
callq 0x452870
movl %eax, -0x24(%rbp)
cmpl $0x0, -0x58(%rbp)
jne 0x451157
movl $0x1, -0x74(%rbp)
jmp 0x451159
cmpl $0x0, -0x24(%rbp)
jne 0x45118f
cmpl $0x0, -0x74(%rbp)
jne 0x45118f
movq -0x10(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x18(%rbp), %rdx
movq -0x50(%rbp), %r8
movl $0x1, %ecx
leaq -0x58(%rbp), %rax
movzwl -0x6a(%rbp), %r9d
movq %rax, (%rsp)
callq 0x452870
movl %eax, -0x24(%rbp)
jmp 0x451191
movq -0x50(%rbp), %rax
cmpl $0x0, 0x38(%rax)
je 0x4511a8
movq -0x50(%rbp), %rax
movq 0x30(%rax), %rdi
callq 0x3c0800
movq -0x38(%rbp), %rax
movq (%rax), %rdi
movq -0x50(%rbp), %rsi
callq 0x3d5ff0
movl -0x24(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0xb0, %rsp
popq %rbp
retq
nopw (%rax,%rax)