// File: /workspace/github_cpp_makefile_star2_O3/sbingner[P]kerneldec/lzfse/src/lzfse_fse.c
// Function: fse_normalize_freq
void fse_normalize_freq(int nstates, int nsymbols, const uint32_t *__restrict t,
                        uint16_t *__restrict freq) {
  uint32_t s_count = 0;
  int remaining = nstates; // must be signed; this may become < 0
  int max_freq = 0;
  int max_freq_sym = 0;
  int shift = __builtin_clz(nstates) - 1;
  uint32_t highprec_step;

  // Compute the total number of symbol occurrences
  for (int i = 0; i < nsymbols; i++)
    s_count += t[i];

  if (s_count == 0)
    highprec_step = 0; // no symbols used
  else
    highprec_step = ((uint32_t)1 << 31) / s_count;

  for (int i = 0; i < nsymbols; i++) {

    // Rescale the occurrence count to get the normalized frequency.
    // Round up if the fractional part is >= 0.5; otherwise round down.
    // For efficiency, we do this calculation using integer arithmetic.
    int f = (((t[i] * highprec_step) >> shift) + 1) >> 1;

    // If a symbol was used, it must be given a nonzero normalized frequency.
    if (f == 0 && t[i] != 0)
      f = 1;

    freq[i] = f;
    remaining -= f;

    // Remember the maximum frequency and which symbol had it.
    if (f > max_freq) {
      max_freq = f;
      max_freq_sym = i;
    }
  }

  // If there remain states to be assigned, then just assign them to the most
  // frequent symbol.  Alternatively, if we assigned more states than were
  // actually available, then either remove states from the most frequent symbol
  // (for minor overruns) or use the slower adjustment algorithm (for major
  // overruns).
  if (-remaining < (max_freq >> 2)) {
    freq[max_freq_sym] += remaining;
  } else {
    fse_adjust_freqs(freq, -remaining, nsymbols);
  }
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rcx, %r8
testl %esi, %esi
jle 0x7a4d
movq %rdx, %r9
bsrl %edi, %ecx
xorl $0x1f, %ecx
decl %ecx
movl %esi, %r10d
xorl %eax, %eax
xorl %ebx, %ebx
addl (%r9,%rax,4), %ebx
incq %rax
cmpq %rax, %r10
jne 0x79d3
xorl %r11d, %r11d
movl $0x0, %eax
testl %ebx, %ebx
je 0x79f4
movl $0x80000000, %eax       # imm = 0x80000000
xorl %edx, %edx
divl %ebx
testl %esi, %esi
jle 0x7a50
xorl %edx, %edx
xorl %ebx, %ebx
xorl %r11d, %r11d
movl (%r9,%rdx,4), %ebp
movl %ebp, %r14d
imull %eax, %r14d
shrl %cl, %r14d
movl %r11d, %r15d
incl %r14d
movl %r14d, %r12d
shrl %r12d
xorl %r11d, %r11d
testl %ebp, %ebp
setne %r11b
cmpl $0x2, %r14d
cmovael %r12d, %r11d
movw %r11w, (%r8,%rdx,2)
subl %r11d, %edi
cmpl %r15d, %r11d
cmoval %edx, %ebx
cmovlel %r15d, %r11d
incq %rdx
cmpq %rdx, %r10
jne 0x79ff
shrl $0x2, %r11d
movslq %ebx, %rcx
jmp 0x7a52
xorl %r11d, %r11d
xorl %ecx, %ecx
movl %edi, %eax
negl %eax
cmpl %eax, %r11d
jle 0x7a62
addw %di, (%r8,%rcx,2)
jmp 0x7aa7
testl %edi, %edi
je 0x7aa7
movl %esi, %edx
movl $0x3, %ecx
testl %esi, %esi
jle 0x7aa1
xorl %edi, %edi
movzwl (%r8,%rdi,2), %r9d
cmpl $0x2, %r9d
jb 0x7a99
leal -0x1(%r9), %r10d
shrl %cl, %r10d
cmpl %eax, %r10d
cmovgel %eax, %r10d
subl %r10d, %r9d
movw %r9w, (%r8,%rdi,2)
subl %r10d, %eax
je 0x7aa7
incq %rdi
cmpq %rdi, %rdx
jne 0x7a73
decl %ecx
testl %eax, %eax
jne 0x7a6d
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq