// File: /workspace/github_c_makefile_star2_O3/genometools[P]genometools/src/external/sqlite-3.33.0/sqlite3.c
// Function: btreeComputeFreeSpace
static int btreeComputeFreeSpace(MemPage *pPage){
  int pc;            /* Address of a freeblock within pPage->aData[] */
  u8 hdr;            /* Offset to beginning of page header */
  u8 *data;          /* Equal to pPage->aData */
  int usableSize;    /* Amount of usable space on each page */
  int nFree;         /* Number of unused bytes on the page */
  int top;           /* First byte of the cell content area */
  int iCellFirst;    /* First allowable cell or freeblock offset */
  int iCellLast;     /* Last possible cell or freeblock offset */

  assert( pPage->pBt!=0 );
  assert( pPage->pBt->db!=0 );
  assert( sqlite3_mutex_held(pPage->pBt->mutex) );
  assert( pPage->pgno==sqlite3PagerPagenumber(pPage->pDbPage) );
  assert( pPage == sqlite3PagerGetExtra(pPage->pDbPage) );
  assert( pPage->aData == sqlite3PagerGetData(pPage->pDbPage) );
  assert( pPage->isInit==1 );
  assert( pPage->nFree<0 );

  usableSize = pPage->pBt->usableSize;
  hdr = pPage->hdrOffset;
  data = pPage->aData;
  /* EVIDENCE-OF: R-58015-48175 The two-byte integer at offset 5 designates
  ** the start of the cell content area. A zero value for this integer is
  ** interpreted as 65536. */
  top = get2byteNotZero(&data[hdr+5]);
  iCellFirst = hdr + 8 + pPage->childPtrSize + 2*pPage->nCell;
  iCellLast = usableSize - 4;

  /* Compute the total free space on the page
  ** EVIDENCE-OF: R-23588-34450 The two-byte integer at offset 1 gives the
  ** start of the first freeblock on the page, or is zero if there are no
  ** freeblocks. */
  pc = get2byte(&data[hdr+1]);
  nFree = data[hdr+7] + top;  /* Init nFree to non-freeblock free space */
  if( pc>0 ){
    u32 next, size;
    if( pc<top ){
      /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will
      ** always be at least one cell before the first freeblock.
      */
      return SQLITE_CORRUPT_PAGE(pPage);
    }
    while( 1 ){
      if( pc>iCellLast ){
        /* Freeblock off the end of the page */
        return SQLITE_CORRUPT_PAGE(pPage);
      }
      next = get2byte(&data[pc]);
      size = get2byte(&data[pc+2]);
      nFree = nFree + size;
      if( next<=pc+size+3 ) break;
      pc = next;
    }
    if( next>0 ){
      /* Freeblock not in ascending order */
      return SQLITE_CORRUPT_PAGE(pPage);
    }
    if( pc+size>(unsigned int)usableSize ){
      /* Last freeblock extends past page end */
      return SQLITE_CORRUPT_PAGE(pPage);
    }
  }

  /* At this point, nFree contains the sum of the offset to the start
  ** of the cell-content area plus the number of free bytes within
  ** the cell-content area. If this is greater than the usable-size
  ** of the page, then the page must be corrupted. This check also
  ** serves to verify that the offset to the start of the cell-content
  ** area, according to the page header, lies within the page.
  */
  if( nFree>usableSize || nFree<iCellFirst ){
    return SQLITE_CORRUPT_PAGE(pPage);
  }
  pPage->nFree = (u16)(nFree - iCellFirst);
  return SQLITE_OK;
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
movq 0x48(%rdi), %rax
movq 0x50(%rdi), %r9
movl 0x38(%rax), %ecx
movzbl 0x9(%rdi), %eax
movzbl 0x5(%r9,%rax), %edx
shll $0x8, %edx
movzbl 0x6(%r9,%rax), %esi
addl %esi, %edx
decl %edx
movzwl %dx, %r10d
movzbl 0xa(%rdi), %esi
movzwl 0x1(%r9,%rax), %r11d
rolw $0x8, %r11w
movzwl 0x18(%rdi), %r8d
movzbl 0x7(%r9,%rax), %edx
addl %r10d, %edx
incl %edx
testw %r11w, %r11w
je 0x2a0a98
movzwl %r11w, %ebx
cmpl %r10d, %ebx
jbe 0x2a0a1b
leal -0x4(%rcx), %r11d
cmpl %r11d, %ebx
jg 0x2a0a44
movl %ebx, %r10d
movl %ebx, %ebx
movzwl (%r9,%rbx), %ebp
rolw $0x8, %bp
movzwl 0x2(%r9,%rbx), %r14d
movzwl %bp, %ebx
rolw $0x8, %r14w
movzwl %r14w, %r14d
addl %r14d, %edx
leal (%r14,%r10), %ebp
addl $0x3, %ebp
cmpl %ebp, %ebx
ja 0x2a09b7
testl %ebx, %ebx
je 0x2a0a6a
leaq 0x1351d2(%rip), %rsi    # 0x3d5bcb
leaq 0x1352dc(%rip), %rdx    # 0x3d5cdc
leaq 0x13502a(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x10367, %ecx          # imm = 0x10367
jmp 0x2a0ad7
leaq 0x1351a9(%rip), %rsi    # 0x3d5bcb
leaq 0x1352b3(%rip), %rdx    # 0x3d5cdc
leaq 0x135001(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x10358, %ecx          # imm = 0x10358
jmp 0x2a0ad7
leaq 0x135180(%rip), %rsi    # 0x3d5bcb
leaq 0x13528a(%rip), %rdx    # 0x3d5cdc
leaq 0x134fd8(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x1035d, %ecx          # imm = 0x1035D
jmp 0x2a0ad7
addl %r10d, %r14d
cmpl %ecx, %r14d
jbe 0x2a0a98
leaq 0x135152(%rip), %rsi    # 0x3d5bcb
leaq 0x13525c(%rip), %rdx    # 0x3d5cdc
leaq 0x134faa(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x1036b, %ecx          # imm = 0x1036B
jmp 0x2a0ad7
cmpl %ecx, %edx
jg 0x2a0ab3
addl %esi, %eax
leal (%rax,%r8,2), %eax
addl $0x8, %eax
subl %eax, %edx
jl 0x2a0ab3
movzwl %dx, %eax
movl %eax, 0x14(%rdi)
xorl %ebx, %ebx
jmp 0x2a0ade
leaq 0x135111(%rip), %rsi    # 0x3d5bcb
leaq 0x13521b(%rip), %rdx    # 0x3d5cdc
leaq 0x134f69(%rip), %r8     # 0x3d5a31
movl $0xb, %ebx
movl $0xb, %edi
movl $0x10377, %ecx          # imm = 0x10377
xorl %eax, %eax
callq 0x274d08
movl %ebx, %eax
popq %rbx
popq %r14
popq %rbp
retq