// File: /workspace/github_c_makefile_star2_O3/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)
pxor %xmm7, %xmm7
xorl %r13d, %r13d
pcmpeqd %xmm8, %xmm8
movaps 0x318ec(%rip), %xmm9    # 0x94890
movdqa 0x38e33(%rip), %xmm10   # 0x9bde0
movdqa 0x38e3a(%rip), %xmm11   # 0x9bdf0
xorl %ebx, %ebx
xorpd %xmm12, %xmm12
movq 0x8(%rsp), %rax
cmpl $0x0, (%rax,%r13,4)
je 0x63246
movapd %xmm12, 0x20(%rsp)
movl (%r14,%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
pxor %xmm1, %xmm1
xorl %ecx, %ecx
pxor %xmm0, %xmm0
movdqu (%r15,%rcx,4), %xmm4
movdqa %xmm4, %xmm2
pcmpeqd %xmm7, %xmm2
movd %xmm2, %eax
notl %eax
testb $0x1, %al
je 0x6302e
movd %xmm4, %esi
movl %ebp, %eax
xorl %edx, %edx
divl %esi
movd %eax, %xmm3
movdqa %xmm2, %xmm5
pxor %xmm8, %xmm5
pextrw $0x2, %xmm5, %eax
testb $0x1, %al
je 0x6305e
pshufd $0x55, %xmm4, %xmm6     # xmm6 = xmm4[1,1,1,1]
movd %xmm6, %esi
movl %ebp, %eax
xorl %edx, %edx
divl %esi
movd %eax, %xmm6
punpcklqdq %xmm3, %xmm6    # xmm6 = xmm6[0],xmm3[0]
shufps $0xe2, %xmm3, %xmm6     # xmm6 = xmm6[2,0],xmm3[2,3]
movaps %xmm6, %xmm3
pextrw $0x4, %xmm5, %eax
testb $0x1, %al
je 0x63082
pshufd $0xee, %xmm4, %xmm6     # xmm6 = xmm4[2,3,2,3]
movd %xmm6, %esi
movl %ebp, %eax
xorl %edx, %edx
divl %esi
movd %eax, %xmm6
shufps $0x30, %xmm3, %xmm6     # xmm6 = xmm6[0,0],xmm3[3,0]
shufps $0x84, %xmm6, %xmm3     # xmm3 = xmm3[0,1],xmm6[0,2]
pextrw $0x6, %xmm5, %eax
testb $0x1, %al
je 0x630a6
pshufd $0xff, %xmm4, %xmm4     # xmm4 = xmm4[3,3,3,3]
movd %xmm4, %esi
movl %ebp, %eax
xorl %edx, %edx
divl %esi
movd %eax, %xmm4
shufps $0xe4, %xmm3, %xmm4     # xmm4 = xmm4[0,1],xmm3[2,3]
shufps $0x24, %xmm4, %xmm3     # xmm3 = xmm3[0,1],xmm4[2,0]
xorps %xmm9, %xmm3
movaps %xmm3, %xmm4
pcmpgtd %xmm10, %xmm4
movdqa %xmm2, %xmm5
pandn %xmm4, %xmm5
psubd %xmm5, %xmm0
pcmpgtd %xmm11, %xmm3
pandn %xmm3, %xmm2
psubd %xmm2, %xmm1
addq $0x4, %rcx
cmpq $0x100, %rcx            # imm = 0x100
jne 0x63008
pshufd $0xee, %xmm1, %xmm2     # xmm2 = xmm1[2,3,2,3]
paddd %xmm1, %xmm2
pshufd $0x55, %xmm2, %xmm1     # xmm1 = xmm2[1,1,1,1]
paddd %xmm2, %xmm1
movd %xmm1, %r12d
pshufd $0xee, %xmm0, %xmm1     # xmm1 = xmm0[2,3,2,3]
paddd %xmm0, %xmm1
pshufd $0x55, %xmm1, %xmm0     # xmm0 = xmm1[1,1,1,1]
paddd %xmm1, %xmm0
movd %xmm0, %eax
addl $0x400, %eax            # imm = 0x400
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
callq 0x4390
movapd %xmm0, 0x10(%rsp)
addl $0x1000, %r12d          # imm = 0x1000
xorps %xmm0, %xmm0
cvtsi2sd %r12d, %xmm0
callq 0x4390
movl (%r14,%r13,4), %eax
xorps %xmm2, %xmm2
cvtsi2sd %rax, %xmm2
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
movapd 0x38cb4(%rip), %xmm1    # 0x9be00
divpd %xmm2, %xmm1
unpcklpd 0x10(%rsp), %xmm0       # xmm0 = xmm0[0],mem[0]
xorl %eax, %eax
xorl %ecx, %ecx
movapd 0x37a8e(%rip), %xmm5    # 0x9abf0
movdqa 0x38ca6(%rip), %xmm6    # 0x9be10
movapd 0x38cae(%rip), %xmm7    # 0x9be20
movapd 0x20(%rsp), %xmm12
movapd 0x38cae(%rip), %xmm8    # 0x9be30
movl (%r15,%rax,4), %edx
testl %edx, %edx
je 0x631e3
incl %ecx
movl %edx, %edx
xorps %xmm2, %xmm2
cvtsi2sd %rdx, %xmm2
unpcklpd %xmm2, %xmm2            # xmm2 = xmm2[0,0]
movapd %xmm1, %xmm3
mulpd %xmm2, %xmm3
maxpd %xmm5, %xmm3
paddq %xmm6, %xmm3
movq %xmm3, %rdx
xorps %xmm4, %xmm4
cvtsi2sd %rdx, %xmm4
pshufd $0xee, %xmm3, %xmm3     # xmm3 = xmm3[2,3,2,3]
movq %xmm3, %rdx
xorps %xmm3, %xmm3
cvtsi2sd %rdx, %xmm3
unpcklpd %xmm3, %xmm4            # xmm4 = xmm4[0],xmm3[0]
mulpd %xmm7, %xmm4
subpd %xmm0, %xmm4
mulpd %xmm2, %xmm4
subpd %xmm4, %xmm12
addpd %xmm8, %xmm12
incq %rax
cmpq $0x100, %rax            # imm = 0x100
jne 0x63182
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
xorpd %xmm7, %xmm7
pcmpeqd %xmm8, %xmm8
movaps 0x3165c(%rip), %xmm9    # 0x94890
movdqa 0x38ba3(%rip), %xmm10   # 0x9bde0
movdqa 0x38baa(%rip), %xmm11   # 0x9bdf0
incq %r13
addq $0x400, %r15            # imm = 0x400
cmpq $0x100, %r13            # imm = 0x100
jne 0x62fbd
movapd %xmm12, %xmm0
unpckhpd %xmm12, %xmm0           # xmm0 = xmm0[1],xmm12[1]
divsd %xmm12, %xmm0
movsd 0x37b24(%rip), %xmm1    # 0x9ad98
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