// File: /workspace/github_c_makefile_star2_O2/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movl %ecx, %r14d
movl %edx, %ebx
movq %rsi, %r13
movq %rdi, %r15
leaq -0x50(%rbp), %rcx
andl $0x0, (%rcx)
movq 0x10(%rdi), %rax
movq %rax, -0x40(%rbp)
xorl %eax, %eax
cmpl %r14d, %edx
cmoveq %rax, %rcx
pushq $0x3
popq %rdx
callq 0x4deec
movl %eax, %r12d
movq %r13, %rdi
callq 0x4e23d
movb %al, -0x29(%rbp)
movb %al, -0x32(%rbp)
incl 0x74(%r15)
movq %r15, %rdi
callq 0x4c550
movq 0x10(%r13), %rsi
movq %r15, %rdi
movl %eax, -0x30(%rbp)
movl %eax, %edx
callq 0x4a07d
movl %r12d, -0x48(%rbp)
cmpl $0x5, %r12d
movq -0x40(%rbp), %r12
jne 0x4c408
movq 0x10(%r13), %rsi
movq 0x20(%r13), %rax
movq %rax, -0x48(%rbp)
movq %r15, %rdi
callq 0x4bb0b
movq %rax, -0x60(%rbp)
movq %r12, %rdi
callq 0x4b9c2
movl %eax, -0x4c(%rbp)
movl %ebx, -0x38(%rbp)
cmpl %r14d, %ebx
movl $0x0, %r13d
movl -0x30(%rbp), %ebx
je 0x4c2c6
movq %r15, %rdi
callq 0x4c550
movl %eax, %r13d
pushq $0x55
popq %rsi
movq -0x40(%rbp), %rdi
movl %ebx, %edx
movl %ebx, %ecx
movl %eax, %r8d
callq 0x385b6
movb -0x29(%rbp), %al
orb $0x10, %al
movb %al, -0x31(%rbp)
xorl %ebx, %ebx
xorl %r12d, %r12d
movq %r15, -0x70(%rbp)
movq %r13, -0x68(%rbp)
movq -0x48(%rbp), %rcx
movslq (%rcx), %rax
cmpq %rax, %r12
jge 0x4c3c4
movq 0x8(%rcx), %rax
movq (%rax,%rbx), %rsi
movq %r15, %rdi
leaq -0x54(%rbp), %rdx
callq 0x4b846
movl %eax, %r15d
testl %r13d, %r13d
je 0x4c331
movq -0x48(%rbp), %rax
movq 0x8(%rax), %rax
movq (%rax,%rbx), %rdi
callq 0x4e28c
testl %eax, %eax
je 0x4c331
movq -0x40(%rbp), %rdi
pushq $0x55
popq %rsi
movl %r13d, %edx
movl %r15d, %ecx
movl %r13d, %r8d
callq 0x385b6
movl %r14d, %r13d
cmpl %r14d, -0x38(%rbp)
jne 0x4c371
movq -0x48(%rbp), %rax
movslq (%rax), %rax
decq %rax
cmpq %rax, %r12
jl 0x4c371
movl $0xfffffffc, (%rsp)     # imm = 0xFFFFFFFC
movq -0x40(%rbp), %r14
movq %r14, %rdi
pushq $0x4e
popq %rsi
movl -0x30(%rbp), %edx
movl -0x38(%rbp), %ecx
movl %r15d, %r8d
movq -0x60(%rbp), %r9
callq 0x4a044
movb -0x31(%rbp), %al
jmp 0x4c397
movl $0xfffffffc, (%rsp)     # imm = 0xFFFFFFFC
movq -0x40(%rbp), %r14
movq %r14, %rdi
pushq $0x4f
popq %rsi
movl -0x30(%rbp), %edx
movl -0x4c(%rbp), %ecx
movl %r15d, %r8d
movq -0x60(%rbp), %r9
callq 0x4a044
movb -0x29(%rbp), %al
movzbl %al, %esi
movq %r14, %rdi
callq 0x13770
movl -0x54(%rbp), %esi
movq -0x70(%rbp), %r15
movq %r15, %rdi
callq 0x4c573
incq %r12
addq $0x20, %rbx
movl %r13d, %r14d
movq -0x68(%rbp), %r13
jmp 0x4c2db
testl %r13d, %r13d
movq -0x40(%rbp), %rbx
je 0x4c3e9
pushq $0x4c
popq %rsi
movq %rbx, %rdi
movl %r13d, %edx
movl %r14d, %ecx
callq 0x4a1ab
movq %rbx, %rdi
movl -0x38(%rbp), %esi
callq 0x4a0cb
movq %rbx, %rdi
movl -0x4c(%rbp), %esi
callq 0x4bacf
movq %r15, %rdi
movl %r13d, %esi
callq 0x4c573
movl -0x30(%rbp), %r12d
jmp 0x4c52e
movq 0x10(%r13), %rdi
callq 0x4e28c
testl %eax, %eax
je 0x4c46f
cmpl %r14d, %ebx
je 0x4c45e
pushq $0x4d
popq %rsi
movl %r14d, %r12d
movq -0x40(%rbp), %r14
movq %r14, %rdi
movl -0x30(%rbp), %edx
callq 0x4b9b3
movl %eax, -0x38(%rbp)
movl 0x2c(%r13), %edx
pushq $0x6e
popq %rsi
movq %r14, %rdi
movl %ebx, %ecx
callq 0x4a1ab
movq %r14, %rdi
movl %r12d, %esi
callq 0x4a0cb
movq %r14, %rdi
movl %r12d, %r14d
movl -0x38(%rbp), %esi
callq 0x4a022
jmp 0x4c46f
pushq $0x4c
popq %rsi
movq -0x40(%rbp), %rdi
movl -0x30(%rbp), %edx
movl %ebx, %ecx
callq 0x4a1ab
cmpl $0x1, -0x48(%rbp)
jne 0x4c4a6
pushq $0x27
popq %rsi
movq -0x40(%rbp), %r14
movq %r14, %rdi
movl -0x30(%rbp), %r12d
movl %r12d, %edx
movl %ebx, %ecx
callq 0x4a1ab
movl 0x2c(%r13), %edx
pushq $0x4a
popq %rsi
movq %r14, %rdi
movl %ebx, %ecx
movl %r12d, %r8d
callq 0x385b6
jmp 0x4c52e
movl %r14d, -0x48(%rbp)
movl $0x1, (%rsp)
pushq $0x31
popq %rsi
pushq $0x1
popq %rcx
leaq -0x32(%rbp), %r9
movq -0x40(%rbp), %r14
movq %r14, %rdi
movl -0x30(%rbp), %r12d
movl %r12d, %edx
xorl %r8d, %r8d
callq 0x4a044
cmpl $0x0, -0x50(%rbp)
movl 0x2c(%r13), %edx
je 0x4c51a
pushq $0x49
popq %rsi
pushq $0x1
popq %r9
movq %r14, %rdi
xorl %ecx, %ecx
movl %r12d, %r8d
callq 0x1373a
movl %eax, %r13d
movl -0x50(%rbp), %edx
pushq $0x4c
popq %rsi
movq %r14, %rdi
movl -0x48(%rbp), %ecx
callq 0x4a1ab
movq %r14, %rdi
movl %ebx, %esi
callq 0x4a0cb
movq %r14, %rdi
movl %r13d, %esi
callq 0x4a022
jmp 0x4c52e
pushq $0x46
popq %rsi
pushq $0x1
popq %r9
movq %r14, %rdi
movl %ebx, %ecx
movl %r12d, %r8d
callq 0x1373a
movq %r15, %rdi
movl %r12d, %esi
callq 0x4c573
movq %r15, %rdi
callq 0x4ba7d
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq