// File: /workspace/github_c_makefile_star2_O3/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, -0x48(%rbp)
movl %edx, %r12d
movq %rsi, %r13
movq %rdi, %rbx
leaq -0x30(%rbp), %rdx
movl $0x0, (%rdx)
movq 0x10(%rdi), %rax
movq %rax, -0x40(%rbp)
callq 0x4efb3
movl %eax, -0x34(%rbp)
movq %r13, %rdi
callq 0x4f3c0
movb %al, -0x29(%rbp)
incl 0x6c(%rbx)
movb 0x1f(%rbx), %al
testb %al, %al
je 0x4d04d
decb %al
movb %al, 0x1f(%rbx)
movzbl %al, %eax
movl 0x28(%rbx,%rax,4), %r14d
jmp 0x4d058
movl 0x58(%rbx), %r14d
incl %r14d
movl %r14d, 0x58(%rbx)
movq 0x10(%r13), %rsi
movq %rbx, %rdi
movl %r14d, %edx
callq 0x4e50a
movl -0x48(%rbp), %r15d
cmpl %r12d, %r15d
movl %r12d, -0x38(%rbp)
movq %r13, -0x50(%rbp)
movl %r14d, -0x44(%rbp)
jne 0x4d098
movq -0x40(%rbp), %rdi
movl $0x49, %esi
movl %r14d, %edx
movl %r15d, %ecx
xorl %r8d, %r8d
callq 0x45f15
movl %r15d, %r13d
jmp 0x4d107
movl %r14d, %edx
movq -0x40(%rbp), %r14
movq %r14, %rdi
movl $0x4a, %esi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x45f15
movl %eax, -0x54(%rbp)
movl 0x2c(%r13), %edx
movq %r14, %rdi
movl $0x65, %esi
movl %r12d, %ecx
xorl %r8d, %r8d
callq 0x45f15
movq %r14, %rdi
movl $0xe, %esi
xorl %edx, %edx
movl %r15d, %ecx
xorl %r8d, %r8d
callq 0x45f15
movl -0x54(%rbp), %edx
testl %edx, %edx
movl %r15d, %r13d
js 0x4d107
movq -0x40(%rbp), %rax
movl 0x34(%rax), %eax
cmpl %edx, %eax
jbe 0x4d107
movq -0x40(%rbp), %rcx
movq 0x8(%rcx), %rcx
movl %edx, %edx
leaq (%rdx,%rdx,2), %rdx
movl %eax, 0x8(%rcx,%rdx,8)
cmpl $0x1, -0x34(%rbp)
jne 0x4d151
movq -0x40(%rbp), %r14
movq %r14, %rdi
movl $0x21, %esi
movl -0x44(%rbp), %r15d
movl %r15d, %edx
movl -0x38(%rbp), %r12d
movl %r12d, %ecx
xorl %r8d, %r8d
callq 0x45f15
movq -0x50(%rbp), %rax
movl 0x2c(%rax), %edx
movq %r14, %rdi
movl %r15d, %r14d
movl $0x3f, %esi
movl %r12d, %ecx
movl %r15d, %r8d
callq 0x45f15
jmp 0x4d2eb
movq -0x40(%rbp), %r15
movq %r15, %rdi
movl $0x2a, %esi
movl -0x44(%rbp), %r14d
movl %r14d, %edx
movl $0x1, %ecx
xorl %r8d, %r8d
callq 0x45f15
leaq -0x29(%rbp), %rdx
movq %r15, %rdi
movl %eax, %esi
movl $0x1, %ecx
callq 0x11a9f
movq -0x50(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x38(%rbp), %ecx
cmpl %ecx, %r13d
je 0x4d2c7
cmpl $0x0, -0x30(%rbp)
je 0x4d2c7
movq %r15, %rdi
movl $0x3d, %esi
xorl %ecx, %ecx
movl %r14d, %r8d
callq 0x45f15
movl $0x1, %edx
movq %r15, %rdi
movl %eax, -0x34(%rbp)
movl %eax, %esi
movl $0xfffffff2, %ecx       # imm = 0xFFFFFFF2
callq 0x11a9f
movl -0x30(%rbp), %edx
movq %r15, %rdi
movl $0x4a, %esi
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x45f15
movl %eax, %r12d
movq -0x50(%rbp), %rax
movl 0x2c(%rax), %edx
movl -0x30(%rbp), %r8d
movq %r15, %rdi
movl $0x3d, %esi
xorl %ecx, %ecx
callq 0x45f15
movl %eax, %r13d
movl $0x1, %edx
movq %r15, %rdi
movl %eax, %esi
movl $0xfffffff2, %ecx       # imm = 0xFFFFFFF2
callq 0x11a9f
movl -0x30(%rbp), %ecx
movq %r15, %rdi
movl $0x15, %esi
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
xorl %r8d, %r8d
callq 0x45f15
testl %r13d, %r13d
js 0x4d248
movl 0x34(%r15), %eax
cmpl %r13d, %eax
jbe 0x4d248
movq 0x8(%r15), %rcx
movl %r13d, %edx
leaq (%rdx,%rdx,2), %rdx
movl %eax, 0x8(%rcx,%rdx,8)
movl -0x30(%rbp), %edx
movq %r15, %rdi
movl $0x20, %esi
movl $0x1, %ecx
xorl %r8d, %r8d
callq 0x45f15
testl %r12d, %r12d
js 0x4d27d
movl 0x34(%r15), %eax
cmpl %r12d, %eax
jbe 0x4d27d
movq 0x8(%r15), %rcx
movl %r12d, %edx
leaq (%rdx,%rdx,2), %rdx
movl %eax, 0x8(%rcx,%rdx,8)
movl -0x30(%rbp), %edx
movq %r15, %rdi
movl $0x27, %esi
movl -0x48(%rbp), %ecx
xorl %r8d, %r8d
callq 0x45f15
movq %r15, %rdi
movl $0xe, %esi
xorl %edx, %edx
movl -0x38(%rbp), %ecx
xorl %r8d, %r8d
callq 0x45f15
movl -0x34(%rbp), %edx
testl %edx, %edx
js 0x4d2eb
movl 0x34(%r15), %eax
cmpl %edx, %eax
jbe 0x4d2eb
movq 0x8(%r15), %rcx
movl %edx, %edx
leaq (%rdx,%rdx,2), %rdx
movl %eax, 0x8(%rcx,%rdx,8)
jmp 0x4d2eb
movq %r15, %rdi
movl $0x3c, %esi
movl %r14d, %r8d
callq 0x45f15
movl $0x1, %edx
movq %r15, %rdi
movl %eax, %esi
movl $0xfffffff2, %ecx       # imm = 0xFFFFFFF2
callq 0x11a9f
testl %r14d, %r14d
je 0x4d324
movzbl 0x1f(%rbx), %eax
cmpq $0x7, %rax
ja 0x4d324
xorl %ecx, %ecx
cmpl %r14d, 0x84(%rbx,%rcx)
je 0x4d31f
addq $0x18, %rcx
cmpl $0xf0, %ecx
jne 0x4d2fc
leal 0x1(%rax), %ecx
movb %cl, 0x1f(%rbx)
movl %r14d, 0x28(%rbx,%rax,4)
jmp 0x4d324
movb $0x1, 0x7c(%rbx,%rcx)
movq %rbx, %rdi
callq 0x4cd64
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq