// File: /workspace/github_c_makefile_star2_O2/barabo[P]advanced-shell-history/src/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, &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 the LHS is NULL, then the result is either false or NULL depending
  ** on whether the RHS is empty or not, respectively.
  */
  if( destIfNull==destIfFalse ){
    /* Shortcut for the common case where the false and NULL outcomes are
    ** the same. */
    sqlite3VdbeAddOp2(v, OP_IsNull, r1, destIfNull);
  }else{
    int addr1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1);
    sqlite3VdbeAddOp2(v, OP_Rewind, pExpr->iTable, destIfFalse);
    sqlite3VdbeAddOp2(v, OP_Goto, 0, 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);
    sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, destIfFalse, r1);
  }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.
    */
    if( rRhsHasNull==0 || destIfFalse==destIfNull ){
      /* 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);

    }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 j1, j2, j3;

      /* First check to see if the LHS is contained in the RHS.  If so,
      ** then the presence of NULLs in the RHS does not matter, so jump
      ** over all of the code that follows.
      */
      j1 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, r1, 1);

      /* Here we begin generating code that runs if the LHS is not
      ** contained within the RHS.  Generate additional code that
      ** tests the RHS for NULLs.  If the RHS contains a NULL then
      ** jump to destIfNull.  If there are no NULLs in the RHS then
      ** jump to destIfFalse.
      */
      j2 = sqlite3VdbeAddOp1(v, OP_NotNull, rRhsHasNull);
      j3 = sqlite3VdbeAddOp4Int(v, OP_Found, pExpr->iTable, 0, rRhsHasNull, 1);
      sqlite3VdbeAddOp2(v, OP_Integer, -1, rRhsHasNull);
      sqlite3VdbeJumpHere(v, j3);
      sqlite3VdbeAddOp2(v, OP_AddImm, rRhsHasNull, 1);
      sqlite3VdbeJumpHere(v, j2);

      /* Jump to the appropriate target depending on whether or not
      ** the RHS contains a NULL
      */
      sqlite3VdbeAddOp2(v, OP_If, rRhsHasNull, destIfNull);
      sqlite3VdbeAddOp2(v, OP_Goto, 0, destIfFalse);

      /* The OP_Found at the top of this branch jumps here when true, 
      ** causing the overall IN expression evaluation to fall through.
      */
      sqlite3VdbeJumpHere(v, j1);
    }
  }
  sqlite3ReleaseTempReg(pParse, r1);
  sqlite3ExprCachePop(pParse, 1);
  VdbeComment((v, "end IN expr"));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movl %ecx, -0x3c(%rbp)
movl %edx, %r14d
movq %rsi, %rbx
movq %rdi, %r15
leaq -0x30(%rbp), %rdx
andl $0x0, (%rdx)
movq 0x10(%rdi), %r13
callq 0x49c33
movl %eax, -0x40(%rbp)
movq %rbx, %rdi
callq 0x49fab
movb %al, -0x29(%rbp)
incl 0x6c(%r15)
movq %r15, %rdi
callq 0x46ff9
movl %eax, %r12d
movq 0x10(%rbx), %rsi
movq %r15, -0x50(%rbp)
movq %r15, %rdi
movl -0x3c(%rbp), %r15d
movl %eax, %edx
callq 0x494eb
cmpl %r14d, %r15d
movl %r14d, -0x38(%rbp)
movl %r12d, -0x34(%rbp)
movq %rbx, -0x48(%rbp)
jne 0x482c8
pushq $0x49
popq %rsi
movq %r13, %rdi
movl %r12d, %edx
movl %r15d, %ecx
callq 0x41f42
movl %r15d, %ebx
movq %r13, %r15
jmp 0x4831d
pushq $0x4a
popq %rsi
movq %r13, %rdi
movl %r12d, %edx
callq 0x42436
movl %eax, %r12d
movl 0x2c(%rbx), %edx
pushq $0x65
popq %rsi
movq %r13, %rdi
movl %r14d, %ecx
callq 0x41f42
pushq $0xe
popq %rsi
movq %r13, %rdi
xorl %edx, %edx
movl %r15d, %ecx
callq 0x41f42
testl %r12d, %r12d
movl %r15d, %ebx
movq %r13, %r15
js 0x4831d
movl 0x34(%r15), %eax
cmpl %r12d, %eax
jbe 0x4831d
movq 0x8(%r15), %rcx
movl %r12d, %edx
imulq $0x18, %rdx, %rdx
movl %eax, 0x8(%rcx,%rdx)
cmpl $0x1, -0x40(%rbp)
jne 0x48359
pushq $0x21
popq %rsi
movq %r15, %rdi
movl -0x34(%rbp), %r12d
movl %r12d, %edx
movl -0x38(%rbp), %r14d
movl %r14d, %ecx
callq 0x41f42
movq -0x48(%rbp), %rax
movl 0x2c(%rax), %edx
pushq $0x3f
popq %rsi
movq %r15, %rdi
movl %r14d, %ecx
movl %r12d, %r8d
callq 0x41f4c
jmp 0x4848d
movl $0x1, (%rsp)
pushq $0x2a
popq %rsi
pushq $0x1
popq %rcx
leaq -0x29(%rbp), %r9
movq %r15, %rdi
movl -0x34(%rbp), %r12d
movl %r12d, %edx
xorl %r8d, %r8d
callq 0x41fd2
movq -0x48(%rbp), %r13
movl 0x2c(%r13), %edx
movl -0x38(%rbp), %ecx
cmpl %ecx, %ebx
je 0x4847b
cmpl $0x0, -0x30(%rbp)
je 0x4847b
pushq $0x3d
popq %rsi
pushq $0x1
popq %r14
movq %r15, %rdi
xorl %ecx, %ecx
movl %r12d, %r8d
movl %r14d, %r9d
callq 0x49ffa
movl %eax, %ebx
movl -0x30(%rbp), %edx
pushq $0x4a
popq %rsi
movq %r15, %rdi
callq 0x42436
movl %eax, %r12d
movl 0x2c(%r13), %edx
movl -0x30(%rbp), %r8d
movq %r15, %rdi
pushq $0x3d
popq %rsi
xorl %ecx, %ecx
movl %r14d, %r9d
callq 0x49ffa
movl %eax, %r13d
movl -0x30(%rbp), %ecx
pushq $0x15
popq %rsi
pushq $-0x1
popq %rdx
movq %r15, %rdi
callq 0x41f42
testl %r13d, %r13d
js 0x4840c
movl 0x34(%r15), %eax
cmpl %r13d, %eax
jbe 0x4840c
movq 0x8(%r15), %rcx
movl %r13d, %edx
imulq $0x18, %rdx, %rdx
movl %eax, 0x8(%rcx,%rdx)
movl -0x30(%rbp), %edx
pushq $0x20
popq %rsi
pushq $0x1
popq %rcx
movq %r15, %rdi
callq 0x41f42
testl %r12d, %r12d
js 0x4843a
movl 0x34(%r15), %eax
cmpl %r12d, %eax
jbe 0x4843a
movq 0x8(%r15), %rcx
movl %r12d, %edx
imulq $0x18, %rdx, %rdx
movl %eax, 0x8(%rcx,%rdx)
movl -0x30(%rbp), %edx
pushq $0x27
popq %rsi
movq %r15, %rdi
movl -0x3c(%rbp), %ecx
callq 0x41f42
pushq $0xe
popq %rsi
movq %r15, %rdi
xorl %edx, %edx
movl -0x38(%rbp), %ecx
callq 0x41f42
testl %ebx, %ebx
movl -0x34(%rbp), %r12d
js 0x4848d
movl 0x34(%r15), %eax
cmpl %ebx, %eax
jbe 0x4848d
movq 0x8(%r15), %rcx
movl %ebx, %edx
imulq $0x18, %rdx, %rdx
movl %eax, 0x8(%rcx,%rdx)
jmp 0x4848d
pushq $0x3c
popq %rsi
pushq $0x1
popq %r9
movq %r15, %rdi
movl %r12d, %r8d
callq 0x49ffa
movq -0x50(%rbp), %rbx
movq %rbx, %rdi
movl %r12d, %esi
callq 0x4701c
movq %rbx, %rdi
callq 0x4803b
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq