// File: /workspace/github_c_makefile_star2_O3/genometools[P]genometools/src/core/bitpackstringop.c
// Function: gt_bsCompare
int gt_bsCompare(constBitString a, BitOffset offsetA, BitOffset numBitsA,
                 constBitString b, BitOffset offsetB, BitOffset numBitsB)
{
  BitOffset totalBitsLeftA = numBitsA, totalBitsLeftB = numBitsB;
  size_t elemStartA = offsetA/bitElemBits, elemStartB = offsetB/bitElemBits;
  unsigned bitTopA = offsetA%bitElemBits, bitTopB = offsetB%bitElemBits;
  const BitElem *pA = a + elemStartA, *pB = b + elemStartB;
  GtUword accumA = 0, accumB = 0;
  unsigned bitsInAccumA, bitsInAccumB;
  gt_assert(a && b);
  /* user requested zero length comparison, treat as equality */
  if (!numBitsA && !numBitsB)
  {
    return 0;
  }
  if (numBitsA > numBitsB)
    return -1 * gt_bsCompare(b, offsetB, numBitsB, a, offsetA, numBitsA);
  if (numBitsB > numBitsA)
  {
    /* B is longer and thus compared with virtual zeros prepended to A */
    unsigned comparePreBits = numBitsB - numBitsA;
    do {
      bitsInAccumB = 0;
      if (bitTopB)
      {
        GtUword mask; /*< all of the bits we want to get from *pB */
        unsigned bits2Read = GT_MIN(bitElemBits - bitTopB, comparePreBits);
        unsigned unreadRightBits = (bitElemBits - bitTopB - bits2Read);
        mask = (~((~(GtUword)0) << bits2Read)) << unreadRightBits;
        accumB = ((*pB++) & mask) >> unreadRightBits;
        bitsInAccumB += bits2Read;
        totalBitsLeftB -= bits2Read;
        comparePreBits -= bits2Read;
      }
      while (bitsInAccumB < CHAR_BIT * sizeof (accumB) && comparePreBits)
      {
        unsigned bits2Read,
          bitsFree = (CHAR_BIT * sizeof (accumA)) - bitsInAccumB;
        GtUword mask;
        bits2Read = GT_MIN3(bitsFree, bitElemBits, comparePreBits);
        mask = ~((~(GtUword)0) << bits2Read);
        accumB = accumB << bits2Read
          | (((*pB) >> (bitElemBits - bits2Read)) & mask);
        bitsInAccumB += bits2Read;
        totalBitsLeftB -= bits2Read;
        comparePreBits -= bits2Read;
        /* all of *pB consumed? */
        if (bits2Read == bitElemBits)
          ++pB, bitTopB = 0;
        else
          bitTopB = bits2Read;
      }
    } while (accumB == 0 && comparePreBits);
    if (accumB > 0)
      return -1;
  }
  do {
    bitsInAccumB = bitsInAccumA = 0;
    /* get bits of first element if not aligned */
    if (bitTopA)
    {
      GtUword mask; /*< all of the bits we want to get from *pA */
      unsigned bits2Read = GT_MIN(bitElemBits - bitTopA, totalBitsLeftA);
      unsigned unreadRightBits = (bitElemBits - bitTopA - bits2Read);
      mask = (~((~(GtUword)0) << bits2Read)) << unreadRightBits;
      accumA = ((*pA++) & mask) >> unreadRightBits;
      bitsInAccumA += bits2Read;
      totalBitsLeftA -= bits2Read;
    }
    else
      accumA = 0;
    /* get bits of first element if not aligned */
    if (bitTopB)
    {
      GtUword mask; /*< all of the bits we want to get from *pB */
      unsigned bits2Read = GT_MIN(bitElemBits - bitTopB, totalBitsLeftB);
      unsigned unreadRightBits = (bitElemBits - bitTopB - bits2Read);
      mask = (~((~(GtUword)0) << bits2Read)) << unreadRightBits;
      accumB = ((*pB++) & mask) >> unreadRightBits;
      bitsInAccumB += bits2Read;
      totalBitsLeftB -= bits2Read;
    }
    else
      accumB = 0;
    while (bitsInAccumA < (CHAR_BIT * sizeof (accumA)) && totalBitsLeftA)
    {
      unsigned bits2Read,
               bitsFree = (CHAR_BIT * sizeof (accumA)) - bitsInAccumA;
      GtUword mask;
      bits2Read = GT_MIN3(bitsFree, bitElemBits, totalBitsLeftA);
      mask = (~((~(GtUword)0) << bits2Read));
      accumA = accumA << bits2Read
        | (((*pA) >> (bitElemBits - bits2Read)) & mask);
      bitsInAccumA += bits2Read;
      totalBitsLeftA -= bits2Read;
      /* all of *pA consumed? */
      if (bits2Read == bitElemBits)
        ++pA, bitTopA = 0;
      else
        bitTopA = bits2Read;
    }
    while (bitsInAccumB < (CHAR_BIT * sizeof (accumA)) && totalBitsLeftB)
    {
      unsigned bits2Read,
        bitsFree = (CHAR_BIT * sizeof (accumA)) - bitsInAccumB;
      GtUword mask;
      bits2Read = GT_MIN3(bitsFree, bitElemBits, totalBitsLeftB);
      mask = (~((~(GtUword)0) << bits2Read));
      accumB = accumB << bits2Read
        | (((*pB) >> (bitElemBits - bits2Read)) & mask);
      bitsInAccumB += bits2Read;
      totalBitsLeftB -= bits2Read;
      /* all of *pB consumed? */
      if (bits2Read == bitElemBits)
        ++pB, bitTopB = 0;
      else
        bitTopB = bits2Read;
    }
  } while (accumA == accumB && totalBitsLeftA);
  return accumA > accumB?1:(accumA < accumB?-1:0);
}

// Assembly:
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
testq %rdi, %rdi
je 0x2f0d5a
testq %rcx, %rcx
je 0x2f0d5a
movq %rdx, %rbx
movq %r9, %rax
orq %rdx, %rax
je 0x2f0aaa
movq %rsi, %r10
movq %rdi, %r11
movq %rsi, %r14
shrq $0x3, %r14
movq %r8, %r15
shrq $0x3, %r15
movl %r10d, %edx
andl $0x7, %edx
movl %r8d, %esi
andl $0x7, %esi
addq %rdi, %r14
addq %rcx, %r15
cmpq %rbx, %r9
jae 0x2f0ab1
movq %rcx, %rdi
movq %r8, %rsi
movq %r9, %rdx
movq %r11, %rcx
movq %r10, %r8
movq %rbx, %r9
callq 0x2f0a3b
negl %eax
jmp 0x2f0d50
xorl %eax, %eax
jmp 0x2f0d50
jbe 0x2f0ba3
movl %r9d, %r8d
subl %ebx, %r8d
xorl %r10d, %r10d
testl %esi, %esi
je 0x2f0b01
movl $0x8, %eax
subl %esi, %eax
cmpl %r8d, %eax
movl %r8d, %edi
cmovbl %eax, %edi
subl %edi, %eax
movq $-0x1, %r11
movl %edi, %ecx
shlq %cl, %r11
notl %r11d
movl %eax, %ecx
shlq %cl, %r11
movzbl (%r15), %ecx
andl %ecx, %r11d
movl %eax, %ecx
shrq %cl, %r11
incq %r15
subq %rdi, %r9
subl %edi, %r8d
jmp 0x2f0b06
xorl %edi, %edi
xorl %r11d, %r11d
testl %r8d, %r8d
setne %al
cmpl $0x3f, %edi
ja 0x2f0b88
testl %r8d, %r8d
je 0x2f0b88
cmpl $0x39, %edi
jb 0x2f0b2b
movl $0x40, %esi
subl %edi, %esi
cmpl %r8d, %esi
cmovael %r8d, %esi
jmp 0x2f0b38
cmpl $0x8, %r8d
movl $0x8, %esi
cmovbl %r8d, %esi
movq $-0x1, %rax
movl %esi, %ecx
shlq %cl, %rax
movq %r11, %r12
shlq %cl, %r12
movl %esi, %r13d
movzbl (%r15), %r11d
movb $0x8, %cl
subb %sil, %cl
shrl %cl, %r11d
subq %r13, %r9
notl %eax
andl %eax, %r11d
orq %r12, %r11
addl %esi, %edi
xorl %eax, %eax
cmpl $0x8, %esi
sete %al
addq %rax, %r15
subl %esi, %r8d
setne %al
cmpl $0x3f, %edi
ja 0x2f0b81
testl %r8d, %r8d
jne 0x2f0b16
cmpl $0x8, %esi
cmovel %r10d, %esi
testq %r11, %r11
jne 0x2f0b95
testb %al, %al
jne 0x2f0ac0
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
testq %r11, %r11
jne 0x2f0d50
xorl %r10d, %r10d
testl %edx, %edx
je 0x2f0be7
movl $0x8, %eax
subl %edx, %eax
cmpq %rax, %rbx
movq %rax, %r8
cmovbq %rbx, %r8
subl %r8d, %eax
movq $-0x1, %r11
movl %r8d, %ecx
shlq %cl, %r11
notl %r11d
movl %eax, %ecx
shlq %cl, %r11
movzbl (%r14), %ecx
incq %r14
andl %ecx, %r11d
movl %eax, %ecx
shrq %cl, %r11
subq %r8, %rbx
jmp 0x2f0bed
xorl %r8d, %r8d
xorl %r11d, %r11d
testl %esi, %esi
je 0x2f0c2c
movl $0x8, %eax
subl %esi, %eax
cmpq %rax, %r9
movq %rax, %rdi
cmovbq %r9, %rdi
subl %edi, %eax
movq $-0x1, %r12
movl %edi, %ecx
shlq %cl, %r12
notl %r12d
movl %eax, %ecx
shlq %cl, %r12
movzbl (%r15), %ecx
incq %r15
andl %ecx, %r12d
movl %eax, %ecx
shrq %cl, %r12
subq %rdi, %r9
jmp 0x2f0c31
xorl %edi, %edi
xorl %r12d, %r12d
cmpl $0x40, %r8d
setb %cl
testq %rbx, %rbx
setne %al
andb %al, %cl
cmpb $0x1, %cl
jne 0x2f0cb2
cmpl $0x39, %r8d
jb 0x2f0c58
movl $0x40, %edx
subl %r8d, %edx
cmpq %rdx, %rbx
jmp 0x2f0c61
cmpq $0x8, %rbx
movl $0x8, %edx
cmovbq %rbx, %rdx
movq $-0x1, %rax
movl %edx, %ecx
shlq %cl, %rax
movq %r11, %r13
shlq %cl, %r13
movzbl (%r14), %r11d
movb $0x8, %cl
subb %dl, %cl
shrl %cl, %r11d
notl %eax
andl %eax, %r11d
orq %r13, %r11
addl %edx, %r8d
xorl %eax, %eax
cmpq $0x8, %rdx
sete %al
addq %rax, %r14
subq %rdx, %rbx
setne %al
cmpl $0x3f, %r8d
ja 0x2f0caa
testq %rbx, %rbx
jne 0x2f0c45
cmpq $0x8, %rdx
cmovel %r10d, %edx
cmpl $0x40, %edi
setb %cl
testq %r9, %r9
setne %r8b
andb %cl, %r8b
cmpb $0x1, %r8b
jne 0x2f0d30
cmpl $0x39, %edi
jb 0x2f0cd9
movl $0x40, %esi
subl %edi, %esi
cmpq %rsi, %r9
jmp 0x2f0ce2
cmpq $0x8, %r9
movl $0x8, %esi
cmovbq %r9, %rsi
movq $-0x1, %r8
movl %esi, %ecx
shlq %cl, %r8
notl %r8d
movq %r12, %r13
shlq %cl, %r13
movzbl (%r15), %r12d
movb $0x8, %cl
subb %sil, %cl
shrl %cl, %r12d
andl %r8d, %r12d
orq %r13, %r12
addl %esi, %edi
subq %rsi, %r9
xorl %ecx, %ecx
cmpq $0x8, %rsi
sete %cl
addq %rcx, %r15
cmpl $0x3f, %edi
ja 0x2f0d28
testq %r9, %r9
jne 0x2f0cc8
cmpq $0x8, %rsi
cmovel %r10d, %esi
cmpq %r12, %r11
sete %cl
testb %al, %cl
jne 0x2f0ba6
xorl %ecx, %ecx
cmpq %r12, %r11
sbbl %ecx, %ecx
cmpq %r12, %r11
movl $0x1, %eax
cmovbel %ecx, %eax
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
retq
callq 0x870d7