// File: /workspace/github_c_makefile_star2_O0/negge[P]xlink/src/paq.c
// Function: xlink_modeler_get_entropy
double xlink_modeler_get_entropy(xlink_modeler *mod, xlink_list *models) {
  XLINK_ERROR(
   xlink_list_length(&mod->counts) != 8*xlink_list_length(&mod->bytes),
   ("Counts model does not match input bytes, counts = %i and bytes = %i",
   xlink_list_length(&mod->counts), xlink_list_length(&mod->bytes)));
  if (xlink_list_length(models) == 0) {
    return DBL_MAX;
  }
  else {
    double entropy;
    int i, j, k;
    /* Include 4 bytes for the weights + 1 byte for each model */
    entropy = 8*(4 + xlink_list_length(models));
    for (j = 0; j < xlink_list_length(&mod->bytes); j++) {
      unsigned char byte;
      byte = *xlink_list_get_byte(&mod->bytes, j);
      for (i = 8; i-- > 0; ) {
        int bit;
        xlink_counts *counts;
        unsigned int c0, c1;
        bit = !!(byte & (1 << i));
        counts = xlink_list_get(&mod->counts, j*8 + (7 - i));
        c0 = c1 = 2;
        for (k = 0; k < xlink_list_length(models); k++) {
          xlink_model *model;
          model = xlink_list_get(models, k);
          c0 += ((unsigned int)(*counts)[model->mask][0]) << model->weight;
          c1 += ((unsigned int)(*counts)[model->mask][1]) << model->weight;
        }
        if (bit) {
          entropy -= M_LOG2E*log(((double)c1)/(c0 + c1));
        }
        else {
          entropy -= M_LOG2E*log(((double)c0)/(c0 + c1));
        }
      }
    }
    return entropy;
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x60, %rsp
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0xc6a0
movl %eax, -0x54(%rbp)
movq -0x10(%rbp), %rdi
callq 0xc6a0
movl %eax, %ecx
movl -0x54(%rbp), %eax
shll $0x3, %ecx
cmpl %ecx, %eax
je 0xbffb
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
callq 0xc6a0
movl %eax, -0x58(%rbp)
movq -0x10(%rbp), %rdi
callq 0xc6a0
movl -0x58(%rbp), %esi
movl %eax, %edx
leaq 0x42df(%rip), %rdi      # 0x102c9
movb $0x0, %al
callq 0xad90
movl $0xffffffff, %edi       # imm = 0xFFFFFFFF
callq 0x21c0
jmp 0xbffd
movq -0x18(%rbp), %rdi
callq 0xc6a0
cmpl $0x0, %eax
jne 0xc01d
movsd 0x41e5(%rip), %xmm0     # 0x101f8
movsd %xmm0, -0x8(%rbp)
jmp 0xc1e5
movq -0x18(%rbp), %rdi
callq 0xc6a0
addl $0x4, %eax
shll $0x3, %eax
cvtsi2sd %eax, %xmm0
movsd %xmm0, -0x20(%rbp)
movl $0x0, -0x28(%rbp)
movl -0x28(%rbp), %eax
movl %eax, -0x5c(%rbp)
movq -0x10(%rbp), %rdi
callq 0xc6a0
movl %eax, %ecx
movl -0x5c(%rbp), %eax
cmpl %ecx, %eax
jge 0xc1db
movq -0x10(%rbp), %rdi
movl -0x28(%rbp), %esi
callq 0xc870
movb (%rax), %al
movb %al, -0x2d(%rbp)
movl $0x8, -0x24(%rbp)
movl -0x24(%rbp), %eax
movl %eax, %ecx
addl $-0x1, %ecx
movl %ecx, -0x24(%rbp)
cmpl $0x0, %eax
jle 0xc1cb
movzbl -0x2d(%rbp), %eax
movl -0x24(%rbp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
andl %ecx, %eax
cmpl $0x0, %eax
setne %al
xorb $-0x1, %al
xorb $-0x1, %al
andb $0x1, %al
movzbl %al, %eax
movl %eax, -0x34(%rbp)
movq -0x10(%rbp), %rdi
addq $0x18, %rdi
movl -0x28(%rbp), %esi
shll $0x3, %esi
movl $0x7, %eax
subl -0x24(%rbp), %eax
addl %eax, %esi
callq 0xc870
movq %rax, -0x40(%rbp)
movl $0x2, -0x48(%rbp)
movl $0x2, -0x44(%rbp)
movl $0x0, -0x2c(%rbp)
movl -0x2c(%rbp), %eax
movl %eax, -0x60(%rbp)
movq -0x18(%rbp), %rdi
callq 0xc6a0
movl %eax, %ecx
movl -0x60(%rbp), %eax
cmpl %ecx, %eax
jge 0xc14e
movq -0x18(%rbp), %rdi
movl -0x2c(%rbp), %esi
callq 0xc870
movq %rax, -0x50(%rbp)
movq -0x40(%rbp), %rax
movq -0x50(%rbp), %rcx
movzbl (%rcx), %ecx
movzbl (%rax,%rcx,2), %eax
movq -0x50(%rbp), %rcx
movl 0x4(%rcx), %ecx
shll %cl, %eax
addl -0x44(%rbp), %eax
movl %eax, -0x44(%rbp)
movq -0x40(%rbp), %rax
movq -0x50(%rbp), %rcx
movzbl (%rcx), %ecx
movzbl 0x1(%rax,%rcx,2), %eax
movq -0x50(%rbp), %rcx
movl 0x4(%rcx), %ecx
shll %cl, %eax
addl -0x48(%rbp), %eax
movl %eax, -0x48(%rbp)
movl -0x2c(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x2c(%rbp)
jmp 0xc0de
cmpl $0x0, -0x34(%rbp)
je 0xc18d
movl -0x48(%rbp), %eax
movl %eax, %ecx
cvtsi2sd %rax, %xmm0
movl -0x44(%rbp), %eax
addl %ecx, %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
callq 0x20c0
movsd -0x20(%rbp), %xmm1
movsd 0x4072(%rip), %xmm2     # 0x101f0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rbp)
jmp 0xc1c6
movl -0x44(%rbp), %eax
movl %eax, %ecx
movl %ecx, %eax
cvtsi2sd %rcx, %xmm0
movl -0x48(%rbp), %ecx
addl %ecx, %eax
cvtsi2sd %rax, %xmm1
divsd %xmm1, %xmm0
callq 0x20c0
movsd -0x20(%rbp), %xmm1
movsd 0x4037(%rip), %xmm2     # 0x101f0
mulsd %xmm2, %xmm0
addsd %xmm1, %xmm0
movsd %xmm0, -0x20(%rbp)
jmp 0xc070
jmp 0xc1cd
movl -0x28(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x28(%rbp)
jmp 0xc03c
movsd -0x20(%rbp), %xmm0
movsd %xmm0, -0x8(%rbp)
movsd -0x8(%rbp), %xmm0
addq $0x60, %rsp
popq %rbp
retq