// File: /workspace/github_cpp_makefile_star2_O1/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:
movq %rcx, %r8
movq %rdx, %r9
xorl %eax, %eax
movl $0x0, %ecx
testl %esi, %esi
jle 0x7d9f
movl %esi, %edx
xorl %r10d, %r10d
xorl %ecx, %ecx
addl (%r9,%r10,4), %ecx
incq %r10
cmpq %r10, %rdx
jne 0x7d93
testl %ecx, %ecx
je 0x7dac
movl $0x80000000, %eax       # imm = 0x80000000
xorl %edx, %edx
divl %ecx
testl %esi, %esi
jle 0x7e1d
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
bsrl %edi, %ecx
xorl $0x1f, %ecx
decl %ecx
movl %esi, %r10d
xorl %r11d, %r11d
xorl %ebx, %ebx
xorl %edx, %edx
movl (%r9,%r11,4), %ebp
movl %ebp, %r14d
imull %eax, %r14d
shrl %cl, %r14d
movl %edx, %r15d
incl %r14d
movl %r14d, %r12d
shrl %r12d
xorl %edx, %edx
testl %ebp, %ebp
setne %dl
cmpl $0x2, %r14d
cmovael %r12d, %edx
movw %dx, (%r8,%r11,2)
subl %edx, %edi
cmpl %r15d, %edx
cmoval %r11d, %ebx
cmovlel %r15d, %edx
incq %r11
cmpq %r11, %r10
jne 0x7dca
shrl $0x2, %edx
movslq %ebx, %rcx
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x7e21
xorl %edx, %edx
xorl %ecx, %ecx
movl %edi, %eax
negl %eax
cmpl %eax, %edx
jle 0x7e2f
addw %di, (%r8,%rcx,2)
retq
testl %edi, %edi
je 0x7e74
movl %esi, %edx
movl $0x3, %ecx
testl %esi, %esi
jle 0x7e6e
xorl %edi, %edi
movzwl (%r8,%rdi,2), %r9d
cmpl $0x2, %r9d
jb 0x7e66
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 0x7e6e
incq %rdi
cmpq %rdi, %rdx
jne 0x7e40
decl %ecx
testl %eax, %eax
jne 0x7e3a
retq