// File: /workspace/github_c_makefile_star2_O0/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: sqlite3CodeRhsOfIN
SQLITE_PRIVATE void sqlite3CodeRhsOfIN(
  Parse *pParse,          /* Parsing context */
  Expr *pExpr,            /* The IN operator */
  int iTab                /* Use this cursor number */
){
  int addrOnce = 0;           /* Address of the OP_Once instruction at top */
  int addr;                   /* Address of OP_OpenEphemeral instruction */
  Expr *pLeft;                /* the LHS of the IN operator */
  KeyInfo *pKeyInfo = 0;      /* Key information */
  int nVal;                   /* Size of vector pLeft */
  Vdbe *v;                    /* The prepared statement under construction */

  v = pParse->pVdbe;
  assert( v!=0 );

  /* The evaluation of the IN must be repeated every time it
  ** is encountered if any of the following is true:
  **
  **    *  The right-hand side is a correlated subquery
  **    *  The right-hand side is an expression list containing variables
  **    *  We are inside a trigger
  **
  ** If all of the above are false, then we can compute the RHS just once
  ** and reuse it many names.
  */
  if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){
    /* Reuse of the RHS is allowed */
    /* If this routine has already been coded, but the previous code
    ** might not have been invoked yet, so invoke it now as a subroutine.
    */
    if( ExprHasProperty(pExpr, EP_Subrtn) ){
      addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
      if( ExprHasProperty(pExpr, EP_xIsSelect) ){
        ExplainQueryPlan((pParse, 0, "REUSE LIST SUBQUERY %d",
              pExpr->x.pSelect->selId));
      }
      sqlite3VdbeAddOp2(v, OP_Gosub, pExpr->y.sub.regReturn,
                        pExpr->y.sub.iAddr);
      sqlite3VdbeAddOp2(v, OP_OpenDup, iTab, pExpr->iTable);
      sqlite3VdbeJumpHere(v, addrOnce);
      return;
    }

    /* Begin coding the subroutine */
    ExprSetProperty(pExpr, EP_Subrtn);
    assert( !ExprHasProperty(pExpr, EP_TokenOnly|EP_Reduced) );
    pExpr->y.sub.regReturn = ++pParse->nMem;
    pExpr->y.sub.iAddr =
      sqlite3VdbeAddOp2(v, OP_Integer, 0, pExpr->y.sub.regReturn) + 1;
    VdbeComment((v, "return address"));

    addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v);
  }

  /* Check to see if this is a vector IN operator */
  pLeft = pExpr->pLeft;
  nVal = sqlite3ExprVectorSize(pLeft);

  /* Construct the ephemeral table that will contain the content of
  ** RHS of the IN operator.
  */
  pExpr->iTable = iTab;
  addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, pExpr->iTable, nVal);
#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS
  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
    VdbeComment((v, "Result of SELECT %u", pExpr->x.pSelect->selId));
  }else{
    VdbeComment((v, "RHS of IN operator"));
  }
#endif
  pKeyInfo = sqlite3KeyInfoAlloc(pParse->db, nVal, 1);

  if( ExprHasProperty(pExpr, EP_xIsSelect) ){
    /* Case 1:     expr IN (SELECT ...)
    **
    ** Generate code to write the results of the select into the temporary
    ** table allocated and opened above.
    */
    Select *pSelect = pExpr->x.pSelect;
    ExprList *pEList = pSelect->pEList;

    ExplainQueryPlan((pParse, 1, "%sLIST SUBQUERY %d",
        addrOnce?"":"CORRELATED ", pSelect->selId
    ));
    /* If the LHS and RHS of the IN operator do not match, that
    ** error will have been caught long before we reach this point. */
    if( ALWAYS(pEList->nExpr==nVal) ){
      SelectDest dest;
      int i;
      sqlite3SelectDestInit(&dest, SRT_Set, iTab);
      dest.zAffSdst = exprINAffinity(pParse, pExpr);
      pSelect->iLimit = 0;
      testcase( pSelect->selFlags & SF_Distinct );
      testcase( pKeyInfo==0 ); /* Caused by OOM in sqlite3KeyInfoAlloc() */
      if( sqlite3Select(pParse, pSelect, &dest) ){
        sqlite3DbFree(pParse->db, dest.zAffSdst);
        sqlite3KeyInfoUnref(pKeyInfo);
        return;
      }
      sqlite3DbFree(pParse->db, dest.zAffSdst);
      assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */
      assert( pEList!=0 );
      assert( pEList->nExpr>0 );
      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
      for(i=0; i<nVal; i++){
        Expr *p = sqlite3VectorFieldSubexpr(pLeft, i);
        pKeyInfo->aColl[i] = sqlite3BinaryCompareCollSeq(
            pParse, p, pEList->a[i].pExpr
        );
      }
    }
  }else if( ALWAYS(pExpr->x.pList!=0) ){
    /* Case 2:     expr IN (exprlist)
    **
    ** For each expression, build an index key from the evaluation and
    ** store it in the temporary table. If <expr> is a column, then use
    ** that columns affinity when building index keys. If <expr> is not
    ** a column, use numeric affinity.
    */
    char affinity;            /* Affinity of the LHS of the IN */
    int i;
    ExprList *pList = pExpr->x.pList;
    struct ExprList_item *pItem;
    int r1, r2;
    affinity = sqlite3ExprAffinity(pLeft);
    if( affinity<=SQLITE_AFF_NONE ){
      affinity = SQLITE_AFF_BLOB;
    }else if( affinity==SQLITE_AFF_REAL ){
      affinity = SQLITE_AFF_NUMERIC;
    }
    if( pKeyInfo ){
      assert( sqlite3KeyInfoIsWriteable(pKeyInfo) );
      pKeyInfo->aColl[0] = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    }

    /* Loop through each expression in <exprlist>. */
    r1 = sqlite3GetTempReg(pParse);
    r2 = sqlite3GetTempReg(pParse);
    for(i=pList->nExpr, pItem=pList->a; i>0; i--, pItem++){
      Expr *pE2 = pItem->pExpr;

      /* If the expression is not constant then we will need to
      ** disable the test that was generated above that makes sure
      ** this code only executes once.  Because for a non-constant
      ** expression we need to rerun this code each time.
      */
      if( addrOnce && !sqlite3ExprIsConstant(pE2) ){
        sqlite3VdbeChangeToNoop(v, addrOnce);
        ExprClearProperty(pExpr, EP_Subrtn);
        addrOnce = 0;
      }

      /* Evaluate the expression and insert it into the temp table */
      sqlite3ExprCode(pParse, pE2, r1);
      sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
      sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iTab, r2, r1, 1);
    }
    sqlite3ReleaseTempReg(pParse, r1);
    sqlite3ReleaseTempReg(pParse, r2);
  }
  if( pKeyInfo ){
    sqlite3VdbeChangeP4(v, addr, (void *)pKeyInfo, P4_KEYINFO);
  }
  if( addrOnce ){
    sqlite3VdbeJumpHere(v, addrOnce);
    /* Subroutine return */
    sqlite3VdbeAddOp1(v, OP_Return, pExpr->y.sub.regReturn);
    sqlite3VdbeChangeP1(v, pExpr->y.sub.iAddr-1, sqlite3VdbeCurrentAddr(v)-1);
    sqlite3ClearTempRegCache(pParse);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xd0, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl $0x0, -0x18(%rbp)
movq $0x0, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
andl $0x20, %eax
cmpl $0x0, %eax
jne 0x431bd5
movq -0x8(%rbp), %rax
cmpl $0x0, 0x40(%rax)
jne 0x431bd5
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
andl $0x2000000, %eax        # imm = 0x2000000
cmpl $0x0, %eax
je 0x431b7d
movq -0x40(%rbp), %rdi
movl $0x11, %esi
callq 0x429a40
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0x431b38
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movl 0x10(%rax), %ecx
xorl %esi, %esi
leaq 0x17b053(%rip), %rdx    # 0x5acb84
movb $0x0, %al
callq 0x430b00
movq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x44(%rax), %edx
movq -0x10(%rbp), %rax
movl 0x40(%rax), %ecx
movl $0xc, %esi
callq 0x410100
movq -0x40(%rbp), %rdi
movl -0x14(%rbp), %edx
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %ecx
movl $0x62, %esi
callq 0x410100
movq -0x40(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x429a70
jmp 0x431fbe
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
orl $0x2000000, %ecx        # imm = 0x2000000
movl %ecx, 0x4(%rax)
movq -0x8(%rbp), %rax
movl 0x38(%rax), %ecx
addl $0x1, %ecx
movl %ecx, 0x38(%rax)
movq -0x10(%rbp), %rax
movl %ecx, 0x44(%rax)
movq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x44(%rax), %ecx
movl $0x45, %esi
xorl %edx, %edx
callq 0x410100
movl %eax, %ecx
addl $0x1, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x40(%rax)
movq -0x40(%rbp), %rdi
movl $0x11, %esi
callq 0x429a40
movl %eax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x42d4d0
movl %eax, -0x34(%rbp)
movl -0x14(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x2c(%rax)
movq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x34(%rbp), %ecx
movl $0x64, %esi
callq 0x410100
movl %eax, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movl -0x34(%rbp), %esi
movl $0x1, %edx
callq 0x42a3a0
movq %rax, -0x30(%rbp)
movq -0x10(%rbp), %rax
movl 0x4(%rax), %eax
andl $0x800, %eax            # imm = 0x800
cmpl $0x0, %eax
je 0x431d78
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x48(%rbp)
movq -0x48(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x50(%rbp)
movq -0x8(%rbp), %rdi
movl -0x18(%rbp), %edx
leaq 0x17aec5(%rip), %rcx    # 0x5acb2a
leaq 0x16b9bc(%rip), %rax    # 0x59d628
cmpl $0x0, %edx
cmovneq %rax, %rcx
movq -0x48(%rbp), %rax
movl 0x10(%rax), %r8d
movl $0x1, %esi
leaq 0x17af14(%rip), %rdx    # 0x5acb9b
movb $0x0, %al
callq 0x430b00
movq -0x50(%rbp), %rax
movl (%rax), %eax
cmpl -0x34(%rbp), %eax
jne 0x431d73
movl -0x14(%rbp), %edx
leaq -0x78(%rbp), %rdi
movl $0xb, %esi
callq 0x430c20
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x430d70
movq %rax, -0x60(%rbp)
movq -0x48(%rbp), %rax
movl $0x0, 0x8(%rax)
movq -0x8(%rbp), %rdi
movq -0x48(%rbp), %rsi
leaq -0x78(%rbp), %rdx
callq 0x41aee0
cmpl $0x0, %eax
je 0x431cfe
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x60(%rbp), %rsi
callq 0x3c00a0
movq -0x30(%rbp), %rdi
callq 0x3eb5a0
jmp 0x431fbe
movq -0x8(%rbp), %rax
movq (%rax), %rdi
movq -0x60(%rbp), %rsi
callq 0x3c00a0
movl $0x0, -0x7c(%rbp)
movl -0x7c(%rbp), %eax
cmpl -0x34(%rbp), %eax
jge 0x431d71
movq -0x28(%rbp), %rdi
movl -0x7c(%rbp), %esi
callq 0x42f090
movq %rax, -0x88(%rbp)
movq -0x8(%rbp), %rdi
movq -0x88(%rbp), %rsi
movq -0x50(%rbp), %rax
addq $0x8, %rax
movslq -0x7c(%rbp), %rcx
imulq $0x18, %rcx, %rcx
addq %rcx, %rax
movq (%rax), %rdx
callq 0x412420
movq %rax, %rdx
movq -0x30(%rbp), %rax
movslq -0x7c(%rbp), %rcx
movq %rdx, 0x20(%rax,%rcx,8)
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x431d15
jmp 0x431d73
jmp 0x431f37
movq -0x10(%rbp), %rax
cmpq $0x0, 0x20(%rax)
je 0x431f35
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x98(%rbp)
movq -0x28(%rbp), %rdi
callq 0x42f230
movb %al, -0x89(%rbp)
movsbl -0x89(%rbp), %eax
cmpl $0x40, %eax
jg 0x431dba
movb $0x41, -0x89(%rbp)
jmp 0x431dcf
movsbl -0x89(%rbp), %eax
cmpl $0x45, %eax
jne 0x431dcd
movb $0x43, -0x89(%rbp)
jmp 0x431dcf
cmpq $0x0, -0x30(%rbp)
je 0x431df2
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x4124c0
movq %rax, %rcx
movq -0x30(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x8(%rbp), %rdi
callq 0x42f190
movl %eax, -0xa4(%rbp)
movq -0x8(%rbp), %rdi
callq 0x42f190
movl %eax, -0xa8(%rbp)
movq -0x98(%rbp), %rax
movl (%rax), %eax
movl %eax, -0x90(%rbp)
movq -0x98(%rbp), %rax
addq $0x8, %rax
movq %rax, -0xa0(%rbp)
cmpl $0x0, -0x90(%rbp)
jle 0x431f17
movq -0xa0(%rbp), %rax
movq (%rax), %rax
movq %rax, -0xb0(%rbp)
cmpl $0x0, -0x18(%rbp)
je 0x431e89
movq -0xb0(%rbp), %rdi
callq 0x422b80
cmpl $0x0, %eax
jne 0x431e89
movq -0x40(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x431fd0
movq -0x10(%rbp), %rax
movl 0x4(%rax), %ecx
andl $0xfdffffff, %ecx       # imm = 0xFDFFFFFF
movl %ecx, 0x4(%rax)
movl $0x0, -0x18(%rbp)
movq -0x8(%rbp), %rdi
movq -0xb0(%rbp), %rsi
movl -0xa4(%rbp), %edx
callq 0x429d30
movq -0x40(%rbp), %rdi
movl -0xa4(%rbp), %edx
movl -0xa8(%rbp), %r8d
movl $0x5b, %esi
movl $0x1, %ecx
leaq -0x89(%rbp), %r9
movl $0x1, (%rsp)
callq 0x429aa0
movq -0x40(%rbp), %rdi
movl -0x14(%rbp), %edx
movl -0xa8(%rbp), %ecx
movl -0xa4(%rbp), %r8d
movl $0x82, %esi
movl $0x1, %r9d
callq 0x3cb970
movl -0x90(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x90(%rbp)
movq -0xa0(%rbp), %rax
addq $0x18, %rax
movq %rax, -0xa0(%rbp)
jmp 0x431e31
movq -0x8(%rbp), %rdi
movl -0xa4(%rbp), %esi
callq 0x42e560
movq -0x8(%rbp), %rdi
movl -0xa8(%rbp), %esi
callq 0x42e560
jmp 0x431f37
cmpq $0x0, -0x30(%rbp)
je 0x431f53
movq -0x40(%rbp), %rdi
movl -0x1c(%rbp), %esi
movq -0x30(%rbp), %rdx
movl $0xfffffff7, %ecx       # imm = 0xFFFFFFF7
callq 0x3cbc30
cmpl $0x0, -0x18(%rbp)
je 0x431fbe
movq -0x40(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x429a70
movq -0x40(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x44(%rax), %edx
movl $0x41, %esi
callq 0x42ba70
movq -0x40(%rbp), %rax
movq %rax, -0xc0(%rbp)
movq -0x10(%rbp), %rax
movl 0x40(%rax), %eax
subl $0x1, %eax
movl %eax, -0xb4(%rbp)
movq -0x40(%rbp), %rdi
callq 0x430ae0
movq -0xc0(%rbp), %rdi
movl -0xb4(%rbp), %esi
movl %eax, %edx
subl $0x1, %edx
callq 0x430c80
movq -0x8(%rbp), %rdi
callq 0x430cb0
addq $0xd0, %rsp
popq %rbp
retq
nopw (%rax,%rax)