// File: /workspace/github_c_makefile_star2_O1/genometools[P]genometools/src/core/bitpackstringop32.c
// Function: gt_bsStoreUniformUInt32Array
void
gt_bsStoreUniformUInt32Array(BitString str, BitOffset offset,
                                 unsigned numBits, size_t numValues,
                                 const uint32_t val[])
{
  /* idea: read as much as possible from val in each iteration,
   * accumulate if bitsInAccum < bitElemBits */
  size_t j = 0;
  BitOffset totalBitsLeft = numValues * numBits;
  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;
  if (numBits < (sizeof (val[0])*CHAR_BIT))
    valMask = ~(valMask << numBits);
  gt_assert(str && val);
  gt_assert(numBits <= 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 = numBits;
  if (totalBitsLeft)
  {
    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)
        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)
        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 >> (numBits - 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 $0x18, %rsp
movq %r8, 0x8(%rsp)
movq %rcx, %r10
movl %edx, %ecx
movq %rsi, %r13
movq $-0x1, %rsi
movq $-0x1, %rax
shlq %cl, %rax
cmpl $0x20, %edx
notq %rax
cmovaeq %rsi, %rax
movq %rax, (%rsp)
testq %rdi, %rdi
je 0xde415
cmpq $0x0, 0x8(%rsp)
je 0xde415
movl %edx, %r8d
cmpl $0x21, %edx
jae 0xde41a
movl %r8d, %edx
movq %rdx, %rsi
imulq %r10, %rsi
testq %rsi, %rsi
je 0xde406
movl %r13d, %r9d
andl $0x7, %r9d
movq %r13, %rcx
shrq $0x3, %rcx
movq 0x8(%rsp), %rax
movl (%rax), %ebp
andl (%rsp), %ebp
cmpq %rdx, %rsi
jne 0xde14f
xorl %r12d, %r12d
xorl %eax, %eax
xorl %r10d, %r10d
xorl %r14d, %r14d
jmp 0xde16d
movq 0x8(%rsp), %rax
movl 0x4(%rax), %r12d
andl (%rsp), %r12d
addq $-0x2, %r10
imulq %rdx, %r10
movl $0x1, %r14d
movl %r8d, %eax
addq %rcx, %rdi
testl %r9d, %r9d
je 0xde264
movl $0x8, %r11d
movl %r9d, 0x14(%rsp)
subl %r9d, %r11d
movl $0xffffffff, %esi       # imm = 0xFFFFFFFF
movl %r11d, %ecx
shll %cl, %esi
movl %esi, 0x10(%rsp)
testq %r10, %r10
setne %sil
testl %eax, %eax
setne %cl
orb %sil, %cl
cmpl %r8d, %r11d
seta %bl
andb %bl, %cl
movl %r8d, %r9d
cmpb $0x1, %cl
jne 0xde21e
movl $0x40, %ebx
subl %r9d, %ebx
cmpl %eax, %ebx
cmovael %eax, %ebx
movl %ebx, %ecx
shlq %cl, %rbp
subl %ebx, %eax
movq %r12, %r15
movl %eax, %ecx
shrq %cl, %r15
orq %r15, %rbp
cmpl $0x40, %ebx
cmovaeq %r12, %rbp
testb $0x1, %sil
je 0xde1fb
testl %eax, %eax
jne 0xde1fb
movq 0x8(%rsp), %rax
movl 0x4(%rax,%r14,4), %r12d
andl (%rsp), %r12d
incq %r14
subq %rdx, %r10
movl %r8d, %eax
addl %ebx, %r9d
testq %r10, %r10
setne %sil
sete %cl
testl %eax, %eax
sete %r15b
cmpl %r11d, %r9d
setb %bl
testb %cl, %r15b
jne 0xde21e
cmpl %r11d, %r9d
jb 0xde1b4
testb %bl, %bl
je 0xde26c
movl 0x14(%rsp), %esi
addl %r9d, %esi
movb $0x8, %cl
subb %sil, %cl
movq $-0x1, %rsi
shlq %cl, %rsi
movl 0x10(%rsp), %r13d
notl %r13d
orl $0xffffff01, %r13d      # imm = 0xFFFFFF01
andl %r13d, %esi
movzbl (%rdi), %r11d
notl %esi
movq %rbp, %r15
shlq %cl, %r15
andl %r11d, %esi
andl %r13d, %r15d
orl %esi, %r15d
movb %r15b, (%rdi)
jmp 0xde296
movl %r8d, %r9d
jmp 0xde3ab
movzbl (%rdi), %ecx
movl 0x10(%rsp), %r15d
andl %ecx, %r15d
orl $0xf8, %r13d
addl %r9d, %r13d
movq %rbp, %rsi
movl %r13d, %ecx
shrq %cl, %rsi
orl %r15d, %esi
movb %sil, (%rdi)
incq %rdi
subl %r11d, %r9d
testb %bl, %bl
je 0xde3ab
jmp 0xde406
testq %r10, %r10
setne %r11b
jne 0xde2b4
testl %eax, %eax
je 0xde382
movq %rbp, %rbx
cmpl $0x8, %r9d
setb %cl
movl %eax, %esi
movl %r9d, %ebp
movl $0x40, %r15d
subq %rbp, %r15
cmpq %rsi, %r15
seta %sil
orb %cl, %sil
cmpb $0x1, %sil
jne 0xde37f
cmpl %r15d, %eax
movl %r15d, %esi
cmovbl %eax, %esi
movq %r12, %rbp
cmpl $0x3f, %esi
ja 0xde32c
movq %rax, %r13
movq %r12, %rax
movq %r14, %rbp
movl %r8d, %r14d
movq $-0x1, %r8
movl %esi, %ecx
shlq %cl, %r8
shlq %cl, %rbx
movl %r13d, %ecx
subl %esi, %ecx
shrq %cl, %r12
notq %r8
andq %r8, %r12
movl %r14d, %r8d
movq %rbp, %r14
movq %r12, %rbp
movq %rax, %r12
movq %r13, %rax
orq %rbx, %rbp
cmpl %r15d, %eax
seta %cl
notb %r11b
orb %cl, %r11b
testb $0x1, %r11b
jne 0xde357
movq 0x8(%rsp), %rax
movl 0x4(%rax,%r14,4), %r12d
andl (%rsp), %r12d
incq %r14
subq %rdx, %r10
movl %r8d, %eax
jmp 0xde359
subl %esi, %eax
addl %r9d, %esi
movl %esi, %r9d
movq %rbp, %rbx
testq %r10, %r10
setne %r11b
jne 0xde2b7
movl %esi, %r9d
movq %rbp, %rbx
testl %eax, %eax
jne 0xde2b7
jmp 0xde385
movq %rbx, %rbp
movl %r9d, %esi
cmpl $0x8, %esi
jb 0xde3a8
movl %esi, %r9d
addq $-0x8, %r9
movq %rbp, %rsi
movl %r9d, %ecx
shrq %cl, %rsi
movb %sil, (%rdi)
incq %rdi
cmpq $0x7, %r9
ja 0xde38d
jmp 0xde3ab
movl %esi, %r9d
testq %r10, %r10
jne 0xde2a3
leal (%rax,%r9), %esi
cmpl $0x9, %esi
jae 0xde2a3
movl %eax, %ecx
shlq %cl, %rbp
subl %eax, %r8d
movl %r8d, %ecx
movq (%rsp), %r8
shrq %cl, %r8
andq %r12, %r8
orq %rbp, %r8
cmpl $0x8, %esi
jb 0xde3e6
movb %r8b, (%rdi)
incq %rdi
xorl %esi, %esi
testl %esi, %esi
je 0xde406
movb $0x8, %cl
subb %sil, %cl
movzbl (%rdi), %eax
movl $0xffffffff, %edx       # imm = 0xFFFFFFFF
shll %cl, %edx
shll %cl, %r8d
notl %edx
andl %eax, %edx
orl %edx, %r8d
movb %r8b, (%rdi)
addq $0x18, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
callq 0x3453a
callq 0x34573