// File: /workspace/github_cpp_makefile_star2_O3/karel-brinda[P]ococo/ext/htslib/cram/cram_codecs.c
// Function: get_bits_MSB
static inline unsigned int get_bits_MSB(cram_block *block, int nbits) {
    unsigned int val = 0;
    int i;

#if 0
    // Fits within the current byte */
    if (nbits <= block->bit+1) {
	val = (block->data[block->byte]>>(block->bit-(nbits-1))) & ((1<<nbits)-1);
	if ((block->bit -= nbits) == -1) {
	    block->bit = 7;
	    block->byte++;
	}
	return val;
    }

    // partial first byte
    val = block->data[block->byte] & ((1<<(block->bit+1))-1);
    nbits -= block->bit+1;
    block->bit = 7;
    block->byte++;

    // whole middle bytes
    while (nbits >= 8) {
	val = (val << 8) | block->data[block->byte++];
	nbits -= 8;
    }

    val <<= nbits;
    val |= (block->data[block->byte]>>(block->bit-(nbits-1))) & ((1<<nbits)-1);
    block->bit -= nbits;
    return val;
#endif

#if 0
    /* Inefficient implementation! */
    //printf("{");
    for (i = 0; i < nbits; i++)
	//val = (val << 1) | get_bit_MSB(block);
	GET_BIT_MSB(block, val);
#endif

#if 1
    /* Combination of 1st two methods */
    if (nbits <= block->bit+1) {
	val = (block->data[block->byte]>>(block->bit-(nbits-1))) & ((1<<nbits)-1);
	if ((block->bit -= nbits) == -1) {
	    block->bit = 7;
	    block->byte++;
	}
	return val;
    }

    switch(nbits) {
//    case 15: GET_BIT_MSB(block, val);
//    case 14: GET_BIT_MSB(block, val);
//    case 13: GET_BIT_MSB(block, val);
//    case 12: GET_BIT_MSB(block, val);
//    case 11: GET_BIT_MSB(block, val);
//    case 10: GET_BIT_MSB(block, val);
//    case  9: GET_BIT_MSB(block, val);
    case  8: GET_BIT_MSB(block, val);
    case  7: GET_BIT_MSB(block, val);
    case  6: GET_BIT_MSB(block, val);
    case  5: GET_BIT_MSB(block, val);
    case  4: GET_BIT_MSB(block, val);
    case  3: GET_BIT_MSB(block, val);
    case  2: GET_BIT_MSB(block, val);
    case  1: GET_BIT_MSB(block, val);
	break;

    default:
	for (i = 0; i < nbits; i++)
	    //val = (val << 1) | get_bit_MSB(block);
	    GET_BIT_MSB(block, val);
    }
#endif

    //printf("=0x%x}", val);

    return val;
}

// Assembly:
movl 0x38(%rdi), %edx
leal 0x1(%rdx), %eax
cmpl %esi, %eax
jge 0x4965a
leal -0x1(%rsi), %eax
cmpl $0x7, %eax
ja 0x49849
leaq 0xb16f(%rip), %rcx      # 0x547b0
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %rcx
xorl %r9d, %r9d
jmp 0x49820
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %r8
movzbl (%rax,%r8), %r9d
subl %esi, %edx
leal 0x1(%rdx), %ecx
shrl %cl, %r9d
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
movl %esi, %ecx
shll %cl, %eax
notl %eax
andl %r9d, %eax
movl %edx, 0x38(%rdi)
incl %edx
jne 0x49692
movl $0x7, 0x38(%rdi)
incq %r8
movq %r8, 0x30(%rdi)
retq
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %rcx
xorl %r9d, %r9d
jmp 0x49772
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %rcx
xorl %r9d, %r9d
jmp 0x497c9
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %rsi
xorl %r8d, %r8d
jmp 0x4979e
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %r8
movzbl (%rax,%r8), %esi
movl %edx, %ecx
shrl %cl, %esi
xorl %ecx, %ecx
testl %edx, %edx
leal -0x1(%rdx), %edx
setle %cl
addq %r8, %rcx
movq %rcx, 0x30(%rdi)
andl $0x7, %edx
movl %edx, 0x38(%rdi)
addl %esi, %esi
andl $0x2, %esi
jmp 0x49719
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %rsi
xorl %r8d, %r8d
jmp 0x497f5
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %rsi
xorl %r8d, %r8d
jmp 0x49747
movq 0x20(%rdi), %rax
movq 0x30(%rdi), %rcx
xorl %esi, %esi
movzbl (%rax,%rcx), %r9d
xorl %r8d, %r8d
btl %edx, %r9d
setb %r8b
orl %esi, %r8d
xorl %esi, %esi
testl %edx, %edx
leal -0x1(%rdx), %edx
setle %sil
addq %rcx, %rsi
movq %rsi, 0x30(%rdi)
andl $0x7, %edx
movl %edx, 0x38(%rdi)
addl %r8d, %r8d
movzbl (%rax,%rsi), %ecx
xorl %r9d, %r9d
btl %edx, %ecx
setb %r9b
orl %r8d, %r9d
xorl %ecx, %ecx
testl %edx, %edx
leal -0x1(%rdx), %edx
setle %cl
addq %rsi, %rcx
movq %rcx, 0x30(%rdi)
andl $0x7, %edx
movl %edx, 0x38(%rdi)
addl %r9d, %r9d
movzbl (%rax,%rcx), %esi
xorl %r8d, %r8d
btl %edx, %esi
setb %r8b
orl %r9d, %r8d
xorl %esi, %esi
testl %edx, %edx
leal -0x1(%rdx), %edx
setle %sil
addq %rcx, %rsi
movq %rsi, 0x30(%rdi)
andl $0x7, %edx
movl %edx, 0x38(%rdi)
addl %r8d, %r8d
movzbl (%rax,%rsi), %ecx
xorl %r9d, %r9d
btl %edx, %ecx
setb %r9b
orl %r8d, %r9d
xorl %ecx, %ecx
testl %edx, %edx
leal -0x1(%rdx), %edx
setle %cl
addq %rsi, %rcx
movq %rcx, 0x30(%rdi)
andl $0x7, %edx
movl %edx, 0x38(%rdi)
addl %r9d, %r9d
movzbl (%rax,%rcx), %esi
xorl %r8d, %r8d
btl %edx, %esi
setb %r8b
orl %r9d, %r8d
xorl %esi, %esi
testl %edx, %edx
leal -0x1(%rdx), %edx
setle %sil
addq %rcx, %rsi
movq %rsi, 0x30(%rdi)
andl $0x7, %edx
movl %edx, 0x38(%rdi)
addl %r8d, %r8d
movzbl (%rax,%rsi), %ecx
xorl %r9d, %r9d
btl %edx, %ecx
setb %r9b
orl %r8d, %r9d
xorl %ecx, %ecx
testl %edx, %edx
leal -0x1(%rdx), %edx
setle %cl
addq %rsi, %rcx
movq %rcx, 0x30(%rdi)
andl $0x7, %edx
movl %edx, 0x38(%rdi)
addl %r9d, %r9d
movzbl (%rax,%rcx), %esi
xorl %eax, %eax
btl %edx, %esi
setb %al
orl %r9d, %eax
leal -0x1(%rdx), %esi
xorl %r8d, %r8d
testl %edx, %edx
setle %r8b
addq %rcx, %r8
movq %r8, 0x30(%rdi)
andl $0x7, %esi
movl %esi, 0x38(%rdi)
retq
testl %esi, %esi
jle 0x4988d
movq 0x20(%rdi), %rcx
movq 0x30(%rdi), %r8
xorl %eax, %eax
movzbl (%rcx,%r8), %r9d
xorl %r10d, %r10d
btl %edx, %r9d
setb %r10b
leal (%r10,%rax,2), %eax
xorl %r9d, %r9d
testl %edx, %edx
leal -0x1(%rdx), %edx
setle %r9b
addq %r9, %r8
movq %r8, 0x30(%rdi)
andl $0x7, %edx
movl %edx, 0x38(%rdi)
decl %esi
jne 0x49857
jmp 0x49692
xorl %eax, %eax
retq