// File: /workspace/github_c_makefile_star2_O1/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, 0x10(%rsp)
movq %rsi, %r15
movq %rdi, 0x18(%rsp)
xorl %r13d, %r13d
xorpd %xmm5, %xmm5
movabsq $-0x3fef127e83d16f12, %rbx # imm = 0xC010ED817C2E90EE
xorpd %xmm10, %xmm10
xorl %ecx, %ecx
movq 0x18(%rsp), %rax
cmpl $0x0, (%rax,%r13,4)
je 0x65ae9
movsd %xmm10, 0x20(%rsp)
movl %ecx, 0xc(%rsp)
movsd %xmm5, 0x28(%rsp)
movq %rdx, %r12
movl (%rdx,%r13,4), %eax
decl %eax
movl %eax, %ecx
shrl %ecx
orl %eax, %ecx
movl %ecx, %eax
shrl $0x2, %eax
orl %ecx, %eax
movl %eax, %ecx
shrl $0x4, %ecx
orl %eax, %ecx
movl %ecx, %eax
shrl $0x8, %eax
orl %ecx, %eax
movl %eax, %ebp
shrl $0x10, %ebp
orl %eax, %ebp
incl %ebp
xorl %ecx, %ecx
xorl %r14d, %r14d
xorl %esi, %esi
movl (%r15,%rcx,4), %edi
testl %edi, %edi
je 0x65988
movl %ebp, %eax
xorl %edx, %edx
divl %edi
cmpl $0x401, %eax            # imm = 0x401
sbbl $-0x1, %esi
testl %edi, %edi
je 0x6599b
movl %ebp, %eax
xorl %edx, %edx
divl %edi
cmpl $0x1001, %eax           # imm = 0x1001
sbbl $-0x1, %r14d
incq %rcx
cmpq $0x100, %rcx            # imm = 0x100
jne 0x65972
addl $0x400, %esi            # imm = 0x400
cvtsi2sd %esi, %xmm0
callq 0x4390
movsd %xmm0, 0x30(%rsp)
addl $0x1000, %r14d          # imm = 0x1000
xorps %xmm0, %xmm0
cvtsi2sd %r14d, %xmm0
callq 0x4390
movq %r12, %rdx
movl (%r12,%r13,4), %eax
cvtsi2sd %rax, %xmm3
movsd 0x39184(%rip), %xmm1    # 0x9eb68
divsd %xmm3, %xmm1
movsd 0x39180(%rip), %xmm2    # 0x9eb70
divsd %xmm3, %xmm2
xorl %eax, %eax
xorl %ecx, %ecx
movsd 0x28(%rsp), %xmm5
movsd 0x3060a(%rip), %xmm6    # 0x96010
movsd 0x38e62(%rip), %xmm7    # 0x9e870
movsd 0x32a09(%rip), %xmm8    # 0x98420
movsd 0x39158(%rip), %xmm9    # 0x9eb78
movsd 0x20(%rsp), %xmm10
movl (%r15,%rax,4), %esi
testl %esi, %esi
je 0x65aa0
incl %ecx
movl %esi, %esi
xorps %xmm3, %xmm3
cvtsi2sd %rsi, %xmm3
movapd %xmm2, %xmm4
mulsd %xmm3, %xmm4
maxsd %xmm6, %xmm4
movq %xmm4, %rsi
addq %rbx, %rsi
xorps %xmm4, %xmm4
cvtsi2sd %rsi, %xmm4
mulsd %xmm7, %xmm4
subsd 0x30(%rsp), %xmm4
mulsd %xmm3, %xmm4
subsd %xmm4, %xmm5
movapd %xmm1, %xmm4
mulsd %xmm3, %xmm4
maxsd %xmm6, %xmm4
movq %xmm4, %rsi
addq %rbx, %rsi
xorps %xmm4, %xmm4
cvtsi2sd %rsi, %xmm4
mulsd %xmm7, %xmm4
subsd %xmm0, %xmm4
mulsd %xmm3, %xmm4
subsd %xmm4, %xmm10
addsd %xmm8, %xmm5
addsd %xmm9, %xmm10
incq %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x65a27
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 0x10(%rsp), %rax
movl %ebp, (%rax,%r13,4)
movl 0xc(%rsp), %ecx
cmpl %ebp, %ecx
cmovbel %ebp, %ecx
incq %r13
addq $0x400, %r15            # imm = 0x400
cmpq $0x100, %r13            # imm = 0x100
jne 0x6591d
divsd %xmm10, %xmm5
movsd 0x38093(%rip), %xmm0    # 0x9dba0
ucomisd %xmm5, %xmm0
setbe %al
cmpl $0x401, %ecx            # 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