// File: /workspace/github_c_makefile_star2_O0/samtools[P]htslib/htscodecs/htscodecs/rANS_static4x16pr.c
// Function: rans_compress_O0_4x16
unsigned char *rans_compress_O0_4x16(unsigned char *in, unsigned int in_size,
                                     unsigned char *out, unsigned int *out_size) {
    unsigned char *cp, *out_end;
    RansEncSymbol syms[256];
    RansState rans0;
    RansState rans2;
    RansState rans1;
    RansState rans3;
    uint8_t* ptr;
    uint32_t F[256+MAGIC] = {0};
    int i, j, tab_size = 0, rle, x;
    // -20 for order/size/meta
    uint32_t bound = rans_compress_bound_4x16(in_size,0)-20;

    if (!out) {
        *out_size = bound;
        out = malloc(*out_size);
    }
    if (!out || bound > *out_size)
        return NULL;

    // If "out" isn't word aligned, tweak out_end/ptr to ensure it is.
    // We already added more round in bound to allow for this.
    if (((size_t)out)&1)
        bound--;
    ptr = out_end = out + bound;

    if (in_size == 0)
        goto empty;

    // Compute statistics
    if (hist8(in, in_size, F) < 0)
        return NULL;

    // Normalise so frequences sum to power of 2
    uint32_t fsum = in_size;
    uint32_t max_val = round2(fsum);
    if (max_val > TOTFREQ)
        max_val = TOTFREQ;

    if (normalise_freq(F, fsum, max_val) < 0)
        return NULL;
    fsum=max_val;

    cp = out;
    cp += encode_freq(cp, F);
    tab_size = cp-out;
    //write(2, out+4, cp-(out+4));

    if (normalise_freq(F, fsum, TOTFREQ) < 0)
        return NULL;

    // Encode statistics.
    for (x = rle = j = 0; j < 256; j++) {
        if (F[j]) {
            RansEncSymbolInit(&syms[j], x, F[j], TF_SHIFT);
            x += F[j];
        }
    }

    RansEncInit(&rans0);
    RansEncInit(&rans1);
    RansEncInit(&rans2);
    RansEncInit(&rans3);

    switch (i=(in_size&3)) {
    case 3: RansEncPutSymbol(&rans2, &ptr, &syms[in[in_size-(i-2)]]);
        // fall-through
    case 2: RansEncPutSymbol(&rans1, &ptr, &syms[in[in_size-(i-1)]]);
        // fall-through
    case 1: RansEncPutSymbol(&rans0, &ptr, &syms[in[in_size-(i-0)]]);
        // fall-through
    case 0:
        break;
    }
    for (i=(in_size &~3); i>0; i-=4) {
        RansEncSymbol *s3 = &syms[in[i-1]];
        RansEncSymbol *s2 = &syms[in[i-2]];
        RansEncSymbol *s1 = &syms[in[i-3]];
        RansEncSymbol *s0 = &syms[in[i-4]];

#if 1
        RansEncPutSymbol(&rans3, &ptr, s3);
        RansEncPutSymbol(&rans2, &ptr, s2);
        RansEncPutSymbol(&rans1, &ptr, s1);
        RansEncPutSymbol(&rans0, &ptr, s0);
#else
        // Slightly beter on gcc, much better on clang
        uint16_t *ptr16 = (uint16_t *)ptr;

        if (rans3 >= s3->x_max) *--ptr16 = (uint16_t)rans3, rans3 >>= 16;
        if (rans2 >= s2->x_max) *--ptr16 = (uint16_t)rans2, rans2 >>= 16;
        uint32_t q3 = (uint32_t) (((uint64_t)rans3 * s3->rcp_freq) >> s3->rcp_shift);
        uint32_t q2 = (uint32_t) (((uint64_t)rans2 * s2->rcp_freq) >> s2->rcp_shift);
        rans3 += s3->bias + q3 * s3->cmpl_freq;
        rans2 += s2->bias + q2 * s2->cmpl_freq;

        if (rans1 >= s1->x_max) *--ptr16 = (uint16_t)rans1, rans1 >>= 16;
        if (rans0 >= s0->x_max) *--ptr16 = (uint16_t)rans0, rans0 >>= 16;
        uint32_t q1 = (uint32_t) (((uint64_t)rans1 * s1->rcp_freq) >> s1->rcp_shift);
        uint32_t q0 = (uint32_t) (((uint64_t)rans0 * s0->rcp_freq) >> s0->rcp_shift);
        rans1 += s1->bias + q1 * s1->cmpl_freq;
        rans0 += s0->bias + q0 * s0->cmpl_freq;

        ptr = (uint8_t *)ptr16;
#endif
    }

    RansEncFlush(&rans3, &ptr);
    RansEncFlush(&rans2, &ptr);
    RansEncFlush(&rans1, &ptr);
    RansEncFlush(&rans0, &ptr);

 empty:
    // Finalise block size and return it
    *out_size = (out_end - ptr) + tab_size;

    memmove(out + tab_size, ptr, out_end-ptr);

    return out;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x14d0, %rsp           # imm = 0x14D0
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movq %rdx, -0x20(%rbp)
movq %rcx, -0x28(%rbp)
leaq -0x1480(%rbp), %rdi
xorl %esi, %esi
movl $0x420, %edx            # imm = 0x420
callq 0x4250
movl $0x0, -0x148c(%rbp)
movl -0x14(%rbp), %edi
xorl %esi, %esi
callq 0x8e2d0
subl $0x14, %eax
movl %eax, -0x1498(%rbp)
cmpq $0x0, -0x20(%rbp)
jne 0x8e4ae
movl -0x1498(%rbp), %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movq -0x28(%rbp), %rax
movl (%rax), %eax
movl %eax, %edi
callq 0x4650
movq %rax, -0x20(%rbp)
cmpq $0x0, -0x20(%rbp)
je 0x8e4c3
movl -0x1498(%rbp), %eax
movq -0x28(%rbp), %rcx
cmpl (%rcx), %eax
jbe 0x8e4d0
movq $0x0, -0x8(%rbp)
jmp 0x8e987
movq -0x20(%rbp), %rax
andq $0x1, %rax
cmpq $0x0, %rax
je 0x8e4ed
movl -0x1498(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x1498(%rbp)
movq -0x20(%rbp), %rax
movl -0x1498(%rbp), %ecx
addq %rcx, %rax
movq %rax, -0x38(%rbp)
movq %rax, -0x1058(%rbp)
cmpl $0x0, -0x14(%rbp)
jne 0x8e510
jmp 0x8e937
movq -0x10(%rbp), %rdi
movl -0x14(%rbp), %esi
leaq -0x1480(%rbp), %rdx
callq 0x8e9a0
cmpl $0x0, %eax
jge 0x8e535
movq $0x0, -0x8(%rbp)
jmp 0x8e987
movl -0x14(%rbp), %eax
movl %eax, -0x149c(%rbp)
movl -0x149c(%rbp), %edi
callq 0x8ede0
movl %eax, -0x14a0(%rbp)
cmpl $0x1000, -0x14a0(%rbp)  # imm = 0x1000
jbe 0x8e565
movl $0x1000, -0x14a0(%rbp)  # imm = 0x1000
leaq -0x1480(%rbp), %rdi
movl -0x149c(%rbp), %esi
movl -0x14a0(%rbp), %edx
callq 0x8ee40
cmpl $0x0, %eax
jge 0x8e58f
movq $0x0, -0x8(%rbp)
jmp 0x8e987
movl -0x14a0(%rbp), %eax
movl %eax, -0x149c(%rbp)
movq -0x20(%rbp), %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rdi
leaq -0x1480(%rbp), %rsi
callq 0x8f0c0
movl %eax, %ecx
movq -0x30(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0x30(%rbp)
movq -0x30(%rbp), %rax
movq -0x20(%rbp), %rcx
subq %rcx, %rax
movl %eax, -0x148c(%rbp)
leaq -0x1480(%rbp), %rdi
movl -0x149c(%rbp), %esi
movl $0x1000, %edx           # imm = 0x1000
callq 0x8ee40
cmpl $0x0, %eax
jge 0x8e5fd
movq $0x0, -0x8(%rbp)
jmp 0x8e987
movl $0x0, -0x1488(%rbp)
movl $0x0, -0x1490(%rbp)
movl $0x0, -0x1494(%rbp)
cmpl $0x100, -0x1488(%rbp)   # imm = 0x100
jge 0x8e698
movslq -0x1488(%rbp), %rax
cmpl $0x0, -0x1480(%rbp,%rax,4)
je 0x8e685
movslq -0x1488(%rbp), %rax
leaq -0x1040(%rbp), %rdi
shlq $0x4, %rax
addq %rax, %rdi
movl -0x1494(%rbp), %esi
movslq -0x1488(%rbp), %rax
movl -0x1480(%rbp,%rax,4), %edx
movl $0xc, %ecx
callq 0x8f160
movslq -0x1488(%rbp), %rax
movl -0x1480(%rbp,%rax,4), %eax
addl -0x1494(%rbp), %eax
movl %eax, -0x1494(%rbp)
jmp 0x8e687
movl -0x1488(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x1488(%rbp)
jmp 0x8e61b
leaq -0x1044(%rbp), %rdi
callq 0x8f300
leaq -0x104c(%rbp), %rdi
callq 0x8f300
leaq -0x1048(%rbp), %rdi
callq 0x8f300
leaq -0x1050(%rbp), %rdi
callq 0x8f300
movl -0x14(%rbp), %eax
andl $0x3, %eax
movl %eax, -0x1484(%rbp)
movl %eax, %ecx
movq %rcx, -0x14c8(%rbp)
subl $0x3, %eax
ja 0x8e7aa
movq -0x14c8(%rbp), %rax
leaq 0x67d44(%rip), %rcx     # 0xf6438
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl -0x1484(%rbp), %edx
subl $0x2, %edx
subl %edx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
leaq -0x1040(%rbp), %rdx
shlq $0x4, %rax
addq %rax, %rdx
leaq -0x1048(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f320
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl -0x1484(%rbp), %edx
subl $0x1, %edx
subl %edx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
leaq -0x1040(%rbp), %rdx
shlq $0x4, %rax
addq %rax, %rdx
leaq -0x104c(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f320
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movl -0x1484(%rbp), %edx
subl $0x0, %edx
subl %edx, %ecx
movl %ecx, %ecx
movzbl (%rax,%rcx), %eax
leaq -0x1040(%rbp), %rdx
shlq $0x4, %rax
addq %rax, %rdx
leaq -0x1044(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f320
jmp 0x8e7aa
movl -0x14(%rbp), %eax
andl $-0x4, %eax
movl %eax, -0x1484(%rbp)
cmpl $0x0, -0x1484(%rbp)
jle 0x8e8eb
movq -0x10(%rbp), %rax
movl -0x1484(%rbp), %ecx
subl $0x1, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
leaq -0x1040(%rbp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x14a8(%rbp)
movq -0x10(%rbp), %rax
movl -0x1484(%rbp), %ecx
subl $0x2, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
leaq -0x1040(%rbp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x14b0(%rbp)
movq -0x10(%rbp), %rax
movl -0x1484(%rbp), %ecx
subl $0x3, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
leaq -0x1040(%rbp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x14b8(%rbp)
movq -0x10(%rbp), %rax
movl -0x1484(%rbp), %ecx
subl $0x4, %ecx
movslq %ecx, %rcx
movzbl (%rax,%rcx), %eax
movl %eax, %ecx
leaq -0x1040(%rbp), %rax
shlq $0x4, %rcx
addq %rcx, %rax
movq %rax, -0x14c0(%rbp)
movq -0x14a8(%rbp), %rdx
leaq -0x1050(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f320
movq -0x14b0(%rbp), %rdx
leaq -0x1048(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f320
movq -0x14b8(%rbp), %rdx
leaq -0x104c(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f320
movq -0x14c0(%rbp), %rdx
leaq -0x1044(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f320
movl -0x1484(%rbp), %eax
subl $0x4, %eax
movl %eax, -0x1484(%rbp)
jmp 0x8e7b6
leaq -0x1050(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f3e0
leaq -0x1048(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f3e0
leaq -0x104c(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f3e0
leaq -0x1044(%rbp), %rdi
leaq -0x1058(%rbp), %rsi
callq 0x8f3e0
movq -0x38(%rbp), %rax
movq -0x1058(%rbp), %rcx
subq %rcx, %rax
movslq -0x148c(%rbp), %rcx
addq %rcx, %rax
movl %eax, %ecx
movq -0x28(%rbp), %rax
movl %ecx, (%rax)
movq -0x20(%rbp), %rdi
movslq -0x148c(%rbp), %rax
addq %rax, %rdi
movq -0x1058(%rbp), %rsi
movq -0x38(%rbp), %rdx
movq -0x1058(%rbp), %rax
subq %rax, %rdx
callq 0x4810
movq -0x20(%rbp), %rax
movq %rax, -0x8(%rbp)
movq -0x8(%rbp), %rax
addq $0x14d0, %rsp           # imm = 0x14D0
popq %rbp
retq
nopw %cs:(%rax,%rax)