// File: /workspace/github_c_makefile_star2_O2/samtools[P]htslib/htscodecs/htscodecs/rANS_static4x16pr.c
// Function: rans_compute_shift
int rans_compute_shift(uint32_t *F0, uint32_t (*F)[256], uint32_t *T,
                       uint32_t *S) {
    int i, j;

    double e10 = 0, e12 = 0;
    int max_tot = 0;
    for (i = 0; i < 256; i++) {
        if (F0[i] == 0)
            continue;
        unsigned int max_val = round2(T[i]);
        int ns = 0;
#define MAX(a,b) ((a)>(b)?(a):(b))

        // Number of samples that get their freq bumped to 1
        int sm10 = 0, sm12 = 0;
        for (j = 0; j < 256; j++) {
            if (F[i][j] && max_val / F[i][j] > TOTFREQ_O1_FAST)
                sm10++;
            if (F[i][j] && max_val / F[i][j] > TOTFREQ_O1)
                sm12++;
        }

        double l10 = log(TOTFREQ_O1_FAST + sm10);
        double l12 = log(TOTFREQ_O1      + sm12);
        double T_slow = (double)TOTFREQ_O1/T[i];
        double T_fast = (double)TOTFREQ_O1_FAST/T[i];

        for (j = 0; j < 256; j++) {
            if (F[i][j]) {
                ns++;

                e10 -= F[i][j] * (fast_log(MAX(F[i][j]*T_fast,1)) - l10);
                e12 -= F[i][j] * (fast_log(MAX(F[i][j]*T_slow,1)) - l12);

                // Estimation of compressed symbol freq table too.
                e10 += 1.3;
                e12 += 4.7;
            }
        }

        // Order-1 frequencies often end up totalling under TOTFREQ.
        // In this case it's smaller to output the real frequencies
        // prior to normalisation and normalise after (with an extra
        // normalisation step needed in the decoder too).
        //
        // Thus we normalise to a power of 2 only, store those,
        // and renormalise later here (and in decoder) by bit-shift
        // to get to the fixed size.
        if (ns < 64 && max_val > 128) max_val /= 2;
        if (max_val > 1024)           max_val /= 2;
        if (max_val > TOTFREQ_O1)     max_val = TOTFREQ_O1;
        S[i] = max_val; // scale to max this
        if (max_tot < max_val)
            max_tot = max_val;
    }
    int shift = e10/e12 < 1.01 || max_tot <= TOTFREQ_O1_FAST
        ? TF_SHIFT_O1_FAST
        : TF_SHIFT_O1;

//    fprintf(stderr, "e10/12 = %f %f %f, shift %d\n",
//          e10/log(256), e12/log(256), e10/e12, shift);

    return shift;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x38, %rsp
movq %rcx, (%rsp)
movq %rdx, %r14
movq %rsi, %r15
movq %rdi, 0x8(%rsp)
xorpd %xmm5, %xmm5
xorl %r13d, %r13d
xorl %ebx, %ebx
cmpq $0x100, %r13            # imm = 0x100
je 0x4fbbb
movq 0x8(%rsp), %rax
cmpl $0x0, (%rax,%r13,4)
je 0x4fbac
movapd %xmm5, 0x20(%rsp)
movl (%r14,%r13,4), %edi
callq 0x4f3aa
movl %eax, %ebp
xorl %ecx, %ecx
xorl %esi, %esi
xorl %r12d, %r12d
cmpq $0x100, %rcx            # imm = 0x100
je 0x4faa1
movl (%r15,%rcx,4), %edi
testl %edi, %edi
je 0x4fa9c
movl %ebp, %eax
xorl %edx, %edx
divl %edi
cmpl $0x401, %eax            # imm = 0x401
sbbl $-0x1, %esi
cmpl $0x1001, %eax           # imm = 0x1001
sbbl $-0x1, %r12d
incq %rcx
jmp 0x4fa74
addl $0x400, %esi            # imm = 0x400
cvtsi2sd %esi, %xmm0
callq 0x4390
movapd %xmm0, 0x10(%rsp)
addl $0x1000, %r12d          # imm = 0x1000
cvtsi2sd %r12d, %xmm0
callq 0x4390
movl (%r14,%r13,4), %eax
cvtsi2sd %rax, %xmm2
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
movapd 0x2e094(%rip), %xmm1    # 0x7db70
divpd %xmm2, %xmm1
unpcklpd 0x10(%rsp), %xmm0       # xmm0 = xmm0[0],mem[0]
xorl %eax, %eax
xorl %ecx, %ecx
movapd 0x20(%rsp), %xmm5
movapd 0x2e088(%rip), %xmm6    # 0x7db80
movdqa 0x2e090(%rip), %xmm7    # 0x7db90
movapd 0x2e097(%rip), %xmm8    # 0x7dba0
movapd 0x2e09e(%rip), %xmm9    # 0x7dbb0
cmpq $0x100, %rax            # imm = 0x100
je 0x4fb77
movl (%r15,%rax,4), %edx
testl %edx, %edx
je 0x4fb72
incl %ecx
movl %edx, %edx
cvtsi2sd %rdx, %xmm2
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
movapd %xmm1, %xmm3
mulpd %xmm2, %xmm3
maxpd %xmm6, %xmm3
paddq %xmm7, %xmm3
movq %xmm3, %rdx
cvtsi2sd %rdx, %xmm4
pshufd $0xee, %xmm3, %xmm3     # xmm3 = xmm3[2,3,2,3]
movq %xmm3, %rdx
cvtsi2sd %rdx, %xmm3
unpcklpd %xmm3, %xmm4            # xmm4 = xmm4[0],xmm3[0]
mulpd %xmm8, %xmm4
subpd %xmm0, %xmm4
mulpd %xmm2, %xmm4
subpd %xmm4, %xmm5
addpd %xmm9, %xmm5
incq %rax
jmp 0x4fb12
cmpl $0x40, %ecx
setl %al
cmpl $0x81, %ebp
setae %cl
andb %al, %cl
shrl %cl, %ebp
cmpl $0x401, %ebp            # imm = 0x401
setae %cl
shrl %cl, %ebp
movl $0x1000, %eax           # imm = 0x1000
cmpl %eax, %ebp
cmovael %eax, %ebp
movq (%rsp), %rax
movl %ebp, (%rax,%r13,4)
cmpl %ebp, %ebx
cmovbel %ebp, %ebx
incq %r13
addq $0x400, %r15            # imm = 0x400
jmp 0x4fa3f
movapd %xmm5, %xmm0
unpckhpd %xmm5, %xmm0            # xmm0 = xmm0[1],xmm5[1]
divsd %xmm5, %xmm0
movsd 0x2cfc9(%rip), %xmm1    # 0x7cb98
ucomisd %xmm0, %xmm1
setbe %al
cmpl $0x401, %ebx            # imm = 0x401
setge %cl
andb %al, %cl
movzbl %cl, %eax
leal 0xa(,%rax,2), %eax
addq $0x38, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq