// File: /workspace/github_c_makefile_star2_O0/snej[P]zdelta/trees.c
// Function: build_tree
local void build_tree(s, desc)
     deflate_state *s;
     tree_desc *desc; /* the tree descriptor */
{
  ct_data *tree         = desc->dyn_tree;
  const ct_data *stree  = desc->stat_desc->static_tree;
  int elems             = desc->stat_desc->elems;
  int n, m;          /* iterate over heap elements */
  int max_code = -1; /* largest code with non zero frequency */
  int node;          /* new node being created */

  /* Construct the initial heap, with least frequent element in
   * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
   * heap[0] is not used.
   */
  s->heap_len = 0, s->heap_max = HEAP_SIZE;

  for (n = 0; n < elems; n++) {
    if (tree[n].Freq != 0) {
      s->heap[++(s->heap_len)] = max_code = n;
      s->depth[n] = 0;
    } else {
      tree[n].Len = 0;
    }
  }

  /* The pkzip format requires that at least one distance code exists,
   * and that at least one bit should be sent even if there is only one
   * possible code. So to avoid special checks later on we force at least
   * two codes of non zero frequency.
   */
  while (s->heap_len < 2) {
    node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
    tree[node].Freq = 1;
    s->depth[node] = 0;
    s->opt_len--; if (stree) s->static_len -= stree[node].Len;
    /* node is 0 or 1 so it does not have extra bits */
  }
  desc->max_code = max_code;
  
  /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
   * establish sub-heaps of increasing lengths:
   */
  for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);

  /* Construct the Huffman tree by repeatedly combining the least two
   * frequent nodes.
   */
  node = elems;              /* next internal node of the tree */
  do {
    pqremove(s, tree, n);  /* n = node of least frequency */
    m = s->heap[SMALLEST]; /* m = node of next least frequency */
    
    s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
    s->heap[--(s->heap_max)] = m;
    
    /* Create a new node father of n and m */
    tree[node].Freq = tree[n].Freq + tree[m].Freq;
    s->depth[node] = (uch) (MAX(s->depth[n], s->depth[m]) + 1);
    tree[n].Dad = tree[m].Dad = (ush)node;
#ifdef DUMP_BL_TREE 
    if (tree == s->bl_tree) {
      fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
	      node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
    }
#endif
    /* and insert the new node in the heap */
    s->heap[SMALLEST] = node++;
    pqdownheap(s, tree, SMALLEST);
    
  } while (s->heap_len >= 2);
  
  s->heap[--(s->heap_max)] = s->heap[SMALLEST];
  
  /* At this point, the fields freq and dad are set. We can now
   * generate the bit lengths.
   */
  gen_bitlen(s, (tree_desc *)desc);
  
  /* The field len is now set, we can generate the bit codes */
  gen_codes ((ct_data *)tree, max_code, s->bl_count);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rax
movq (%rax), %rax
movq %rax, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movq (%rax), %rax
movq %rax, -0x20(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rax
movl 0x14(%rax), %eax
movl %eax, -0x24(%rbp)
movl $0xffffffff, -0x30(%rbp) # imm = 0xFFFFFFFF
movq -0x8(%rbp), %rax
movl $0x0, 0x17ec(%rax)
movq -0x8(%rbp), %rax
movl $0x23f, 0x17f0(%rax)    # imm = 0x23F
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
cmpl -0x24(%rbp), %eax
jge 0x82f0
movq -0x18(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzwl (%rax,%rcx,4), %eax
cmpl $0x0, %eax
je 0x82d4
movl -0x28(%rbp), %edx
movl %edx, -0x30(%rbp)
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rsi
movl 0x17ec(%rsi), %ecx
addl $0x1, %ecx
movl %ecx, 0x17ec(%rsi)
movslq %ecx, %rcx
movl %edx, 0xef0(%rax,%rcx,4)
movq -0x8(%rbp), %rax
movslq -0x28(%rbp), %rcx
movb $0x0, 0x17f4(%rax,%rcx)
jmp 0x82e3
movq -0x18(%rbp), %rax
movslq -0x28(%rbp), %rcx
movw $0x0, 0x2(%rax,%rcx,4)
jmp 0x82e5
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x8282
jmp 0x82f2
movq -0x8(%rbp), %rax
cmpl $0x2, 0x17ec(%rax)
jge 0x83a9
cmpl $0x2, -0x30(%rbp)
jge 0x8317
movl -0x30(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x30(%rbp)
movl %eax, -0x38(%rbp)
jmp 0x831e
xorl %eax, %eax
movl %eax, -0x38(%rbp)
jmp 0x831e
movl -0x38(%rbp), %eax
movq -0x8(%rbp), %rcx
movq -0x8(%rbp), %rsi
movl 0x17ec(%rsi), %edx
addl $0x1, %edx
movl %edx, 0x17ec(%rsi)
movslq %edx, %rdx
movl %eax, 0xef0(%rcx,%rdx,4)
movl %eax, -0x34(%rbp)
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movw $0x1, (%rax,%rcx,4)
movq -0x8(%rbp), %rax
movslq -0x34(%rbp), %rcx
movb $0x0, 0x17f4(%rax,%rcx)
movq -0x8(%rbp), %rax
movq 0x1a58(%rax), %rcx
addq $-0x1, %rcx
movq %rcx, 0x1a58(%rax)
cmpq $0x0, -0x20(%rbp)
je 0x83a4
movq -0x20(%rbp), %rax
movslq -0x34(%rbp), %rcx
movzwl 0x2(%rax,%rcx,4), %eax
movl %eax, %edx
movq -0x8(%rbp), %rax
movq 0x1a60(%rax), %rcx
subq %rdx, %rcx
movq %rcx, 0x1a60(%rax)
jmp 0x82f2
movl -0x30(%rbp), %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
movq -0x8(%rbp), %rax
movl 0x17ec(%rax), %eax
movl $0x2, %ecx
cltd
idivl %ecx
movl %eax, -0x28(%rbp)
cmpl $0x1, -0x28(%rbp)
jl 0x83e9
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl -0x28(%rbp), %edx
callq 0x9a20
movl -0x28(%rbp), %eax
addl $-0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0x83c8
movl -0x24(%rbp), %eax
movl %eax, -0x34(%rbp)
movq -0x8(%rbp), %rax
movl 0xef4(%rax), %eax
movl %eax, -0x28(%rbp)
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rdx
movl 0x17ec(%rdx), %ecx
movl %ecx, %esi
addl $-0x1, %esi
movl %esi, 0x17ec(%rdx)
movslq %ecx, %rcx
movl 0xef0(%rax,%rcx,4), %ecx
movq -0x8(%rbp), %rax
movl %ecx, 0xef4(%rax)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x1, %edx
callq 0x9a20
movq -0x8(%rbp), %rax
movl 0xef4(%rax), %eax
movl %eax, -0x2c(%rbp)
movl -0x28(%rbp), %edx
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rsi
movl 0x17f0(%rsi), %ecx
addl $-0x1, %ecx
movl %ecx, 0x17f0(%rsi)
movslq %ecx, %rcx
movl %edx, 0xef0(%rax,%rcx,4)
movl -0x2c(%rbp), %edx
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rsi
movl 0x17f0(%rsi), %ecx
addl $-0x1, %ecx
movl %ecx, 0x17f0(%rsi)
movslq %ecx, %rcx
movl %edx, 0xef0(%rax,%rcx,4)
movq -0x18(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzwl (%rax,%rcx,4), %eax
movq -0x18(%rbp), %rcx
movslq -0x2c(%rbp), %rdx
movzwl (%rcx,%rdx,4), %ecx
addl %ecx, %eax
movw %ax, %dx
movq -0x18(%rbp), %rax
movslq -0x34(%rbp), %rcx
movw %dx, (%rax,%rcx,4)
movq -0x8(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzbl 0x17f4(%rax,%rcx), %eax
movq -0x8(%rbp), %rcx
movslq -0x2c(%rbp), %rdx
movzbl 0x17f4(%rcx,%rdx), %ecx
cmpl %ecx, %eax
jl 0x84f2
movq -0x8(%rbp), %rax
movslq -0x28(%rbp), %rcx
movzbl 0x17f4(%rax,%rcx), %eax
movl %eax, -0x3c(%rbp)
jmp 0x8505
movq -0x8(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movzbl 0x17f4(%rax,%rcx), %eax
movl %eax, -0x3c(%rbp)
movl -0x3c(%rbp), %eax
addl $0x1, %eax
movb %al, %dl
movq -0x8(%rbp), %rax
movslq -0x34(%rbp), %rcx
movb %dl, 0x17f4(%rax,%rcx)
movl -0x34(%rbp), %eax
movw %ax, %dx
movq -0x18(%rbp), %rax
movslq -0x2c(%rbp), %rcx
movw %dx, 0x2(%rax,%rcx,4)
movq -0x18(%rbp), %rax
movslq -0x28(%rbp), %rcx
movw %dx, 0x2(%rax,%rcx,4)
movl -0x34(%rbp), %ecx
movl %ecx, %eax
addl $0x1, %eax
movl %eax, -0x34(%rbp)
movq -0x8(%rbp), %rax
movl %ecx, 0xef4(%rax)
movq -0x8(%rbp), %rdi
movq -0x18(%rbp), %rsi
movl $0x1, %edx
callq 0x9a20
movq -0x8(%rbp), %rax
cmpl $0x2, 0x17ec(%rax)
jge 0x83ef
movq -0x8(%rbp), %rax
movl 0xef4(%rax), %edx
movq -0x8(%rbp), %rax
movq -0x8(%rbp), %rsi
movl 0x17f0(%rsi), %ecx
addl $-0x1, %ecx
movl %ecx, 0x17f0(%rsi)
movslq %ecx, %rcx
movl %edx, 0xef0(%rax,%rcx,4)
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
callq 0x9c00
movq -0x18(%rbp), %rdi
movl -0x30(%rbp), %esi
movq -0x8(%rbp), %rdx
addq $0xed0, %rdx            # imm = 0xED0
callq 0x9f60
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)