// File: /workspace/github_cpp_makefile_star2_O2/cloudinary[P]fuif/encoding/../maniac/symbol_enc.h
// Function: int estimate_writer<15, FinalCompoundSymbolBitCoder<SimpleBitChance, RacOutput24<BlobIO>, 15>>(FinalCompoundSymbolBitCoder<SimpleBitChance, RacOutput24<BlobIO>, 15>&, int, int, int)
int estimate_writer(SymbolCoder& coder, int min, int max, int value) {
    assert(min<=max);
    assert(value>=min);
    assert(value<=max);

    uint64_t total=0;

    // avoid doing anything if the value is already known
    if (min == max) return total;

    if (value == 0) { // value is zero
        coder.estimate(true, BIT_ZERO,0,total);
        return total;
    }

    assert(min <= 0 && max >= 0); // should always be the case, because guess should always be in valid range

    coder.estimate(false,BIT_ZERO,0,total);
    int sign = (value > 0 ? 1 : 0);
    if (max > 0 && min < 0) {
        // only output sign bit if value can be both pos and neg
        coder.estimate(sign,BIT_SIGN,0,total);
    }
    if (sign) min = 1;
    if (!sign) max = -1;
    const int a = abs(value);
    const int e = maniac::util::ilog2(a);
    int amin = sign ? abs(min) : abs(max);
    int amax = sign ? abs(max) : abs(min);

    int emax = maniac::util::ilog2(amax);
    int i = maniac::util::ilog2(amin);

    while (i < emax) {
        // if exponent >i is impossible, we are done
        if ((1 << (i+1)) > amax) break;
        // if exponent i is possible, output the exponent bit
        coder.estimate(i==e, BIT_EXP, i,total);
        if (i==e) break;
        i++;
    }

    int have = (1 << e);
    int left = have-1;
    for (int pos = e; pos>0;) {
        int bit = 1;
        left ^= (1 << (--pos));
        int minabs1 = have | (1<<pos);
        if (minabs1 > amax) { // 1-bit is impossible
            bit = 0;
        } else {
            bit = (a >> pos) & 1;
            coder.estimate(bit, BIT_MANT, pos,total);
        }
        have |= (bit << pos);
    }
//    printf("Total to write %i in %i..%i: %lu\n",value,min,max,total);
    return total;
}

// Assembly:
xorl %eax, %eax
cmpl %edx, %esi
je 0x15500
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq 0x10(%rdi), %r8
movzwl (%r8), %eax
testl %ecx, %ecx
je 0x154ed
movl $0x1000, %edi           # imm = 0x1000
movl $0x1000, %r10d          # imm = 0x1000
subq %rax, %r10
leaq 0x17240(%rip), %r9      # 0x2c650
movzwl (%r9,%r10,2), %eax
testl %edx, %edx
setle %r10b
testl %esi, %esi
setns %r11b
orb %r10b, %r11b
jne 0x1543b
movzwl 0x2(%r8), %r10d
subq %r10, %rdi
testl %ecx, %ecx
cmovgq %r10, %rdi
movzwl (%r9,%rdi,2), %edi
addl %edi, %eax
movl %ecx, %r10d
negl %r10d
cmovsl %ecx, %r10d
bsrl %r10d, %edi
testl %ecx, %ecx
cmovgl %edx, %esi
movl %esi, %edx
negl %edx
cmovsl %esi, %edx
bsrl %edx, %r11d
leaq 0x1(%rdi), %rbx
xorl %ecx, %ecx
movl $0x2, %ebp
movl %ebp, %r14d
shll %cl, %r14d
testl %esi, %esi
je 0x154a1
cmpq %r11, %rcx
jae 0x154a1
cmpl %edx, %r14d
jg 0x154a1
movzwl 0x4(%r8,%rcx,2), %r14d
movl $0x1000, %r15d          # imm = 0x1000
subq %r14, %r15
cmpq %rcx, %rdi
leaq 0x1(%rcx), %r12
cmoveq %r14, %r15
movzwl (%r9,%r15,2), %ecx
addl %ecx, %eax
movq %r12, %rcx
cmpq %r12, %rbx
jne 0x15464
movl $0x1, %esi
movl %edi, %ecx
shll %cl, %esi
testq %rdi, %rdi
jle 0x154f8
leaq -0x1(%rdi), %rcx
movl %esi, %ebx
btsl %ecx, %ebx
xorl %r11d, %r11d
cmpl %edx, %ebx
jg 0x154e2
movl %r10d, %r11d
shrl %cl, %r11d
movzwl 0x1e(%r8,%rdi,2), %edi
movl $0x1000, %ebx           # imm = 0x1000
subq %rdi, %rbx
andl $0x1, %r11d
cmovneq %rdi, %rbx
movzwl (%r9,%rbx,2), %edi
addl %edi, %eax
shll %cl, %r11d
orl %r11d, %esi
movq %rcx, %rdi
jmp 0x154aa
leaq 0x1715c(%rip), %rcx     # 0x2c650
movzwl (%rcx,%rax,2), %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
nop