// File: cloudinary[P]fuif/encoding/../maniac/symbol_enc.h
// Function: void writer<15, CompoundSymbolBitCoder<SimpleBitChance, RacDummy<DummyIO>, 15>>(CompoundSymbolBitCoder<SimpleBitChance, RacDummy<DummyIO>, 15>&, int, int, int)
void writer(SymbolCoder& coder, int min, int max, int value) {
    assert(min<=max);
    assert(value>=min);
    assert(value<=max);

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

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

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

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

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

    int i = 0; //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.write(i==e, BIT_EXP, i);
        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.write(bit, BIT_MANT, pos);
        }
        have |= (bit << pos);
    }
}

// Assembly:
subq $0x48, %rsp
movq %rdi, 0x40(%rsp)
movl %esi, 0x3c(%rsp)
movl %edx, 0x38(%rsp)
movl %ecx, 0x34(%rsp)
movl 0x3c(%rsp), %eax
cmpl 0x38(%rsp), %eax
jne 0x32e24
jmp 0x33015
cmpl $0x0, 0x34(%rsp)
jne 0x32e43
movq 0x40(%rsp), %rdi
movl $0x1, %esi
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x33020
jmp 0x33015
movq 0x40(%rsp), %rdi
xorl %ecx, %ecx
movl %ecx, %esi
movl %ecx, %edx
callq 0x33020
movl 0x34(%rsp), %edx
xorl %eax, %eax
movl $0x1, %ecx
cmpl $0x0, %edx
cmovgl %ecx, %eax
movl %eax, 0x30(%rsp)
cmpl $0x0, 0x38(%rsp)
jle 0x32e95
cmpl $0x0, 0x3c(%rsp)
jge 0x32e95
movq 0x40(%rsp), %rdi
cmpl $0x0, 0x30(%rsp)
setne %al
movzbl %al, %esi
andl $0x1, %esi
movl $0x1, %edx
xorl %ecx, %ecx
callq 0x33020
movl 0x34(%rsp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, 0x2c(%rsp)
movl 0x2c(%rsp), %edi
callq 0x1ebd0
movl %eax, 0x28(%rsp)
cmpl $0x0, 0x30(%rsp)
je 0x32ec9
movl 0x38(%rsp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, 0x4(%rsp)
jmp 0x32ed8
movl 0x3c(%rsp), %eax
movl %eax, %ecx
negl %ecx
cmovnsl %ecx, %eax
movl %eax, 0x4(%rsp)
movl 0x4(%rsp), %eax
movl %eax, 0x24(%rsp)
movl 0x24(%rsp), %edi
callq 0x1ebd0
movl %eax, 0x20(%rsp)
movl $0x0, 0x1c(%rsp)
movl 0x1c(%rsp), %eax
cmpl 0x20(%rsp), %eax
jge 0x32f52
movl 0x1c(%rsp), %ecx
addl $0x1, %ecx
movl $0x1, %eax
shll %cl, %eax
cmpl 0x24(%rsp), %eax
jle 0x32f15
jmp 0x32f52
movq 0x40(%rsp), %rdi
movl 0x1c(%rsp), %eax
cmpl 0x28(%rsp), %eax
sete %al
movl 0x1c(%rsp), %ecx
movzbl %al, %esi
andl $0x1, %esi
movl $0x2, %edx
callq 0x33020
movl 0x1c(%rsp), %eax
cmpl 0x28(%rsp), %eax
jne 0x32f45
jmp 0x32f52
movl 0x1c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x1c(%rsp)
jmp 0x32ef5
movl 0x28(%rsp), %ecx
movl $0x1, %eax
shll %cl, %eax
movl %eax, 0x18(%rsp)
movl 0x18(%rsp), %eax
subl $0x1, %eax
movl %eax, 0x14(%rsp)
movl 0x28(%rsp), %eax
movl %eax, 0x10(%rsp)
cmpl $0x0, 0x10(%rsp)
jle 0x33015
movl $0x1, 0xc(%rsp)
movl 0x10(%rsp), %ecx
addl $-0x1, %ecx
movl %ecx, 0x10(%rsp)
movl $0x1, %eax
shll %cl, %eax
xorl 0x14(%rsp), %eax
movl %eax, 0x14(%rsp)
movl 0x18(%rsp), %eax
movl 0x10(%rsp), %ecx
movl $0x1, %edx
shll %cl, %edx
movl %edx, %ecx
orl %ecx, %eax
movl %eax, 0x8(%rsp)
movl 0x8(%rsp), %eax
cmpl 0x24(%rsp), %eax
jle 0x32fcc
movl $0x0, 0xc(%rsp)
jmp 0x32ffe
movl 0x2c(%rsp), %eax
movl 0x10(%rsp), %ecx
sarl %cl, %eax
andl $0x1, %eax
movl %eax, 0xc(%rsp)
movq 0x40(%rsp), %rdi
cmpl $0x0, 0xc(%rsp)
setne %al
movl 0x10(%rsp), %ecx
movzbl %al, %esi
andl $0x1, %esi
movl $0x3, %edx
callq 0x33020
movl 0xc(%rsp), %eax
movl 0x10(%rsp), %ecx
shll %cl, %eax
orl 0x18(%rsp), %eax
movl %eax, 0x18(%rsp)
jmp 0x32f74
addq $0x48, %rsp
retq
nopw (%rax,%rax)