// File: /workspace/github_c_makefile_star2_O2/samtools[P]htslib/htscodecs/htscodecs/pack.c
// Function: hts_unpack
uint8_t *hts_unpack(uint8_t *data, int64_t len, uint8_t *out, uint64_t out_len, int nsym, uint8_t *p) {
    //uint8_t *out;
    uint8_t c = 0;
    int64_t i, j = 0, olen;

    if (nsym == 1) {
        // raw data; FIXME: shortcut the need for malloc & memcpy here
        memcpy(out, data, len);
        return out;
    }

    switch(nsym) {
    case 8: {
        union {
            uint64_t w;
            uint8_t c[8];
        } map[256];
        int x;
        for (x = 0; x < 256; x++) {
            map[x].c[0] = p[x>>0&1];
            map[x].c[1] = p[x>>1&1];
            map[x].c[2] = p[x>>2&1];
            map[x].c[3] = p[x>>3&1];
            map[x].c[4] = p[x>>4&1];
            map[x].c[5] = p[x>>5&1];
            map[x].c[6] = p[x>>6&1];
            map[x].c[7] = p[x>>7&1];
        }
        if ((out_len+7)/8 > len)
            return NULL;
        olen = out_len & ~7;

        for (i = 0; i < olen; i+=8)
            memcpy(&out[i], &map[data[j++]].w, 8);

        if (out_len != olen) {
            c = data[j++];
            while (i < out_len) {
                out[i++] = p[c & 1];
                c >>= 1;
            }
        }
        break;
    }

    case 4: {
        union {
            uint32_t w;
            uint8_t c[4];
        } map[256];

        int x, y, z, _, P=0;
        for (x = 0; x < 4; x++)
            for (y = 0; y < 4; y++)
                for (z = 0; z < 4; z++)
                    for (_ = 0; _ < 4; _++, P++) {
                        map[P].c[0] = p[_];
                        map[P].c[1] = p[z];
                        map[P].c[2] = p[y];
                        map[P].c[3] = p[x];
                    }

        if ((out_len+3)/4 > len)
            return NULL;
        olen = out_len & ~3;

        for (i = 0; i < olen-12; i+=16) {
            uint32_t w[] = {
                map[data[j+0]].w,
                map[data[j+1]].w,
                map[data[j+2]].w,
                map[data[j+3]].w
            };
            j += 4;
            memcpy(&out[i], &w, 16);
        }

        for (; i < olen; i+=4)
            memcpy(&out[i], &map[data[j++]].w, 4);

        if (out_len != olen) {
            c = data[j++];
            while (i < out_len) {
                out[i++] = p[c & 3];
                c >>= 2;
            }
        }
        break;
    }

    case 2: {
        union {
            uint16_t w;
            uint8_t c[2];
        } map[256];

        int x, y;
        for (x = 0; x < 16; x++) {
            for (y = 0; y < 16; y++) {
                map[x*16+y].c[0] = p[y];
                map[x*16+y].c[1] = p[x];
            }
        }

        if ((out_len+1)/2 > len)
            return NULL;
        olen = out_len & ~1;

        for (i = j = 0; i+2 < olen; i+=4) {
            uint16_t w[] = {
                map[data[j+0]].w,
                map[data[j+1]].w
            };
            memcpy(&out[i], &w, 4);

            j += 2;
        }

        for (; i < olen; i+=2)
            memcpy(&out[i], &map[data[j++]].w, 2);

        if (out_len != olen) {
            c = data[j++];
            out[i+0] = p[c&15];
        }
        break;
    }

    case 0:
        memset(out, p[0], out_len);
        break;

    default:
        return NULL;
    }

    return out;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x798, %rsp            # imm = 0x798
movq %rsi, -0x78(%rsp)
xorl %eax, %eax
cmpl $0x8, %r8d
ja 0x4ec8f
movq %rdi, %rsi
movl %r8d, %edi
leaq 0x2f198(%rip), %r8      # 0x7db24
movslq (%r8,%rdi,4), %rdi
addq %r8, %rdi
jmpq *%rdi
movzbl (%r9), %esi
movq %rdx, %rdi
movq %rcx, %rdx
addq $0x798, %rsp            # imm = 0x798
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x4260
leaq -0x6f(%rsp), %rax
xorl %edi, %edi
cmpq $0x10, %rdi
je 0x4e9ea
movb (%r9,%rdi), %r8b
xorl %r11d, %r11d
cmpq $0x10, %r11
je 0x4e9e1
movb (%r9,%r11), %r10b
movb %r10b, -0x1(%rax,%r11,2)
movb %r8b, (%rax,%r11,2)
incq %r11
jmp 0x4e9c9
incq %rdi
addq $0x20, %rax
jmp 0x4e9bc
leaq 0x1(%rcx), %rax
shrq %rax
cmpq -0x78(%rsp), %rax
ja 0x4ec2a
movq %rcx, %rdi
andq $-0x2, %rdi
movabsq $0x2, %rax
cmpq %rdi, %rax
jge 0x4ec2e
movzbl (%rsi), %r8d
movzwl -0x70(%rsp,%r8,2), %r8d
movzbl 0x1(%rsi), %r10d
movzwl -0x70(%rsp,%r10,2), %r10d
movw %r8w, -0x2(%rdx,%rax)
movw %r10w, (%rdx,%rax)
addq $0x2, %rsi
addq $0x4, %rax
jmp 0x4ea0d
movq %rdx, %rdi
movq -0x78(%rsp), %rdx
addq $0x798, %rsp            # imm = 0x798
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x43c0
xorl %eax, %eax
leaq -0x6d(%rsp), %rdi
xorl %r8d, %r8d
cmpq $0x4, %rax
je 0x4eaca
movb (%r9,%rax), %r11b
xorl %ebx, %ebx
cmpq $0x4, %rbx
je 0x4eac5
movb (%r9,%rbx), %bpl
xorl %r14d, %r14d
cmpq $0x4, %r14
je 0x4eac0
movb (%r9,%r14), %r15b
movslq %r8d, %r12
leaq (%rdi,%r12,4), %r13
xorl %r12d, %r12d
cmpq $0x4, %r12
je 0x4eab8
movb (%r9,%r12), %r10b
movb %r10b, -0x3(%r13,%r12,4)
movb %r15b, -0x2(%r13,%r12,4)
movb %bpl, -0x1(%r13,%r12,4)
movb %r11b, (%r13,%r12,4)
incq %r12
jmp 0x4ea95
addl %r12d, %r8d
incq %r14
jmp 0x4ea81
incq %rbx
jmp 0x4ea74
incq %rax
jmp 0x4ea68
leaq 0x3(%rcx), %rax
shrq $0x2, %rax
cmpq -0x78(%rsp), %rax
ja 0x4ec2a
movq %rcx, %rdi
andq $-0x4, %rdi
leaq -0xc(%rdi), %r8
xorl %eax, %eax
cmpq %r8, %rax
jge 0x4eb43
movzbl (%rsi), %r10d
movl -0x70(%rsp,%r10,4), %r10d
movzbl 0x1(%rsi), %r11d
movl -0x70(%rsp,%r11,4), %r11d
movzbl 0x2(%rsi), %ebx
movl -0x70(%rsp,%rbx,4), %ebx
movzbl 0x3(%rsi), %r14d
movl -0x70(%rsp,%r14,4), %ebp
movl %r10d, (%rdx,%rax)
movl %r11d, 0x4(%rdx,%rax)
movl %ebx, 0x8(%rdx,%rax)
movl %ebp, 0xc(%rdx,%rax)
addq $0x10, %rax
addq $0x4, %rsi
jmp 0x4eaea
movzbl (%rsi), %r8d
movl -0x70(%rsp,%r8,4), %r8d
movl %r8d, (%rdx,%rax)
addq $0x4, %rax
incq %rsi
cmpq %rdi, %rax
jl 0x4eb2f
cmpq %rcx, %rdi
je 0x4ec8c
movb (%rsi), %sil
cmpq %rcx, %rax
jae 0x4ec8c
movzbl %sil, %esi
movl %esi, %edi
andl $0x3, %edi
movb (%r9,%rdi), %dil
movb %dil, (%rdx,%rax)
incq %rax
shrb $0x2, %sil
jmp 0x4eb54
xorl %eax, %eax
cmpq $0x100, %rax            # imm = 0x100
je 0x4ec1b
movl %eax, %edi
andl $0x1, %edi
movb (%r9,%rdi), %dil
movb %dil, -0x70(%rsp,%rax,8)
btl $0x1, %eax
movq %r9, %rdi
adcq $0x0, %rdi
movb (%rdi), %dil
btl $0x2, %eax
movq %r9, %r8
adcq $0x0, %r8
movb %dil, -0x6f(%rsp,%rax,8)
movb (%r8), %dil
movb %dil, -0x6e(%rsp,%rax,8)
btl $0x3, %eax
movq %r9, %rdi
adcq $0x0, %rdi
movb (%rdi), %dil
btl $0x4, %eax
movq %r9, %r8
adcq $0x0, %r8
movb %dil, -0x6d(%rsp,%rax,8)
movb (%r8), %dil
movb %dil, -0x6c(%rsp,%rax,8)
btl $0x5, %eax
movq %r9, %rdi
adcq $0x0, %rdi
movb (%rdi), %dil
btl $0x6, %eax
movq %r9, %r8
adcq $0x0, %r8
movb %dil, -0x6b(%rsp,%rax,8)
movb (%r8), %dil
movb %dil, -0x6a(%rsp,%rax,8)
movl %eax, %edi
shrl $0x7, %edi
movb (%r9,%rdi), %dil
movb %dil, -0x69(%rsp,%rax,8)
incq %rax
jmp 0x4eb79
leaq 0x7(%rcx), %rax
shrq $0x3, %rax
cmpq -0x78(%rsp), %rax
jbe 0x4ec63
xorl %eax, %eax
jmp 0x4ec8f
addq $-0x2, %rax
cmpq %rdi, %rax
jge 0x4ec4f
movzbl (%rsi), %r8d
movzwl -0x70(%rsp,%r8,2), %r8d
movw %r8w, (%rdx,%rax)
addq $0x2, %rax
incq %rsi
jmp 0x4ec32
cmpq %rcx, %rdi
je 0x4ec8c
movzbl (%rsi), %ecx
andl $0xf, %ecx
movb (%r9,%rcx), %cl
movb %cl, (%rdx,%rax)
jmp 0x4ec8c
movq %rcx, %rdi
andq $-0x8, %rdi
xorl %eax, %eax
cmpq %rdi, %rax
jge 0x4ec87
movzbl (%rsi), %r8d
movq -0x70(%rsp,%r8,8), %r8
movq %r8, (%rdx,%rax)
addq $0x8, %rax
incq %rsi
jmp 0x4ec6c
cmpq %rcx, %rdi
jne 0x4eca1
movq %rdx, %rax
addq $0x798, %rsp            # imm = 0x798
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movb (%rsi), %sil
cmpq %rcx, %rax
jae 0x4ec8c
movzbl %sil, %esi
movl %esi, %edi
andl $0x1, %edi
movb (%r9,%rdi), %dil
movb %dil, (%rdx,%rax)
incq %rax
shrb %sil
jmp 0x4eca4