// File: /workspace/github_c_makefile_star2_O0/barabo[P]advanced-shell-history/src/sqlite3.c
// Function: sqlite3VdbeRecordCompare
SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
  int nKey1, const void *pKey1, /* Left key */
  UnpackedRecord *pPKey2        /* Right key */
){
  u32 d1;            /* Offset into aKey[] of next data element */
  u32 idx1;          /* Offset into aKey[] of next header element */
  u32 szHdr1;        /* Number of bytes in header */
  int i = 0;
  int rc = 0;
  const unsigned char *aKey1 = (const unsigned char *)pKey1;
  KeyInfo *pKeyInfo;
  Mem mem1;

  pKeyInfo = pPKey2->pKeyInfo;
  mem1.enc = pKeyInfo->enc;
  mem1.db = pKeyInfo->db;
  /* mem1.flags = 0;  // Will be initialized by sqlite3VdbeSerialGet() */
  VVA_ONLY( mem1.zMalloc = 0; ) /* Only needed by assert() statements */

  /* Compilers may complain that mem1.u.i is potentially uninitialized.
  ** We could initialize it, as shown here, to silence those complaints.
  ** But in fact, mem1.u.i will never actually be used uninitialized, and doing 
  ** the unnecessary initialization has a measurable negative performance
  ** impact, since this routine is a very high runner.  And so, we choose
  ** to ignore the compiler warnings and leave this variable uninitialized.
  */
  /*  mem1.u.i = 0;  // not needed, here to silence compiler warning */
  
  idx1 = getVarint32(aKey1, szHdr1);
  d1 = szHdr1;
  assert( pKeyInfo->nField+1>=pPKey2->nField );
  assert( pKeyInfo->aSortOrder!=0 );
  while( idx1<szHdr1 && i<pPKey2->nField ){
    u32 serial_type1;

    /* Read the serial types for the next element in each key. */
    idx1 += getVarint32( aKey1+idx1, serial_type1 );

    /* Verify that there is enough key space remaining to avoid
    ** a buffer overread.  The "d1+serial_type1+2" subexpression will
    ** always be greater than or equal to the amount of required key space.
    ** Use that approximation to avoid the more expensive call to
    ** sqlite3VdbeSerialTypeLen() in the common case.
    */
    if( d1+serial_type1+2>(u32)nKey1
     && d1+sqlite3VdbeSerialTypeLen(serial_type1)>(u32)nKey1 
    ){
      break;
    }

    /* Extract the values to be compared.
    */
    d1 += sqlite3VdbeSerialGet(&aKey1[d1], serial_type1, &mem1);

    /* Do the comparison
    */
    rc = sqlite3MemCompare(&mem1, &pPKey2->aMem[i], pKeyInfo->aColl[i]);
    if( rc!=0 ){
      assert( mem1.zMalloc==0 );  /* See comment below */

      /* Invert the result if we are using DESC sort order. */
      if( pKeyInfo->aSortOrder[i] ){
        rc = -rc;
      }
    
      /* If the PREFIX_SEARCH flag is set and all fields except the final
      ** rowid field were equal, then clear the PREFIX_SEARCH flag and set 
      ** pPKey2->rowid to the value of the rowid field in (pKey1, nKey1).
      ** This is used by the OP_IsUnique opcode.
      */
      if( (pPKey2->flags & UNPACKED_PREFIX_SEARCH) && i==(pPKey2->nField-1) ){
        assert( idx1==szHdr1 && rc );
        assert( mem1.flags & MEM_Int );
        pPKey2->flags &= ~UNPACKED_PREFIX_SEARCH;
        pPKey2->rowid = mem1.u.i;
      }
    
      return rc;
    }
    i++;
  }

  /* No memory allocation is ever used on mem1.  Prove this using
  ** the following assert().  If the assert() fails, it indicates a
  ** memory leak and a need to call sqlite3VdbeMemRelease(&mem1).
  */
  assert( mem1.zMalloc==0 );

  /* rc==0 here means that one of the keys ran out of fields and
  ** all the fields up to that point were equal. If the UNPACKED_INCRKEY
  ** flag is set, then break the tie by treating key2 as larger.
  ** If the UPACKED_PREFIX_MATCH flag is set, then keys with common prefixes
  ** are considered to be equal.  Otherwise, the longer key is the 
  ** larger.  As it happens, the pPKey2 will always be the longer
  ** if there is a difference.
  */
  assert( rc==0 );
  if( pPKey2->flags & UNPACKED_INCRKEY ){
    rc = -1;
  }else if( pPKey2->flags & UNPACKED_PREFIX_MATCH ){
    /* Leave rc==0 */
  }else if( idx1<szHdr1 ){
    rc = 1;
  }
  return rc;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq %rdx, -0x18(%rbp)
movl $0x0, -0x28(%rbp)
movl $0x0, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x38(%rbp)
movq -0x18(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movb 0x8(%rax), %al
movb %al, -0x51(%rbp)
movq -0x40(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x78(%rbp)
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
cmpl $0x80, %eax
jge 0x415be
movq -0x38(%rbp), %rax
movzbl (%rax), %eax
movl %eax, -0x24(%rbp)
movl $0x1, %eax
movl %eax, -0x80(%rbp)
jmp 0x415d1
movq -0x38(%rbp), %rdi
leaq -0x24(%rbp), %rsi
callq 0x2c290
movzbl %al, %eax
movl %eax, -0x80(%rbp)
movl -0x80(%rbp), %eax
movzbl %al, %eax
movl %eax, -0x20(%rbp)
movl -0x24(%rbp), %eax
movl %eax, -0x1c(%rbp)
movl -0x20(%rbp), %ecx
xorl %eax, %eax
cmpl -0x24(%rbp), %ecx
movb %al, -0x81(%rbp)
jae 0x41606
movl -0x28(%rbp), %eax
movq -0x18(%rbp), %rcx
movzwl 0x8(%rcx), %ecx
cmpl %ecx, %eax
setl %al
movb %al, -0x81(%rbp)
movb -0x81(%rbp), %al
testb $0x1, %al
jne 0x41615
jmp 0x4175a
movq -0x38(%rbp), %rax
movl -0x20(%rbp), %ecx
movzbl (%rax,%rcx), %eax
cmpl $0x80, %eax
jge 0x41642
movq -0x38(%rbp), %rax
movl -0x20(%rbp), %ecx
movzbl (%rax,%rcx), %eax
movl %eax, -0x7c(%rbp)
movl $0x1, %eax
movl %eax, -0x88(%rbp)
jmp 0x4165e
movq -0x38(%rbp), %rdi
movl -0x20(%rbp), %eax
addq %rax, %rdi
leaq -0x7c(%rbp), %rsi
callq 0x2c290
movzbl %al, %eax
movl %eax, -0x88(%rbp)
movl -0x88(%rbp), %eax
movzbl %al, %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x1c(%rbp), %eax
addl -0x7c(%rbp), %eax
addl $0x2, %eax
cmpl -0x8(%rbp), %eax
jbe 0x416a0
movl -0x1c(%rbp), %eax
movl %eax, -0x8c(%rbp)
movl -0x7c(%rbp), %edi
callq 0x3b8f0
movl %eax, %ecx
movl -0x8c(%rbp), %eax
addl %ecx, %eax
cmpl -0x8(%rbp), %eax
jbe 0x416a0
jmp 0x4175a
movq -0x38(%rbp), %rdi
movl -0x1c(%rbp), %eax
addq %rax, %rdi
movl -0x7c(%rbp), %esi
leaq -0x78(%rbp), %rdx
callq 0x3b930
addl -0x1c(%rbp), %eax
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rax
movq 0x18(%rax), %rsi
movslq -0x28(%rbp), %rax
imulq $0x38, %rax, %rax
addq %rax, %rsi
movq -0x40(%rbp), %rax
movslq -0x28(%rbp), %rcx
movq 0x18(%rax,%rcx,8), %rdx
leaq -0x78(%rbp), %rdi
callq 0x3b1c0
movl %eax, -0x2c(%rbp)
cmpl $0x0, -0x2c(%rbp)
je 0x4174c
movq -0x40(%rbp), %rax
movq 0x10(%rax), %rax
movslq -0x28(%rbp), %rcx
cmpb $0x0, (%rax,%rcx)
je 0x41708
xorl %eax, %eax
subl -0x2c(%rbp), %eax
movl %eax, -0x2c(%rbp)
movq -0x18(%rbp), %rax
movzbl 0xa(%rax), %eax
andl $0x4, %eax
cmpl $0x0, %eax
je 0x41744
movl -0x28(%rbp), %eax
movq -0x18(%rbp), %rcx
movzwl 0x8(%rcx), %ecx
subl $0x1, %ecx
cmpl %ecx, %eax
jne 0x41744
movq -0x18(%rbp), %rax
movzbl 0xa(%rax), %ecx
andl $-0x5, %ecx
movb %cl, 0xa(%rax)
movq -0x60(%rbp), %rcx
movq -0x18(%rbp), %rax
movq %rcx, 0x10(%rax)
movl -0x2c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x4179e
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x415e0
movq -0x18(%rbp), %rax
movzbl 0xa(%rax), %eax
andl $0x1, %eax
cmpl $0x0, %eax
je 0x41773
movl $0xffffffff, -0x2c(%rbp) # imm = 0xFFFFFFFF
jmp 0x41798
movq -0x18(%rbp), %rax
movzbl 0xa(%rax), %eax
andl $0x2, %eax
cmpl $0x0, %eax
je 0x41785
jmp 0x41796
movl -0x20(%rbp), %eax
cmpl -0x24(%rbp), %eax
jae 0x41794
movl $0x1, -0x2c(%rbp)
jmp 0x41796
jmp 0x41798
movl -0x2c(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopw (%rax,%rax)