// File: /workspace/github_c_makefile_star2_O3/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: defragmentPage
static int defragmentPage(MemPage *pPage, int nMaxFrag){
  int i;                     /* Loop counter */
  int pc;                    /* Address of the i-th cell */
  int hdr;                   /* Offset to the page header */
  int size;                  /* Size of a cell */
  int usableSize;            /* Number of usable bytes on a page */
  int cellOffset;            /* Offset to the cell pointer array */
  int cbrk;                  /* Offset to the cell content area */
  int nCell;                 /* Number of cells on the page */
  unsigned char *data;       /* The page data */
  unsigned char *temp;       /* Temp area for cell content */
  unsigned char *src;        /* Source of content */
  int iCellFirst;            /* First allowable cell index */
  int iCellLast;             /* Last possible cell index */

  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  assert( pPage->pBt!=0 );
  assert( pPage->pBt->usableSize <= SQLITE_MAX_PAGE_SIZE );
  assert( pPage->nOverflow==0 );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  temp = 0;
  src = data = pPage->aData;
  hdr = pPage->hdrOffset;
  cellOffset = pPage->cellOffset;
  nCell = pPage->nCell;
  assert( nCell==get2byte(&data[hdr+3]) || CORRUPT_DB );
  iCellFirst = cellOffset + 2*nCell;
  usableSize = pPage->pBt->usableSize;

  /* This block handles pages with two or fewer free blocks and nMaxFrag
  ** or fewer fragmented bytes. In this case it is faster to move the
  ** two (or one) blocks of cells using memmove() and add the required
  ** offsets to each pointer in the cell-pointer array than it is to
  ** reconstruct the entire page.  */
  if( (int)data[hdr+7]<=nMaxFrag ){
    int iFree = get2byte(&data[hdr+1]);
    if( iFree>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
    if( iFree ){
      int iFree2 = get2byte(&data[iFree]);
      if( iFree2>usableSize-4 ) return SQLITE_CORRUPT_PAGE(pPage);
      if( 0==iFree2 || (data[iFree2]==0 && data[iFree2+1]==0) ){
        u8 *pEnd = &data[cellOffset + nCell*2];
        u8 *pAddr;
        int sz2 = 0;
        int sz = get2byte(&data[iFree+2]);
        int top = get2byte(&data[hdr+5]);
        if( top>=iFree ){
          return SQLITE_CORRUPT_PAGE(pPage);
        }
        if( iFree2 ){
          if( iFree+sz>iFree2 ) return SQLITE_CORRUPT_PAGE(pPage);
          sz2 = get2byte(&data[iFree2+2]);
          if( iFree2+sz2 > usableSize ) return SQLITE_CORRUPT_PAGE(pPage);
          memmove(&data[iFree+sz+sz2], &data[iFree+sz], iFree2-(iFree+sz));
          sz += sz2;
        }else if( NEVER(iFree+sz>usableSize) ){
          return SQLITE_CORRUPT_PAGE(pPage);
        }

        cbrk = top+sz;
        assert( cbrk+(iFree-top) <= usableSize );
        memmove(&data[cbrk], &data[top], iFree-top);
        for(pAddr=&data[cellOffset]; pAddr<pEnd; pAddr+=2){
          pc = get2byte(pAddr);
          if( pc<iFree ){ put2byte(pAddr, pc+sz); }
          else if( pc<iFree2 ){ put2byte(pAddr, pc+sz2); }
        }
        goto defragment_out;
      }
    }
  }

  cbrk = usableSize;
  iCellLast = usableSize - 4;
  for(i=0; i<nCell; i++){
    u8 *pAddr;     /* The i-th cell pointer */
    pAddr = &data[cellOffset + i*2];
    pc = get2byte(pAddr);
    testcase( pc==iCellFirst );
    testcase( pc==iCellLast );
    /* These conditions have already been verified in btreeInitPage()
    ** if PRAGMA cell_size_check=ON.
    */
    if( pc<iCellFirst || pc>iCellLast ){
      return SQLITE_CORRUPT_PAGE(pPage);
    }
    assert( pc>=iCellFirst && pc<=iCellLast );
    size = pPage->xCellSize(pPage, &src[pc]);
    cbrk -= size;
    if( cbrk<iCellFirst || pc+size>usableSize ){
      return SQLITE_CORRUPT_PAGE(pPage);
    }
    assert( cbrk+size<=usableSize && cbrk>=iCellFirst );
    testcase( cbrk+size==usableSize );
    testcase( pc+size==usableSize );
    put2byte(pAddr, cbrk);
    if( temp==0 ){
      int x;
      if( cbrk==pc ) continue;
      temp = sqlite3PagerTempSpace(pPage->pBt->pPager);
      x = get2byte(&data[hdr+5]);
      memcpy(&temp[x], &data[x], (cbrk+size) - x);
      src = temp;
    }
    memcpy(&data[cbrk], &src[pc], size);
  }
  data[hdr+7] = 0;

 defragment_out:
  assert( pPage->nFree>=0 );
  if( data[hdr+7]+cbrk-iCellFirst!=pPage->nFree ){
    return SQLITE_CORRUPT_PAGE(pPage);
  }
  assert( cbrk>=iCellFirst );
  put2byte(&data[hdr+5], cbrk);
  data[hdr+1] = 0;
  data[hdr+2] = 0;
  memset(&data[iCellFirst], 0, cbrk-iCellFirst);
  assert( sqlite3PagerIswriteable(pPage->pDbPage) );
  return SQLITE_OK;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x58, %rsp
movq 0x48(%rdi), %rax
movq 0x50(%rdi), %rbx
movzbl 0x9(%rdi), %ecx
movzwl 0x12(%rdi), %r15d
movq %rdi, 0x40(%rsp)
movzwl 0x18(%rdi), %edx
movq %rdx, 0x48(%rsp)
leal (%r15,%rdx,2), %edi
movl 0x38(%rax), %r13d
movzbl 0x7(%rbx,%rcx), %eax
cmpl %esi, %eax
movq %rbx, 0x10(%rsp)
movl %edi, 0xc(%rsp)
jle 0x2a308e
leal -0x4(%r13), %eax
movl %eax, 0x24(%rsp)
movq %rcx, 0x28(%rsp)
cmpq $0x0, 0x48(%rsp)
je 0x2a3119
leaq (%r15,%rbx), %rax
incq %rax
movq %rax, 0x30(%rsp)
xorl %r12d, %r12d
movq %r13, 0x50(%rsp)
movl %r13d, %ebp
movq $0x0, 0x38(%rsp)
movq %rbx, 0x18(%rsp)
movq 0x30(%rsp), %rax
movzwl -0x1(%rax,%r12,2), %eax
rolw $0x8, %ax
movzwl %ax, %ebx
cmpl %edi, %ebx
jb 0x2a3184
cmpl 0x24(%rsp), %ebx
jg 0x2a3184
movl %ebx, %r14d
movq 0x18(%rsp), %rax
leaq (%rax,%r14), %rsi
movq 0x40(%rsp), %rdi
callq *0x78(%rdi)
movl 0xc(%rsp), %edi
movzwl %ax, %r15d
movl %ebp, %r13d
subl %r15d, %r13d
cmpl %edi, %r13d
jl 0x2a31aa
leal (%rbx,%r15), %eax
cmpl 0x50(%rsp), %eax
jg 0x2a31aa
movl %r13d, %eax
rolw $0x8, %ax
movq 0x30(%rsp), %rcx
movw %ax, -0x1(%rcx,%r12,2)
cmpq $0x0, 0x38(%rsp)
jne 0x2a3059
cmpl %ebx, %r13d
jne 0x2a3014
movq $0x0, 0x38(%rsp)
movq 0x10(%rsp), %rbx
jmp 0x2a3078
movq 0x40(%rsp), %rax
movq 0x48(%rax), %rax
movq (%rax), %rax
movq 0x110(%rax), %rbx
movq 0x10(%rsp), %rcx
movq 0x28(%rsp), %rax
movzwl 0x5(%rcx,%rax), %eax
rolw $0x8, %ax
movzwl %ax, %eax
leaq (%rbx,%rax), %rdi
leaq (%rcx,%rax), %rsi
subl %eax, %ebp
movslq %ebp, %rdx
callq 0x17660
movq %rbx, 0x18(%rsp)
movq %rbx, 0x38(%rsp)
movq 0x10(%rsp), %rbx
movl %r13d, %edi
addq %rbx, %rdi
addq 0x18(%rsp), %r14
movq %r14, %rsi
movq %r15, %rdx
callq 0x17660
movl 0xc(%rsp), %edi
incq %r12
movl %r13d, %ebp
cmpq %r12, 0x48(%rsp)
jne 0x2a2f88
jmp 0x2a3119
movzwl 0x1(%rbx,%rcx), %eax
rolw $0x8, %ax
movzwl %ax, %r14d
leal -0x4(%r13), %eax
movl %eax, 0x24(%rsp)
cmpl %eax, %r14d
jle 0x2a30d1
leaq 0x132b1c(%rip), %rsi    # 0x3d5bcb
leaq 0x132c26(%rip), %rdx    # 0x3d5cdc
leaq 0x132974(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x10187, %ecx          # imm = 0x10187
jmp 0x2a31ce
testl %r14d, %r14d
je 0x2a2f52
movzwl (%rbx,%r14), %eax
rolw $0x8, %ax
movzwl %ax, %esi
cmpl 0x24(%rsp), %esi
jbe 0x2a31e6
leaq 0x132ad4(%rip), %rsi    # 0x3d5bcb
leaq 0x132bde(%rip), %rdx    # 0x3d5cdc
leaq 0x13292c(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x1018a, %ecx          # imm = 0x1018A
jmp 0x2a31ce
movq 0x28(%rsp), %rdx
movb $0x0, 0x7(%rbx,%rdx)
movzbl 0x7(%rbx,%rdx), %ecx
movl %r13d, %eax
subl %edi, %eax
addl %eax, %ecx
movq 0x40(%rsp), %rsi
cmpl 0x14(%rsi), %ecx
jne 0x2a315e
rolw $0x8, %r13w
movw %r13w, 0x5(%rbx,%rdx)
movw $0x0, 0x1(%rbx,%rdx)
movl %edi, %edi
addq %rbx, %rdi
movslq %eax, %rdx
xorl %ebx, %ebx
xorl %esi, %esi
callq 0x173a0
jmp 0x2a31d5
leaq 0x132a66(%rip), %rsi    # 0x3d5bcb
leaq 0x132b70(%rip), %rdx    # 0x3d5cdc
leaq 0x1328be(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x101d2, %ecx          # imm = 0x101D2
jmp 0x2a31ce
leaq 0x132a40(%rip), %rsi    # 0x3d5bcb
leaq 0x132b4a(%rip), %rdx    # 0x3d5cdc
leaq 0x132898(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x101b7, %ecx          # imm = 0x101B7
jmp 0x2a31ce
leaq 0x132a1a(%rip), %rsi    # 0x3d5bcb
leaq 0x132b24(%rip), %rdx    # 0x3d5cdc
leaq 0x132872(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x101bd, %ecx          # imm = 0x101BD
xorl %eax, %eax
callq 0x274d08
movl %ebx, %eax
addq $0x58, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
testl %esi, %esi
je 0x2a31ff
cmpb $0x0, (%rbx,%rsi)
jne 0x2a2f52
cmpb $0x0, 0x1(%rbx,%rsi)
jne 0x2a2f52
movzwl 0x5(%rbx,%rcx), %eax
rolw $0x8, %ax
movzwl %ax, %r9d
movl %r14d, %ebp
subl %r9d, %ebp
jbe 0x2a3262
movq %rcx, 0x28(%rsp)
movzwl 0x2(%rbx,%r14), %eax
rolw $0x8, %ax
movzwl %ax, %r12d
leal (%r12,%r14), %eax
testl %esi, %esi
je 0x2a328b
movl %esi, %ecx
subl %eax, %ecx
jae 0x2a32c4
leaq 0x13298b(%rip), %rsi    # 0x3d5bcb
leaq 0x132a95(%rip), %rdx    # 0x3d5cdc
leaq 0x1327e3(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x10195, %ecx          # imm = 0x10195
jmp 0x2a31ce
leaq 0x132962(%rip), %rsi    # 0x3d5bcb
leaq 0x132a6c(%rip), %rdx    # 0x3d5cdc
leaq 0x1327ba(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x10192, %ecx          # imm = 0x10192
jmp 0x2a31ce
movq %rsi, 0x30(%rsp)
xorl %ecx, %ecx
cmpl %r13d, %eax
jle 0x2a3333
leaq 0x132929(%rip), %rsi    # 0x3d5bcb
leaq 0x132a33(%rip), %rdx    # 0x3d5cdc
leaq 0x132781(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x1019b, %ecx          # imm = 0x1019B
jmp 0x2a31ce
movzwl 0x2(%rbx,%rsi), %edx
rolw $0x8, %dx
movzwl %dx, %r8d
leal (%r8,%rsi), %edx
cmpl %r13d, %edx
jle 0x2a3303
leaq 0x1328ea(%rip), %rsi    # 0x3d5bcb
leaq 0x1329f4(%rip), %rdx    # 0x3d5cdc
leaq 0x132742(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x10197, %ecx          # imm = 0x10197
jmp 0x2a31ce
movq %rsi, 0x30(%rsp)
leal (%r8,%rax), %edi
addq %rbx, %rdi
movl %eax, %esi
addq %rbx, %rsi
movslq %ecx, %rdx
movq %r8, %r13
movq %r9, 0x18(%rsp)
callq 0x17cd0
movq 0x18(%rsp), %r9
movq %r13, %rcx
movl 0xc(%rsp), %edi
addl %ecx, %r12d
movq %rcx, 0x18(%rsp)
movq %rbx, %rax
movl %edi, %ebx
leal (%r12,%r9), %r13d
leaq (%rax,%r13), %rdi
movl %r9d, %esi
addq %rax, %rsi
movslq %ebp, %rdx
callq 0x17cd0
cmpl %ebx, %r15d
jae 0x2a33ab
movq 0x10(%rsp), %rax
addq %rax, %rbx
addq %r15, %rax
movl 0xc(%rsp), %edi
movq 0x30(%rsp), %rsi
movq 0x18(%rsp), %r8
movzwl (%rax), %ecx
rolw $0x8, %cx
movzwl %cx, %ecx
movl %r12d, %edx
cmpl %r14d, %ecx
jb 0x2a338a
movl %r8d, %edx
cmpl %esi, %ecx
jae 0x2a3393
addl %edx, %ecx
rolw $0x8, %cx
movw %cx, (%rax)
addq $0x2, %rax
cmpq %rbx, %rax
jb 0x2a3371
movq 0x10(%rsp), %rbx
movq 0x28(%rsp), %rdx
jmp 0x2a3123
movq 0x10(%rsp), %rbx
movq 0x28(%rsp), %rdx
movl 0xc(%rsp), %edi
jmp 0x2a3123