// File: /workspace/github_c_makefile_star2_O2/genometools[P]genometools/src/core/bitpackstringop.c
// Function: gt_bsCopy
void
gt_bsCopy(constBitString src, BitOffset offsetSrc,
       BitString dest, BitOffset offsetDest, BitOffset numBits)
{
  size_t elemStartSrc = offsetSrc/bitElemBits,
    elemStartDest = offsetDest/bitElemBits;
  unsigned bitTopSrc = offsetSrc%bitElemBits,
    bitTopDest = offsetDest%bitElemBits;
  BitOffset bitsLeft = numBits;
  const BitElem *p = src + elemStartSrc;
  BitElem *q = dest + elemStartDest;
  gt_assert(src && dest);
  /* special optimization if equally aligned data will be copied */
  if (bitTopSrc == bitTopDest)
  {
    if (bitTopSrc)
    {
      BitElem mask = (~(BitElem)0) >> bitTopSrc;
      if (numBits < bitElemBits - bitTopSrc)
      {
        unsigned backShift = bitElemBits - numBits - bitTopSrc;
        mask &= ~(BitElem)0 << backShift;
        *q = (*q & ~mask) | (*p & mask);
        /* TODO: try wether  r = a ^ ((a ^ b) & mask) is faster, see above */
        return;
      }
      else
      {
        *q = (*q & ~mask) | (*p & mask);
        ++p, ++q;
        bitsLeft -= bitElemBits - bitTopSrc;
      }
    }
    if (bitsLeft)
    {
      size_t completeElems = bitsLeft/bitElemBits;
      memcpy(q, p, completeElems);
      p += completeElems, q += completeElems;
      bitsLeft %= bitElemBits;
    }
    if (bitsLeft)
    {
      BitElem mask = (~(BitElem)0) << (bitElemBits - bitsLeft);
      *q = (*q & ~mask) | (*p & mask);
    }
  }
  else
  {
    GtUword accum = 0;
    unsigned bitsInAccum = 0;
    while (bitsLeft && (bitTopSrc || bitTopDest))
    {
      if (bitTopSrc)
      {
        GtUword mask;
        unsigned bits2Read = GT_MIN3(bitElemBits - bitTopSrc, bitsLeft,
                                  sizeof (accum) * CHAR_BIT - bitsInAccum);
        unsigned unreadRightBits = (bitElemBits - bitTopSrc - bits2Read);
        mask = (~((~(GtUword)0) << bits2Read));
        accum = (accum << bits2Read) | (((*p) >> unreadRightBits) & mask);
        bitsLeft -= bits2Read;
        bitsInAccum += bits2Read;
        if ((bitTopSrc += bits2Read) == bitElemBits)
          bitTopSrc = 0, ++p;
      }
      if (bitTopDest)
      {
        unsigned bits2Write = GT_MIN(bitsLeft + bitsInAccum,
                                  bitElemBits - bitTopDest);
        while (bitsLeft >= bitElemBits
               && sizeof (accum) * CHAR_BIT - bitsInAccum > bitElemBits)
        {
          accum = accum << bitElemBits | (*p++);
          bitsLeft -= bitElemBits;
          bitsInAccum += bitElemBits;
        }
        if (bits2Write > bitsInAccum)
        {
          /* very inconvinient: we have to take all the bits we can get
           * just to fill the first incomplete element */
          while (bitsInAccum < bits2Write)
          {
            GtUword mask;
            unsigned bits2Read = GT_MIN3(sizeof (accum) * CHAR_BIT
                                         - bitsInAccum, bitsLeft, bitElemBits);
            unsigned unreadRightBits = (bitElemBits - bits2Read);
            mask = (~((~(GtUword)0) << bits2Read)) << unreadRightBits;
            accum = (accum << bits2Read) | ((*p) & mask) >> unreadRightBits;
            bitsLeft -= bits2Read;
            bitsInAccum += bits2Read;
            bitTopSrc = bits2Read;
          }
        }
        /* accum holds enough bits to fill incomplete region at dest start */
        {
          unsigned unwrittenRightBits = bitElemBits
            - bitTopDest - bits2Write;
          GtUword mask =
            (~((~(GtUword)0) << bits2Write)) << unwrittenRightBits;
          *q = (*q & ~mask)
            | (((accum >> (bitsInAccum -= bits2Write))
                << unwrittenRightBits) & mask);
          if ((bitTopDest += bits2Write) == bitElemBits)
            ++q, bitTopDest = 0;
        }
        while (bitsInAccum >= bitElemBits)
        {
          *q++ = accum >> (bitsInAccum -= bitElemBits);
        }
      }
    }
    /* all reads and writes are aligned on BitElems in this loop */
    do
    {
      /* fill accumulator */
      while (bitsLeft >= bitElemBits
             && sizeof (accum) * CHAR_BIT - bitsInAccum > bitElemBits)
      {
        accum = accum << bitElemBits | (*p++);
        bitsInAccum += bitElemBits;
        bitsLeft -= bitElemBits;
      }
      /* write out accum */
      while (bitsInAccum >= bitElemBits)
      {
        *q++ = accum >> (bitsInAccum -= bitElemBits);
      }
    }
    while (bitsLeft >= bitElemBits);
    /* write remaining (trailing) bits */
    while (bitsLeft || bitsInAccum)
    {
      while (bitsLeft && bitsInAccum < sizeof (accum) * CHAR_BIT)
      {
        unsigned bits2Read = GT_MIN3(bitsLeft, bitElemBits - bitTopSrc,
                                  sizeof (accum) * CHAR_BIT - bitsInAccum);
        unsigned unreadRightBits = (bitElemBits - bitTopSrc - bits2Read);
        GtUword mask =
          ~((~(GtUword)0) << bits2Read);
        accum = (accum << bits2Read) | (((*p) >> unreadRightBits) & mask);
        bitsLeft -= bits2Read;
        bitsInAccum += bits2Read;
        if ((bitTopSrc += bits2Read) == bitElemBits)
          ++p, bitTopSrc = 0;
      }
      while (bitsInAccum)
      {
        unsigned bits2Write = GT_MIN(bitsInAccum, bitElemBits - bitTopDest),
          unwrittenRightBits = bitElemBits - bits2Write - bitTopDest;
        GtUword mask = (~(GtUword)0);
        if (bits2Write != bitElemBits)
        {
          mask = (~(mask << bits2Write)) << unwrittenRightBits;
        }
        *q = (*q & ~mask) |
            (((accum >> (bitsInAccum -= bits2Write))
              << unwrittenRightBits) & mask);
        if ((bitTopDest += bits2Write) == bitElemBits)
          bitTopDest = 0, ++q;
      }
    }
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
testq %rdi, %rdi
je 0x28b029
movq %rdx, %r14
testq %rdx, %rdx
je 0x28b029
movq %rdi, %rbx
movq %rsi, %rdi
shrq $0x3, %rdi
movq %rcx, %rdx
shrq $0x3, %rdx
movl %esi, %eax
andl $0x7, %eax
addq %rdi, %rbx
addq %rdx, %r14
andl $0x7, %ecx
pushq $0x8
popq %r10
cmpl %ecx, %eax
jne 0x28ad17
testl %eax, %eax
je 0x28afc5
subl %eax, %r10d
movq %r8, %r12
subq %r10, %r12
jae 0x28afca
andl $0x7, %esi
addl %esi, %r8d
movb $0x8, %cl
subb %r8b, %cl
movzbl (%r14), %eax
movzbl (%rbx), %edx
xorl %eax, %edx
shrl %cl, %edx
shll %cl, %edx
xorl %eax, %edx
movb %dl, (%r14)
jmp 0x28b01a
xorl %ebp, %ebp
xorl %edx, %edx
xorl %r15d, %r15d
movl %ecx, %r12d
testq %r8, %r8
je 0x28ae9d
movl %eax, %ecx
orl %r12d, %ecx
je 0x28ae9d
xorl %ecx, %ecx
testl %eax, %eax
je 0x28ad56
movl %r10d, %edi
subl %eax, %edi
movl %edx, %ecx
pushq $0x40
popq %rsi
subq %rcx, %rsi
cmpq %rdi, %r8
jbe 0x28ad5a
cmpq %rdi, %rsi
cmovaeq %rdi, %rsi
jmp 0x28ad61
xorl %eax, %eax
jmp 0x28ad9b
cmpq %rsi, %r8
cmovbq %r8, %rsi
subl %esi, %edi
movl %esi, %r11d
pushq $-0x1
popq %r13
movl %esi, %ecx
shlq %cl, %r13
shlq %cl, %r15
movzbl (%rbx), %r9d
movl %edi, %ecx
shrl %cl, %r9d
notl %r13d
andl %r13d, %r9d
orq %r9, %r15
subq %r11, %r8
addl %esi, %edx
addl %esi, %eax
xorl %ecx, %ecx
cmpl $0x8, %eax
sete %cl
cmovel %ebp, %eax
addq %rcx, %rbx
xorl %ecx, %ecx
testl %r12d, %r12d
je 0x28ad1e
movl %edx, %ecx
addq %r8, %rcx
movl %r10d, %esi
subl %r12d, %esi
cmpq $0x8, %r8
jb 0x28add7
movl %edx, %edi
addq $-0x41, %rdi
cmpq $-0xa, %rdi
ja 0x28add7
shlq $0x8, %r15
movzbl (%rbx), %edi
incq %rbx
orq %rdi, %r15
addq $-0x8, %r8
addl $0x8, %edx
jmp 0x28adaf
cmpq %rsi, %rcx
movl %esi, %edi
cmovbl %ecx, %edi
cmpl %edx, %edi
jbe 0x28ae28
cmpl %edi, %edx
jae 0x28ae28
movl %edx, %ecx
pushq $0x40
popq %rax
subq %rcx, %rax
cmpq %r8, %rax
cmovaeq %r8, %rax
cmpq $0x8, %rax
pushq $0x8
popq %rcx
cmovaeq %rcx, %rax
pushq $-0x1
popq %r9
movl %eax, %ecx
shll %cl, %r9d
shlq %cl, %r15
notl %r9d
movzbl (%rbx), %r11d
movb $0x8, %cl
subb %al, %cl
shrq %cl, %r11
andl %r9d, %r11d
orq %r11, %r15
subq %rax, %r8
addl %eax, %edx
jmp 0x28ade3
pushq $-0x1
popq %r9
movl %edi, %ecx
shlq %cl, %r9
subl %edi, %esi
notq %r9
movq %r9, %r11
movl %esi, %ecx
shlq %cl, %r11
subl %edi, %edx
movq %r15, %r13
movl %edx, %ecx
shrq %cl, %r13
andl %r9d, %r13d
movzbl (%r14), %r9d
notl %r11d
movl %esi, %ecx
shlq %cl, %r13
andl %r9d, %r11d
orl %r11d, %r13d
movb %r13b, (%r14)
addl %edi, %r12d
xorl %esi, %esi
cmpl $0x8, %r12d
sete %sil
addq %r14, %rsi
cmpq $0x8, %rdx
jb 0x28ae8a
addq $-0x8, %rdx
movq %r15, %rdi
movl %edx, %ecx
shrq %cl, %rdi
movb %dil, (%rsi)
incq %rsi
jmp 0x28ae70
cmpl $0x8, %r12d
cmovel %ebp, %r12d
movq %rsi, %r14
movl %r12d, %ecx
jmp 0x28ad1e
movl %edx, %edx
cmpq $0x8, %r8
jb 0x28aed7
leaq -0x41(%rdx), %rcx
cmpq $-0x9, %rcx
jae 0x28aed7
shlq $0x8, %r15
movzbl (%rbx), %ecx
incq %rbx
orq %rcx, %r15
addl $0x8, %edx
addq $-0x8, %r8
jmp 0x28ae9d
addq $-0x8, %rdx
movq %r15, %rsi
movl %edx, %ecx
shrq %cl, %rsi
movb %sil, (%r14)
incq %r14
cmpq $0x8, %rdx
jae 0x28aec5
cmpq $0x7, %r8
ja 0x28ae9d
pushq $0x40
popq %r9
xorl %r13d, %r13d
testl %edx, %edx
jne 0x28aef7
testq %r8, %r8
je 0x28b01a
testq %r8, %r8
je 0x28afba
cmpl $0x40, %edx
jae 0x28afba
movl %r10d, %edi
subl %eax, %edi
movl %r9d, %esi
subl %edx, %esi
cmpq %rdi, %r8
jae 0x28af21
cmpq %rsi, %r8
cmovbq %r8, %rsi
jmp 0x28af28
cmpq %rdi, %rsi
cmovaeq %rdi, %rsi
subl %esi, %edi
pushq $-0x1
popq %r11
movl %esi, %ecx
shlq %cl, %r11
shlq %cl, %r15
movzbl (%rbx), %ebp
movl %edi, %ecx
shrl %cl, %ebp
notl %r11d
andl %r11d, %ebp
orq %rbp, %r15
subq %rsi, %r8
addl %esi, %edx
addl %esi, %eax
xorl %ecx, %ecx
cmpl $0x8, %eax
sete %cl
cmovel %r13d, %eax
addq %rcx, %rbx
jmp 0x28aef7
movl %r10d, %esi
subl %r12d, %esi
cmpl %esi, %edx
cmovbl %edx, %esi
pushq $-0x1
popq %r11
movl %esi, %ecx
shlq %cl, %r11
addl %esi, %r12d
notl %r11d
movb $0x8, %dil
subb %r12b, %dil
movl %edi, %ecx
shlq %cl, %r11
subl %esi, %edx
movq %r15, %rbp
movl %edx, %ecx
shrq %cl, %rbp
movl %edi, %ecx
shlq %cl, %rbp
cmpl $0x8, %esi
movzbl (%r14), %ecx
pushq $-0x1
popq %rsi
cmovel %esi, %r11d
xorl %ecx, %ebp
andl %r11d, %ebp
xorl %ecx, %ebp
movb %bpl, (%r14)
xorl %ecx, %ecx
cmpl $0x8, %r12d
sete %cl
cmovel %r13d, %r12d
addq %rcx, %r14
testl %edx, %edx
jne 0x28af5e
xorl %edx, %edx
jmp 0x28aeea
movq %r8, %r12
jmp 0x28afd5
movb (%rbx), %al
movb %al, (%r14)
incq %rbx
incq %r14
testq %r12, %r12
je 0x28b01a
movq %r12, %r15
shrq $0x3, %r15
movq %r14, %rdi
movq %rbx, %rsi
movq %r15, %rdx
callq 0x17630
andq $0x7, %r12
je 0x28b01a
movb $0x8, %cl
subb %r12b, %cl
pushq $-0x1
popq %rdx
shll %cl, %edx
movl %edx, %eax
notl %eax
movzbl (%r14,%r15), %ecx
orl $0x1, %eax
andl %ecx, %eax
movzbl (%rbx,%r15), %ecx
andl %edx, %ecx
orl %eax, %ecx
movb %cl, (%r14,%r15)
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x1acf38(%rip), %rax    # 0x437f68
movq (%rax), %rdi
leaq 0x59fd9(%rip), %rsi     # 0x2e5013
leaq 0xefc67(%rip), %rdx     # 0x37aca8
leaq 0xefc6c(%rip), %rcx     # 0x37acb4
leaq 0xefc3e(%rip), %r8      # 0x37ac8d
movl $0xef, %r9d
xorl %eax, %eax
callq 0x17a50
callq 0x17390