// File: /workspace/github_c_makefile_star2_O0/shifengbin[P]bishe/Output/../Persistence/sqlite3.c
// Function: sqlite3ExprCodeIN
static void sqlite3ExprCodeIN(
  Parse *pParse,        /* Parsing and code generating context */
  Expr *pExpr,          /* The IN expression */
  int destIfFalse,      /* Jump here if LHS is not contained in the RHS */
  int destIfNull        /* Jump here if the results are unknown due to NULLs */
){
  int rRhsHasNull = 0;  /* Register that is true if RHS contains NULL values */
  char affinity;        /* Comparison affinity to use */
  int eType;            /* Type of the RHS */
  int r1;               /* Temporary use register */
  Vdbe *v;              /* Statement under construction */

  /* Compute the RHS.   After this step, the table with cursor
  ** pExpr->iTable will contains the values that make up the RHS.
  */
  v = pParse->pVdbe;
  assert( v!=0 );       /* OOM detected prior to this routine */
  VdbeNoopComment((v, "begin IN expr"));
  eType = sqlite3FindInIndex(pParse, pExpr,
                             IN_INDEX_MEMBERSHIP | IN_INDEX_NOOP_OK,
                             destIfFalse==destIfNull ? 0 : &rRhsHasNull);

  /* Figure out the affinity to use to create a key from the results
  ** of the expression. affinityStr stores a static string suitable for
  ** P4 of OP_MakeRecord.
  */
  affinity = comparisonAffinity(pExpr);

  /* Code the LHS, the <expr> from "<expr> IN (...)".
  */
  sqlite3ExprCachePush(pParse);
  r1 = sqlite3GetTempReg(pParse);
  sqlite3ExprCode(pParse, pExpr->pLeft, r1);

  /* If sqlite3FindInIndex() did not find or create an index that is
  ** suitable for evaluating the IN operator, then evaluate using a
  ** sequence of comparisons.
  */
  if( eType==IN_INDEX_NOOP ){
    ExprList *pList = pExpr->x.pList;
    CollSeq *pColl = sqlite3ExprCollSeq(pParse, pExpr->pLeft);
    int labelOk = sqlite3VdbeMakeLabel(v);
    int r2, regToFree;
    int regCkNull = 0;
    int ii;
    assert( !ExprHasProperty(pExpr, EP_xIsSelect) );
    if( destIfNull!=destIfFalse ){
      regCkNull = sqlite3GetTempReg(pParse);
      sqlite3VdbeAddOp3(v, OP_BitAnd, r1, r1, regCkNull);
    }
    for(ii=0; ii<pList->nExpr; ii++){
      r2 = sqlite3ExprCodeTemp(pParse, pList->a[ii].pExpr, &regToFree);
      if( regCkNull && sqlite3ExprCanBeNull(pList->a[ii].pExpr) ){
        sqlite3VdbeAddOp3(v, OP_BitAnd, regCkNull, r2, regCkNull);
      }
      if( ii<pList->nExpr-1 || destIfNull!=destIfFalse ){
        sqlite3VdbeAddOp4(v, OP_Eq, r1, labelOk, r2,
                          (void*)pColl, P4_COLLSEQ);
        VdbeCoverageIf(v, ii<pList->nExpr-1);
        VdbeCoverageIf(v, ii==pList->nExpr-1);
        sqlite3VdbeChangeP5(v, affinity);
      }else{
        assert( destIfNull==destIfFalse );
        sqlite3VdbeAddOp4(v, OP_Ne, r1, destIfFalse, r2,
                          (void*)pColl, P4_COLLSEQ); VdbeCoverage(v);
        sqlite3VdbeChangeP5(v, affinity | SQLITE_JUMPIFNULL);
      }
      sqlite3ReleaseTempReg(pParse, regToFree);
    }
    if( regCkNull ){
      sqlite3VdbeAddOp2(v, OP_IsNull, regCkNull, destIfNull); VdbeCoverage(v);
      sqlite3VdbeGoto(v, destIfFalse);
    }
    sqlite3VdbeResolveLabel(v, labelOk);
    sqlite3ReleaseTempReg(pParse, regCkNull);
  }else{
  
    /* If the LHS is NULL, then the result is either false or NULL depending
    ** on whether the RHS is empty or not, respectively.
    */
    if( sqlite3ExprCanBeNull(pExpr->pLeft) ){
      if( destIfNull==destIfFalse ){
        /* Shortcut for the common case where the false and NULL outcomes are
        ** the same. */
        sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull); VdbeCoverage(v);
      }else{
        int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1); VdbeCoverage(v);
        sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
        VdbeCoverage(v);
        sqlite3VdbeGoto(v, destIfNull);
        sqlite3VdbeJumpHere(v, addr1);
      }
    }
  
    if( eType==IN_INDEX_ROWID ){
      /* In this case, the RHS is the ROWID of table b-tree
      */
      sqlite3VdbeAddOp2(v, OP_MustBeInt, r1, destIfFalse); VdbeCoverage(v);
      sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
      VdbeCoverage(v);
    }else{
      /* In this case, the RHS is an index b-tree.
      */
      sqlite3VdbeAddOp4(v, OP_Affinity, r1, 1, 0, &affinity, 1);
  
      /* If the set membership test fails, then the result of the 
      ** "x IN (...)" expression must be either 0 or NULL. If the set
      ** contains no NULL values, then the result is 0. If the set 
      ** contains one or more NULL values, then the result of the
      ** expression is also NULL.
      */
      assert( destIfFalse!=destIfNull || rRhsHasNull==0 );
      if( rRhsHasNull==0 ){
        /* This branch runs if it is known at compile time that the RHS
        ** cannot contain NULL values. This happens as the result
        ** of a "NOT NULL" constraint in the database schema.
        **
        ** Also run this branch if NULL is equivalent to FALSE
        ** for this particular IN operator.
        */
        sqlite3VdbeAddOp4Int(v, OP_NotFound, pExpr->iTable, destIfFalse, r1, 1);
        VdbeCoverage(v);
      }else{
        /* In this branch, the RHS of the IN might contain a NULL and
        ** the presence of a NULL on the RHS makes a difference in the
        ** outcome.
        */
        int addr1;
  
        /* First check to see if the LHS is contained in the RHS.  If so,
        ** then the answer is TRUE the presence of NULLs in the RHS does
        ** not matter.  If the LHS is not contained in the RHS, then the
        ** answer is NULL if the RHS contains NULLs and the answer is
        ** FALSE if the RHS is NULL-free.
        */
        addr1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);
        VdbeCoverage(v);
        sqlite3VdbeAddOp2(v, OP_IsNull, rRhsHasNull, destIfNull);
        VdbeCoverage(v);
        sqlite3VdbeGoto(v, destIfFalse);
        sqlite3VdbeJumpHere(v, addr1);
      }
    }
  }
  sqlite3ReleaseTempReg(pParse, r1);
  sqlite3ExprCachePop(pParse);
  VdbeComment((v, "end IN expr"));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x80, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl %edx, -0x14(%rbp)
movl %ecx, -0x18(%rbp)
movl $0x0, -0x1c(%rbp)
movq -0x8(%rbp), %rax
movq 0x10(%rax), %rax
movq %rax, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq %rax, -0x70(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x68(%rbp)
movl -0x14(%rbp), %eax
cmpl -0x18(%rbp), %eax
jne 0x6f5cc
xorl %eax, %eax
movq %rax, -0x78(%rbp)
jmp 0x6f5d6
leaq -0x1c(%rbp), %rax
movq %rax, -0x78(%rbp)
jmp 0x6f5d6
movq -0x68(%rbp), %rsi
movq -0x70(%rbp), %rdi
movq -0x78(%rbp), %rcx
movl $0x3, %edx
callq 0x72690
movl %eax, -0x24(%rbp)
movq -0x10(%rbp), %rdi
callq 0x72ab0
movb %al, -0x1d(%rbp)
movq -0x8(%rbp), %rdi
callq 0x6e6d0
movq -0x8(%rbp), %rdi
callq 0x6f960
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
movl -0x28(%rbp), %edx
callq 0x6c120
cmpl $0x5, -0x24(%rbp)
jne 0x6f7e5
movq -0x10(%rbp), %rax
movq 0x20(%rax), %rax
movq %rax, -0x38(%rbp)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rsi
callq 0x6e810
movq %rax, -0x40(%rbp)
movq -0x30(%rbp), %rdi
callq 0x6e5a0
movl %eax, -0x44(%rbp)
movl $0x0, -0x50(%rbp)
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
je 0x6f68e
movq -0x8(%rbp), %rdi
callq 0x6f960
movl %eax, -0x50(%rbp)
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl -0x28(%rbp), %ecx
movl -0x50(%rbp), %r8d
movl $0x55, %esi
callq 0x56c10
movl $0x0, -0x54(%rbp)
movl -0x54(%rbp), %eax
movq -0x38(%rbp), %rcx
cmpl (%rcx), %eax
jge 0x6f7a2
movq -0x8(%rbp), %rdi
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x54(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq (%rax), %rsi
leaq -0x4c(%rbp), %rdx
callq 0x6e360
movl %eax, -0x48(%rbp)
cmpl $0x0, -0x50(%rbp)
je 0x6f708
movq -0x38(%rbp), %rax
movq 0x8(%rax), %rax
movslq -0x54(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movq (%rax), %rdi
callq 0x72b40
cmpl $0x0, %eax
je 0x6f708
movq -0x30(%rbp), %rdi
movl -0x50(%rbp), %edx
movl -0x48(%rbp), %ecx
movl -0x50(%rbp), %r8d
movl $0x55, %esi
callq 0x56c10
movl -0x54(%rbp), %eax
movq -0x38(%rbp), %rcx
movl (%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jl 0x6f720
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
je 0x6f752
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl -0x44(%rbp), %ecx
movl -0x48(%rbp), %r8d
movq -0x40(%rbp), %r9
movl $0x4f, %esi
movl $0xfffffffc, (%rsp)     # imm = 0xFFFFFFFC
callq 0x6be70
movq -0x30(%rbp), %rdi
movzbl -0x1d(%rbp), %esi
callq 0x17b70
jmp 0x6f788
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl -0x14(%rbp), %ecx
movl -0x48(%rbp), %r8d
movq -0x40(%rbp), %r9
movl $0x4e, %esi
movl $0xfffffffc, (%rsp)     # imm = 0xFFFFFFFC
callq 0x6be70
movq -0x30(%rbp), %rdi
movsbl -0x1d(%rbp), %eax
orl $0x10, %eax
movzbl %al, %esi
callq 0x17b70
movq -0x8(%rbp), %rdi
movl -0x4c(%rbp), %esi
callq 0x6f9b0
movl -0x54(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x54(%rbp)
jmp 0x6f695
cmpl $0x0, -0x50(%rbp)
je 0x6f7c8
movq -0x30(%rbp), %rdi
movl -0x50(%rbp), %edx
movl -0x18(%rbp), %ecx
movl $0x4c, %esi
callq 0x6c310
movq -0x30(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x6c1b0
movq -0x30(%rbp), %rdi
movl -0x44(%rbp), %esi
callq 0x6e780
movq -0x8(%rbp), %rdi
movl -0x50(%rbp), %esi
callq 0x6f9b0
jmp 0x6f938
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x72b40
cmpl $0x0, %eax
je 0x6f85b
movl -0x18(%rbp), %eax
cmpl -0x14(%rbp), %eax
jne 0x6f815
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl -0x18(%rbp), %ecx
movl $0x4c, %esi
callq 0x6c310
jmp 0x6f859
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl $0x4d, %esi
callq 0x6e570
movl %eax, -0x58(%rbp)
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x14(%rbp), %ecx
movl $0x6e, %esi
callq 0x6c310
movq -0x30(%rbp), %rdi
movl -0x18(%rbp), %esi
callq 0x6c1b0
movq -0x30(%rbp), %rdi
movl -0x58(%rbp), %esi
callq 0x6be30
jmp 0x6f85b
cmpl $0x1, -0x24(%rbp)
jne 0x6f896
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl -0x14(%rbp), %ecx
movl $0x27, %esi
callq 0x6c310
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x14(%rbp), %ecx
movl -0x28(%rbp), %r8d
movl $0x4a, %esi
callq 0x56c10
jmp 0x6f936
movq -0x30(%rbp), %rdi
movl -0x28(%rbp), %edx
movl $0x31, %esi
movl $0x1, %ecx
xorl %r8d, %r8d
leaq -0x1d(%rbp), %r9
movl $0x1, (%rsp)
callq 0x6be70
cmpl $0x0, -0x1c(%rbp)
jne 0x6f8e4
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x14(%rbp), %ecx
movl -0x28(%rbp), %r8d
movl $0x46, %esi
movl $0x1, %r9d
callq 0x17b10
jmp 0x6f934
movq -0x30(%rbp), %rdi
movq -0x10(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x28(%rbp), %r8d
movl $0x49, %esi
xorl %ecx, %ecx
movl $0x1, %r9d
callq 0x17b10
movl %eax, -0x5c(%rbp)
movq -0x30(%rbp), %rdi
movl -0x1c(%rbp), %edx
movl -0x18(%rbp), %ecx
movl $0x4c, %esi
callq 0x6c310
movq -0x30(%rbp), %rdi
movl -0x14(%rbp), %esi
callq 0x6c1b0
movq -0x30(%rbp), %rdi
movl -0x5c(%rbp), %esi
callq 0x6be30
jmp 0x6f936
jmp 0x6f938
movq -0x8(%rbp), %rdi
movl -0x28(%rbp), %esi
callq 0x6f9b0
movq -0x8(%rbp), %rdi
callq 0x6e6f0
addq $0x80, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)