// File: /workspace/github_c_makefile_star2_O2/genometools[P]genometools/src/core/bitpackstringop32.c
// Function: gt_bsStoreNonUniformUInt32Array
void
gt_bsStoreNonUniformUInt32Array(
  BitString str, BitOffset offset, GT_UNUSED size_t numValues,
  BitOffset totalBitsLeft, unsigned numBitsList[], const uint32_t val[])
{
  /* idea: read as much as possible from val in each iteration,
   * accumulate if bitsInAccum < bitElemBits */
  size_t j = 0;
  unsigned bitTop = offset%bitElemBits,
    bitsLeft; /*< how many bits in currentVal == val[j] are left */
  BitElem *p = str + offset/bitElemBits;
  unsigned bitsInAccum;
  GtUword accum, valMask = ~(GtUword)0, currentVal;
  gt_assert(numBitsList != NULL);
  gt_assert(val != NULL);
  gt_assert(numValues != 0);
  if (numBitsList[0] < (sizeof (val[0])*CHAR_BIT))
    valMask = ~(valMask << numBitsList[0]);
  gt_assert(str && val);
  gt_assert(numBitsList[0] <= sizeof (val[0])*CHAR_BIT);
  /* user requested zero values, ugly but must be handled, since legal */
  if (!totalBitsLeft)
  {
    return;
  }
  accum = val[0] & valMask;
  totalBitsLeft -= bitsInAccum = numBitsList[0];
  if (totalBitsLeft)
  {
    unsigned numBits = numBitsList[++j];
    gt_assert(numBits <= sizeof (val[0])*CHAR_BIT);
    valMask = (numBits < 32)?
      ~((~(uint32_t)0) << numBits):~(uint32_t)0;
    currentVal = val[j] & valMask;
    totalBitsLeft -= bitsLeft = numBits;
  }
  else
  {
    currentVal = 0;
    bitsLeft = 0;
  }
  /* set bits of first element if not aligned */
  if (bitTop)
  {
    BitElem mask = ~(~(GtUword)0 << (bitElemBits - bitTop));
    while ((totalBitsLeft || bitsLeft) && bitsInAccum < bitElemBits - bitTop)
    {
      unsigned bits2Read, bitsFree = sizeof (accum)*CHAR_BIT - bitsInAccum;

      if ((bits2Read = GT_MIN(bitsFree, bitsLeft)) < sizeof (accum)*CHAR_BIT)
      {
        accum = accum << bits2Read
          | ((currentVal) >> (bitsLeft - bits2Read));
      }
      else
        accum = currentVal;

      /* all of val[j] consumed? */
      bitsInAccum += bits2Read;
      if (!(bitsLeft -= bits2Read) && totalBitsLeft)
      {
        unsigned numBits = numBitsList[++j];
        gt_assert(numBits <= sizeof (val[0])*CHAR_BIT);
        valMask = (numBits < 32)?
          ~((~(uint32_t)0) << numBits):~(uint32_t)0;
        currentVal = val[j] & valMask, totalBitsLeft -= bitsLeft = numBits;
      }
    }
    /* at this point accum holds as many bits as we could get
     * to fill the first BitElem in str, but did we get enough? */
    if (bitsInAccum < bitElemBits - bitTop)
    {
      /* no there's not enough */
      unsigned backShift = bitElemBits - bitsInAccum - bitTop;
      mask &= ~(GtUword)0 << backShift;
      *p = (*p & ~mask) | ((accum << backShift) & mask);
      /* TODO: try wether  r = a ^ ((a ^ b) & mask) is faster, see below */
      return; /* if we couldn't gather more bits, there's none left */
    }
    else
    {
      /* yep, just or with accumVals */
      *p = (*p & ~mask) | (accum >> (bitsInAccum - bitElemBits + bitTop));
      ++p;
      bitsInAccum -= bitElemBits - bitTop;
    }
  }

  while (totalBitsLeft || (bitsInAccum + bitsLeft) > bitElemBits)
  {
    while ((totalBitsLeft || bitsLeft)
          && ((bitsInAccum < bitElemBits)
              || (bitsLeft < sizeof (accum)*CHAR_BIT - bitsInAccum)))
    {
      unsigned bits2Read, bitsFree = sizeof (accum)*CHAR_BIT - bitsInAccum;
      if ((bits2Read = GT_MIN(bitsFree, bitsLeft)) < sizeof (accum)*CHAR_BIT)
      {
        GtUword mask = ~((~(GtUword)0) << bits2Read);
        accum = accum << bits2Read
          | ((currentVal >> (bitsLeft - bits2Read)) & mask);
      }
      else
        accum = currentVal;
      bitsInAccum += bits2Read;
      /* all of currentVal == val[j] consumed? */
      if (bits2Read == bitsLeft && totalBitsLeft)
      {
        unsigned numBits = numBitsList[++j];
        gt_assert(numBits <= sizeof (val[0])*CHAR_BIT);
        valMask = (numBits < 32)?
          ~((~(uint32_t)0) << numBits):~(uint32_t)0;
        currentVal = val[j] & valMask, totalBitsLeft -= bitsLeft = numBits;
      }
      else
        bitsLeft -= bits2Read;
    }
    /* now we have enough bits in accum */
    while (bitsInAccum >= bitElemBits)
    {
      *p++ = accum >> (bitsInAccum - bitElemBits);
      bitsInAccum -= bitElemBits;
    }
  }
  /* write the rest bits left in accum and currentVal */
  accum = (accum << bitsLeft)
    | (currentVal & (valMask >> (numBitsList[j] - bitsLeft)));
  bitsInAccum += bitsLeft;
  while (bitsInAccum >= bitElemBits)
  {
    *p++ = accum >> (bitsInAccum - bitElemBits);
    bitsInAccum -= bitElemBits;
  }
  if (bitsInAccum)
  {
    GtUword mask =
      ~(GtUword)0 << (bitElemBits - bitsInAccum);
    *p = (*p & ~mask) | ((accum << (bitElemBits - bitsInAccum))& mask);
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %r8, 0x8(%rsp)
testq %r8, %r8
je 0xc7950
testq %r9, %r9
je 0xc797e
testq %rdx, %rdx
je 0xc79ac
movq %rcx, %rax
movq 0x8(%rsp), %rcx
movl (%rcx), %r10d
pushq $-0x1
popq %rbx
movq %rbx, %r14
movl %r10d, %ecx
shlq %cl, %r14
cmpq $0x20, %r10
notq %r14
cmovaeq %rbx, %r14
testq %rdi, %rdi
je 0xc79dd
cmpl $0x21, %r10d
jae 0xc7a0e
testq %rax, %rax
je 0xc7909
movq %rsi, %r11
movl (%r9), %r13d
andl %r14d, %r13d
cmpq %rax, %r10
jne 0xc7662
xorl %r15d, %r15d
xorl %edx, %edx
xorl %r12d, %r12d
xorl %eax, %eax
jmp 0xc769a
movq 0x8(%rsp), %rcx
movl 0x4(%rcx), %edx
cmpl $0x21, %edx
jae 0xc7a70
pushq $-0x1
popq %rsi
movl %esi, %r14d
movl %edx, %ecx
shll %cl, %r14d
cmpl $0x20, %edx
notl %r14d
cmovel %esi, %r14d
movl %r14d, %r15d
andl 0x4(%r9), %r15d
leal (%rdx,%r10), %ecx
subq %rcx, %rax
pushq $0x1
popq %r12
movl %r11d, %r8d
andl $0x7, %r8d
movq %r11, %rcx
shrq $0x3, %rcx
addq %rcx, %rdi
testl %r8d, %r8d
movq %r9, 0x18(%rsp)
je 0xc77cd
movq %r11, 0x20(%rsp)
pushq $0x8
popq %r11
subl %r8d, %r11d
pushq $-0x1
popq %rcx
movl %ecx, %esi
movl %r11d, %ecx
shll %cl, %esi
movl %esi, 0x14(%rsp)
pushq $0x40
popq %rsi
movl %r10d, %r9d
testq %rax, %rax
sete %cl
testl %edx, %edx
sete %r10b
testb %cl, %r10b
jne 0xc776f
cmpl %r11d, %r9d
jae 0xc776f
movl %esi, %r10d
subl %r9d, %r10d
cmpl %edx, %r10d
cmovael %edx, %r10d
movl %r10d, %ecx
shlq %cl, %r13
subl %r10d, %edx
movq %r15, %rbp
movl %edx, %ecx
shrq %cl, %rbp
orq %rbp, %r13
cmpl $0x40, %r10d
cmovaeq %r15, %r13
addl %r9d, %r10d
movl %r10d, %r9d
testl %edx, %edx
jne 0xc76d9
movl %r10d, %r9d
testq %rax, %rax
je 0xc76d9
movq 0x8(%rsp), %rcx
movl 0x4(%rcx,%r12,4), %edx
cmpq $0x21, %rdx
jae 0xc7a3f
incq %r12
pushq $-0x1
popq %r9
movl %r9d, %r14d
movl %edx, %ecx
shll %cl, %r14d
cmpl $0x20, %edx
notl %r14d
cmovel %r9d, %r14d
movl %r14d, %r15d
movq 0x18(%rsp), %rcx
andl (%rcx,%r12,4), %r15d
subq %rdx, %rax
jmp 0xc76d6
movl %r9d, %r10d
subl %r11d, %r10d
jae 0xc77a7
addl %r9d, %r8d
movb $0x8, %cl
subb %r8b, %cl
shlq %cl, %rbx
movl 0x14(%rsp), %eax
notl %eax
orl $0xff01, %eax           # imm = 0xFF01
movzwl %ax, %eax
andl %eax, %ebx
movzbl (%rdi), %edx
shlq %cl, %r13
notl %ebx
andl %edx, %ebx
andl %eax, %r13d
orl %ebx, %r13d
jmp 0xc7906
movzbl (%rdi), %esi
movq 0x20(%rsp), %rcx
orl $0xf8, %ecx
addl %r9d, %ecx
movq %r13, %r8
shrq %cl, %r8
movl 0x14(%rsp), %ecx
andl %esi, %ecx
orl %ecx, %r8d
movb %r8b, (%rdi)
incq %rdi
pushq $0x40
popq %r11
testq %rax, %rax
jne 0xc77e3
leal (%rdx,%r10), %esi
cmpl $0x9, %esi
jb 0xc78c0
movq %r13, %r9
movl %r10d, %ecx
testq %rax, %rax
jne 0xc77f6
testl %edx, %edx
je 0xc789b
cmpl $0x8, %r10d
setb %sil
movl %edx, %r13d
movq %r11, %r8
subq %rcx, %r8
cmpq %r13, %r8
seta %bpl
orb %sil, %bpl
cmpb $0x1, %bpl
jne 0xc78af
cmpl %r8d, %edx
movl %r8d, %esi
cmovbl %edx, %esi
movq %r15, %r13
cmpl $0x3f, %esi
ja 0xc784a
movq %rbx, %rbp
movl %esi, %ecx
shlq %cl, %rbp
shlq %cl, %r9
movl %edx, %ecx
subl %esi, %ecx
movq %r15, %r13
shrq %cl, %r13
notq %rbp
andq %rbp, %r13
orq %r9, %r13
addl %esi, %r10d
cmpl %r8d, %edx
ja 0xc7857
testq %rax, %rax
jne 0xc785b
subl %esi, %edx
jmp 0xc77e3
movq 0x8(%rsp), %rcx
movl 0x4(%rcx,%r12,4), %edx
cmpq $0x21, %rdx
jae 0xc7918
incq %r12
pushq $-0x1
popq %rsi
movl %esi, %r14d
movl %edx, %ecx
shll %cl, %r14d
cmpl $0x20, %edx
notl %r14d
cmovel %esi, %r14d
movl %r14d, %r15d
movq 0x18(%rsp), %rcx
andl (%rcx,%r12,4), %r15d
subq %rdx, %rax
jmp 0xc77e3
xorl %edx, %edx
jmp 0xc78af
addq $-0x8, %rcx
movq %r9, %rsi
shrq %cl, %rsi
movb %sil, (%rdi)
incq %rdi
cmpq $0x8, %rcx
jae 0xc789f
movq %r9, %r13
movl %ecx, %r10d
jmp 0xc77d1
movl %edx, %ecx
shlq %cl, %r13
movq 0x8(%rsp), %rax
movl (%rax,%r12,4), %ecx
subl %edx, %ecx
shrq %cl, %r14
andq %r15, %r14
orq %r13, %r14
cmpl $0x8, %esi
jb 0xc78e8
movb %r14b, (%rdi)
incq %rdi
xorl %esi, %esi
jmp 0xc78d9
testl %esi, %esi
je 0xc7909
movb $0x8, %cl
subb %sil, %cl
movzbl (%rdi), %eax
pushq $-0x1
popq %rdx
shll %cl, %edx
shlq %cl, %r14
notl %edx
andl %eax, %edx
orq %rdx, %r14
movq %r14, %r13
movb %r13b, (%rdi)
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq 0x66699(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x273d(%rip), %rsi      # 0xca066
leaq 0x2da1d(%rip), %rdx     # 0xf534d
leaq 0x2daa6(%rip), %rcx     # 0xf53dd
leaq 0x2d969(%rip), %r8      # 0xf52a7
movl $0x25a, %r9d            # imm = 0x25A
xorl %eax, %eax
callq 0xb8c0
callq 0xb300
movq 0x66661(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x2705(%rip), %rsi      # 0xca066
leaq 0x2da61(%rip), %rdx     # 0xf53c9
leaq 0x2da6e(%rip), %rcx     # 0xf53dd
leaq 0x2d931(%rip), %r8      # 0xf52a7
movl $0x1fb, %r9d            # imm = 0x1FB
jmp 0xc7944
movq 0x66633(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x26d7(%rip), %rsi      # 0xca066
leaq 0x2da67(%rip), %rdx     # 0xf53fd
leaq 0x2da40(%rip), %rcx     # 0xf53dd
leaq 0x2d903(%rip), %r8      # 0xf52a7
movl $0x1fc, %r9d            # imm = 0x1FC
jmp 0xc7944
movq 0x66605(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x26a9(%rip), %rsi      # 0xca066
leaq 0x2da45(%rip), %rdx     # 0xf5409
leaq 0x2da12(%rip), %rcx     # 0xf53dd
leaq 0x2d8d5(%rip), %r8      # 0xf52a7
movl $0x1fd, %r9d            # imm = 0x1FD
jmp 0xc7944
movq 0x665d4(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x2678(%rip), %rsi      # 0xca066
leaq 0x2d932(%rip), %rdx     # 0xf5327
leaq 0x2d9e1(%rip), %rcx     # 0xf53dd
leaq 0x2d8a4(%rip), %r8      # 0xf52a7
movl $0x200, %r9d            # imm = 0x200
jmp 0xc7944
movq 0x665a3(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x2647(%rip), %rsi      # 0xca066
leaq 0x2d9f2(%rip), %rdx     # 0xf5418
leaq 0x2d9b0(%rip), %rcx     # 0xf53dd
leaq 0x2d873(%rip), %r8      # 0xf52a7
movl $0x201, %r9d            # imm = 0x201
jmp 0xc7944
movq 0x66572(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x2616(%rip), %rsi      # 0xca066
leaq 0x2d8f6(%rip), %rdx     # 0xf534d
leaq 0x2d97f(%rip), %rcx     # 0xf53dd
leaq 0x2d842(%rip), %r8      # 0xf52a7
movl $0x22c, %r9d            # imm = 0x22C
jmp 0xc7944
movq 0x66541(%rip), %rax     # 0x12dfb8
movq (%rax), %rdi
leaq 0x25e5(%rip), %rsi      # 0xca066
leaq 0x2d8c5(%rip), %rdx     # 0xf534d
leaq 0x2d94e(%rip), %rcx     # 0xf53dd
leaq 0x2d811(%rip), %r8      # 0xf52a7
movl $0x20c, %r9d            # imm = 0x20C
jmp 0xc7944