// File: /workspace/github_c_makefile_star2_O0/Cyan4973[P]FiniteStateEntropy/programs/../lib/huf_compress.c
// Function: HUF_setMaxHeight
static U32 HUF_setMaxHeight(nodeElt* huffNode, U32 lastNonNull, U32 maxNbBits)
{
    const U32 largestBits = huffNode[lastNonNull].nbBits;
    if (largestBits <= maxNbBits) return largestBits;   /* early exit : no elt > maxNbBits */

    /* there are several too large elements (at least >= 2) */
    {   int totalCost = 0;
        const U32 baseCost = 1 << (largestBits - maxNbBits);
        int n = (int)lastNonNull;

        while (huffNode[n].nbBits > maxNbBits) {
            totalCost += baseCost - (1 << (largestBits - huffNode[n].nbBits));
            huffNode[n].nbBits = (BYTE)maxNbBits;
            n --;
        }  /* n stops at huffNode[n].nbBits <= maxNbBits */
        while (huffNode[n].nbBits == maxNbBits) n--;   /* n end at index of smallest symbol using < maxNbBits */

        /* renorm totalCost */
        totalCost >>= (largestBits - maxNbBits);  /* note : totalCost is necessarily a multiple of baseCost */

        /* repay normalized cost */
        {   U32 const noSymbol = 0xF0F0F0F0;
            U32 rankLast[HUF_TABLELOG_MAX+2];

            /* Get pos of last (smallest) symbol per rank */
            memset(rankLast, 0xF0, sizeof(rankLast));
            {   U32 currentNbBits = maxNbBits;
                int pos;
                for (pos=n ; pos >= 0; pos--) {
                    if (huffNode[pos].nbBits >= currentNbBits) continue;
                    currentNbBits = huffNode[pos].nbBits;   /* < maxNbBits */
                    rankLast[maxNbBits-currentNbBits] = (U32)pos;
            }   }

            while (totalCost > 0) {
                U32 nBitsToDecrease = BIT_highbit32((U32)totalCost) + 1;
                for ( ; nBitsToDecrease > 1; nBitsToDecrease--) {
                    U32 const highPos = rankLast[nBitsToDecrease];
                    U32 const lowPos = rankLast[nBitsToDecrease-1];
                    if (highPos == noSymbol) continue;
                    if (lowPos == noSymbol) break;
                    {   U32 const highTotal = huffNode[highPos].count;
                        U32 const lowTotal = 2 * huffNode[lowPos].count;
                        if (highTotal <= lowTotal) break;
                }   }
                /* only triggered when no more rank 1 symbol left => find closest one (note : there is necessarily at least one !) */
                /* HUF_MAX_TABLELOG test just to please gcc 5+; but it should not be necessary */
                while ((nBitsToDecrease<=HUF_TABLELOG_MAX) && (rankLast[nBitsToDecrease] == noSymbol))
                    nBitsToDecrease ++;
                totalCost -= 1 << (nBitsToDecrease-1);
                if (rankLast[nBitsToDecrease-1] == noSymbol)
                    rankLast[nBitsToDecrease-1] = rankLast[nBitsToDecrease];   /* this rank is no longer empty */
                huffNode[rankLast[nBitsToDecrease]].nbBits ++;
                if (rankLast[nBitsToDecrease] == 0)    /* special case, reached largest symbol */
                    rankLast[nBitsToDecrease] = noSymbol;
                else {
                    rankLast[nBitsToDecrease]--;
                    if (huffNode[rankLast[nBitsToDecrease]].nbBits != maxNbBits-nBitsToDecrease)
                        rankLast[nBitsToDecrease] = noSymbol;   /* this rank is now empty */
            }   }   /* while (totalCost > 0) */

            while (totalCost < 0) {  /* Sometimes, cost correction overshoot */
                if (rankLast[1] == noSymbol) {  /* special case : no rank 1 symbol (using maxNbBits-1); let's create one from largest rank 0 (using maxNbBits) */
                    while (huffNode[n].nbBits == maxNbBits) n--;
                    huffNode[n+1].nbBits--;
                    assert(n >= 0);
                    rankLast[1] = (U32)(n+1);
                    totalCost++;
                    continue;
                }
                huffNode[ rankLast[1] + 1 ].nbBits--;
                rankLast[1]++;
                totalCost ++;
    }   }   }   /* there are several too large elements (at least >= 2) */

    return maxNbBits;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x90, %rsp
movq %rdi, -0x10(%rbp)
movl %esi, -0x14(%rbp)
movl %edx, -0x18(%rbp)
movq -0x10(%rbp), %rax
movl -0x14(%rbp), %ecx
movzbl 0x7(%rax,%rcx,8), %eax
movl %eax, -0x1c(%rbp)
movl -0x1c(%rbp), %eax
cmpl -0x18(%rbp), %eax
ja 0x15c07
movl -0x1c(%rbp), %eax
movl %eax, -0x4(%rbp)
jmp 0x15f18
movl $0x0, -0x20(%rbp)
movl -0x1c(%rbp), %ecx
subl -0x18(%rbp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, -0x24(%rbp)
movl -0x14(%rbp), %eax
movl %eax, -0x28(%rbp)
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzbl 0x7(%rax,%rcx,8), %eax
cmpl -0x18(%rbp), %eax
jbe 0x15c78
movl -0x24(%rbp), %eax
movl -0x1c(%rbp), %ecx
movq -0x10(%rbp), %rdx
movslq -0x28(%rbp), %rsi
movzbl 0x7(%rdx,%rsi,8), %edx
subl %edx, %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
subl %ecx, %eax
addl -0x20(%rbp), %eax
movl %eax, -0x20(%rbp)
movl -0x18(%rbp), %eax
movb %al, %dl
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
movb %dl, 0x7(%rax,%rcx,8)
movl -0x28(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x15c24
jmp 0x15c7a
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzbl 0x7(%rax,%rcx,8), %eax
cmpl -0x18(%rbp), %eax
jne 0x15c97
movl -0x28(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x15c7a
movl -0x1c(%rbp), %ecx
subl -0x18(%rbp), %ecx
movl -0x20(%rbp), %eax
sarl %cl, %eax
movl %eax, -0x20(%rbp)
movl $0xf0f0f0f0, -0x2c(%rbp) # imm = 0xF0F0F0F0
leaq -0x70(%rbp), %rdi
movl $0xf0, %esi
movl $0x38, %edx
callq 0x10c0
movl -0x18(%rbp), %eax
movl %eax, -0x74(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x78(%rbp)
cmpl $0x0, -0x78(%rbp)
jl 0x15d0f
movq -0x10(%rbp), %rax
movslq -0x78(%rbp), %rcx
movzbl 0x7(%rax,%rcx,8), %eax
cmpl -0x74(%rbp), %eax
jb 0x15ce5
jmp 0x15d04
movq -0x10(%rbp), %rax
movslq -0x78(%rbp), %rcx
movzbl 0x7(%rax,%rcx,8), %eax
movl %eax, -0x74(%rbp)
movl -0x78(%rbp), %ecx
movl -0x18(%rbp), %eax
subl -0x74(%rbp), %eax
movl %eax, %eax
movl %ecx, -0x70(%rbp,%rax,4)
movl -0x78(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x78(%rbp)
jmp 0x15ccb
jmp 0x15d11
cmpl $0x0, -0x20(%rbp)
jle 0x15e84
movl -0x20(%rbp), %edi
callq 0x16c10
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
cmpl $0x1, -0x7c(%rbp)
jbe 0x15da6
movl -0x7c(%rbp), %eax
movl -0x70(%rbp,%rax,4), %eax
movl %eax, -0x80(%rbp)
movl -0x7c(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl -0x70(%rbp,%rax,4), %eax
movl %eax, -0x84(%rbp)
cmpl $0xf0f0f0f0, -0x80(%rbp) # imm = 0xF0F0F0F0
jne 0x15d56
jmp 0x15d9b
cmpl $0xf0f0f0f0, -0x84(%rbp) # imm = 0xF0F0F0F0
jne 0x15d64
jmp 0x15da6
movq -0x10(%rbp), %rax
movl -0x80(%rbp), %ecx
movl (%rax,%rcx,8), %eax
movl %eax, -0x88(%rbp)
movq -0x10(%rbp), %rax
movl -0x84(%rbp), %ecx
movl (%rax,%rcx,8), %eax
shll %eax
movl %eax, -0x8c(%rbp)
movl -0x88(%rbp), %eax
cmpl -0x8c(%rbp), %eax
ja 0x15d99
jmp 0x15da6
jmp 0x15d9b
movl -0x7c(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x15d29
jmp 0x15da8
xorl %eax, %eax
cmpl $0xc, -0x7c(%rbp)
movb %al, -0x8d(%rbp)
ja 0x15dca
movl -0x7c(%rbp), %eax
cmpl $0xf0f0f0f0, -0x70(%rbp,%rax,4) # imm = 0xF0F0F0F0
sete %al
movb %al, -0x8d(%rbp)
movb -0x8d(%rbp), %al
testb $0x1, %al
jne 0x15dd6
jmp 0x15de1
movl -0x7c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x7c(%rbp)
jmp 0x15da8
movl -0x7c(%rbp), %ecx
subl $0x1, %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, %ecx
movl -0x20(%rbp), %eax
subl %ecx, %eax
movl %eax, -0x20(%rbp)
movl -0x7c(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
cmpl $0xf0f0f0f0, -0x70(%rbp,%rax,4) # imm = 0xF0F0F0F0
jne 0x15e1d
movl -0x7c(%rbp), %eax
movl -0x70(%rbp,%rax,4), %ecx
movl -0x7c(%rbp), %eax
subl $0x1, %eax
movl %eax, %eax
movl %ecx, -0x70(%rbp,%rax,4)
movq -0x10(%rbp), %rax
movl -0x7c(%rbp), %ecx
movl -0x70(%rbp,%rcx,4), %ecx
movb 0x7(%rax,%rcx,8), %dl
addb $0x1, %dl
movb %dl, 0x7(%rax,%rcx,8)
movl -0x7c(%rbp), %eax
cmpl $0x0, -0x70(%rbp,%rax,4)
jne 0x15e4a
movl -0x7c(%rbp), %eax
movl $0xf0f0f0f0, -0x70(%rbp,%rax,4) # imm = 0xF0F0F0F0
jmp 0x15e7f
movl -0x7c(%rbp), %eax
movl -0x70(%rbp,%rax,4), %ecx
addl $-0x1, %ecx
movl %ecx, -0x70(%rbp,%rax,4)
movq -0x10(%rbp), %rax
movl -0x7c(%rbp), %ecx
movl -0x70(%rbp,%rcx,4), %ecx
movzbl 0x7(%rax,%rcx,8), %eax
movl -0x18(%rbp), %ecx
subl -0x7c(%rbp), %ecx
cmpl %ecx, %eax
je 0x15e7d
movl -0x7c(%rbp), %eax
movl $0xf0f0f0f0, -0x70(%rbp,%rax,4) # imm = 0xF0F0F0F0
jmp 0x15e7f
jmp 0x15d11
jmp 0x15e86
cmpl $0x0, -0x20(%rbp)
jge 0x15f12
cmpl $0xf0f0f0f0, -0x6c(%rbp) # imm = 0xF0F0F0F0
jne 0x15ee4
jmp 0x15e9b
movq -0x10(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzbl 0x7(%rax,%rcx,8), %eax
cmpl -0x18(%rbp), %eax
jne 0x15eb8
movl -0x28(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x15e9b
movq -0x10(%rbp), %rax
movl -0x28(%rbp), %ecx
addl $0x1, %ecx
movslq %ecx, %rcx
movb 0x7(%rax,%rcx,8), %dl
addb $-0x1, %dl
movb %dl, 0x7(%rax,%rcx,8)
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x15e86
movq -0x10(%rbp), %rax
movl -0x6c(%rbp), %ecx
addl $0x1, %ecx
movl %ecx, %ecx
movb 0x7(%rax,%rcx,8), %dl
addb $-0x1, %dl
movb %dl, 0x7(%rax,%rcx,8)
movl -0x6c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x6c(%rbp)
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x15e86
movl -0x18(%rbp), %eax
movl %eax, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x90, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)