// File: /workspace/github_c_makefile_star2_O3/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
xorl %eax, %eax
cmpl $0x8, %r8d
ja 0x61cea
movq %rsi, %r10
movq %rdi, %rbx
movl %r8d, %edi
leaq 0x3a454(%rip), %r8      # 0x9bd94
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 -0x70(%rsp), %rax
xorl %edi, %edi
movzbl (%r9,%rdi), %esi
movd %esi, %xmm0
punpcklbw %xmm0, %xmm0    # xmm0 = xmm0[0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7]
pshuflw $0x0, %xmm0, %xmm0      # xmm0 = xmm0[0,0,0,0,4,5,6,7]
xorl %r8d, %r8d
movq (%r9,%r8), %xmm1
punpcklbw %xmm0, %xmm1    # xmm1 = xmm1[0],xmm0[0],xmm1[1],xmm0[1],xmm1[2],xmm0[2],xmm1[3],xmm0[3],xmm1[4],xmm0[4],xmm1[5],xmm0[5],xmm1[6],xmm0[6],xmm1[7],xmm0[7]
movdqa %xmm1, (%rax,%r8,2)
addq $0x8, %r8
cmpq $0x10, %r8
jne 0x61985
incq %rdi
addq $0x20, %rax
cmpq $0x10, %rdi
jne 0x61970
leaq 0x1(%rcx), %rax
shrq %rax
cmpq %r10, %rax
ja 0x61bd2
movq %rcx, %rdi
andq $-0x2, %rdi
cmpq $0x3, %rdi
jl 0x61c15
movl $0x2, %eax
xorl %r8d, %r8d
movzbl (%rbx,%r8), %esi
movzwl -0x70(%rsp,%rsi,2), %esi
movzbl 0x1(%rbx,%r8), %r10d
movzwl -0x70(%rsp,%r10,2), %r10d
movw %si, -0x2(%rdx,%rax)
movw %r10w, (%rdx,%rax)
addq $0x2, %r8
addq $0x4, %rax
cmpq %rdi, %rax
jl 0x619d5
addq $-0x2, %rax
jmp 0x61c31
movq %rdx, %rdi
movq %rbx, %rsi
movq %r10, %rdx
addq $0x798, %rsp            # imm = 0x798
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
jmp 0x43c0
movq %r10, -0x78(%rsp)
movq %rbx, -0x80(%rsp)
leaq -0x6d(%rsp), %rax
xorl %edi, %edi
xorl %r8d, %r8d
movb (%r9,%rdi), %r11b
xorl %ebx, %ebx
movb (%r9,%rbx), %bpl
xorl %r12d, %r12d
movq %r8, %r14
movb (%r9,%r12), %r13b
movslq %r14d, %r8
leaq (%rax,%r8,4), %r10
xorl %r15d, %r15d
movb (%r9,%r15), %sil
movb %sil, -0x3(%r10,%r15,4)
movb %r13b, -0x2(%r10,%r15,4)
movb %bpl, -0x1(%r10,%r15,4)
movb %r11b, (%r10,%r15,4)
incq %r15
cmpq $0x4, %r15
jne 0x61a5c
incq %r12
addq %r15, %r8
cmpq $0x4, %r12
jne 0x61a4b
incq %rbx
movslq %r14d, %r8
addq %r15, %r8
cmpq $0x4, %rbx
jne 0x61a44
incq %rdi
movslq %r14d, %r8
addq %r15, %r8
cmpq $0x4, %rdi
jne 0x61a3e
leaq 0x3(%rcx), %rax
shrq $0x2, %rax
cmpq -0x78(%rsp), %rax
ja 0x61bd2
movq %rcx, %r15
movq %rcx, %rdi
andq $-0x4, %rdi
cmpq $0xd, %rdi
jl 0x61c53
leaq -0xc(%rdi), %r10
xorl %eax, %eax
xorl %r8d, %r8d
movq -0x80(%rsp), %rcx
movzbl (%rcx,%r8), %esi
movl -0x70(%rsp,%rsi,4), %esi
movzbl 0x1(%rcx,%r8), %r11d
movl -0x70(%rsp,%r11,4), %r11d
movzbl 0x2(%rcx,%r8), %ebx
movl -0x70(%rsp,%rbx,4), %ebx
movzbl 0x3(%rcx,%r8), %r14d
movl -0x70(%rsp,%r14,4), %ebp
addq $0x4, %r8
movl %esi, (%rdx,%rax)
movl %r11d, 0x4(%rdx,%rax)
movl %ebx, 0x8(%rdx,%rax)
movl %ebp, 0xc(%rdx,%rax)
addq $0x10, %rax
cmpq %r10, %rax
jl 0x61adb
jmp 0x61c72
xorl %eax, %eax
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
movb %dil, -0x6f(%rsp,%rax,8)
btl $0x2, %eax
movq %r9, %rdi
adcq $0x0, %rdi
movb (%rdi), %dil
movb %dil, -0x6e(%rsp,%rax,8)
btl $0x3, %eax
movq %r9, %rdi
adcq $0x0, %rdi
movb (%rdi), %dil
movb %dil, -0x6d(%rsp,%rax,8)
btl $0x4, %eax
movq %r9, %rdi
adcq $0x0, %rdi
movb (%rdi), %dil
movb %dil, -0x6c(%rsp,%rax,8)
btl $0x5, %eax
movq %r9, %rdi
adcq $0x0, %rdi
movb (%rdi), %dil
movb %dil, -0x6b(%rsp,%rax,8)
btl $0x6, %eax
movq %r9, %rdi
adcq $0x0, %rdi
movb (%rdi), %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
cmpq $0x100, %rax            # imm = 0x100
jne 0x61b28
leaq 0x7(%rcx), %rax
shrq $0x3, %rax
cmpq %r10, %rax
jbe 0x61bd9
xorl %eax, %eax
jmp 0x61cea
movq %rcx, %r8
andq $-0x8, %r8
jle 0x61cac
leaq -0x1(%r8), %rdi
shrq $0x3, %rdi
incq %rdi
xorl %eax, %eax
xorl %r10d, %r10d
movzbl (%rbx,%r10), %r11d
incq %r10
movq -0x70(%rsp,%r11,8), %r11
movq %r11, (%rdx,%rax)
addq $0x8, %rax
cmpq %r10, %rdi
jne 0x61bf6
jmp 0x61cb0
xorl %r8d, %r8d
xorl %eax, %eax
jmp 0x61c31
movzbl (%rbx,%r8), %esi
incq %r8
movzwl -0x70(%rsp,%rsi,2), %esi
movw %si, (%rdx,%rax)
addq $0x2, %rax
cmpq %rdi, %rax
jl 0x61c1c
cmpq %rcx, %rdi
je 0x61ce7
movzbl (%rbx,%r8), %ecx
andl $0xf, %ecx
movb (%r9,%rcx), %cl
movb %cl, (%rdx,%rax)
jmp 0x61ce7
xorl %r8d, %r8d
xorl %eax, %eax
movq -0x80(%rsp), %rcx
jmp 0x61c72
movzbl (%rcx,%r8), %esi
incq %r8
movl -0x70(%rsp,%rsi,4), %esi
movl %esi, (%rdx,%rax)
addq $0x4, %rax
cmpq %rdi, %rax
jl 0x61c5f
cmpq %r15, %rdi
sete %sil
cmpq %r15, %rax
setae %dil
orb %sil, %dil
jne 0x61ce7
movb (%rcx,%r8), %sil
movzbl %sil, %esi
movl %esi, %ecx
andl $0x3, %ecx
movb (%r9,%rcx), %cl
movb %cl, (%rdx,%rax)
incq %rax
shrb $0x2, %sil
cmpq %rax, %r15
jne 0x61c8e
jmp 0x61ce7
xorl %edi, %edi
xorl %eax, %eax
cmpq %rcx, %r8
setne %r8b
cmpq %rcx, %rax
setb %r10b
andb %r8b, %r10b
cmpb $0x1, %r10b
jne 0x61ce7
movb (%rbx,%rdi), %sil
movzbl %sil, %esi
movl %esi, %edi
andl $0x1, %edi
movb (%r9,%rdi), %dil
movb %dil, (%rdx,%rax)
incq %rax
shrb %sil
cmpq %rax, %rcx
jne 0x61ccb
movq %rdx, %rax
addq $0x798, %rsp            # imm = 0x798
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq